heart--canvas
使用canvas在鼠标点击处 绘制图形
by Evermenot
HTML
<canvas></canvas>
CSS
* {
margin: 0;
padding: 0;
}
JavaScript
(function(win) {
let Heart = function(ctx, x, y, size) {
this.ctx = ctx;
this.x= x;
this.y = y;
this.size = size;
this.vertices = getVector();
function getVector() {
let vertices = [];
// console.log(this == win) //true
for(let i = 0; i < 50; i++) {
let step = i/50 * (Math.PI * 2);
let vector = {
x : size * (16 * Math.pow(Math.sin(step), 3)),
y : size * (13 * Math.cos(step) - 5 * Math.cos(2 * step) - 2 * Math.cos(3 * step) - Math.cos(4 * step))
}
vertices.push(vector);
}
return vertices;
};
}
Heart.prototype.draw = function() {
/* 期望效果:
* 在鼠标点击位置绘制图形
*
* 错误做法: (引以为戒。。。)
* 使用canvas API中的translate,分别以鼠标点击位置的offsetX、offsetY为画布坐标的水平和竖直方向的偏移量,绘制图形,但实际效果和预期完全不太一样(大哭~~~)
*
* 错误原因:
* translate是以上个坐标原点为基础,进行平移 (原谅我的无知~~~~~)
*
* 解决问题:
* 在开始绘制前,将当前状态使用save()保存下来,并在每一次绘制结束之后,使用restore()将状态重置,以免影响下次点击
*
* 最后吐槽下:
* 有很多文章在介绍相同效果的绘制,但是真的有自测过吗。。。
*/
this.ctx.save();
this.ctx.beginPath();
this.ctx.translate(this.x, this.y);
this.ctx.rotate(Math.PI);
let vertices = this.vertices
for(let i = 0; i < vertices.length; i++) {
let vector = vertices[i];
this.ctx.lineTo(vector.x, vector.y);
}
// this.ctx.fillStyle = '#ccc';
// this.ctx.fill();
this.ctx.strokeStyle = "#ccc";
this.ctx.stroke();
this.ctx.closePath();
this.ctx.restore();
};
win.Heart = Heart;
})(window)
let canvas = document.querySelector('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
let ctx = canvas.getContext('2d');
canvas.onclick = function(e) {
let size = 6;
let x = e.offsetX;
let y = e.offsetY;
let heart = null;
heart = new Heart(ctx, x, y, size);
heart.draw();
}