第一个版本,只是单纯用来画多边形的,而且只能画一个。
<template>
<div class="main">
<div>这纷纷飞花,这纷纷飞花已坠落</div>
<div>
<canvas
id="mycanvas"
ref="mycanvas"
width="700"
height="450"
@mousedown="canvasDown($event)"
@mousemove="canvasMove($event)"
@dblclick="doubleclick()"></canvas>
</div>
</div>
</template>
<script>
export default {
data() {
return {
isdraw: false,
context: null,
coordinates: [],
};
},
methods: {
initDraw() {
const canvas = document.querySelector("#mycanvas");
this.context = canvas.getContext("2d");
this.context.strokeStyle='blue';
},
canvasDown(e) {
var x = e.offsetX;
var y = e.offsetY;
this.coordinates.push({cor_x:x,cor_y:y});
this.isdraw = true;
},
drawline(){
for(var i=0; i<this.coordinates.length-1; i++){
this.context.beginPath();
var x0 = this.coordinates[i].cor_x;
var y0 = this.coordinates[i].cor_y;
var x1 = this.coordinates[i+1].cor_x;
var y1 = this.coordinates[i+1].cor_y;
this.context.moveTo(x0, y0);
this.context.lineTo(x1, y1);
this.context.stroke();
this.context.closePath();
}
},
canvasMove(e){
if(this.coordinates.length == 0){
return 0;
}
if(this.isdraw == false){
return 0;
}
var last_x = this.coordinates[this.coordinates.length-1].cor_x;
var last_y = this.coordinates[this.coordinates.length-1].cor_y;
this.context.clearRect(0,0,700,450);
this.drawline();
this.context.beginPath();
this.context.moveTo(last_x,last_y);
var x = e.offsetX;
var y = e.offsetY;
this.context.lineTo(x,y);
this.context.stroke();
this.context.closePath();
},
doubleclick(){
var x0 = this.coordinates[0].cor_x;
var y0 = this.coordinates[0].cor_y;
var x1 = this.coordinates[this.coordinates.length-1].cor_x;
var y1 = this.coordinates[this.coordinates.length-1].cor_y;
this.context.beginPath();
this.context.moveTo(x0,y0);
this.context.lineTo(x1,y1);
this.context.stroke();
this.context.closePath();
this.isdraw = false
}
},
mounted() {
this.initDraw()
},
beforeDestroy() {},
};
</script>
<style scoped>
.main {
height: 90vh;
color: black;
background: white;
}
#mycanvas {
border: 1px solid red;
}
</style>
下面是第二个版本,添加了很多效果,自行体会。
<template>
<div class="main">
<div>绘制多边形,单击开始,双击结束。支持多个</div>
<div>
<button @click="test">清空</button>
</div>
<div>
<img src="../assets/gate.jpg" id="img">
<canvas
id="mycanvas"
ref="mycanvas"
width="700"
height="450"
@mousedown="canvasDown($event)"
@mousemove="canvasMove($event)"
@mouseup="canvasUp($event)"
@dblclick="doubleclick()">浏览器不持之canvas</canvas>
</div>
</div>
</template>
<script>
export default {
data() {
return {
isdraw: false, //是否在画图形
ctx: null, //canvas对象
coordinates: [], //一个多边形的坐标信息
cor_index: 0, //当前多边形的索引
endtip: false, //是否结束一个多边形的绘制
all_coordinates: [], //所有多边形的信息
isdrag: false,
drag_index: [-1,-1],
img: ""
};
},
methods: {
test(){
this.all_coordinates = [];
this.coordinates = []
this.isdraw = false;
this.endtip = false;
this.ctx.clearRect(0,0,700,450);
},
fillarea(){
this.ctx.fillStyle = 'rgba(0, 195, 155,0.4)';
for(var i=0;i<this.all_coordinates.length;i++){
var cors = this.all_coordinates[i];
var x0 = cors[0].cor_x;
var y0 = cors[0].cor_y;
this.ctx.beginPath();
this.ctx.moveTo(x0,y0);
for(var j=1;j<cors.length;j++){
var x = cors[j].cor_x;
var y = cors[j].cor_y;
this.ctx.lineTo(x,y);
}
this.ctx.fill();
this.ctx.closePath();
}
},
initDraw() { //初始化画布对象
const canvas = document.querySelector("#mycanvas");
this.ctx = canvas.getContext("2d");
this.ctx.strokeStyle = 'rgb(0, 195, 155)';
},
isdragpoint(x,y){
if(this.all_coordinates.length == 0){
return false;
}
for(var i=0;i<this.all_coordinates.length;i++){
for(var j=0;j<this.all_coordinates[i].length;j++){
var px = this.all_coordinates[i][j].cor_x;
var py = this.all_coordinates[i][j].cor_y;
if(Math.abs(x-px) <= 5 && Math.abs(y-py) <= 5){
this.drag_index[0] = i;
this.drag_index[1] = j;
return true;
}
}
}
return false;
},
canvasDown(e) {
var x = e.offsetX;
var y = e.offsetY;
if(this.isdragpoint(x,y)){
this.isdrag = true;
return 0;
}
//画布中鼠标按下
if(this.endtip){//已经结束了上个多边形的绘制,把上个多边形的坐标放入数组,同时清空单个多边形数组信息
this.endtip = false;
}
//获取鼠标按下的坐标,放入数组中
this.coordinates.push({cor_x:x,cor_y:y});
this.isdraw = true; //正在画多边形
},
drawlines(){
//把所有多边形画出来
for(var i=0; i<this.all_coordinates.length; i++){
var cors = this.all_coordinates[i];
//前后坐标连线
for(var j=0; j<cors.length-1; j++){
this.ctx.beginPath();
var x0 = cors[j].cor_x;
var y0 = cors[j].cor_y;
var x1 = cors[j+1].cor_x;
var y1 = cors[j+1].cor_y;
this.ctx.moveTo(x0,y0);
this.ctx.lineTo(x1,y1);
this.ctx.stroke();
this.ctx.closePath();
}
//最后一个与第一个连线
var begin_x = cors[0].cor_x;
var begin_y = cors[0].cor_y;
var end_x = cors[cors.length-1].cor_x;
var end_y = cors[cors.length-1].cor_y;
this.ctx.beginPath();
this.ctx.moveTo(begin_x,begin_y);
this.ctx.lineTo(end_x,end_y);
this.ctx.stroke();
this.ctx.closePath();
}
},
drawline(){
//把当前绘制的多边形之前的坐标线段绘制出来
for(var i=0; i<this.coordinates.length-1; i++){
this.ctx.beginPath();
var x0 = this.coordinates[i].cor_x;
var y0 = this.coordinates[i].cor_y;
var x1 = this.coordinates[i+1].cor_x;
var y1 = this.coordinates[i+1].cor_y;
this.ctx.moveTo(x0, y0);
this.ctx.lineTo(x1, y1);
this.ctx.stroke();
this.ctx.closePath();
}
},
drawcircle(){
//为当前的多边形端点画圆
this.ctx.fillStyle = 'rgb(0, 195, 155)';
for(var i=0;i<this.coordinates.length;i++){
var x = this.coordinates[i].cor_x;
var y = this.coordinates[i].cor_y;
this.ctx.beginPath();
this.ctx.moveTo(x,y);
this.ctx.arc(x,y,5,0,Math.PI*2);
this.ctx.fill();
this.ctx.closePath();
}
},
drawcircles(){
//为所有的多边形端点画圆
this.ctx.fillStyle = 'rgb(0, 195, 155)';
for(var i = 0; i<this.all_coordinates.length; i++){
var cors = this.all_coordinates[i];
for(var j=0; j<cors.length; j++){
var x = cors[j].cor_x;
var y = cors[j].cor_y;
this.ctx.beginPath();
this.ctx.moveTo(x,y);
this.ctx.arc(x,y,5,0,Math.PI*2);
this.ctx.fill();
this.ctx.closePath();
}
}
},
canvasUp(e){
if(this.isdrag){
this.isdrag = false;
}
this.drag_index = [-1,-1];
},
canvasMove(e){
//画布中鼠标移动
//没开始画或者结束画之后不进行操作
var x = e.offsetX;
var y = e.offsetY;
if(this.isdrag){
this.ctx.clearRect(0,0,700,450);
this.all_coordinates[this.drag_index[0]][this.drag_index[1]].cor_x = x;
this.all_coordinates[this.drag_index[0]][this.drag_index[1]].cor_y = y;
this.drawlines();
this.drawcircles();
this.fillarea();
}
if(this.coordinates.length == 0 || !this.isdraw || this.endtip){
return 0;
}
//获取上一个点
var last_x = this.coordinates[this.coordinates.length-1].cor_x;
var last_y = this.coordinates[this.coordinates.length-1].cor_y;
this.ctx.clearRect(0,0,700,450); //清空画布
this.drawline();//把之前的点连线
this.drawcircle();
if(this.all_coordinates.length != 0){//不止一个多边形,把多边形们画出来
this.drawlines();
this.drawcircles();
this.fillarea();
}
//获取鼠标移动时的点,画线,实现线段跟踪效果。
this.ctx.beginPath();
this.ctx.moveTo(last_x,last_y);
this.ctx.lineTo(x,y);
this.ctx.stroke();
this.ctx.closePath();
},
doubleclick(){
//双击画布,在最后一个点的时候双击,自动连线第一个点,同时宣告画结束
var x0 = this.coordinates[0].cor_x;
var y0 = this.coordinates[0].cor_y;
var x1 = this.coordinates[this.coordinates.length-1].cor_x;
var y1 = this.coordinates[this.coordinates.length-1].cor_y;
this.ctx.beginPath();
this.ctx.moveTo(x0,y0);
this.ctx.lineTo(x1,y1);
this.ctx.stroke();
this.ctx.closePath();
this.isdraw = false;
this.endtip = true
this.drawcircle();
this.coordinates.pop();
this.all_coordinates.push(this.coordinates);
this.ctx.fillStyle = 'rgba(0, 195, 155,0.4)';
var bx = this.coordinates[0].cor_x;
var by = this.coordinates[0].cor_y;
this.ctx.beginPath();
this.ctx.moveTo(bx,by);
for(var k=1;k<this.coordinates.length;k++){
var x = this.coordinates[k].cor_x;
var y = this.coordinates[k].cor_y;
this.ctx.lineTo(x,y)
}
this.ctx.fill();
this.ctx.closePath();
console.log(this.coordinates)
this.coordinates = [];
}
},
mounted() {
this.initDraw()
},
beforeDestroy() {},
};
</script>
<style scoped>
.main {
height: 90vh;
color: black;
background: white;
}
#mycanvas {
border: 1px solid red;
position: fixed;
left: 0;
right: 0;
margin: auto;
}
#img{
width: 700px;
height: 450px;
user-select:none;
}
</style>