前言
本文主要介绍如何通过鼠标点击绘制任意多边形,以及通过鼠标移动改变多边形的形状
一、通用代码封装
class Point {
constructor(opts = {}) {
this.x = opts.x || 0;
this.y = opts.y || 0;
}
}
const CanvasUtils = {
// 获取在dom元素上点击的坐标
getPointOnEle(e) {
e = e || window.event;
return new Point({
x: e.offsetX,
y: e.offsetY
});
},
}
二、canvas类的封装
1.定义类
class CanvasServer {
constructor(opts) {
// 画布
this.canvas = null;
// 画布上下文
this.ctx = null;
// 存放绘制的点
this.pointList = [];
// 圆点的定义
this.arcInfo = {
radius : 8,
curPointColor : '#ff0000',
pointColor : 'blue'
}
// 当前点是否存在
this.isPointExist = false;
// 当前移动点的坐标
this.curMovePoint = {};
// 当前移动点的下标
this.curMovePointIndex = 0;
// 初始化canvas
this._init(opts);
// 初始化鼠标事件
this._initCanvasEvent();
}
...
global.CanvasServer = CanvasServer;
})(this);
2.初始化
_init(opts){
this.canvas = opts.canvas;
this.canvas.width = opts.width;
this.canvas.height = opts.height;
this.ctx = this.canvas.getContext(`2d`);
}
3.初始化鼠标事件
_initCanvasEvent(){
EventUtil.addHandler(this.canvas, `mousedown`, this._handleMouseDown, this);
EventUtil.addHandler(this.canvas, `mousemove`, this._handleMouseMove, this);
EventUtil.addHandler(this.canvas, `mouseup`, this._handleMouseUp, this);
}
3.鼠标事件处理
// 鼠标按下
_handleMouseDown(e){
e = e || window.event;
const point = CanvasUtils.getPointOnEle(e, this.canvas);
for(let index = 0 ; index < this.pointList.length ; index++){
let item = this.pointList[index];
if (Math.abs(item.x - point.x) < this.arcInfo.radius && Math.abs(item.y - point.y) < this.arcInfo.radius) {
this.isPointExist = true;
this.curMovePoint = item;
this.curMovePointIndex = index;
return;
}
}
this.isPointExist = false;
this.pointList.push(point);
this._drawPolygon();
this._drawKeyPoints();
}
// 鼠标移动
_handleMouseMove(e){
// 如果没有选中关键点,则直接返回
if(!this.isPointExist){
return;
}
e = e || window.event;
const point = CanvasUtils.getPointOnEle(e, this.canvas);
this.pointList.splice(this.curMovePointIndex,1,point);
this._drawPolygon();
this._drawKeyPoints();
}
// 鼠标按起
_handleMouseUp(e){
this.isPointExist = false;
this.curMovePoint = {};
this.curMovePointIndex = 0;
}
4.绘制多边形及顶点
// 绘制多边形
_drawPolygon(){
this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);
this.ctx.strokeStyle = '#000';
this.ctx.beginPath();
this.ctx.moveTo(this.pointList[0].x,this.pointList[0].y);
for(var i=1;i<this.pointList.length;i++) {
this.ctx.lineTo(this.pointList[i].x,this.pointList[i].y);
}
this.ctx.closePath();
this.ctx.stroke();
}
// 绘制鼠标点击的关键点
_drawKeyPoints(){
if(this.pointList.length === 0){
return;
}
let pointList = this.pointList.slice(0);
// 如果是移动关键点,则点绘制统一的颜色
if(!this.isPointExist){
let curPoint = pointList.pop();
// 绘制当前点
this._drawArc(curPoint.x,curPoint.y,this.arcInfo.curPointColor);
}
pointList.forEach(item => {
this._drawArc(item.x,item.y,this.arcInfo.pointColor);
});
}
// 绘图圆点
_drawArc(x,y,color){
this.ctx.beginPath();
this.ctx.fillStyle = color;
this.ctx.arc(x,y,this.arcInfo.radius,0,2 * Math.PI, false);
this.ctx.fill();
this.ctx.closePath();
}
5.调用方式
<canvas id="myCanvas"></canvas>
<script type="text/javascript">
window.onload = function() {
drawCanvas();
}
function drawCanvas() {
var canvas = document.getElementById("myCanvas");
canvas.width = document.body.clientWidth;
canvas.height = document.body.clientHeight;
var width = document.body.clientWidth;
var height = document.body.clientHeight;
new CanvasServer({
canvas,
width,
height,
});
}
</script>
效果图