之前写了一篇随笔是讲 fabric.js 的,基于vue的,查看:https://www.cnblogs.com/reround/p/11468844.html
如果不基于vue用js也是可以实现的
代码如下,直接copy到html文件里就可以,无需加载其他插件,代码里都有注释
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>js画板</title>
<style>
* {
margin: 0;
padding: 0;
}
html,
body,
.container {
height: 100%;
}
#controls {
padding-left: 20px;
height: 60px;
line-height: 60px;
}
canvas {
border: 1px solid #ccc;
margin-left: 20px;
}
#controls li {
list-style: none;
display: inline-block;
margin-right: 10px;
}
#img{
width: 1000px;
height: 400px;
background: #eee;
display: inline-block;
margin-left: 20px;
}
.word{
margin: 10px 0 10px 20px;
}
</style>
</head>
<body>
<div class="container">
<ul id="controls">
<li>
<label for="shape" class="label">选择形状 : </label>
<select id="shape">
<option value="rect">矩形</option>
<option value="line">直线</option>
<!--<option value="circle">内切圆</option>-->
<option value="circle">圆</option>
<!--<option value="circle2">中心圆</option>-->
<option value="poly">多边形</option>
<option value="pen">铅笔</option>
<option value="eraser">橡皮擦</option>
</select>
</li>
<li>
<label for="color" class="label">选择颜色 : </label>
<input type="color" id="color" value="#ff0000">
</li>
<li>
<label for="color" class="label">选择线宽 : </label>
<input type="number" id="width" value="1" step="1" min="2" max="20">
</li>
<li>
<label for="shape" class="label">选择方式 : </label>
<select id="style">
<option value="stroke">描边</option>
<option value="fill">填充</option>
</select>
</li>
<li>
<label for="side" class="label">选择边数 : </label>
<input type="number" id="side" value="3" min="3" max="20">
</li>
<li>
<button id="redo">撤销</button>
<button id="clear">清空</button>
<button id="save">保存</button>
</li>
</ul>
<div class="word">canvas面板:</div>
<canvas width="1000px" height="400px"></canvas>
<div class="word">显示保存的图片:</div>
<img src="" id="img" alt="" />
</div>
<script>
var canvas = document.querySelector("canvas");
var canvasObj = canvas.getContext("2d");
var shape = document.querySelector("#shape");
var color = document.querySelector("#color");
var width = document.querySelector("#width");
var style = document.querySelector("#style");
var side = document.querySelector("#side");
var redo = document.querySelector("#redo");
var save = document.querySelector("#save");
var clear = document.querySelector("#clear");
var data = [];
var s = "rect";
shape.onchange = function() { //获取形状
s = this.value;
};
var c = "#f00";
color.onchange = function() { //获取颜色
c = this.value;
};
var w = "2";
width.onchange = function() { //获取宽度
w = this.value;
};
var st = "stroke";
style.onchange = function() { //获取绘画方式
st = this.value;
};
var sd = "3";
side.onchange = function() { //获取边数
sd = this.value;
};
canvas.onmousedown = function(e) { //canvas上按下鼠标事件
var ox = e.offsetX;
var oy = e.offsetY;
var draw = new Draw(canvasObj, {
color: c,
width: w,
style: st,
side: sd
});
if(s === "pen") {
canvasObj.beginPath();
canvasObj.moveTo(ox, oy);
}
canvas.onmousemove = function(e) { //移动事件
var mx = e.offsetX;
var my = e.offsetY;
if(s !== "eraser") {
canvasObj.clearRect(0, 0, 1000, 400);
if(data.length !== 0) {
canvasObj.putImageData(data[data.length - 1], 0, 0, 0, 0, 1000, 400); //将数据添加到画布中
}
}
draw[s](ox, oy, mx, my, sd);
};
document.onmouseup = function() {
data.push(canvasObj.getImageData(0, 0, 1000, 400)); //获取画布中的数据
canvas.onmousemove = null;
document.onmouseup = null;
}
};
redo.onclick = function() { //撤回
if(data.length == 0) {
alert("没有可以撤销的内容了");
return;
}
canvasObj.clearRect(0, 0, 1000, 400);
data.pop();
if(data.length == 0) {
return;
}
canvasObj.putImageData(data[data.length - 1], 0, 0, 0, 0, 1000, 400);
};
save.onclick = function() { //保存
var r = canvas.toDataURL();
document.getElementById('img').src = r
};
clear.onclick = function() { //清除
canvasObj.clearRect(0, 0, 1000, 400);
data = [];
}
class Draw {
constructor(canvasObj, option) {
this.canvasObj = canvasObj;
this.color = option.color;
this.width = option.width;
this.style = option.style;
}
init() { //初始化
this.canvasObj.strokeStyle = this.color;
this.canvasObj.fillStyle = this.color;
this.canvasObj.lineWidth = this.width;
}
rect(ox, oy, mx, my) {
this.init();
this.canvasObj.beginPath();
this.canvasObj.rect(ox, oy, mx - ox, my - oy);
this.canvasObj[this.style]();
}
line(ox, oy, mx, my) {
this.init();
this.canvasObj.beginPath();
this.canvasObj.moveTo(ox, oy);
this.canvasObj.lineTo(mx, my);
this.canvasObj.stroke();
}
circle(ox, oy, mx, my) { //圆
this.init();
this.canvasObj.beginPath();
var r = Math.sqrt(Math.pow(mx - ox, 2) + Math.pow(my - oy, 2));
this.canvasObj.arc(ox, oy, r, 0, 2 * Math.PI);
this.canvasObj[this.style]();
}
poly(ox, oy, mx, my, sd) {
this.init();
this.canvasObj.save();
canvasObj.translate(ox, oy);
this.canvasObj.rotate(Math.PI / 2);
var angle = Math.PI / sd;
var r = Math.sqrt(Math.pow(mx - ox, 2) + Math.pow(my - oy, 2));
var x = Math.cos(angle) * r;
var y = Math.sin(angle) * r;
this.canvasObj.beginPath();
this.canvasObj.moveTo(x, y);
for(var i = 0; i < sd; i++) {
this.canvasObj.lineTo(x, -y);
this.canvasObj.rotate(-angle * 2)
}
this.canvasObj[this.style]();
this.canvasObj.restore()
}
pen(ox, oy, mx, my) {
this.init();
this.canvasObj.lineTo(mx, my);
this.canvasObj.stroke();
}
eraser(ox, oy, mx, my) {
console.log(canvas.style)
console.log(canvas.style.cursor)
this.canvasObj.clearRect(mx, my, 20, 20);
}
}
</script>
</body>
</html>
