我正在参加「码上掘金挑战赛」详情请看:码上掘金挑战赛来了!
前言
大家好,我是小阵 🔥,一路奔波不停的码字业务员
如果喜欢我的文章,可以关注 ➕ 点赞,与我一同成长吧~😋
加我微信:zzz886885,邀你进群,一起学习交流,摸鱼学习两不误🌟
开开心心学技术大法~~
来了来了,他真的来了~
正文
实现思路
-
看到了画板就想到了canvas
-
可以看到我们需要捕捉
mousedown、mousemove与mouseup事件,mousedown的时候捕捉到当前的位置- 通过
moveTo来确定canvas的笔触起点 - 然后每次
mousemove的时候,捕捉到mousemove的每次当前位置 - 从上次的canvas的起点,通过canvas的
lineTo到当前mousemove的位置画上路径 - 然后再次触发
mousemove,将新的位置信息与老的作比较 - 老的位置作为canvas的
moveTo的起点,新的位置作为canvas的lineTo的终点划上路径 - 以此类推
- 通过
-
我们可以直接选择路径来绘制,也就是直接用
lintTo来绘制-
但是这里有个坑,如果我们的路径宽度
lineWidth比较小的时候,我们看上去是这样的可以看到是正常的,但是当
lineWidth比较大时可以看到已经出现了锯齿,当
lineWidth为20时所以我们需要另外绘制一些东西来补上这些锯齿部分
-
-
我们可以选择矩形、椭圆或圆形,联想到我们的画笔笔触一般都是圆形,所以使用
arc再画一条路径即可- 当然,因为
arc不能单独话路径,还需要通过fill来填充满颜色
- 当然,因为
-
主体内容就是上面了,通过
arc与moveTo、lineTo绘制完整的轨迹路径 -
接下来就是画笔粗细了,每次
+或者-的时候改变路径的lineWidth与arc的直径- 我这里用的是
lineWidth*2,与半径 - 可以根据你的需要来设置画笔的宽度
- 我这里用的是
- 颜色可以通过
input标签来实现,只需要设置type为color即可使用最原生的颜色选择器 - 然后最后次的清空画布用的就是
ctx.clearRect()方法
具体实现
基础html
<body>
<canvas id="canvas" width="800" height="700"></canvas>
<div class="toolbox">
<button id="decrease">-</button>
<span id="size">10</span>
<button id="increase">+</button>
<input type="color" id="color">
<button id="clear">X</button>
</div>
<script src="script.js"></script>
</body>
css样式
* {
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;
}
canvas逻辑
定义基础变量
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');
const ctx = canvas.getContext('2d');
let size = 10
let isPressed = false
colorEl.value = 'black'
let color = colorEl.value
let x
let y
创建canvas。这里的color与size后续都会随时变化,所以是全局变量
落笔
canvas.addEventListener('mousedown', (e) => {
isPressed = true
x = e.offsetX
y = e.offsetY
})
画笔移动
canvas.addEventListener('mousemove', (e) => {
if(isPressed) {
const x2 = e.offsetX
const y2 = e.offsetY
// 这里是画圆形与路径
drawCircle(x2, y2)
drawLine(x, y, x2, y2)
x = x2
y = y2
}
})
抬笔
document.addEventListener('mouseup', (e) => {
isPressed = false
x = undefined
y = undefined
})
绘制圆形与路径
function drawCircle(x, y) {
ctx.beginPath();
ctx.arc(x, y, size, 0, Math.PI * 2)
ctx.fillStyle = color
ctx.fill()
}
function drawLine(x1, y1, x2, y2) {
ctx.beginPath()
ctx.moveTo(x1, y1)
ctx.lineTo(x2, y2)
ctx.strokeStyle = color
ctx.lineWidth = size * 2
ctx.stroke()
}
注意圆形需要填充fill,而路径只需要画stroke即可。
调整画笔大小
function updateSizeOnScreen() {
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))
完整代码
总结
- 重点是canvas的使用
- 还有画笔的
arc与moveTo、lineTo的配合使用消除画笔锯齿 - 调整颜色的
input设置type为color也是一个小知识点
结语
如果文章真的有帮到你,希望可以多多点赞、收藏、关注支持一波呀!!小阵会很开心哒~
热爱开源,支持开源,拥抱开源!
文章如有错误或不严谨之处,还望指出,感谢感谢!!!
往期好文推荐