Jump to content
Search Community

Draw square in canvas by animating lineTo, then shrink it

SammyC123 test
Moderator Tag

Go to solution Solved by OSUblake,

Recommended Posts

My task has two components.

 

First, I'm trying to draw a 800x800 pixel square in canvas via lineTo, but I'm not sure I understand how to use the onUpdate callback with lineTo to properly execute it. If I shift the y value, it skews the line rather continuing it. How would I achieve a point-to-point effect, as if you're drawing each side of the square consecutively? If someone could help me understand how to draw a straight line down after the initial horizontal line is drawn in the Codepen, I can probably take it from there.

 

My second issue, and one that seems easy once I get this figured out, is how do I then shrink that square to half its size (so 400x400)? Seems like I could use the same approach, but with each callback shrink the total line size (length and width) little by little until I end up at the appropriate size.

 

All thoughts and suggestions are greatly appreciated.

See the Pen wvJwRwm by codepenrequiredit (@codepenrequiredit) on CodePen

Link to comment
Share on other sites

Oh wow, both of those Codepens were a huge help. Thanks, Blake!

 

I'm a lot closer than I was, but I think I still have a long way to go. I've taken a different approach:

  • Centered canvas elements via translate so everything starts at 0,0
  • Drew in the lines using lineTo()
  • Faked the shrinking transition by drawing a rect on top of the lines, then clearing the lines, then shrinking the rect (probably not the best solution, but sufficient for now)
  • Lastly, I'm working toward making the canvas be responsive on resize while keeping the elements within it fixed in size

But there are a few things I'm still struggling with.

  1. When the rect comes in, it's seemingly a different stroke color than the lines... closer to light gray than white. Any idea why that is?
  2. I'm scratching my head trying to make the rect shrink from all sides equally to the center, rather than shrinking into the top left.
  3. Animating point5(via the function animateLineTopLeftOut) happens instantaneously and I don't quite understand why. I think it has to do with the fact that I need to animate both x and y properties, but it's unclear to me.

If you have any more wisdom to share, I'd greatly appreciate it. I don't want to keep leaning on you for answers, but you always make it look so easy on these forums. 😀

 

See the Pen eYvYdoJ?editors=0010 by codepenrequiredit (@codepenrequiredit) on CodePen

Edited by SammyC123
Clarity
Link to comment
Share on other sites

  • Solution
2 hours ago, SammyC123 said:

When the rect comes in, it's seemingly a different stroke color than the lines... closer to light gray than white.

 

Probably antialiasing. The stroke might not lie perfectly in the pixel grid. Kind of like here. The top box looks lighter with a thicker stroke. That's just nature of how graphics are displayed on a monitor.

 

See the Pen 03a55f0e37f66d5c9c85ef7a91e28705 by osublake (@osublake) on CodePen

 

If you click the translate 1/2 pixel checkbox here, you should see the line go from gray to black.

 

See the Pen 08be2488622766dc922010a69c5b40c8 by osublake (@osublake) on CodePen

 

The only way to really fix that is to move anything that has an odd stroke width 1, 3, 5, etc over 1/2 a pixel. It's probably not worth it if you're animating it as it won't look smooth.

 

So I'm not exactly sure what the end result is supposed to be, but I think a good first step would be to reorganize your code. Everything should be controlled by a single render/update function, and that function could draw stuff based on a simple scene graph like so...

 

See the Pen f5b7c30693a9555cbc598e56388b4b3c by osublake (@osublake) on CodePen

 

And with canvas, you can draw other canvases onto a canvas. This is useful if you want to combine different rendering techniques.

 

const canvas = document.querySelector("#canvas");
const ctx = canvas.getContext("2d");

const canvas2 = document.createElement("canvas");
const ctx2 = canvas2.getContext("2d");

...

// draw canvas2 on canvas
ctx.drawImage(canvas2);

 

That's how I do the filter effects in this.

 

See the Pen RLOzxo by osublake (@osublake) on CodePen

 

 

  • Thanks 1
Link to comment
Share on other sites

I'm truly blown away. The breadth and depth of information contained in your post is enough to save me weeks or months of headaches and Google / Stackoverflow research, and your examples are incredibly well structured and easy to follow.

 

I really can't thank you enough, @OSUblake. This is fantastic. You're one of the reasons GSAP is worth every penny.

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...