Maison  >  Article  >  interface Web  >  Comment dessiner des courbes douces à l'aide de Canvas (code)

Comment dessiner des courbes douces à l'aide de Canvas (code)

不言
不言avant
2018-10-15 13:55:214303parcourir

Le contenu de cet article explique comment utiliser le canevas pour dessiner des courbes douces ? (code). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

Résumé de base

Je pense que tout le monde aurait dû rencontrer un tel besoin en apprenant Canvas ou en utilisant Canvas dans le développement de projets : mettre en œuvre une petite planche à dessin qui peut être écrite outil.

Eh bien, je pense que cela peut être fait avec seulement quelques dizaines de lignes de code pour les enfants qui sont familiers avec Canvas. La démo suivante est un exemple simple :

nbsp;html>


    <title>Sketchpad demo</title>
    <style>
        canvas {
            border: 1px blue solid; 
        }
    </style>


    <canvas></canvas>
    <script>
        let isDown = false;
        let beginPoint = null;
        const canvas = document.querySelector(&#39;#canvas&#39;);
        const ctx = canvas.getContext(&#39;2d&#39;);

        // 设置线条颜色
        ctx.strokeStyle = &#39;red&#39;;
        ctx.lineWidth = 1;
        ctx.lineJoin = &#39;round&#39;;
        ctx.lineCap = &#39;round&#39;;

        canvas.addEventListener(&#39;mousedown&#39;, down, false);
        canvas.addEventListener(&#39;mousemove&#39;, move, false);
        canvas.addEventListener(&#39;mouseup&#39;, up, false);
        canvas.addEventListener(&#39;mouseout&#39;, 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();
        }
    </script>

Sa logique de mise en œuvre. est également très simple :

  1. Nous écoutons principalement trois événements sur le canevas : mousedown, mouseup et mousemove, et nous créons également une variable isDown ;

    Lorsque l'utilisateur appuie sur la souris (mousedown), définissez isDown sur true, et lorsque l'utilisateur pose la souris (mouseup), définissez-la sur false. Ceci est fait. L'avantage est que vous pouvez déterminer si le. l'utilisateur est actuellement dans l'état de dessin ;

  2. Collectez en continu les points de coordonnées traversés par la souris via l'événement mousemove, si et seulement si isDown est vrai (c'est-à-dire dans l'état d'écriture) Lors de la connexion et du dessin du point actuel avec le point précédent via la méthode lineTo du canevas

  3. 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. Des chaussures pour enfants prudentes peuvent rencontrer un problème très grave : les lignes ainsi tracées sont irrégulières et pas assez lisses, et plus vous dessinez vite, plus la sensation de pliage est forte. Les performances sont présentées dans la figure ci-dessous :

Comment dessiner des courbes douces à laide de Canvas (code)Pourquoi est-ce ?

Analyse du problème

Les principales raisons de ce phénomène sont :

Nous connectons les points en utilisant la méthode lineTo du canevas , reliant deux points adjacents est une ligne droite, pas une courbe, donc ce qui est dessiné de cette manière est une polyligne

  • Comment dessiner des courbes douces à laide de Canvas (code)
    Limité par la fréquence de collecte des événements mousemove par le navigateur, tout le monde sait que pendant le déplacement de la souris, le navigateur collecte les coordonnées de la souris actuelle à intervalles de temps courts, donc plus la souris se déplace rapidement, plus la distance est grande. entre les deux points adjacents collectés, plus la « sensation de ligne de rupture » est évidente


  • Comment tracer une courbe lisse ?

En fait, il existe des méthodes pour 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 de la méthode quadraticCurveTo nécessite quatre paramètres, cp1x, cp1y décrivent les points de contrôle, et x et y sont les points finaux de la courbe :

Des informations plus détaillées peuvent être trouvées sur MDNComment dessiner des courbes douces à laide de Canvas (code)Puisque vous souhaitez utiliser la courbe de Bézier , évidemment 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 informationsAlgorithme d'obtention des points clés quadratiques de Bézier

Cet algorithme n'est pas difficile à comprendre, ici je vais directement Donnons un exemple :

Supposons que nous collections un total de 6 coordonnées de souris dans un tableau, à savoir A, B, C, D, E, F

  1. Prenez les trois points précédents A, B et C et calculez le point médian B1 entre B et C. Avec A comme point de départ, B comme point de contrôle et B1 comme point final, utilisez quadraticCurveTo pour dessiner un segment de courbe de Searle


  2. Comment dessiner des courbes douces à laide de Canvas (code)
    Ensuite, calculez le centre ; des points C et D Point C1, continuez à tracer la courbe avec B1 comme point de départ, C comme point de contrôle et C1 comme point final ; >

  3. Le dessin continue par analogie Lorsqu'il atteint le dernier point F, 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.

    Comment dessiner des courbes douces à laide de Canvas (code)

OK,算法就是这样,那我们基于该算法再对现有代码进行一次升级改造:

let isDown = false;
let points = [];
let beginPoint = null;
const canvas = document.querySelector('#canvas');
const ctx = canvas.getContext('2d');

// 设置线条颜色
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;
    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();
}

在原有的基础上,我们创建了一个变量points用于保存之前mousemove事件中鼠标经过的点,根据该算法可知要绘制二次贝塞尔曲线起码需要3个点以上,因此我们只有在points中的点数大于3时才开始绘制。接下来的处理就跟该算法一毛一样了,这里不再赘述。

代码更新后我们的曲线也变得平滑了许多,如下图所示:

Comment dessiner des courbes douces à laide de Canvas (code)

本文到这里就结束了,希望大家在canvas画板中“画”得愉快~我们下次再见:)


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer