#【情人节】代码SHOW出你的爱#
雷迪森安的乡亲们,欢迎来到老实人的前端课堂,这情人节的,我把爱心都给你们准备好了,今天我们来写个爱心吧。

正片
注意看到最后哦,下面还有一个更好看的特效,这个是个动态的♥♥

结构就两行
样式
以下样式大部分是js代码渲染上dom后表现出来的
表现
关键代码,满满注释哦,这我可够意思了哈,不懂的话再私下问我吧。
function init() {
renderable = [];
path = new Shape(new Heart(), new Point(cw / 2, ch / 2), new Color(244, 244, 244, 1), {
scale: 10
});
animate();
}
function animate() {
addShape(angle);
addShape(angle2);
angle += 0.05;
angle2 -= 0.05;
ctx.clearRect(0, 0, cw, ch);
for (var i = 0; i < renderable.length; i++) {
renderable[i].draw(canvas);
if (renderable[i].scale <= 0) renderable.splice(i, 1);
}
path.draw(canvas);
requestAnimationFrame(animate);
}
function addShape(angle) {
renderable.push(new Shape(new Circle(5), new Point(cw / 2, ch / 2), new Color(253, 192, 192, 1), {
position: (((path.geometry.getPositionByAngle(angle)).multiply(path.scale)).add(path.position.clone())),
decay: 0.1,
scale: 3
}));
}
var canvas, ctx, cw, ch;
var FPS = 60;
var renderable = [],
path,
path2,
angle = 0,
angle2 = 0,
color;
var requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) {
return setTimeout(callback, FPS);
};
window.onload = function() {
initCanvas();
ctx.clearRect(0, 0, cw, ch);
init();
}
window.onresize = function() {
initCanvas();
ctx.clearRect(0, 0, cw, ch);
};
function initCanvas() {
canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');
cw = window.innerWidth;
ch = window.innerHeight;
canvas.width = cw;
canvas.height = ch;
}
function getRandomNumber(min, max) {
return Math.random() * (max - min + 1) + min;
}
function Shape(geometry, position, color, properties) {
this.position = (position == null || position.classname != "Point") ? new Point() : position;
this.geometry = (geometry == null || geometry.constructor.name != "GenericObject") ? new Circle() : geometry;
this.color = (color == null || color.classname != "Color") ? null : color;
this.lineColor = null;
this.lineWidth = 1;
this.scale = 1;
this.decay = 0;
if (properties != null) this.setProperties(properties);
GenericObject.call(this, "Shape");
}
Shape.prototype = new GenericObject();
Shape.prototype.setProperties = function(properties) {
for (var p in properties) {
this[p] = properties[p];
}
}
Shape.prototype.draw = function(canvas) {
if (this.scale > 0) {
var ctx = canvas.getContext('2d');
var cw = canvas.width;
var ch = canvas.height;
ctx.beginPath();
if (this.lineWidth > 0 && (this.lineColor != null && this.lineColor.classname == "Color")) {
ctx.strokeStyle = this.lineColor.getRGBA();
ctx.lineWidth = this.lineWidth;
}
if (this.color != null && this.color.classname == "Color") {
ctx.fillStyle = this.color.getRGBA();
}
switch (this.geometry.classname) {
case "Circle":
ctx.arc(this.position.x, this.position.y, this.geometry.radius * this.scale, 0, Math.PI * 2);
break;
case "Heart":
for (var i = 0; i < Math.PI * 2; i += 0.05) {
var p = this.geometry.getPositionByAngle(i);
p.multiply(this.scale);
p.add(this.position);
if (i == 0) ctx.moveTo(p.x, p.y);
else ctx.lineTo(p.x, p.y);
}
break;
}
if (this.lineColor != null && this.lineColor.classname == "Color") ctx.stroke();
if (this.color != null) ctx.fill();
this.scale -= this.decay;
}
}
function Point(x, y) {
this.x = (x != null && !isNaN(x)) ? x : 0;
this.y = (y != null && !isNaN(y)) ? y : 0;
GenericObject.call(this, "Point");
}
Point.prototype = new GenericObject();
Point.prototype.add = function(p2) {
if (p2.classname != this.classname) return null;
this.x += p2.x;
this.y += p2.y;
return this;
}
Point.prototype.multiply = function(scale) {
this.x *= scale;
this.y *= scale;
return this;
}
function Circle(radius) {
this.center = new Point();
this.radius = (radius != null && !isNaN(radius)) ? radius : 1;
GenericObject.call(this, "Circle");
}
Circle.prototype = new GenericObject();
function Heart(scale) {
this.scale = (scale != null && !isNaN(scale)) ? scale : 1;
GenericObject.call(this, "Heart");
}
Heart.prototype = new GenericObject();
Heart.prototype.getPositionByAngle = function(angle) {
if (angle == null || isNaN(angle)) return null;
var x = 16 * Math.pow(Math.sin(angle), 3);
var y = -(13 * Math.cos(angle) - 5 * Math.cos(2 * angle) - 2 * Math.cos(3 * angle) - Math.cos(4 * angle));
return new Point(x * this.scale, y * this.scale);
}
function Color(r, g, b, a) {
this.r = (r != null || isNaN(r)) ? r : 0;
this.g = (g != null || isNaN(g)) ? g : 0;
this.b = (b != null || isNaN(b)) ? b : 0;
this.a = (a != null || isNaN(a)) ? a : 1;
this.hex = this.toHex();
GenericObject.call(this, "Color");
}
Color.prototype = new GenericObject();
Color.prototype.toHex = function() {
var bin = this.r << 16 | this.g << 8 | this.b;
return (function(h) {
return "#" + new Array(7 - h.length).join("0") + h
})(bin.toString(16).toUpperCase())
}
Color.prototype.getRGBA = function() {
return "rgba(" + this.r + "," + this.g + "," + this.b + "," + this.a + ")";
}
Color.prototype.setHex = function(hex) {
this.r = hex >> 16;
this.g = hex >> 8 & 0xFF;
this.b = hex & 0xFF;
this.hex = this.toHex();
}
function GenericObject(name) {
this.classname = name;
}
GenericObject.prototype.clone = function() {
var copy = new GenericObject(this.classname);
for (var attr in this) {
if (this.hasOwnProperty(attr)) {
if (this[attr].constructor.name == "GenericObject") copy[attr] = this[attr].clone();
else copy[attr] = this[attr];
}
}
return copy;
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
- 133.
- 134.
- 135.
- 136.
- 137.
- 138.
- 139.
- 140.
- 141.
- 142.
- 143.
- 144.
- 145.
- 146.
- 147.
- 148.
- 149.
- 150.
- 151.
- 152.
- 153.
- 154.
- 155.
- 156.
- 157.
- 158.
- 159.
- 160.
- 161.
- 162.
- 163.
- 164.
- 165.
- 166.
- 167.
- 168.
- 169.
- 170.
- 171.
- 172.
- 173.
- 174.
- 175.
- 176.
- 177.
- 178.
- 179.
- 180.
- 181.
- 182.
- 183.
- 184.
- 185.
- 186.
- 187.
- 188.
- 189.
- 190.
- 191.
- 192.
- 193.
- 194.
- 195.
- 196.
- 197.
- 198.
- 199.
- 200.
- 201.
- 202.
- 203.
- 204.
- 205.
- 206.
- 207.
- 208.
- 209.
- 210.
- 211.
- 212.
- 213.
- 214.
不学没思路,看完是不是感觉也不难啊?你做出来了吗?
还有下面这个情人节代码我就不写了,更多表白代码可以在评论区留言获取~

最后
博主为人老实,无偿解答问题,也会录制一些学习视频教同学们知识❤
如果对您有帮助,希望能给个👍/评论/收藏
您的三连~是对我创作最大的动力支持
够意思,三连走起