-1

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.

RadhoFan
  • 17
  • 2

1 Answers1

0

Instead of having val as a variable, try using useState to set the new width

For Ex:

const [val,setVal] = useState();
  useEffect(() => {
    // Update line width when draw state changes
    if (line) {
      setVal(draw ? 10 : 0)
      two.update();
    }
  }, [draw]);
CraZyDroiD
  • 6,622
  • 30
  • 95
  • 182