So im trying to make a drawing app with two.js, im currently trying to implement a feature where you can change the width of a line by clicking in a button. I used useEffect hook to set up a variable that will determine the width of the line, then i will assign the line.linewdith with the variable in the drag function. Problem is that it doesnt update itself correctly and im not sure what the cause is
import React, { useRef, useEffect, useState, useLayoutEffect } from 'react'
import { Outlet, Link, Navigate } from "react-router-dom";
import Two from "two.js";
import './paintApp.css';
function PaintApp() {
///////////////////////////////////////////////////////////////////////////
const ref = useRef(null);
var el;
var two = new Two({
type: Two.Types.svg,
width: 900,
height: 500,
autostart: true
});
useEffect(() => {
el = ref.current;
two.appendTo(el)
}, []);
///////////////////////////////////////////////////////////////////////////
const [draw,setDraw] = useState(false);
function handleDraw(){
setDraw(current => !current)
console.log(draw)
}
//HERE IS THE USEEFFECT
var val;
useEffect(() => {
// Update line width when draw state changes
if (line) {
val = draw ? 10 : 0;
two.update();
}
}, [draw]);
///////////////////////////////////////////////////////////////////////////
var x, y, line, mouse = new Two.Vector();
window.addEventListener('mousedown', function(e) {
mouse.set(e.offsetX, e.offsetY);
line = null;
window.addEventListener('mousemove', drag, false);
window.addEventListener('mouseup', dragEnd, false);
}, false);
window.addEventListener('touchstart', function(e) {
e.preventDefault();
var touch = e.originalEvent.changedTouches[0];
mouse.set(touch.pageX, touch.pageY);
line = null;
window.addEventListener('touchmove', touchDrag, false);
window.addEventListener('touchend', touchEnd, false);
return false;
}, false);
two.bind('update', update);
function drag(e) {
x = e.offsetX;
y = e.offsetY;
//console.log(x, "and", y);
if (!line) {
var v1 = makePoint(mouse);
var v2 = makePoint(x, y);
line = two.makeCurve([v1, v2], true);
line.noFill().stroke = '#333';
//HERE IS THE LINE.LINEWIDTH
line.linewidth = val;
line.vertices.forEach(function(v) {
v.addSelf(line.translation);
});
line.translation.clear();
} else {
var v1 = makePoint(x, y);
line.vertices.push(v1);
}
mouse.set(x, y);
}
function dragEnd(e) {
window.removeEventListener('mousemove', drag, false);
window.removeEventListener('mouseup', dragEnd, false);
}
function touchDrag(e) {
e.preventDefault();
var touch = e.changedTouches[0];
drag({
clientX: touch.pageX,
clientY: touch.pageY
});
return false;
};
function touchEnd(e) {
e.preventDefault();
window.removeEventListener('touchmove', touchDrag, false);
window.removeEventListener('touchend', touchEnd, false);
return false;
}
function update(frameCount, timeDelta) {
for (var i = 0; i < two.scene.children.length; i++) {
//console.log(two.scene.children.length);
var child = two.scene.children[i];
for (var j = 0; j < child.vertices.length; j++) {
var v = child.vertices[j];
if (!v.position) {
return;
}
v.x = v.position.x;
v.y = v.position.y;
}
}
}
function makePoint(x, y) {
if (arguments.length <= 1) {
y = x.y;
x = x.x;
}
var v = new Two.Anchor(x, y);
v.position = new Two.Vector().copy(v);
return v;
}
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
return (
<div>
<div>paintApp</div>
<div><Link to='/application'>Back</Link></div>
<button onClick={handleDraw}>Erase</button>
<div ref={ref} id="picture">
</div>
</div>
)
}
export default PaintApp
i tried several solutions but it doesnt seem to work and the value wont change so if anyone can help then i would be really grateful.