作用需求

新项目需求:必须完成一个能够随意撰写的小绘图工具

简易完成

针对了解canvas的同学们而言,这一需求非常简单,大概逻辑性以下:

1)监视恶性事件pointerdown,pointermove,pointerup

2)标识是不是拖动画线方式自变量 isDrawing,在down恶性事件时置为true,up的情况下置为false

3)应用canvas的api,设定线条款式,启用绘图线条插口lineTo方式

短短的几十行编码就能完成:

<!doctype html>
<html>

<head>
    <meta charset=utf-8>
    <style>
        canvas {
            border: 1px solid #ccc
        }

        body {
            margin: 0;
        }
    </style>
</head>

<body style="overflow: hidden;background-color: rgb(250, 250, 250);touch-action: none;">
    <canvas id="c" width="1920" height="1080"></canvas>
    <script>
        var el = document.getElementById('c');
        var ctx = el.getContext('2d');
        //设定绘图线条款式
        ctx.strokeStyle = 'red';
        ctx.lineWidth = 1;
        ctx.lineJoin = 'round';
        ctx.lineCap = 'round';
        var isDrawing;//标识是不是要绘图
        //储存座标点
        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();
        }
    </script>
</body>
</html>

完成实际效果如下图:

canvas小画板之平滑曲线的实现 平滑曲线 Canvas html5  第1张

之上就简易的完成了绘图工具作用,假如规定不太高的客户能够应用,但一旦碰到有点儿规定的客户就没法交货这类商品,细心看是线条曲线感太强。

怎么会有曲线感呢?

关键缘故:

大家启用的api方式 lineTo是二点联线也就是平行线

电脑浏览器对鼠标事件mousemove的收集是有收集頻率的,并并不是每一个电脑鼠标挪动历经的每一个像素数都是会开启恶性事件。

当鼠标挪动的越来越快,那麼两点之间的间距就越来越远,那麼曲线感就更显著。

canvas小画板之平滑曲线的实现 平滑曲线 Canvas html5  第2张

怎样能绘图光滑的曲线图?

canvas出示的api中是有现有插口的,贝塞尔系列产品的插口就能考虑大家的规定,接下去大家讲一下应用二次贝塞尔曲线绘图光滑曲线图。

quadraticCurveTo(cpx,cpy,x,y)

二次贝塞尔曲线插口必须四个主要参数,cpx,cpy是曲线图的基准点,x,y是曲线图终点站。

有些人问那曲线图的起始点在哪儿?实际上曲线图的起始点在于上一实际操作情况,能够是moveTo的部位,或是是lineTo的部位,或是是贝塞尔的终点站。

那麼如何启用quadraticCurveTo,主要参数如何传呢?

大家必须找到重要部位,立即用事例告知大伙儿吧

1)倘若大家用电脑鼠标收集到ABCDEF六个点

2)取前边三个点ABC测算,BC的圆心B1,以A为起始点,B为基准点,B1为终点站,那麼运用quadraticCurveTo能够绘图出那样一条贝塞尔曲线

canvas小画板之平滑曲线的实现 平滑曲线 Canvas html5  第3张

3)接下去测算CD的圆心C1,以B1为起始点,C为基准点,C1为终点站,那麼运用quadraticCurveTo能够绘图出那样一条贝塞尔曲线

canvas小画板之平滑曲线的实现 平滑曲线 Canvas html5  第4张

4)依此类推,当来到最终一个点时以D1为起始点,E为基准点,F为终点站,完毕贝塞尔绘图。

canvas小画板之平滑曲线的实现 平滑曲线 Canvas html5  第5张

依据优化算法开展编码更新改造

OK大家详细介绍了实际优化算法的危害,那用该优化算法对大家前边的编码开展更新改造:

<!doctype html>
<html>

<head>
    <meta charset=utf-8>
    <style>
        canvas {
            border: 1px solid #ccc
        }

        body {
            margin: 0;
        }
    </style>
</head>

<body style="overflow: hidden;background-color: rgb(250, 250, 250);touch-action: none;">
    <canvas id="c" width="1920" height="1080"></canvas>
    <script>
        var el = document.getElementById('c');
        var ctx = el.getContext('2d');
        //设定绘图线条款式
        ctx.strokeStyle = 'red';
        ctx.lineWidth = 1;
        ctx.lineJoin = 'round';
        ctx.lineCap = 'round';
        var isDrawing;//标识是不是要绘图
        //储存座标点
        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.length - 2].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);

        }
    </script>
</body>

</html>

在原来基本上大家用了一个数字能量数组points储存电脑鼠标历经的点,依据优化算法得知绘图贝塞尔曲线最少要用三个点,绘图全过程中维护保养points数字能量数组。

完成实际效果以下,由此可见光滑了许多 !

canvas小画板之平滑曲线的实现 平滑曲线 Canvas html5  第6张

事后文章内容:

完成水彩颜料实际效果,完成笔锋实际效果,画笔工具性能优化

到此这篇有关canvas小绘图工具之光滑曲线图的完成的文章内容就详细介绍到这了,大量有关canvas光滑曲线图內容请搜索之前的文章内容或再次访问下边的类似文章,期待大伙儿之后多多的适用!