Je pense que tout le monde aurait dû rencontrer un tel besoin en apprenant ou en utilisant Canvas dans le développement de projets : implémenter un gadget carnet de croquis qui peut être écrit.
Eh bien, je pense que pour les enfants qui sont plus familiers avec Canvas, cela peut être fait avec seulement quelques dizaines de lignes de code. La démo suivante est un exemple simple :
<!DOCTYPE html><html><head> <title>Démo de Sketchpad</title> <style type=text/css> canvas { border: 1px blue solid } </style></head><body> <canvas id=canvas width=800 height=500></canvas> <script type=text/javascript> let isDown = false; document.querySelector('#canvas'); const ctx = Canvas.getContext('2d'); // Définir la couleur de la ligne ctx.StrokeStyle = 'ctx.lineWidth = 1; .lineCap = 'round'; canvas.addEventListener('mousedown', down, false); move, false); canvas.addEventListener('mouseup', up, false); canvas.addEventListener('mouseout', up, false); function down(evt) { isDown = true; move(evt) { if (!isDown) return; const endPoint = getPos(evt); drawLine(beginPoint, endPointbeginPoint = endPoint } function; up(evt) { if (!isDown) return; const endPoint = getPos(evt); drawLine(beginPoint, endPoint); null isDown = false; y : evt.clientY } } function drawLine(beginPoint, endPoint) { ctx.beginPath(); ctx.moveTo(beginPoint.x, beginPoint.y); ctx.lineTo(endPoint.x, endPoint.y); ctx.closePath(); >
Sa logique de mise en œuvre est également très simple :
mousedown
, mouseup
et mousemove
, et nous créons également une variable isDown
;mousedown
), définissez isDown
sur true
, et lorsque l'utilisateur pose la souris ( mouseup
), définissez-la sur false
. L'avantage est qu'il peut déterminer si l'utilisateur est actuellement dans un état de dessin. ;mousemove
Si et seulement si isDown
est true
(c'est-à-dire dans l'état d'écriture), le point actuel sera connecté et dessiné avec le point précédent via la méthode lineTo
de l'objet. toile;Grâce aux étapes ci-dessus, nous pouvons réaliser la fonction de base de la planche à dessin. Cependant, les choses ne sont pas si simples. Si vous faites attention, les chaussures pour enfants peuvent rencontrer un problème très grave : les lignes ainsi tracées sont irrégulières et pas assez lisses, et vous serez plus rapide. dessinez, plus la sensation de lignes brisées sera forte. Les performances sont présentées ci-dessous :
Pourquoi cela se produit-il ? Analyse du problèmeLes principales raisons de ce phénomène sont :
Nous connectons les points en utilisant la méthode lineTo
du canevas. Ce qui relie deux points adjacents est une ligne droite, pas une courbe, donc ce qui est dessiné de cette manière est une polyligne ;
Limité par la fréquence de collecte des événements mousemove
par le navigateur, tout le monde sait que pendant mousemove
, le navigateur collecte les coordonnées de la souris actuelle à intervalles courts. Par conséquent, plus la souris se déplace rapidement, plus la distance entre les deux points adjacents collectés est éloignée. loin, plus le sens des lignes de pliage est évident ;
Il existe en fait des moyens de dessiner des courbes lisses. Si lineTo
n'est pas fiable, nous pouvons utiliser une autre API de dessin de canvas - quadraticCurveTo
, qui est utilisée pour dessiner des courbes de Bézier quadratiques.
courbe de Bézier quadratique
quadraticCurveTo(cp1x, cp1y, x, y)
L’appel quadraticCurveTo
nécessite quatre paramètres cp1x
et cp1y
décrivant les points de contrôle, tandis que x
et y
sont les points finaux de la courbe :
Des informations plus détaillées peuvent être trouvées sur MDN
Puisque nous voulons utiliser une courbe de Bézier, il est évident que nos données ne suffisent pas. Pour décrire complètement une courbe de Bézier quadratique, nous avons besoin de : point de départ, point de contrôle et point final. D'où viennent ces données ?
Il existe un algorithme très intelligent qui peut nous aider à obtenir ces informations
Algorithme d'obtention des points clés quadratiques de BézierCet algorithme n'est pas difficile à comprendre. Permettez-moi de donner un exemple directement :
Supposons que nous collections un total de 6 coordonnées de souris dans un tableau, à savoir A, B, C, D, E, F
; prenons les trois points précédents A, B, C
, calculons le milieu B1
de B
et C
et utilisons A
est le point de départ, B
est le point de contrôle B1
est le point final. Utilisez quadraticCurveTo
pour dessiner un segment de courbe de Bézier quadratique ;
Ensuite, calculez le point médian C1
entre les points C
et D
et continuez à tracer la courbe avec B1
comme point de départ, C
comme point de contrôle et C1
comme point final ;
Le dessin continue par analogie Lorsque le dernier point F
est atteint, la courbe de Bézier se termine par D1
, milieu de D
et E
, comme point de départ, E
comme point de contrôle et F
comme point final.
OK, l'algorithme est comme ceci, alors nous mettrons à jour le code existant en fonction de cet algorithme :
let isDown = false;let points = [];letbeginPoint = null;const canvas = document.querySelector('#canvas');const ctx = canvas.getContext('2d');//Définir la couleur de la ligne ctx.StrokeStyle = 'rouge';ctx.lineWidth = 1;ctx.lineJoin = 'rond';ctx.lineCap = 'rond';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}); startPoint = {x, y};}function move(evt) { if (!isDown) return; const { x, y} = getPos(evt); x, y}); if (points.length > 3) { const lastTwoPoints = points.slice(-2); const controlPoint = lastTwoPoints[0]; x : (lastTwoPoints[0].x + lastTwoPoints[1].x) / 2, y : (lastTwoPoints[0].y + lastTwoPoints[1].y) / 2, } drawLine(beginPoint, controlPoint, endPoint); startPoint = 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]; , controlPoint, endPoint); } startPoint = 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); y, endPoint.x, endPoint.y); ctx.AVC(); ctx.closePath();}
Sur la base de l'original, nous avons créé une variable points
pour enregistrer les points passés par la souris lors de l'événement mousemove
précédent. Selon cet algorithme, nous savons que dessiner une courbe de Bézier quadratique nécessite au moins 3 points, nous n'avons donc que les points. points en points
Le dessin ne démarre que lorsque le nombre de points est supérieur à 3. Le traitement ultérieur est exactement le même que cet algorithme, je n’entrerai donc pas dans les détails ici.
Après la mise à jour du code, notre courbe est devenue beaucoup plus lisse, comme le montre la figure ci-dessous :
Cet article se termine ici. J'espère que vous vous amuserez tous à dessiner sur toile ~ À la prochaine fois :)
Si vous êtes intéressé par les chaussures pour enfants, vous pouvez cliquer ici pour suivre mon blog. Tous les nouveaux articles intéressants seront partagés ici dès que possible~.
Ce qui précède représente l’intégralité du contenu de cet article. J’espère qu’il sera utile à l’étude de chacun. J’espère également que tout le monde soutiendra le réseau VeVb Wulin.