PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Wednesday, July 27, 2022

[FIXED] Why is ctx.strokeRect() behaving differently than sequential ctx.rect() ctx.stroke() calls

 July 27, 2022     canvas, crop, reactjs     No comments   

Issue

I created a React app using create-react-app. In this app, a user uploads a picture that is drawn to the canvas. This app allows the user to crop the image, and I'm trying to draw a rectangle preview of the cropped area as the user mouse-drags over the image.

Here is the function that draws the dynamic crop-area preview. This one works well because it is using ctx.strokeRect(). Every time the user moves the mouse, rectXY gets updated, and calls drawCropRect to clear the previous rectangle and make a new one.

    // draw rectangle preview of cropped area
  const drawCropRect = (
    canvasRef,
    rectXY,
    croppedCanvasData
  ) => {
    const canvas = canvasRef.current;
    const ctx = canvas.getContext("2d");
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.putImageData(croppedCanvasData,0,0, 0,0,canvas.width,canvas.height);
    ctx.strokeStyle = "#f6dd43";
    // calling strokeRect() - this works
    ctx.strokeRect(
      rectXY.xStart,
      rectXY.yStart,
      rectXY.xCurrent - rectXY.xStart,
      rectXY.yCurrent - rectXY.yStart
    );
  };

  // calls drawCropRect when the user is dragging the mouse to crop image 

  useEffect(() => {
    if (props.step === "crop") {
      drawCropRect(canvasRef, cropRect, croppedCanvasData[0]);
    }
  }, [cropRect]);
  // cropRect is a state hook containing starting and current mouse positions
// drawCropRect will get called every time cropRect updates.. so whenever the user moves the mouse during a crop event. 

However, if instead of calling ctx.strokeRect(), I called ctx.rect() and then ctx.stroke(), the rectangles are not cleared, and I see all of the rectangles generated on the image.

picture of many crop rectangles - but there should only be one!

Here is the same function but with calling separate ctx.rect() and ctx.stroke().

  // draw rectangle preview of cropped area
  const drawCropRect = (canvasRef, rectXY, croppedCanvasData) => {
    const canvas = canvasRef.current;
    const ctx = canvas.getContext("2d");
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.putImageData(
      croppedCanvasData,
      0,
      0,
      0,
      0,
      canvas.width,
      canvas.height
    );
    ctx.strokeStyle = "#f6dd43";
    // calling rect() and then stroke()- this does not work
    ctx.rect(
      rectXY.xStart,
      rectXY.yStart,
      rectXY.xCurrent - rectXY.xStart,
      rectXY.yCurrent - rectXY.yStart
    );
    ctx.stroke();
  };

Why is this happening? How does calling separate ctx.rect() and ctx.stroke() prevent them from being cleared when the user moves the mouse?


Solution

Try using ctx.beginPath() at the start of the rect() section of drawCropRect().

If you don't use ctx.beginPath() it throws off the canvas.

Hope this helps!



Answered By - Ameer
Answer Checked By - Willingham (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing