作用要求
新项目要求:必须完成一个能够随意撰写的小画板
简易完成
针对了解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>
完成实际效果以下图:
之上就简易的完成了画板作用,假如规定不太高的客户可使用,但一旦碰到有点儿规定的客户就没法交货这类商品,细心看是线框折线感过强。
为何会出现折线感呢?
关键缘故:
大家启用的api方式lineTo是二点联线也便是平行线
访问器对电脑鼠标恶性事件mousemove的收集是有收集頻率的,其实不是每一个电脑鼠标移动历经的每个清晰度点都是开启恶性事件。
当电脑鼠标移动的越来越快,那麼二点中间的间距就会越远,那麼折线感就更显著。
怎样能绘图光滑的曲线图?
canvas出示的api中是有现有插口的,贝塞尔系列产品的插口就可以考虑大家的规定,接下去大家讲一下应用二次贝塞尔曲线图绘图光滑曲线图。
quadraticCurveTo(cpx,cpy,x,y)
二次贝塞尔曲线图插口必须四个主要参数,cpx,cpy是曲线图的操纵点,x,y是曲线图终点站。
有些人问那曲线图的起始点在哪儿里?实际上曲线图的起始点在于上一实际操作情况,能够是moveTo的部位,或是是lineTo的部位,或是是贝塞尔的终点站。
那麼如何启用quadraticCurveTo,主要参数如何传呢?
大家必须找到重要部位,立即测试用例子告知大伙儿吧
1)倘若大家用电脑鼠标收集到ABCDEF六个点
2)取前边三个点ABC测算,BC的中点B1,以A为起始点,B为操纵点,B1为终点站,那麼运用quadraticCurveTo能够绘图出那样一条贝塞尔曲线图
3)接下去测算CD的中点C1,以B1为起始点,C为操纵点,C1为终点站,那麼运用quadraticCurveTo能够绘图出那样一条贝塞尔曲线图
4)为此类推,当来到最终一个点时以D1为起始点,E为操纵点,F为终点站,完毕贝塞尔绘图。
依据优化算法开展编码更新改造
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光滑曲线图內容请检索脚本制作之家之前的文章内容或再次访问下边的有关文章内容,期待大伙儿之后多多的适用脚本制作之家!