Get the App
SLTechnology News&Howtos  ›  Development  › 

How to use canvas Sketchpad to smooth Curves in html5

Shulou Source: shulou.com Published: 2022-06-01 13:09:33 10月01日 Update

This article mainly introduces how to use canvas Sketchpad in html5 to achieve smooth curve, has a certain reference value, interested friends can refer to, I hope you can learn a lot after reading this article, the following let Xiaobian take you to understand.

Functional requirements

Project requirements: need to implement a small sketchboard that can be written freely

Simple implementation

For students who are familiar with canvas, this requirement is very simple, and the general logic is as follows:

1) listen for event pointerdown,pointermove,pointerup

2) whether to drag and drop the linework mode variable isDrawing, and set it to false when the down event is set to true,up

3) use the api of canvas to set the line style and call the lineTo method of drawing line interface

Just a few dozen lines of code can do this:

Canvas {border: 1px solid # ccc} body {margin: 0;} var el = document.getElementById ('c'); var ctx = el.getContext ('2d'); / / set line drawing style ctx.strokeStyle =' red'; ctx.lineWidth = 1; ctx.lineJoin = 'round' Ctx.lineCap = 'round'; var isDrawing;// tag whether to draw / / store coordinate points let lastX, lastY; document.body.onpointerdown = function (e) {console.log (' pointerdown'); isDrawing = true; lastX = e.clientX; lastY = e.clientY;} Document.body.onpointermove = function (e) {console.log ('pointermove'); if (isDrawing) {draw (e.clientX, e.clientY, lastX, lastY);} lastX = e.clientX, lastY = e.clientY;} Document.body.onpointerup = function (e) {if (isDrawing) {draw (e.clientX, e.clientY, lastX, lastY);} lastX = e.clientX, lastY = e.clientY; isDrawing = false;}; function draw (x, y, lastX, lastY) {ctx.beginPath () Ctx.moveTo (lastX, lastY); ctx.lineTo (x, y); ctx.stroke ();}

The implementation effect is as follows:

The above is a simple realization of the drawing board function, if the requirements of users can be used, but once encountered a little demand of users will not be able to deliver this product, look carefully is the line broken line feeling is too strong.

Why is there a sense of broken line?

Main reasons:

The api method lineTo that we call is a two-point line, that is, a straight line.

The browser collects the mouse event mousemove with a collection frequency, and not every pixel over which the mouse moves will trigger the event.

The faster the mouse moves, the farther the distance between the two points, and the more obvious the sense of broken lines.

How can I draw a smooth curve?

There are ready-made interfaces in the api provided by canvas, and the interfaces of Bezier series can meet our requirements. Next we will talk about using quadratic Bezier curves to draw smooth curves.

QuadraticCurveTo (cpx,cpy,x,y)

The interface of the quadratic Bezier curve requires four parameters, cpx,cpy is the control point of the curve, and x _ pencil y is the end point of the curve.

Some people ask where the curve starts. In fact, the starting point of the curve depends on the state of the previous operation, which can be the position of moveTo, or the position of lineTo, or the end of Bezier.

So how to call quadraticCurveTo and how to pass parameters?

We need to find out the key location and tell you directly with examples.

1) if we use the mouse to collect six points of ABCDEF

2) taking the ABC calculation of the first three points, the midpoint B1 of BC, with An as the starting point, B as the control point and B1 as the end point, then such a Bezier curve can be drawn by quadraticCurveTo.

3) then the midpoint C1 of CD is calculated, with B1 as the starting point, C as the control point and C1 as the end point, then such a Bezier curve can be drawn by quadraticCurveTo.

4) by analogy, when the last point is reached, the Bezier drawing is finished with D1 as the starting point, E as the control point and F as the end point.

Transform the code according to the algorithm

OK We introduced the impact of the specific algorithm, so use this algorithm to modify our previous code:

Canvas {border: 1px solid # ccc} body {margin: 0;} var el = document.getElementById ('c'); var ctx = el.getContext ('2d'); / / set line drawing style ctx.strokeStyle =' red'; ctx.lineWidth = 1; ctx.lineJoin = 'round' Ctx.lineCap = 'round'; var isDrawing;// tag whether to draw / / store coordinate points let points = []; document.body.onpointerdown = function (e) {console.log (' pointerdown'); isDrawing = true; points.push ({x: e.clientX, y: e.clientY});} Document.body.onpointermove = function (e) {console.log ('pointermove'); if (isDrawing) {draw (e.clientX, e.clientY);}}; document.body.onpointerup = function (e) {if (isDrawing) {draw (e.clientX, e.clientY) } points = []; isDrawing = false;}; function draw (mousex, mousey) {points.push ({x: mousex, y: mousey}); ctx.beginPath () Let x = (points [points.length-2] .x + points [points.length-1] .x) / 2, y = (points [points.length-2] .y + points [points.length-1] .y) / 2; if (points.length = = 2) {ctx.moveTo (points [points] .x, points [points.length-2] .y) Ctx.lineTo (x, y);} else {let lastX = (points [points.length-3] .x + points [points.length-2] .x) / 2, lastY = (points [points.length-3] .y + points [points.length-2] .y) / 2; ctx.moveTo (lastX, lastY) Ctx.quadraticCurveTo (points [points.length-2] .x, points [points.length-2] .y, x, y);} ctx.stroke (); points.slice (0,1) } Thank you for reading this article carefully. I hope the article "how to use canvas Sketchpad to achieve smooth Curves in html5" shared by the editor will be helpful to you. At the same time, I hope you will support us and pay attention to the industry information channel. More related knowledge is waiting for you to learn!

Tags: Curves Bezier Bezier lines end points start points smoothing artboards events interfaces control points articles mouse control code position broken lines marks styles algorithms Apple Docker Huawei Linux macOS MariaDB Microsoft MySQL NVidia OPPO Reno Shulou Information Huawei macOS NVidia Xiaomi