大家好,本篇文章,小编将和大家完成一个手写画板的示例,这个例子比较简单只能画简单的线条,并能调节线条的粗细和颜色,还有一个清除的功能,具体示例如下视频所示:
如视频所示,在这个示例中,我们用到了画布 canvas 相关的知识,比如创建画布、画圆形、
画直线的基础知识,有了这些基础后,我们就能轻松完成示例。
在 Html 文档中创建一个<canvas width="xx" height="xx">
的画布,然后使用document.getElementById('canvas')
方法获取画布,然后在调用 canvas.getContext('2d')
使用2D的模式渲染画布,接下来我们就可以在画布里进行画直线画圆操作了。
画一条直线,首先调用 beginPath() 绘制路径的起始点,使用 moveTo()移动画笔,然后再使用lineTo()连接子路径的终点到x,y坐标,最后调用 ctx.stroke() 设置样式的方法,就这样我们完成了画直线,相关示例代码如下:
ctx.beginPath(); ctx.moveTo(0,0); ctx.lineTo(100, 100); ctx.stroke();
CanvasRenderingContext2D.arc() 是 Canvas 2D API 绘制圆弧路径的方法。 圆弧路径的圆心在 (x, y) 位置,半径为 r ,根据 anticlockwise (默认为顺时针)指定的方向从 startAngle 开始绘制,到 endAngle 结束。具体语法如下所示:
void ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
示例代码如下所示:
// 获得元素对象 var canvas = document.querySelector('canvas'); // 获得对象ctx, 画笔 var ctx = canvas.getContext('2d'); // 绘制圆 ctx.arc(300, 200, 100, 0, Math.PI * 2); // 着色---填充颜色,整个图形都有颜色,另一种为描边,只是有线条的路径 // 设置填充颜色 ctx.fillStyle = 'orange'; // 填充 ctx.fill();
复习完基础知识后,我们开始编写具体的代码,HTML 结构比较简单,如视频示例所示,一个画布、两个增加线条粗细的加减按钮、一个显示粗细数值的文本、一个调整颜色的 HTML5 控件、一个清楚画布内容的按钮,由于代码比较简单,这里不过多解释,示例代码如下:
<canvasid="canvas"width="800"height="700"></canvas> <divclass="toolbox"> <buttonid="decrease">-</button> <spanid="size">10</span> <buttonid="increase">+</button> <inputtype="color"id="color"> <buttonid="clear">X</button> </div>
完成后的效果如下
接下来,我们来编写相关的CSS样式,代码很简单,这里只是简单说明下:
示例代码如下:
@importurl('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap'); * { box-sizing: border-box; } body { background-color: #f5f5f5; font-family: 'Roboto', sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; margin: 0; } canvas { border: 2px solid steelblue; } .toolbox{ background-color: steelblue; border: 1px solid slateblue; display: flex; width: 804px; padding: 1rem; } .toolbox> * { background-color: #fff; border: none; display: inline-flex; align-items: center; justify-content: center; font-size: 2rem; height: 50px; width: 50px; margin: 0.25rem; padding: 0.25rem; cursor: pointer; } .toolbox> *:last-child{ margin-left: auto; }
完成后的效果如下所示:
最后进入代码的核心部分,编写 JS 脚本,这里我们只是简单的实现画直线,为啥会用画圆形的API,主要为了让线条更加有手绘的感觉,在画线停顿的地方,有停顿的点,以线条的粗细为半径的原点。
具体的思路如下:
思路就聊到这里,下面给出脚本相关的代码,示例代码如下:
const canvas = document.getElementById('canvas'); const increaseBtn= document.getElementById('increase'); const decreaseBtn= document.getElementById('decrease'); const sizeEl=document.getElementById('size'); const colorEl=document.getElementById('color'); const clearEl=document.getElementById('clear'); constctx = canvas.getContext('2d'); let size = 10; let isPressed=false; colorEl.value='black'; let color = colorEl.value; let x; let y; canvas.addEventListener('mousedown', (e) => { isPressed =true x = e.offsetX y = e.offsetY }) canvas.addEventListener('mouseup',(e)=>{ isPressed=false; x=undefined; y=undefined; }); canvas.addEventListener('mousemove',(e)=>{ if(isPressed){ constx2 = e.offsetX; consty2 = e.offsetY; drawCircle(x2,y2); drawLine(x,y,x2,y2); x=x2; y=y2; } }); functiondrawCircle(x,y){ ctx.beginPath(); ctx.arc(x, y, size, 0, Math.PI * 2) ctx.fillStyle = color ctx.fill(); } functiondrawLine(x1,y1,x2,y2){ ctx.beginPath() ctx.moveTo(x1, y1) ctx.lineTo(x2, y2) ctx.strokeStyle = color; ctx.lineWidth = size * 2 ctx.stroke() } functionupdateSizeOnScreen(){ sizeEl.innerText = size; } increaseBtn.addEventListener('click',()=>{ size+=5; if(size>50){ size=50; } updateSizeOnScreen(); }); decreaseBtn.addEventListener('click',()=>{ size -= 5; if(size<5){ size=5; } updateSizeOnScreen(); }); colorEl.addEventListener('change',(e)=>color=e.target.value); clearEl.addEventListener('click',()=>ctx.clearRect(0,0,canvas.width,canvas.height));
好了,今天的项目就到这里结束了,想必大家都熟悉了如何手写一个简易的画布,基于这个基础我们可以增加更多图形形状的绘制,画布上图形的移动等多种功能,大家可以抽空完善下。
点击阅读原文,大家可以在线体验下交互效果(在PC端体验),如果想获取源码,请公众号回复 “a2” 获取本项目源码。
注:本文属于原创文章,版权属于「前端达人」公众号及 qianduandaren.com 所有,未经授权,谢绝一切形式的转载