Let’s see what happens
Realize the principle of
1. Each heart in the animation has its own animation of changes in transparency, displacement, Angle and zoom. For these animations, relevant API of Canvas can be called respectively:
ctx.translate(this.x, this.y);
ctx.rotate(this.angle);
ctx.scale(this.scale, this.scale);
ctx.globalAlpha = this.opacity;
Copy the code
2. When there is more than one heart, the state of the last canvas must be saved for each heart during the realization of the Angle and scaling, and the change will be restored after completion:
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate(this.angle);
ctx.scale(this.scale, this.scale);
ctx.globalAlpha = this.opacity;
ctx.restore();
Copy the code
3. Calculating the path of center displacement (cubic Sayle curve)
Formula:
Convert to JS code to calculate the displacement of the center in the x and y directions:
Function getBezierLine(heart){var obj = heart. BezierPoint; var p0 = obj.p0; var p1 = obj.p1; var p2 = obj.p2; var p3 = obj.p3; var t = heart.bezierDis; var cx = 3 * (p1.x - p0.x), bx = 3 * (p2.x - p1.x) - cx, ax = p3.x - p0.x - cx - bx, cy = 3 * (p1.y - p0.y), by = 3 * (p2.y - p1.y) - cy, ay = p3.y - p0.y - cy - by, xt = ax * (t * t * t) + bx * (t * t) + cx * t + p0.x, yt = ay * (t * t * t) + by * (t * t) + cy * t + p0.y; heart.bezierDis += heart.speed; return { xt: xt, yt: yt } }Copy the code
The path is shown in the figure below:
According to the curve path method, the movement trajectory of the heart can be realized:
4. For each frame need to dynamically modify the displacement, Angle, and zoom of the heart:
*/ function getFScale(heart){let _scale = heart. Scale; // Let dis = heart. Origny-heart. Y; _scale = (dis / heart.scaleDis); If (dis >= heart. ScaleDis) {_scale = 1; } return _scale; }Copy the code
5. Calculate the change in cardiac Angle
*/ function rangeAngle(heart) {let _angle = heart. Angle; If (_angle >= heart. AngelEnd) {// Heart. AngleLeft = false; } else if (_angle <= heart. AngelBegin){if (_angle <= heart. } if (heart. AngleLeft) {_angle = _angle + 1; } else { _angle = _angle - 1; } return _angle; }Copy the code
componentization
The entire component has no more than 200 lines of code and is lighter, less DOM, and performs better than cSS3 implementations. Component address: github.com/lvming68160…