<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>canvas 实现画板</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
justify-items: flex-start;
}
.caidan {
height: 100px;
width: 100vw;
display: flex;
border-bottom: 3px solid #ccc;
justify-content: space-around;
align-items: center;
}
#canvas {
flex: 1;
width: 100vw;
}
.btn ,.btn1{
width: 150px;
height: 50px;
border: 1px solid #CCC;
border-radius: 20px;
text-align: center;
line-height: 50px;
color: #ccc;
}
.btn.active {
box-shadow: 0 0 20px deepskyblue;
border: 1px solid deepskyblue;
}
.btn1.active {
box-shadow: 0 0 20px deepskyblue;
border: 1px solid deepskyblue;
}
</style>
</head>
<body>
<div class="caidan">
<div class="btn" id="huabi">画笔</div>
<div class="btn" id="rect">矩形</div>
<div class="btn">圆形</div>
<div class="btn1 line xi active">细</div>
<div class="btn1 line normal">普通</div>
<div class="btn1 line cu">粗</div>
<!-- 颜色选择器 -->
<div class="btn1"><input type="color" name="color" id="color" value=""></div>
</div>
<canvas id="canvas"></canvas>
<!--画板的宽度,高度通过js来获取实时的-->
<script>
var allBtn = document.querySelectorAll('.btn')
var canvas = document.querySelector('#canvas')
var ctx = canvas.getContext('2d')
canvas.setAttribute('width', canvas.offsetWidth)
canvas.setAttribute('height', canvas.offsetHeight)
var huaban = {
type: 'none',
isDraw: false,
beginX: 0, //矩形描绘的开始位置
beginY: 0,
lineWidth:6,
imageData:null, //用于保存之前画板的内容
huabiFn: function (e) {
var x = e.pageX - canvas.offsetLeft
var y = e.pageY - canvas.offsetTop
ctx.lineWidth = huaban.lineWidth
ctx.lineCap = 'round'
ctx.lineJoin = 'round'
ctx.lineTo(x,y)
ctx.stroke()
},
rectFn: function (e) {
ctx.beginPath()
var x = e.pageX - canvas.offsetLeft
var y = e.pageY - canvas.offsetTop
ctx.clearRect(0, 0, canvas.offsetWidth, canvas.offsetHeight) //每一次清除画板的矩形
// 一开始是空的
if(huaban.imageData != null){
ctx.putImageData(huaban.imageData,0,0,0,0,canvas.offsetWidth, canvas.offsetHeight); //参数:内容、位置、数据位置、宽高
}
ctx.rect(huaban.beginX, huaban.beginY, x - huaban.beginX, y - huaban.beginY)
ctx.stroke()
ctx.closePath()
}
}
var huabiBtn = document.querySelector('#huabi')
huabiBtn.onclick = function () {
allBtn.forEach((item, index) => {
item.classList.remove('active')
})
huabiBtn.classList.add('active')
huaban.type = 'huabi'
}
// 监听鼠标按下事件
canvas.onmousedown = function (e) {
huaban.isDraw = true
if (huaban.type == 'rect') {
var x = e.pageX - canvas.offsetLeft
var y = e.pageY - canvas.offsetTop
huaban.beginX = x;
huaban.beginY = y;
}
if (huaban.type == 'huabi') {
var x = e.pageX - canvas.offsetLeft
var y = e.pageY - canvas.offsetTop
huaban.beginX = x;
huaban.beginY = y;
ctx.beginPath() //画笔操作的开始
ctx.moveTo(x,y) //移动到x,y的位置
}
}
// 监听鼠标抬起事件
canvas.onmouseup = function () {
huaban.isDraw = false
huaban.imageData = ctx.getImageData(0,0,canvas.offsetWidth,canvas.offsetHeight) //保存之前画板描绘的内容
if(huaban.type == 'huabi'){ //抬起关闭描绘
ctx.closePath()
}
}
canvas.onmousemove = function (e) {
if (huaban.isDraw) { //调用不同的函数执行按钮时间
huaban[huaban.type + 'Fn'](e)//调用对象里的函数
}
}
var rectBtn = document.querySelector('#rect')
rectBtn.onclick = function () {
allBtn.forEach((item, index) => {
item.classList.remove('active')
})
rectBtn.classList.add('active')
huaban.type = 'rect'
}
var lineDivs = document.querySelectorAll('.line')
lineDivs.forEach((item,i) =>{
item.onclick = function(){ //遍历清除所有按钮的样式
lineDivs.forEach((a,b)=>{
a.classList.remove('active')
})
item.classList.add("active")
if(i == 0) {
huaban.lineWidth = 6
}else if(i == 1){
huaban.lineWidth = 16
}else{
huaban.lineWidth = 32
}
}
})
</script>
</body>
</html>