Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use canvas tags to draw smooth curves in html5

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article focuses on "how to use canvas tags in html5 to draw a smooth curve". Interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn how to draw a smooth curve using canvas tags in html5.

Background summary

I believe that everyone should have encountered such a requirement when learning canvas or using canvas in project development: to achieve a scribble drawing board gadget.

Well, I'm sure this can be done in just a few dozen lines of code for canvas's familiar children's shoes, and the following demo is a simple example:

Sketchpad demo canvas {border: 1px blue solid;} let isDown = false; let beginPoint = null; const canvas = document.querySelector ('# canvas'); const ctx = canvas.getContext ('2d'); / / set line color ctx.strokeStyle =' red'; ctx.lineWidth = 1; ctx.lineJoin = 'round' Ctx.lineCap = 'round'; canvas.addEventListener (' mousedown', down, false); canvas.addEventListener ('mousemove', move, false); canvas.addEventListener (' mouseup', up, false); canvas.addEventListener ('mouseout', up, false); function down (evt) {isDown = true; beginPoint = getPos (evt) } function move (evt) {if (! isDown) return; const endPoint = getPos (evt); drawLine (beginPoint, endPoint); beginPoint = endPoint;} function up (evt) {if (! isDown) return; const endPoint = getPos (evt); drawLine (beginPoint, endPoint) BeginPoint = null; isDown = false;} function getPos (evt) {return {x: evt.clientX, y: evt.clientY}} function drawLine (beginPoint, endPoint) {ctx.beginPath (); ctx.moveTo (beginPoint.x, beginPoint.y) Ctx.lineTo (endPoint.x, endPoint.y); ctx.stroke (); ctx.closePath ();}

Its implementation logic is also simple:

We listened to three main events on the canvas canvas: mousedown, mouseup, and mousemove, and we also created an isDown variable

The isDown is set to true when the user presses the mouse (mousedown) and to false when the mouse (mouseup) is lowered. The advantage of this is that you can judge whether the user is currently in a state of painting.

Continuously collect the coordinate points passed by the mouse through the mousemove event, and connect and draw the current point with the previous point through the lineTo method of canvas when and only if the isDown is true (that is, in the writing state).

Through the above steps, we can achieve the basic function of the drawing board, but things are not that simple. Careful children's shoes may find a serious problem-the lines drawn in this way are jagged and not smooth enough. and the faster you draw, the stronger the broken line. The performance is shown in the following figure:

What causes it?

Analysis of problems

The main reasons for this phenomenon are:

We connect the points by canvas's lineTo method, and the two adjacent points are connected by a straight line, not a curve, so what is drawn in this way is a broken line.

Limited by the frequency with which the browser collects mousemove events, we all know that in mousemove, the browser collects the current mouse coordinates at short intervals, so the faster the mouse moves, the farther the distance between the two nearby points, so the "broken line feeling is more obvious."

How can I draw a smooth curve?

In fact, there is a way to draw a smooth curve, lineTo is unreliable, then we can use another drawing API--quadraticCurveTo of canvas, which is used to draw quadratic Bezier curves.

Quadratic Bezier curve

QuadraticCurveTo (cp1x, cp1y, x, y)

Calling the quadraticCurveTo method requires four parameters, cp1x and cp1y describe the control points, and x and y are the end points of the curve:

For more detailed information, you can go to MDN

Since we are going to use Bezier curves, it is obvious that our data is not enough. To fully describe a quadratic Bezier curve, we need: starting point, control point and end point. How do these data come from?

There is an ingenious algorithm that can help us get this information.

An algorithm for obtaining Quadratic Bezier key points

This algorithm is not difficult to understand, so let me give you a direct example here:

Suppose we collect a total of six mouse coordinates in a painting, namely A, B, C, D, E, F; take the front A, B, C three points, calculate the midpoint B1 of B and C, take An as the starting point, B as the control point, B1 as the end point, use quadraticCurveTo to draw a quadratic Bezier curve segment

Next, the midpoint C1 of points C and D is calculated, and the curve is drawn with B1 as the starting point, C as the control point and C1 as the end point.

When the last point F is drawn, the midpoint D1 of D and E is taken as the starting point, E as the control point and F as the end point to end the Bezier curve.

OK, this is the algorithm, so let's upgrade the existing code based on the algorithm:

Let isDown = false;let points = []; let beginPoint = null;const canvas = document.querySelector ('# canvas'); const ctx = canvas.getContext ('2d'); / / set line color ctx.strokeStyle =' red';ctx.lineWidth = 1terctx.lineJoin = 'round';ctx.lineCap =' round';canvas.addEventListener ('mousedown', down, false); canvas.addEventListener (' mousemove', move, false); canvas.addEventListener ('mouseup', up, false); canvas.addEventListener (' mouseout', up, false) Function down (evt) {isDown = true; const {x, y} = getPos (evt); points.push ({x, y}); beginPoint = {x, y};} function move (evt) {if (! isDown) return; const {x, y} = getPos (evt); points.push ({x, y}); if (points.length > 3) {const lastTwoPoints = points.slice (- 2) Const controlPoint = lastTwoPoints [0]; const endPoint = {x: (lastTwoPoints [0] .x + lastTwoPoints [1] .x) / 2, y: (lastTwoPoints [0] .y + lastTwoPoints [1] .y) / 2,} drawLine (beginPoint, controlPoint, endPoint); beginPoint = endPoint;}} function up (evt) {if (! isDown) return Const {x, y} = getPos (evt); points.push ({x, y}); if (points.length > 3) {const lastTwoPoints = points.slice (- 2); const controlPoint = lastTwoPoints [0]; const endPoint = lastTwoPoints [1]; drawLine (beginPoint, controlPoint, endPoint);} beginPoint = null; isDown = false; points = [] } function getPos (evt) {return {x: evt.clientX, y: evt.clientY}} function drawLine (beginPoint, controlPoint, endPoint) {ctx.beginPath (); ctx.moveTo (beginPoint.x, beginPoint.y); ctx.quadraticCurveTo (controlPoint.x, controlPoint.y, endPoint.x, endPoint.y); ctx.stroke (); ctx.closePath ();}

On the basis of the original, we create a variable points to save the points passed by the mouse in the previous mousemove event. According to this algorithm, we know that it takes at least 3 points to draw a quadratic Bezier curve, so we start drawing only when the number of points in points is greater than 3. The next processing is the same as the algorithm, so I won't repeat it here.

At this point, I believe you have a deeper understanding of "how to use canvas tags in html5 to draw a smooth curve". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report