//一个简单的画板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>putImageData</title>
<style>
body,
html {
margin: 0;
padding: 0;
}
#myCanvas {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.tools {
position: fixed;
top: 0;
right: 0;
left: 0;
padding: 15px 10px;
font-size: 0;
background: #1a1a1a;
z-index: 1;
}
.tool {
display: inline-block;
font-size: 12px;
background: #eee;
padding: 5px;
cursor: pointer;
vertical-align: middle;
/* width: 40px; */
text-align: center;
}
.tool+.tool {
margin-left: 5px;
}
</style>
</head>
<body>
<div class="tools">
<div class="tool" οnclick="selToolClick('line')">线</div>
<div class="tool" οnclick="selToolClick('rect')">矩形</div>
<div class="tool" οnclick="selToolClick('circle')">圆</div>
<div class="tool" οnclick="selToolClick('ellipse')">椭圆</div>
<div class="tool" οnclick="selToolClick('cloud')">云线</div>
<div class="tool" οnclick="selToolClick('polygon')">多边形</div>
<div class="tool" οnclick="exportImgData()">导出图片</div>
</div>
<canvas id="myCanvas">
</canvas>
<script>
function coord(startPoint, endPoint) {
return {
a: endPoint.x - startPoint.x, //x的差
b: endPoint.y - startPoint.y, //y的差
c: Math.sqrt(Math.pow(endPoint.x - startPoint.x, 2) + Math.pow(endPoint.y - startPoint.y, 2)), //两点间的距离
k: Math.atan2(endPoint.y - startPoint.y, endPoint.x - startPoint.x) //斜率
};
}
function polar(p, k) {
// p 长度
// k 角度, 斜率
return {
x: p * Math.cos(k),
y: p * Math.sin(k)
};
}
class baseTool {
constructor(ctx) {
this.canvasContext = ctx;
this.startPoint = {};
this.endPoint = {}
this.points = []
}
setCanvasStyle() {
this.canvasContext.lineWidth = 2;
this.canvasContext.strokeStyle = "blue";
this.canvasContext.fillStyle = "blue";
}
drawGraph() {
}
}
class lineTool extends baseTool {
constructor(ctx) {
super(ctx);
}
drawGraph() {
this.setCanvasStyle();
this.canvasContext.beginPath();
this.canvasContext.moveTo(this.startPoint.x, this.startPoint.y);
this.canvasContext.lineTo(this.endPoint.x, this.endPoint.y);
this.canvasContext.stroke();
}
}
class rectTool extends baseTool {
constructor(ctx) {
super(ctx);
}
drawGraph() {
this.setCanvasStyle();
this.canvasContext.beginPath();
this.canvasContext.rect(this.startPoint.x, this.startPoint.y, this.endPoint.x - this.startPoint.x, this.endPoint.y - this.startPoint.y);
this.canvasContext.stroke();
}
}
class circleTool extends baseTool {
constructor(ctx) {
super(ctx);
}
drawGraph() {
this.setCanvasStyle();
let _x = this.startPoint.x - this.endPoint.x;
let _y = this.startPoint.y - this.endPoint.y;
let r = Math.sqrt(_x * _x + _y * _y);
this.canvasContext.beginPath();
this.canvasContext.arc(this.startPoint.x, this.startPoint.y, 1, 0, 2 * Math.PI);
this.canvasContext.stroke();
this.canvasContext.beginPath();
this.canvasContext.arc(this.startPoint.x, this.startPoint.y, r, 0, 2 * Math.PI);
this.canvasContext.stroke();
}
}
class ellipseTool extends baseTool {
constructor(ctx) {
super(ctx);
}
drawGraph() {
this.setCanvasStyle();
this.canvasContext.beginPath();
//椭圆圆心坐标
//圆心点
let _x = (this.endPoint.x + this.startPoint.x) / 2;
let _y = (this.endPoint.y + this.startPoint.y) / 2
//
let radiusX = Math.abs((this.startPoint.x - this.endPoint.x) / 2);
let radiusY = Math.abs((this.startPoint.y - this.endPoint.y) / 2);
this.canvasContext.ellipse(_x, _y, radiusX, radiusY, 0, 0, 2 * Math.PI);
this.canvasContext.stroke();
// this.canvasContext.fill();
}
}
class polygonTool extends baseTool {
constructor(ctx) {
super(ctx);
this.isCloseGraph = false;
this.cloudRadiusMin = 20;
this.cloudRadiusMax = 30;
}
get allPoints() {
let points = [];
points.push(this.startPoint);
points = points.concat(this.points);
points.push(this.endPoint);
return points
}
set allPoints(val) {
}
drawGraph() {
this.setCanvasStyle();
this.canvasContext.beginPath();
this.canvasContext.moveTo(this.startPoint.x, this.startPoint.y);
for (let i = 0; i < this.points.length; i++) {
var point = { ...this.points[i] }
this.canvasContext.lineTo(point.x, point.y);
}
this.canvasContext.lineTo(this.endPoint.x, this.endPoint.y);
this.canvasContext.stroke();
}
}
class cloudTool extends polygonTool {
constructor(ctx) {
super(ctx);
}
drawGraph() {
this.setCanvasStyle();
for (let i = 0; i < this.allPoints.length - 1; i++) {
const CPoint = this.allPoints[i];
const NPoint = this.allPoints[i + 1];
const c = coord(CPoint, NPoint).c;//俩点之间的距离
const k = coord(CPoint, NPoint).k;//俩点之间的斜率
let tmpPoints = [];//俩点之间的分割点集
let tmpPoints2 = []; let index = 0;
index = index + 1;
tmpPoints.push({ ...CPoint })
for (let j = 0; j < Math.round((c + this.cloudRadiusMin / 2) / this.cloudRadiusMin); j++) {
let newPoint = {
x: this.cloudRadiusMin * Math.cos(k) + tmpPoints[index - 1].x,
y: this.cloudRadiusMin * Math.sin(k) + tmpPoints[index - 1].y
}
tmpPoints.push({ ...newPoint });
index = index + 1;
}
for (let n = 0; n < tmpPoints.length; n++) {
var point = {
x: tmpPoints[n].x - polar(this.cloudRadiusMin / 2, k).x,
y: tmpPoints[n].y - polar(this.cloudRadiusMin / 2, k).y
};
tmpPoints2.push(point)
}
for (let m = 0; m < tmpPoints2.length - 1; m++) {
const tp = tmpPoints2[m];
var c1 = coord(tmpPoints2[m], tmpPoints2[m + 1]).c;//俩点之间的距离
var x1 = polar(c1 / 2, k).x + tmpPoints2[m].x;
var y1 = polar(c1 / 2, k).y + tmpPoints2[m].y;
let r1 = c1 / 2 / Math.cos(30 / 180 * Math.PI);
var distance = coord({ x: x1, y: y1 }, NPoint).c;
var distanceHalf = distance / 2;
if (m == tmpPoints2.length - 1) {
this.canvasContext.beginPath();
this.canvasContext.arc(x1, y1, r1, k, k + Math.PI * 7 / 6, true);
this.canvasContext.stroke();
} else {
this.canvasContext.beginPath();
this.canvasContext.arc(x1, y1, r1, k, k + Math.PI * 7 / 6, true);
this.canvasContext.stroke();
}
}
}
}
isNearStartPoint() {
}
}
class Print {
constructor(id) {
this.id = id;
this.canvas = null;
this.ctx = null;
this.canvasGraph = null;
this.canvasGraphContext = null;
this.canvasMedia = null;
this.canvasMediaContext = null;
this.tool = null;
this.tools = [];//所有的数据
this.toolName = null;
this.viewStyle = {};
this.mouse = {
down: {
x: null, y: null
},
move: {
x: null, y: null
},
up: {
x: null, y: null
},
isMove: false
}
this.init();
this.bindEvent();
}
init() {
var height = document.documentElement.clientHeight;
var width = document.documentElement.clientWidth;
this.viewStyle.height = height;
this.viewStyle.width = width;
this.canvas = document.getElementById(this.id);
this.canvas.width = width;
this.canvas.height = height;
this.ctx = this.canvas.getContext('2d');
}
saveData() {
this.tools.push(this.tool);
}
newGraph() {
this.setTool();
this.tool.startPoint = { ...this.mouse.down };
this.saveData();
}
update() {
this.clear();
this.draw();
}
draw() {
this.tools.forEach(d => {
d.drawGraph()
})
}
clear() {
this.ctx.clearRect(0, 0, this.viewStyle.width, this.viewStyle.height);
}
bindEvent() {
this.onEvent();
}
createImgData() {
// this.canvas.toDataURL('image/jpeg', 0.99);
this.canvas.toBlob(function (blob) {
var link = document.getElementById('downMyCavans');
if (!link) {
link = document.createElement('a');
document.body.appendChild(link);
}
var url = URL.createObjectURL(blob);
link.href = url;
link.download = Math.floor(Math.random() * 10000000) + "Download.jpg";
link.click();
URL.revokeObjectURL(url);
}, 'image/jpeg', 0.99);
}
selTool(toolName) {
this.toolName = toolName;
}
setTool() {
switch (this.toolName) {
case 'line':
this.tool = new lineTool(this.ctx);
break;
case 'rect':
this.tool = new rectTool(this.ctx);
break;
case 'circle':
this.tool = new circleTool(this.ctx);
break;
case 'ellipse':
this.tool = new ellipseTool(this.ctx);
break;
case 'cloud':
this.tool = new cloudTool(this.ctx);
break;
case 'polygon':
this.tool = new polygonTool(this.ctx);
break;
default:
break;
}
}
onEvent() {
this.canvas.onmousedown = (e) => {
this.mouseDown(e);
}
this.canvas.onmouseup = (e) => {
this.mouseUp(e);
}
this.canvas.onmousemove = (e) => {
this.mouseMove(e);
}
this.canvas.ondblclick = (e) => {
this.dblClick(e);
}
}
offEvent() {
this.canvas.onmousedown = null;
this.canvas.onmouseup = null;
this.canvas.onmousemove = null;
}
mouseDown(e) {
this.mouse.isMove = true;
let x = e.x, y = e.y;
let point = { x: x, y: y };
this.mouse.down = { x: x, y: y };
if (['cloud', 'polygon'].indexOf(this.toolName) >= 0) {
if (this.tool && !this.tool.isCloseGraph) {
this.tool.points.push({ ...this.mouse.down });
return true;
}
}
this.newGraph();
}
mouseMove(e) {
if (this.mouse.isMove) {
let x = e.x, y = e.y;
let point = { x: x, y: y };
this.mouse.move = { x: x, y: y };
this.tool.endPoint = { ...this.mouse.move }
this.update();
}
}
mouseUp(e) {
if (['cloud', 'polygon'].indexOf(this.toolName) >= 0) {
let x = e.x, y = e.y;
let point = { x: x, y: y };
this.mouse.up = { x: x, y: y };
} else {
this.mouse.isMove = false;
}
}
clearMouse() {
this.mouse = {
down: {
x: null, y: null
},
move: {
x: null, y: null
},
up: {
x: null, y: null
},
isMove: false
}
}
dblClick(e) {
if (['cloud', 'polygon'].indexOf(this.toolName) >= 0) {
//结束
let point = { ...this.tool.startPoint }
const { x, y } = point;
if (this.tool) {
this.tool.isCloseGraph = true;
this.tool.endPoint = { x, y };
}
this.clearMouse();
this.update();
}
}
}
let canvas = new Print('myCanvas');
function selToolClick(toolName) {
canvas.selTool(toolName);
}
function exportImgData() {
canvas.createImgData()
}
</script>
</body>
</html>