这是我参与「第五届青训营 」伴学笔记创作活动的第 18 天
- 先展示一下效果,中间一个爱心图标,两侧是ldm和zyy的手写字母
- 实现思路:
- 首先前端方面采用的是js的canvas控件,使用canvas控件创建画布
<canvas id="canvas"><canvas> - 使用js实现画布的属性变化以及一些画布的方法函数
- 初始化,其中this.ldm和this.zyy代表手写路径的坐标变化点阵,即后一个点对于前一个点的相对位移点阵
init() {
this.canvas = document.getElementById("canvas");
this.ctx = this.canvas.getContext("2d"); // 获取一个画布,赋值给 this.ctx
window.addEventListener("resize", this.reset.bind(this));
this.ldm = [[15,-28],[15,-28],[15,-28],[15,-28],[15,-28],[15,-28],[15,-28],[15,-28],[15,-28],[-13,34],[-13,34],[-13,34],[-13,34],[-7,34],[-7,34],[-7,34],[-1,30],[-1,30],[-1,30],[-1,30],[1,39],[1,39],[1,39],[12,-36],[12,-36],[12,-36],[9,-31],[9,-31],[9,-31],[9,-31],[25,-25],[25,-25],[49,-30],[-22,22],[-22,22],[-22,22],[0,33],[0,33],[45,10],[13,-39],[13,-39],[9,-34],[9,-34],[9,-34],[9,-34],[9,-34],[9,-34],[-12,31],[-12,31],[-12,31],[-1,30],[-1,30],[-1,30],[-1,30],[0,36],[0,36],[9,-30],[9,-30],[9,-30],[27,-16],[1,46],[-7,42],[-7,42],[-3,34],[-3,34],[6,-31],[6,-31],[9,-43],[6,-30],[6,-30],[16,-27],[16,-27],[24,-21],[24,-21],[4,33],[4,33],[-9,43],[-9,43],[-3,31],[-3,31],[-3,31],[4,-36],[4,-36],[4,-36],[12,-31],[12,-31],[12,-31],[12,-31],[12,-31],[3,37],[3,37],[3,37],[-1,36],[-1,36],[-1,36],[16,-33],[16,-33],[16,-33]];
this.zyy = [[33,-34],[31,-21],[31,-21],[31,-21],[33,-9],[33,-9],[-22,28],[-22,28],[-22,28],[-16,28],[-16,28],[-16,28],[-16,28],[43,0],[22,-19],[22,-19],[22,-19],[22,-19],[22,-19],[12,-30],[25,-19],[25,-19],[25,-19],[-7,37],[-7,37],[6,54],[24,-31],[24,-31],[12,-28],[12,-28],[12,-28],[-3,36],[-3,36],[-3,36],[-3,36],[-10,49],[-16,33],[-16,33],[19,-25],[19,-25],[19,-25],[19,-25],[25,-43],[27,-16],[13,-27],[27,-21],[27,-21],[27,-21],[-6,33],[-6,33],[-3,57],[15,-27],[15,-27],[18,-36],[18,-36],[-1,30],[-1,30],[-1,30],[-1,30],[-3,33],[-25,39],[-42,33],[18,-25],[18,-25],[18,-25],[18,-25],[18,-25],[34,-33]];
this.render();
}
- 上述代码中的this.render是程序起始的函数,其中包含reset和step两个函数
render() {
this.reset();
this.step();
}
- reset函数是重置代码参数的,即清空屏幕的内容,并将画笔置于屏幕最左侧的起始位置
- step函数是一个循环函数,step内部使用
requestAnimationFrame函数定义一个动画 - 动画基本思想是采用canvas的线条绘制函数,根据有序点集绘制线条路径
- 最后就实现了上面的效果
- 中间爱心的绘制
- 中间的爱心采用数学计算的方法,生成爱心路径函数形式如下:
- 最终的计算结果储存在this.heartData这样一个二维数组中
- 数组中存储的内容为相对起始点的坐标数值二元组[(x,y),(x2,y2)]
getHeart() {
let t = Math.PI + 0.5;
let maxt = 2 * Math.PI - 1;
let vt = this.speed/100;
let x = 0;
let y = 0;
let r = this.heartR;
for (let i = 0; i < Math.ceil(maxt / vt); i++) {
x = 16 * Math.pow(Math.sin(t), 3);
y = 13 * Math.cos(t) - 5 * Math.cos(2 * t) - 2 * Math.cos(3 * t) - Math.cos(4 * t);
t += vt;
x *= r;
y = -y * r - r * Math.PI * 4;
if (y < 0) {
this.heartData.push({ x, y });
}
}
}
4.参考代码: github.com/degiminnal/…