• 最新的爱心代码已就绪 发射成功 速来领取啦


     哈喽,大家好,我是木易巷!

    爱情,是每个人都在追求的东西。身为一个IT行业人士,我也会追求爱情,我也会像心爱的人表达感情,只是我所表达的方式与他人有所不同。我的主要战场在计算机上,所以我就想到了用计算机来表达感情,在网页上做爱心,还是会动的爱心给她~

    这次给大家带来炫酷的跳动爱心,有三种效果,大家自行领取~

    目录

    第一种效果图

                            代码部分

    第二种效果图

                            代码部分

    第三种效果图

                            代码部分


    上一篇的三个爱心:https://blog.csdn.net/qq_44794321/article/details/127719490icon-default.png?t=M85Bhttps://blog.csdn.net/qq_44794321/article/details/127719490


    第一种效果图:

    代码部分

    代码如下仅供参考,可以直接拿去复制粘贴!

    1. import random
    2. from math import sin, cos, pi, log
    3. from tkinter import *
    4. CANVAS_WIDTH = 640
    5. CANVAS_HEIGHT = 480
    6. CANVAS_CENTER_X = CANVAS_WIDTH / 2
    7. CANVAS_CENTER_Y = CANVAS_HEIGHT / 2
    8. IMAGE_ENLARGE = 11
    9. HEART_COLOR = "#FF99CC"
    10. def heart_function(t, shrink_ratio: float = IMAGE_ENLARGE):
    11. x = 16 * (sin(t) ** 3)
    12. y = -(13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t))
    13. # 放大
    14. x *= shrink_ratio
    15. y *= shrink_ratio
    16. # 移到画布中央
    17. x += CANVAS_CENTER_X
    18. y += CANVAS_CENTER_Y
    19. return int(x), int(y)
    20. def scatter_inside(x, y, beta=0.15):
    21. ratio_x = - beta * log(random.random())
    22. ratio_y = - beta * log(random.random())
    23. dx = ratio_x * (x - CANVAS_CENTER_X)
    24. dy = ratio_y * (y - CANVAS_CENTER_Y)
    25. return x - dx, y - dy
    26. def shrink(x, y, ratio):
    27. force = -1 / (((x - CANVAS_CENTER_X) ** 2 + (y - CANVAS_CENTER_Y) ** 2) ** 0.6)
    28. dx = ratio * force * (x - CANVAS_CENTER_X)
    29. dy = ratio * force * (y - CANVAS_CENTER_Y)
    30. return x - dx, y - dy
    31. def curve(p):
    32. return 2 * (2 * sin(4 * p)) / (2 * pi)
    33. class Heart:
    34. def __init__(self, generate_frame=20):
    35. self._points = set() # 原始爱心坐标集合
    36. self._edge_diffusion_points = set() # 边缘扩散效果点坐标集合
    37. self._center_diffusion_points = set() # 中心扩散效果点坐标集合
    38. self.all_points = {} # 每帧动态点坐标
    39. self.build(2000)
    40. self.random_halo = 1000
    41. self.generate_frame = generate_frame
    42. for frame in range(generate_frame):
    43. self.calc(frame)
    44. def build(self, number):
    45. for _ in range(number):
    46. t = random.uniform(0, 2 * pi)
    47. x, y = heart_function(t)
    48. self._points.add((x, y))
    49. # 爱心内扩散
    50. for _x, _y in list(self._points):
    51. for _ in range(3):
    52. x, y = scatter_inside(_x, _y, 0.05)
    53. self._edge_diffusion_points.add((x, y))
    54. # 爱心内再次扩散
    55. point_list = list(self._points)
    56. for _ in range(4000):
    57. x, y = random.choice(point_list)
    58. x, y = scatter_inside(x, y, 0.17)
    59. self._center_diffusion_points.add((x, y))
    60. @staticmethod
    61. def calc_position(x, y, ratio):
    62. force = 1 / (((x - CANVAS_CENTER_X) ** 2 + (y - CANVAS_CENTER_Y) ** 2) ** 0.520)
    63. dx = ratio * force * (x - CANVAS_CENTER_X) + random.randint(-1, 1)
    64. dy = ratio * force * (y - CANVAS_CENTER_Y) + random.randint(-1, 1)
    65. return x - dx, y - dy
    66. def calc(self, generate_frame):
    67. ratio = 10 * curve(generate_frame / 10 * pi)
    68. halo_radius = int(4 + 6 * (1 + curve(generate_frame / 10 * pi)))
    69. halo_number = int(3000 + 4000 * abs(curve(generate_frame / 10 * pi) ** 2))
    70. all_points = []
    71. # 光环
    72. heart_halo_point = set()
    73. for _ in range(halo_number):
    74. t = random.uniform(0, 2 * pi)
    75. x, y = heart_function(t, shrink_ratio=11.6)
    76. x, y = shrink(x, y, halo_radius)
    77. if (x, y) not in heart_halo_point:
    78. heart_halo_point.add((x, y))
    79. x += random.randint(-14, 14)
    80. y += random.randint(-14, 14)
    81. size = random.choice((1, 2, 2))
    82. all_points.append((x, y, size))
    83. # 轮廓
    84. for x, y in self._points:
    85. x, y = self.calc_position(x, y, ratio)
    86. size = random.randint(1, 3)
    87. all_points.append((x, y, size))
    88. # 内容
    89. for x, y in self._edge_diffusion_points:
    90. x, y = self.calc_position(x, y, ratio)
    91. size = random.randint(1, 2)
    92. all_points.append((x, y, size))
    93. for x, y in self._center_diffusion_points:
    94. x, y = self.calc_position(x, y, ratio)
    95. size = random.randint(1, 2)
    96. all_points.append((x, y, size))
    97. self.all_points[generate_frame] = all_points
    98. def render(self, render_canvas, render_frame):
    99. for x, y, size in self.all_points[render_frame % self.generate_frame]:
    100. render_canvas.create_rectangle(x, y, x + size, y + size, width=0, fill=HEART_COLOR)
    101. def draw(main: Tk, render_canvas: Canvas, render_heart: Heart, render_frame=0):
    102. render_canvas.delete('all')
    103. render_heart.render(render_canvas, render_frame)
    104. main.after(160, draw, main, render_canvas, render_heart, render_frame + 1)
    105. if __name__ == '__main__':
    106. root = Tk()
    107. canvas = Canvas(root, bg='black', height=CANVAS_HEIGHT, width=CANVAS_WIDTH)
    108. canvas.pack()
    109. heart = Heart()
    110. draw(root, canvas, heart)
    111. root.title("公众号:木易巷")
    112. root.mainloop()

    第二种效果图:

    代码部分

    代码如下仅供参考,可以直接拿去复制粘贴!

    1. HTML>
    2. html PUBLIC "" ""><HTML><HEAD><META content="IE=11.0000"
    3. http-equiv="X-UA-Compatible">
    4. <META charset="utf-8"> <TITLE>木易巷TITLE>
    5. <STYLE type="text/css">
    6. body {
    7. margin: 0;
    8. overflow: hidden;
    9. background: #000;
    10. }
    11. canvas {
    12. position: absolute;
    13. width: 100%;
    14. height: 100%;
    15. }
    16. #pinkboard {
    17. animation: anim 1.5s ease-in-out infinite;
    18. -webkit-animation: anim 1.5s ease-in-out infinite;
    19. -o-animation: anim 1.5s ease-in-out infinite;
    20. -moz-animation: anim 1.5s ease-in-out infinite;
    21. }
    22. @keyframes anim {
    23. 0% {
    24. transform: scale(0.8);
    25. }
    26. 25% {
    27. transform: scale(0.7);
    28. }
    29. 50% {
    30. transform: scale(1);
    31. }
    32. 75% {
    33. transform: scale(0.7);
    34. }
    35. 100% {
    36. transform: scale(0.8);
    37. }
    38. }
    39. @-webkit-keyframes anim {
    40. 0% {
    41. -webkit-transform: scale(0.8);
    42. }
    43. 25% {
    44. -webkit-transform: scale(0.7);
    45. }
    46. 50% {
    47. -webkit-transform: scale(1);
    48. }
    49. 75% {
    50. -webkit-transform: scale(0.7);
    51. }
    52. 100% {
    53. -webkit-transform: scale(0.8);
    54. }
    55. }
    56. @-o-keyframes anim {
    57. 0% {
    58. -o-transform: scale(0.8);
    59. }
    60. 25% {
    61. -o-transform: scale(0.7);
    62. }
    63. 50% {
    64. -o-transform: scale(1);
    65. }
    66. 75% {
    67. -o-transform: scale(0.7);
    68. }
    69. 100% {
    70. -o-transform: scale(0.8);
    71. }
    72. }
    73. @-moz-keyframes anim {
    74. 0% {
    75. -moz-transform: scale(0.8);
    76. }
    77. 25% {
    78. -moz-transform: scale(0.7);
    79. }
    80. 50% {
    81. -moz-transform: scale(1);
    82. }
    83. 75% {
    84. -moz-transform: scale(0.7);
    85. }
    86. 100% {
    87. -moz-transform: scale(0.8);
    88. }
    89. }
    90. #name {
    91. position: absolute;
    92. top: 50%;
    93. left: 50%;
    94. transform: translate(-50%, -50%);
    95. margin-top: -20px;
    96. font-size: 46px;
    97. color: #ea80b0;
    98. }
    99. STYLE>
    100. <META name="GENERATOR" content="MSHTML 11.00.10570.1001">HEAD>
    101. <BODY><CANVAS id="pinkboard">CANVAS>
    102. <CANVAS id="canvas">CANVAS>
    103. <SCRIPT type="text/javascript">
    104. const colors = [
    105. "#eec996",
    106. "#8fb7d3",
    107. "#b7d4c6",
    108. "#c3bedd",
    109. "#f1d5e4",
    110. "#cae1d3",
    111. "#f3c89d",
    112. "#d0b0c3",
    113. "#819d53",
    114. "#c99294",
    115. "#cec884",
    116. "#ff8e70",
    117. "#e0a111",
    118. "#fffdf6",
    119. "#cbd7ac",
    120. "#e8c6c0",
    121. "#dc9898",
    122. "#ecc8ba",
    123. ]; //用来设置的颜色
    124. var canvas = document.getElementById("canvas");
    125. var ctx = canvas.getContext("2d");
    126. let count = 1;
    127. var ww = window.innerWidth;
    128. var wh = window.innerHeight;
    129. var hearts = [];
    130. function init() {
    131. requestAnimationFrame(render);
    132. canvas.width = ww;
    133. canvas.height = wh;
    134. for (var i = 0; i < 100; i++) {
    135. hearts.push(new Heart());
    136. }
    137. }
    138. function Heart() {
    139. this.x = Math.random() * ww;
    140. this.y = Math.random() * wh;
    141. this.opacity = Math.random() * 0.5 + 0.5;
    142. this.vel = {
    143. x: (Math.random() - 0.5) * 4,
    144. y: (Math.random() - 0.5) * 4,
    145. };
    146. this.targetScale = Math.random() * 0.15 + 0.02;
    147. this.scale = this.targetScale * Math.random();
    148. }
    149. Heart.prototype.update = function (i) {
    150. this.x += this.vel.x;
    151. this.y += this.vel.y;
    152. this.scale += (this.targetScale - this.scale) * 0.01;
    153. if (this.x - this.width > ww || this.x + this.width < 0) {
    154. this.scale = 0;
    155. this.x = Math.random() * ww;
    156. }
    157. if (this.y - this.height > wh || this.y + this.height < 0) {
    158. this.scale = 0;
    159. this.y = Math.random() * wh;
    160. }
    161. this.width = 473.8;
    162. this.height = 408.6;
    163. };
    164. Heart.prototype.draw = function (i) {
    165. ctx.globalAlpha = this.opacity;
    166. ctx.font = `${180 * this.scale}px "微软雅黑"`;
    167. // ctx.font="20px";
    168. ctx.fillStyle = colors[i % 18];
    169. ctx.fillText(
    170. "木易巷",
    171. this.x - this.width * 0.5,
    172. this.y - this.height * 0.5,
    173. this.width,
    174. this.height
    175. );
    176. // ctx.drawImage(
    177. // heartImage,
    178. // this.x - this.width * 0.5,
    179. // this.y - this.height * 0.5,
    180. // this.width,
    181. // this.height
    182. // );
    183. };
    184. function render() {
    185. ctx.clearRect(0, 0, ww, wh);
    186. // ctx.globalAlpha = 1;
    187. // ctx.fillStyle = "rgba(255,255,255,0.3)";
    188. // ctx.fillRect(0, 0, ww, wh);
    189. for (var i = 0; i < 100; i++) {
    190. hearts[i].update(i);
    191. hearts[i].draw(i);
    192. }
    193. requestAnimationFrame(render);
    194. }
    195. init();
    196. // var heartImage = new Image();
    197. // heartImage.onload = init();
    198. // heartImage.src =
    199. // "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NzMuOHB4IiBoZWlnaHQ9IjQwOC42cHgiIHZpZXdCb3g9IjAgMCA0NzMuOCA0MDguNiI+PHBhdGggZmlsbD0iI2QzMjkzMiIgZD0iTTQwNC42LDE2LjZDMzg1LjQsNi4xLDM2My41LDAsMzQwLDBjLTQxLjUsMC03OC41LDE4LjktMTAzLDQ4LjVDMjEyLjMsMTguOSwxNzUuMywwLDEzMy44LDAgYy0yMy4zLDAtNDUuMyw2LjEtNjQuNSwxNi42QzI3LjksMzkuNSwwLDgzLjQsMCwxMzMuOWMwLDE0LjQsMi40LDI4LjMsNi42LDQxLjJDMjkuNiwyNzguNCwyMzcsNDA4LjYsMjM3LDQwOC42IHMyMDcuMi0xMzAuMiwyMzAuMi0yMzMuNWM0LjMtMTIuOSw2LjYtMjYuOCw2LjYtNDEuMkM0NzMuOCw4My40LDQ0NS45LDM5LjYsNDA0LjYsMTYuNnoiLz48L3N2Zz4=";
    200. window.addEventListener("resize", function () {
    201. ww = window.innerWidth;
    202. wh = window.innerHeight;
    203. });
    204. SCRIPT>
    205. <SCRIPT>
    206. /*
    207. * Settings
    208. */
    209. var settings = {
    210. particles: {
    211. length: 500, // maximum amount of particles
    212. duration: 2, // particle duration in sec
    213. velocity: 100, // particle velocity in pixels/sec
    214. effect: -0.75, // play with this for a nice effect
    215. size: 30, // particle size in pixels
    216. },
    217. };
    218. /*
    219. * RequestAnimationFrame polyfill by Erik M?ller
    220. */
    221. (function () {
    222. var b = 0;
    223. var c = ["ms", "moz", "webkit", "o"];
    224. for (var a = 0; a < c.length && !window.requestAnimationFrame; ++a) {
    225. window.requestAnimationFrame = window[c[a] + "RequestAnimationFrame"];
    226. window.cancelAnimationFrame =
    227. window[c[a] + "CancelAnimationFrame"] ||
    228. window[c[a] + "CancelRequestAnimationFrame"];
    229. }
    230. if (!window.requestAnimationFrame) {
    231. window.requestAnimationFrame = function (h, e) {
    232. var d = new Date().getTime();
    233. var f = Math.max(0, 16 - (d - b));
    234. var g = window.setTimeout(function () {
    235. h(d + f);
    236. }, f);
    237. b = d + f;
    238. return g;
    239. };
    240. }
    241. if (!window.cancelAnimationFrame) {
    242. window.cancelAnimationFrame = function (d) {
    243. clearTimeout(d);
    244. };
    245. }
    246. })();
    247. /*
    248. * Point class
    249. */
    250. var Point = (function () {
    251. function Point(x, y) {
    252. this.x = typeof x !== "undefined" ? x : 0;
    253. this.y = typeof y !== "undefined" ? y : 0;
    254. }
    255. Point.prototype.clone = function () {
    256. return new Point(this.x, this.y);
    257. };
    258. Point.prototype.length = function (length) {
    259. if (typeof length == "undefined")
    260. return Math.sqrt(this.x * this.x + this.y * this.y);
    261. this.normalize();
    262. this.x *= length;
    263. this.y *= length;
    264. return this;
    265. };
    266. Point.prototype.normalize = function () {
    267. var length = this.length();
    268. this.x /= length;
    269. this.y /= length;
    270. return this;
    271. };
    272. return Point;
    273. })();
    274. /*
    275. * Particle class
    276. */
    277. var Particle = (function () {
    278. function Particle() {
    279. this.position = new Point();
    280. this.velocity = new Point();
    281. this.acceleration = new Point();
    282. this.age = 0;
    283. }
    284. Particle.prototype.initialize = function (x, y, dx, dy) {
    285. this.position.x = x;
    286. this.position.y = y;
    287. this.velocity.x = dx;
    288. this.velocity.y = dy;
    289. this.acceleration.x = dx * settings.particles.effect;
    290. this.acceleration.y = dy * settings.particles.effect;
    291. this.age = 0;
    292. };
    293. Particle.prototype.update = function (deltaTime) {
    294. this.position.x += this.velocity.x * deltaTime;
    295. this.position.y += this.velocity.y * deltaTime;
    296. this.velocity.x += this.acceleration.x * deltaTime;
    297. this.velocity.y += this.acceleration.y * deltaTime;
    298. this.age += deltaTime;
    299. };
    300. Particle.prototype.draw = function (context, image) {
    301. function ease(t) {
    302. return --t * t * t + 1;
    303. }
    304. var size = image.width * ease(this.age / settings.particles.duration);
    305. context.globalAlpha = 1 - this.age / settings.particles.duration;
    306. context.drawImage(
    307. image,
    308. this.position.x - size / 2,
    309. this.position.y - size / 2,
    310. size,
    311. size
    312. );
    313. };
    314. return Particle;
    315. })();
    316. /*
    317. * ParticlePool class
    318. */
    319. var ParticlePool = (function () {
    320. var particles,
    321. firstActive = 0,
    322. firstFree = 0,
    323. duration = settings.particles.duration;
    324. function ParticlePool(length) {
    325. // create and populate particle pool
    326. particles = new Array(length);
    327. for (var i = 0; i < particles.length; i++)
    328. particles[i] = new Particle();
    329. }
    330. ParticlePool.prototype.add = function (x, y, dx, dy) {
    331. particles[firstFree].initialize(x, y, dx, dy);
    332. // handle circular queue
    333. firstFree++;
    334. if (firstFree == particles.length) firstFree = 0;
    335. if (firstActive == firstFree) firstActive++;
    336. if (firstActive == particles.length) firstActive = 0;
    337. };
    338. ParticlePool.prototype.update = function (deltaTime) {
    339. var i;
    340. // update active particles
    341. if (firstActive < firstFree) {
    342. for (i = firstActive; i < firstFree; i++)
    343. particles[i].update(deltaTime);
    344. }
    345. if (firstFree < firstActive) {
    346. for (i = firstActive; i < particles.length; i++)
    347. particles[i].update(deltaTime);
    348. for (i = 0; i < firstFree; i++) particles[i].update(deltaTime);
    349. }
    350. // remove inactive particles
    351. while (
    352. particles[firstActive].age >= duration &&
    353. firstActive != firstFree
    354. ) {
    355. firstActive++;
    356. if (firstActive == particles.length) firstActive = 0;
    357. }
    358. };
    359. ParticlePool.prototype.draw = function (context, image) {
    360. // draw active particles
    361. if (firstActive < firstFree) {
    362. for (i = firstActive; i < firstFree; i++)
    363. particles[i].draw(context, image);
    364. }
    365. if (firstFree < firstActive) {
    366. for (i = firstActive; i < particles.length; i++)
    367. particles[i].draw(context, image);
    368. for (i = 0; i < firstFree; i++) particles[i].draw(context, image);
    369. }
    370. };
    371. return ParticlePool;
    372. })();
    373. /*
    374. * Putting it all together
    375. */
    376. (function (canvas) {
    377. var context = canvas.getContext("2d"),
    378. particles = new ParticlePool(settings.particles.length),
    379. particleRate =
    380. settings.particles.length / settings.particles.duration, // particles/sec
    381. time;
    382. // get point on heart with -PI <= t <= PI
    383. function pointOnHeart(t) {
    384. return new Point(
    385. 160 * Math.pow(Math.sin(t), 3),
    386. 130 * Math.cos(t) -
    387. 50 * Math.cos(2 * t) -
    388. 20 * Math.cos(3 * t) -
    389. 10 * Math.cos(4 * t) +
    390. 25
    391. );
    392. }
    393. // creating the particle image using a dummy canvas
    394. var image = (function () {
    395. var canvas = document.createElement("canvas"),
    396. context = canvas.getContext("2d");
    397. canvas.width = settings.particles.size;
    398. canvas.height = settings.particles.size;
    399. // helper function to create the path
    400. function to(t) {
    401. var point = pointOnHeart(t);
    402. point.x =
    403. settings.particles.size / 2 +
    404. (point.x * settings.particles.size) / 350;
    405. point.y =
    406. settings.particles.size / 2 -
    407. (point.y * settings.particles.size) / 350;
    408. return point;
    409. }
    410. // create the path
    411. context.beginPath();
    412. var t = -Math.PI;
    413. var point = to(t);
    414. context.moveTo(point.x, point.y);
    415. while (t < Math.PI) {
    416. t += 0.01; // baby steps!
    417. point = to(t);
    418. context.lineTo(point.x, point.y);
    419. }
    420. context.closePath();
    421. // create the fill
    422. context.fillStyle = "#B22222";
    423. context.fill();
    424. // create the image
    425. var image = new Image();
    426. image.src = canvas.toDataURL();
    427. return image;
    428. })();
    429. // render that thing!
    430. function render() {
    431. // next animation frame
    432. requestAnimationFrame(render);
    433. // update time
    434. var newTime = new Date().getTime() / 1000,
    435. deltaTime = newTime - (time || newTime);
    436. time = newTime;
    437. // clear canvas
    438. context.clearRect(0, 0, canvas.width, canvas.height);
    439. // create new particles
    440. var amount = particleRate * deltaTime;
    441. for (var i = 0; i < amount; i++) {
    442. var pos = pointOnHeart(Math.PI - 2 * Math.PI * Math.random());
    443. var dir = pos.clone().length(settings.particles.velocity);
    444. particles.add(
    445. canvas.width / 2 + pos.x,
    446. canvas.height / 2 - pos.y,
    447. dir.x,
    448. -dir.y
    449. );
    450. }
    451. // update and draw particles
    452. particles.update(deltaTime);
    453. particles.draw(context, image);
    454. }
    455. // handle (re-)sizing of the canvas
    456. function onResize() {
    457. canvas.width = canvas.clientWidth;
    458. canvas.height = canvas.clientHeight;
    459. }
    460. window.onresize = onResize;
    461. // delay rendering bootstrap
    462. setTimeout(function () {
    463. onResize();
    464. render();
    465. }, 10);
    466. })(document.getElementById("pinkboard"));
    467. SCRIPT>
    468. BODY>HTML>

    第三种效果图:

    代码部分

     

    代码如下仅供参考,可以直接拿去复制粘贴!

    1. HTML>
    2. html PUBLIC "" "">
    3. <HTML>
    4. <HEAD>
    5. <META content="IE=11.0000"
    6. http-equiv="X-UA-Compatible">
    7. <META charset="utf-8">
    8. <TITLE>木易巷TITLE>
    9. <STYLE type="text/css">
    10. body {
    11. margin: 0;
    12. overflow: hidden;
    13. background: #000;
    14. }
    15. canvas {
    16. position: absolute;
    17. width: 100%;
    18. height: 100%;
    19. }
    20. #pinkboard {
    21. animation: anim 1.5s ease-in-out infinite;
    22. -webkit-animation: anim 1.5s ease-in-out infinite;
    23. -o-animation: anim 1.5s ease-in-out infinite;
    24. -moz-animation: anim 1.5s ease-in-out infinite;
    25. }
    26. @keyframes anim {
    27. 0% {
    28. transform: scale(0.8);
    29. }
    30. 25% {
    31. transform: scale(0.7);
    32. }
    33. 50% {
    34. transform: scale(1);
    35. }
    36. 75% {
    37. transform: scale(0.7);
    38. }
    39. 100% {
    40. transform: scale(0.8);
    41. }
    42. }
    43. @-webkit-keyframes anim {
    44. 0% {
    45. -webkit-transform: scale(0.8);
    46. }
    47. 25% {
    48. -webkit-transform: scale(0.7);
    49. }
    50. 50% {
    51. -webkit-transform: scale(1);
    52. }
    53. 75% {
    54. -webkit-transform: scale(0.7);
    55. }
    56. 100% {
    57. -webkit-transform: scale(0.8);
    58. }
    59. }
    60. @-o-keyframes anim {
    61. 0% {
    62. -o-transform: scale(0.8);
    63. }
    64. 25% {
    65. -o-transform: scale(0.7);
    66. }
    67. 50% {
    68. -o-transform: scale(1);
    69. }
    70. 75% {
    71. -o-transform: scale(0.7);
    72. }
    73. 100% {
    74. -o-transform: scale(0.8);
    75. }
    76. }
    77. @-moz-keyframes anim {
    78. 0% {
    79. -moz-transform: scale(0.8);
    80. }
    81. 25% {
    82. -moz-transform: scale(0.7);
    83. }
    84. 50% {
    85. -moz-transform: scale(1);
    86. }
    87. 75% {
    88. -moz-transform: scale(0.7);
    89. }
    90. 100% {
    91. -moz-transform: scale(0.8);
    92. }
    93. }
    94. #name {
    95. position: absolute;
    96. top: 50%;
    97. left: 50%;
    98. transform: translate(-50%, -50%);
    99. margin-top: -20px;
    100. font-size: 46px;
    101. color: #ea80b0;
    102. }
    103. STYLE>
    104. <META name="GENERATOR" content="MSHTML 11.00.10570.1001">
    105. HEAD>
    106. <BODY>
    107. <CANVAS id="pinkboard">CANVAS>
    108. <SCRIPT>
    109. const colors = [
    110. "#eec996",
    111. "#8fb7d3",
    112. "#b7d4c6",
    113. "#c3bedd",
    114. "#f1d5e4",
    115. "#cae1d3",
    116. "#f3c89d",
    117. "#d0b0c3",
    118. "#819d53",
    119. "#c99294",
    120. "#cec884",
    121. "#ff8e70",
    122. "#e0a111",
    123. "#fffdf6",
    124. "#cbd7ac",
    125. "#e8c6c0",
    126. "#dc9898",
    127. "#ecc8ba",
    128. ]; //用来设置的颜色
    129. var canvas = document.getElementById("canvas");
    130. var ctx = canvas.getContext("2d");
    131. let count = 1;
    132. var ww = window.innerWidth;
    133. var wh = window.innerHeight;
    134. var hearts = [];
    135. function init() {
    136. requestAnimationFrame(render);
    137. canvas.width = ww;
    138. canvas.height = wh;
    139. for (var i = 0; i < 100; i++) {
    140. hearts.push(new Heart());
    141. }
    142. }
    143. function Heart() {
    144. this.x = Math.random() * ww;
    145. this.y = Math.random() * wh;
    146. this.opacity = Math.random() * 0.5 + 0.5;
    147. this.vel = {
    148. x: (Math.random() - 0.5) * 4,
    149. y: (Math.random() - 0.5) * 4,
    150. };
    151. this.targetScale = Math.random() * 0.15 + 0.02;
    152. this.scale = this.targetScale * Math.random();
    153. }
    154. Heart.prototype.update = function (i) {
    155. this.x += this.vel.x;
    156. this.y += this.vel.y;
    157. this.scale += (this.targetScale - this.scale) * 0.01;
    158. if (this.x - this.width > ww || this.x + this.width < 0) {
    159. this.scale = 0;
    160. this.x = Math.random() * ww;
    161. }
    162. if (this.y - this.height > wh || this.y + this.height < 0) {
    163. this.scale = 0;
    164. this.y = Math.random() * wh;
    165. }
    166. this.width = 473.8;
    167. this.height = 408.6;
    168. };
    169. Heart.prototype.draw = function (i) {
    170. ctx.globalAlpha = this.opacity;
    171. ctx.font = `${180 * this.scale}px "微软雅黑"`;
    172. // ctx.font="20px";
    173. ctx.fillStyle = colors[i % 18];
    174. ctx.fillText(
    175. "木易巷",
    176. this.x - this.width * 0.5,
    177. this.y - this.height * 0.5,
    178. this.width,
    179. this.height
    180. );
    181. // ctx.drawImage(
    182. // heartImage,
    183. // this.x - this.width * 0.5,
    184. // this.y - this.height * 0.5,
    185. // this.width,
    186. // this.height
    187. // );
    188. };
    189. function render() {
    190. ctx.clearRect(0, 0, ww, wh);
    191. // ctx.globalAlpha = 1;
    192. // ctx.fillStyle = "rgba(255,255,255,0.3)";
    193. // ctx.fillRect(0, 0, ww, wh);
    194. for (var i = 0; i < 100; i++) {
    195. hearts[i].update(i);
    196. hearts[i].draw(i);
    197. }
    198. requestAnimationFrame(render);
    199. }
    200. init();
    201. // var heartImage = new Image();
    202. // heartImage.onload = init();
    203. // heartImage.src =
    204. // "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NzMuOHB4IiBoZWlnaHQ9IjQwOC42cHgiIHZpZXdCb3g9IjAgMCA0NzMuOCA0MDguNiI+PHBhdGggZmlsbD0iI2QzMjkzMiIgZD0iTTQwNC42LDE2LjZDMzg1LjQsNi4xLDM2My41LDAsMzQwLDBjLTQxLjUsMC03OC41LDE4LjktMTAzLDQ4LjVDMjEyLjMsMTguOSwxNzUuMywwLDEzMy44LDAgYy0yMy4zLDAtNDUuMyw2LjEtNjQuNSwxNi42QzI3LjksMzkuNSwwLDgzLjQsMCwxMzMuOWMwLDE0LjQsMi40LDI4LjMsNi42LDQxLjJDMjkuNiwyNzguNCwyMzcsNDA4LjYsMjM3LDQwOC42IHMyMDcuMi0xMzAuMiwyMzAuMi0yMzMuNWM0LjMtMTIuOSw2LjYtMjYuOCw2LjYtNDEuMkM0NzMuOCw4My40LDQ0NS45LDM5LjYsNDA0LjYsMTYuNnoiLz48L3N2Zz4=";
    205. window.addEventListener("resize", function () {
    206. ww = window.innerWidth;
    207. wh = window.innerHeight;
    208. });
    209. SCRIPT>
    210. <SCRIPT>
    211. /*
    212. * Settings
    213. */
    214. var settings = {
    215. particles: {
    216. length: 500, // maximum amount of particles-最大颗粒量
    217. duration: 2, // particle duration in sec-粒子持续时间(秒)
    218. velocity: 100, // particle velocity in pixels/sec-粒子速度(像素/秒)
    219. effect: -0.75, // play with this for a nice effect-玩这个会有很好的效果
    220. size: 30, // particle size in pixels-颗粒尺寸(像素)
    221. },
    222. };
    223. /*
    224. * RequestAnimationFrame polyfill
    225. * 请求动画帧多边形填充,立即执行函数,当解析到这一行,代码立即执行,后面的括号可以传递参数
    226. */
    227. (function () {
    228. var b = 0;
    229. var c = ["ms", "moz", "webkit", "o"];
    230. for (var a = 0; a < c.length && !window.requestAnimationFrame; ++a) {
    231. window.requestAnimationFrame = window[c[a] + "RequestAnimationFrame"];
    232. window.cancelAnimationFrame =
    233. window[c[a] + "CancelAnimationFrame"] ||
    234. window[c[a] + "CancelRequestAnimationFrame"];
    235. }
    236. if (!window.requestAnimationFrame) {
    237. window.requestAnimationFrame = function (h, e) {
    238. var d = new Date().getTime();
    239. var f = Math.max(0, 16 - (d - b));
    240. var g = window.setTimeout(function () {
    241. h(d + f);
    242. }, f);
    243. b = d + f;
    244. return g;
    245. };
    246. }
    247. if (!window.cancelAnimationFrame) {
    248. window.cancelAnimationFrame = function (d) {
    249. clearTimeout(d);
    250. };
    251. }
    252. })();
    253. /*
    254. * Point class
    255. * 像素点的类,prototype可以给类中添加方法
    256. */
    257. var Point = (function () {
    258. function Point(x, y) {
    259. this.x = typeof x !== "undefined" ? x : 0;
    260. this.y = typeof y !== "undefined" ? y : 0;
    261. }
    262. Point.prototype.clone = function () {
    263. return new Point(this.x, this.y);
    264. };
    265. Point.prototype.length = function (length) {
    266. if (typeof length == "undefined")
    267. return Math.sqrt(this.x * this.x + this.y * this.y);
    268. this.normalize();
    269. this.x *= length;
    270. this.y *= length;
    271. return this;
    272. };
    273. Point.prototype.normalize = function () {
    274. var length = this.length();
    275. this.x /= length;
    276. this.y /= length;
    277. return this;
    278. };
    279. return Point;
    280. })();
    281. /*
    282. * Particle class
    283. *粒子类
    284. */
    285. var Particle = (function () {
    286. function Particle() {
    287. this.position = new Point();
    288. this.velocity = new Point();
    289. this.acceleration = new Point();
    290. this.age = 0;
    291. }
    292. Particle.prototype.initialize = function (x, y, dx, dy) {
    293. this.position.x = x;
    294. this.position.y = y;
    295. this.velocity.x = dx;
    296. this.velocity.y = dy;
    297. this.acceleration.x = dx * settings.particles.effect;
    298. this.acceleration.y = dy * settings.particles.effect;
    299. this.age = 0;
    300. };
    301. Particle.prototype.update = function (deltaTime) {
    302. this.position.x += this.velocity.x * deltaTime;
    303. this.position.y += this.velocity.y * deltaTime;
    304. this.velocity.x += this.acceleration.x * deltaTime;
    305. this.velocity.y += this.acceleration.y * deltaTime;
    306. this.age += deltaTime;
    307. };
    308. Particle.prototype.draw = function (context, image) {
    309. function ease(t) {
    310. return --t * t * t + 1;
    311. }
    312. var size = image.width * ease(this.age / settings.particles.duration);
    313. context.globalAlpha = 1 - this.age / settings.particles.duration;
    314. context.drawImage(
    315. image,
    316. this.position.x - size / 2,
    317. this.position.y - size / 2,
    318. size,
    319. size
    320. );
    321. };
    322. return Particle;
    323. })();
    324. /*
    325. * ParticlePool class
    326. * 粒子池类
    327. */
    328. var ParticlePool = (function () {
    329. var particles,
    330. firstActive = 0,
    331. firstFree = 0,
    332. duration = settings.particles.duration;
    333. function ParticlePool(length) {
    334. // create and populate particle pool
    335. particles = new Array(length);
    336. for (var i = 0; i < particles.length; i++)
    337. particles[i] = new Particle();
    338. }
    339. ParticlePool.prototype.add = function (x, y, dx, dy) {
    340. particles[firstFree].initialize(x, y, dx, dy);
    341. // handle circular queue
    342. firstFree++;
    343. if (firstFree == particles.length) firstFree = 0;
    344. if (firstActive == firstFree) firstActive++;
    345. if (firstActive == particles.length) firstActive = 0;
    346. };
    347. ParticlePool.prototype.update = function (deltaTime) {
    348. var i;
    349. // update active particles
    350. if (firstActive < firstFree) {
    351. for (i = firstActive; i < firstFree; i++)
    352. particles[i].update(deltaTime);
    353. }
    354. if (firstFree < firstActive) {
    355. for (i = firstActive; i < particles.length; i++)
    356. particles[i].update(deltaTime);
    357. for (i = 0; i < firstFree; i++) particles[i].update(deltaTime);
    358. }
    359. // remove inactive particles
    360. while (
    361. particles[firstActive].age >= duration &&
    362. firstActive != firstFree
    363. ) {
    364. firstActive++;
    365. if (firstActive == particles.length) firstActive = 0;
    366. }
    367. };
    368. ParticlePool.prototype.draw = function (context, image) {
    369. // draw active particles
    370. //绘制活性粒子
    371. if (firstActive < firstFree) {
    372. for (i = firstActive; i < firstFree; i++)
    373. particles[i].draw(context, image);
    374. }
    375. if (firstFree < firstActive) {
    376. for (i = firstActive; i < particles.length; i++)
    377. particles[i].draw(context, image);
    378. for (i = 0; i < firstFree; i++) particles[i].draw(context, image);
    379. }
    380. };
    381. return ParticlePool;
    382. })();
    383. /*
    384. * Putting it all together
    385. * 把它们放在一起,立即执行
    386. * 执行行为:
    387. * 1、渲染一个
    388. */
    389. (function (canvas) {
    390. //下面的canvas对象获取,由立即执行函数的参数传递了,不需要get获取
    391. // var canvas = document.getElementById("pinkboard")
    392. //获取上下文容器、new粒子池对象、定义变量粒子比率变量并赋值、定义事件变量
    393. var context = canvas.getContext("2d"),
    394. particles = new ParticlePool(settings.particles.length),
    395. particleRate =
    396. settings.particles.length / settings.particles.duration, // particles/sec
    397. time;
    398. // get point on heart with -PI <= t <= PI
    399. //定义得到像素点对象的方法,在下面虚拟画布中调用了该方法
    400. function pointOnHeart(t) {
    401. return new Point(
    402. 160 * Math.pow(Math.sin(t), 3),
    403. 130 * Math.cos(t) -
    404. 50 * Math.cos(2 * t) -
    405. 20 * Math.cos(3 * t) -
    406. 10 * Math.cos(4 * t) +
    407. 25
    408. );
    409. }
    410. function gradientColor(startColor, endColor, step) {
    411. startRGB = colorRgb(startColor);//转换为rgb数组模式
    412. startR = startRGB[0];
    413. startG = startRGB[1];
    414. startB = startRGB[2];
    415. endRGB = colorRgb(endColor);
    416. endR = endRGB[0];
    417. endG = endRGB[1];
    418. endB = endRGB[2];
    419. sR = (endR - startR) / step;//总差值
    420. sG = (endG - startG) / step;
    421. sB = (endB - startB) / step;
    422. var colorArr = [];
    423. for (var i = 0; i < step; i++) {
    424. //计算每一步的hex值
    425. var hex = colorHex('rgb(' + parseInt((sR * i + startR)) + ',' + parseInt((sG * i + startG)) + ',' + parseInt((sB * i + startB)) + ')');
    426. colorArr.push(hex);
    427. }
    428. return colorArr;
    429. }
    430. var colorRgb = function (sColor) {
    431. var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
    432. var sColor = sColor.toLowerCase();
    433. if (sColor && reg.test(sColor)) {
    434. if (sColor.length === 4) {
    435. var sColorNew = "#";
    436. for (var i = 1; i < 4; i += 1) {
    437. sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1));
    438. }
    439. sColor = sColorNew;
    440. }
    441. //处理六位的颜色值
    442. var sColorChange = [];
    443. for (var i = 1; i < 7; i += 2) {
    444. sColorChange.push(parseInt("0x" + sColor.slice(i, i + 2)));
    445. }
    446. return sColorChange;
    447. } else {
    448. return sColor;
    449. }
    450. }
    451. // 将rgb表示方式转换为hex表示方式
    452. var colorHex = function (rgb) {
    453. var _this = rgb;
    454. var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
    455. if (/^(rgb|RGB)/.test(_this)) {
    456. var aColor = _this.replace('rgb', "").replace('(', "").replace(')', "").split(",");
    457. var strHex = "#";
    458. for (var i = 0; i < aColor.length; i++) {
    459. var hex = Number(aColor[i]).toString(16);
    460. hex = hex < 10 ? 0 + '' + hex : hex;// 保证每个rgb的值为2位
    461. if (hex === "0") {
    462. hex += hex;
    463. }
    464. strHex += hex;
    465. }
    466. if (strHex.length !== 7) {
    467. strHex = _this;
    468. }
    469. return strHex;
    470. } else if (reg.test(_this)) {
    471. var aNum = _this.replace(/#/, "").split("");
    472. if (aNum.length === 6) {
    473. return _this;
    474. } else if (aNum.length === 3) {
    475. var numHex = "#";
    476. for (var i = 0; i < aNum.length; i += 1) {
    477. numHex += (aNum[i] + aNum[i]);
    478. }
    479. return numHex;
    480. }
    481. } else {
    482. return _this;
    483. }
    484. }
    485. var weight = 20;
    486. var colorArrAsc = gradientColor('#FF0000', '#0000FF', weight);
    487. var colorArrDesc = gradientColor('#0000FF', '#FF0000', weight);
    488. // alert(weight + ',' + colorArrAsc.length + ',' + colorArrDesc.length);
    489. //用来设置的颜色\
    490. // creating the particle image using a dummy canvas
    491. //使用虚拟画布创建粒子图像,返回了图像的像素点
    492. function getImageAsc(i) {
    493. var canvas = document.createElement("canvas");
    494. var context = canvas.getContext("2d");
    495. canvas.width = settings.particles.size;
    496. canvas.height = settings.particles.size;
    497. // helper function to create the path
    498. // Helper函数来创建路径
    499. function to(t) {
    500. var point = pointOnHeart(t);
    501. point.x =
    502. settings.particles.size / 2 +
    503. (point.x * settings.particles.size) / 350;
    504. point.y =
    505. settings.particles.size / 2 -
    506. (point.y * settings.particles.size) / 350;
    507. return point;
    508. }
    509. // create the path
    510. //创建路径
    511. context.beginPath();
    512. var t = -Math.PI;
    513. var point = to(t);
    514. context.moveTo(point.x, point.y);
    515. while (t < Math.PI) {
    516. t += 0.01; // baby steps!
    517. point = to(t);
    518. context.lineTo(point.x, point.y);
    519. }
    520. context.closePath();
    521. // create the fill
    522. //创建填充
    523. context.fillStyle = colorArrAsc[i % (weight+1)];
    524. // alert('asc,'+(i % weight));
    525. context.fill();
    526. // create the image
    527. var image = new Image();
    528. image.src = canvas.toDataURL();
    529. return image;
    530. };
    531. function getImageDesc(i) {
    532. var canvas = document.createElement("canvas");
    533. var context = canvas.getContext("2d");
    534. canvas.width = settings.particles.size;
    535. canvas.height = settings.particles.size;
    536. // helper function to create the path
    537. // Helper函数来创建路径
    538. function to(t) {
    539. var point = pointOnHeart(t);
    540. point.x =
    541. settings.particles.size / 2 +
    542. (point.x * settings.particles.size) / 350;
    543. point.y =
    544. settings.particles.size / 2 -
    545. (point.y * settings.particles.size) / 350;
    546. return point;
    547. }
    548. // create the path
    549. //创建路径
    550. context.beginPath();
    551. var t = -Math.PI;
    552. var point = to(t);
    553. context.moveTo(point.x, point.y);
    554. while (t < Math.PI) {
    555. t += 0.01; // baby steps!
    556. point = to(t);
    557. context.lineTo(point.x, point.y);
    558. }
    559. context.closePath();
    560. // create the fill
    561. //创建填充
    562. context.fillStyle = colorArrDesc[i % (weight+1)];
    563. // alert('desc,'+(i % (weight+1));
    564. context.fill();
    565. // create the image
    566. var image = new Image();
    567. image.src = canvas.toDataURL();
    568. return image;
    569. };
    570. var image1 = getImageAsc(0);
    571. // render that thing!
    572. //定义了一个渲染的方法,使用渲染器,渲染这些点
    573. function render() {
    574. // next animation frame
    575. //下一个动画帧
    576. requestAnimationFrame(render);
    577. // update time
    578. //更新时间,
    579. var newTime = new Date().getTime() / 1000,
    580. deltaTime = newTime - (time || newTime);
    581. time = newTime;
    582. // alert(newTime);
    583. // clear canvas
    584. //在给定矩形内清空一个矩形:
    585. context.clearRect(0, 0, canvas.width, canvas.height);
    586. // create new particles
    587. // 创建新粒子
    588. var amount = particleRate * deltaTime;
    589. for (var i = 0; i < amount; i++) {
    590. var pos = pointOnHeart(Math.PI - 2 * Math.PI * Math.random());
    591. var dir = pos.clone().length(settings.particles.velocity);
    592. particles.add(
    593. canvas.width / 2 + pos.x,
    594. canvas.height / 2 - pos.y,
    595. dir.x,
    596. -dir.y
    597. );
    598. }
    599. // update and draw particles
    600. particles.update(deltaTime);
    601. particles.draw(context, image1);
    602. }
    603. // handle (re-)sizing of the canvas
    604. //定义一个方法,初始化画布的大小
    605. function onResize() {
    606. canvas.width = canvas.clientWidth;
    607. canvas.height = canvas.clientHeight;
    608. }
    609. window.onresize = onResize;
    610. // delay rendering bootstrap
    611. //定义一个延迟呈现引导的方法,10微秒后重设画布,并且重新渲染,模拟心跳的效果
    612. setTimeout(function () {
    613. onResize();
    614. render();
    615. }, 10);
    616. var x = 0
    617. setInterval(function () {
    618. if (x <= weight) {
    619. image1 = getImageAsc(x);
    620. }
    621. if (x > weight && x < 2 * weight) {
    622. image1 = getImageDesc(x - weight)
    623. }
    624. if (x == 2 * weight) {
    625. image1 = getImageDesc(x - weight)
    626. x = 0;
    627. }
    628. x++;
    629. }, 1000);
    630. })
    631. (document.getElementById("pinkboard"));
    632. SCRIPT>
    633. <script>
    634. script>
    635. BODY>
    636. HTML>

    好啦,本次分享就到这里,祝大家开心~

    最后

    博主为人老实,无偿解答问题,也会录制一些学习视频❤

    如果对您有帮助,希望能给个👍/评论/收藏

    您的三连~是对我创作最大的动力支持

  • 相关阅读:
    Compiling TraX library操作
    数据科学与大数据(学习记录)
    【干货】Python注释快捷键
    2.数据及其预处理
    【Linux】如何实现虚拟机系统与本地系统的通信连接
    docker安装skyWalking笔记
    使用Python分析14亿条数据
    springboot+vue项目合同申报系统java
    看了这篇不用再苦恼如何将视频压缩了
    curl命令介绍
  • 原文地址:https://blog.csdn.net/qq_44794321/article/details/127736297