首页 前端知识 HTML JavaScript CSS:爱心代码

HTML JavaScript CSS:爱心代码

2024-04-30 11:04:05 前端知识 前端哥 493 9 我要收藏

请添加图片描述

1、创建heart.js文件

// 定义画布的宽度和高度,以及画布的中心点坐标
const CANVAS_WIDTH = 640;
const CANVAS_HEIGHT = 480;
const CANVAS_CENTER_X = CANVAS_WIDTH / 2;
const CANVAS_CENTER_Y = CANVAS_HEIGHT / 2;

// 定义图像的放大因子,用于调整爱心的大小
const IMAGE_ENLARGE_FACTOR = 11;

// 定义爱心的颜色
const HEART_COLOR = "#FF69B4";

// 生成爱心上的一个点的坐标
function generateHeartCoordinate(t, shrinkRatio = IMAGE_ENLARGE_FACTOR) {
  // 使用参数t计算原始的x和y坐标
  let x = 16 * (Math.sin(t) ** 3);
  let y = -(13 * Math.cos(t) - 5 * Math.cos(2 * t) - 2 * Math.cos(3 * t) - Math.cos(4 * t));

  // 根据缩放比例调整x和y坐标
  x *= shrinkRatio;
  y *= shrinkRatio;

  // 将坐标转换到画布的中心
  x += CANVAS_CENTER_X;
  y += CANVAS_CENTER_Y;

  // 返回调整后的坐标,向下取整以确保坐标为整数
  return { x: Math.floor(x), y: Math.floor(y) };
}

// 绘制爱心的函数
function drawHeart(context, ratio, frame) {
  // 清空画布
  context.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);

  // 绘制爱心的光晕部分
  let heartHaloPoints = new Set();
  for (let i = 0; i < 3000 + 4000 * Math.abs(customCurve(frame / 10 * Math.PI) ** 2); i++) {
    // 生成一个随机的t值,用于计算坐标
    let t = Math.random() * 4 * Math.PI;
    // 使用generateHeartCoordinate函数计算坐标,并使用一个更大的缩放比例来使光晕更大
    let { x, y } = generateHeartCoordinate(t, 11.5);
    // 计算一个力的大小,用于调整光晕的扩散效果
    let force = -1 / (((x - CANVAS_CENTER_X) ** 2 + (y - CANVAS_CENTER_Y) ** 2) ** 0.6);
    // 根据力的大小调整x和y坐标
    x -= ratio * force * (x - CANVAS_CENTER_X);
    y -= ratio * force * (y - CANVAS_CENTER_Y);
    // 添加一些随机的偏移量,使光晕更加自然
    x += Math.floor(Math.random() * 29 - 14);
    y += Math.floor(Math.random() * 29 - 14);
    // 使用fillRect函数绘制一个2x2的正方形,作为光晕的一个点
    context.fillStyle = HEART_COLOR;
    context.fillRect(x, y, 2, 2);
  }

  // 绘制爱心的主体部分
  let allPoints = []; // 存储所有点的数组
  let originalPoints = new Set(); // 存储原始点的集合
  let edgeDiffusionPoints = new Set(); // 存储边缘扩散点的集合
  let centerDiffusionPoints = new Set(); // 存储中心扩散点的集合

  // 生成原始点
  for (let i = 0; i < 2000; i++) {
    let t = Math.random() * 2 * Math.PI;
    let { x, y } = generateHeartCoordinate(t);
    originalPoints.add({ x, y });
  }

  // 从原始点生成边缘扩散点
  originalPoints.forEach(({ x, y }) => {
    for (let i = 0; i < 3; i++) {
      let newX = x, newY = y;
      newX += Math.random() * 5 - 2.5;
      newY += Math.random() * 5 - 2.5;
      edgeDiffusionPoints.add({ x: newX, y: newY });
    }
  });

  // 生成中心扩散点
  for (let i = 0; i < 6000; i++) {
    let { x, y } = Array.from(originalPoints)[Math.floor(Math.random() * originalPoints.size)];
    let newX = x, newY = y;
    newX += Math.random() * 15 - 7.5;
    newY += Math.random() * 15 - 7.5;
    centerDiffusionPoints.add({ x: newX, y: newY });
  }

  // 根据力的大小调整所有点的坐标,并将它们添加到allPoints数组中
  originalPoints.forEach(({ x, y }) => {
    let newX = x, newY = y;
    let force = 1 / (((x - CANVAS_CENTER_X) ** 2 + (y - CANVAS_CENTER_Y) ** 2) ** 0.52);
    newX -= ratio * force * (x - CANVAS_CENTER_X);
    newY -= ratio * force * (y - CANVAS_CENTER_Y);
    allPoints.push({ x: Math.floor(newX), y: Math.floor(newY), size: Math.floor(Math.random() * 3 + 1) });
  });

  edgeDiffusionPoints.forEach(({ x, y }) => {
    let newX = x, newY = y;
    let force = 1 / (((x - CANVAS_CENTER_X) ** 2 + (y - CANVAS_CENTER_Y) ** 2) ** 0.52);
    newX -= ratio * force * (x - CANVAS_CENTER_X);
    newY -= ratio * force * (y - CANVAS_CENTER_Y);
    allPoints.push({ x: Math.floor(newX), y: Math.floor(newY), size: Math.floor(Math.random() * 2 + 1) });
  });

  centerDiffusionPoints.forEach(({ x, y }) => {
    let newX = x, newY = y;
    let force = 1 / (((x - CANVAS_CENTER_X) ** 2 + (y - CANVAS_CENTER_Y) ** 2) ** 0.52);
    newX -= ratio * force * (x - CANVAS_CENTER_X);
    newY -= ratio * force * (y - CANVAS_CENTER_Y);
    allPoints.push({ x: Math.floor(newX), y: Math.floor(newY), size: Math.floor(Math.random() * 2 + 1) });
  });

  // 绘制所有点
  allPoints.forEach(({ x, y, size }) => {
    context.fillStyle = HEART_COLOR;
    context.fillRect(x, y, size, size);
  });

  // 添加文本 "stormsha" 到爱心中间
  context.font = "bold 24px Arial";
  context.fillStyle = HEART_COLOR;
  context.textAlign = "center";
  context.fillText("stormsha", CANVAS_CENTER_X, CANVAS_CENTER_Y);
}

// 定义一个自定义的曲线函数,用于调整爱心的跳动效果
function customCurve(p) {
  return 2 * (2 * Math.sin(4 * p)) / (2 * Math.PI);
}

// 当文档加载完成时,开始动画
document.addEventListener("DOMContentLoaded", () => {
  // 获取画布和2d上下文
  const canvas = document.getElementById("heartCanvas");
  const context = canvas.getContext("2d");

  // 定义一些变量,用于控制动画
  let ratio = 0; // 力的大小比例
  let frame = 0; // 当前帧数

  // 动画函数
  function animate() {
    // 根据当前帧数计算力的大小比例
    ratio = 10 * customCurve(frame / 10 * Math.PI);
    // 调用drawHeart函数绘制爱心
    drawHeart(context, ratio, frame);
    // 增加帧数
    frame++;
    // 请求下一帧的动画
    requestAnimationFrame(animate);
  }

  // 开始动画
  animate();
});

这段代码实现了一个跳动的爱心动画。首先,它定义了一些常量,如画布的尺寸和爱心的颜色。然后,它定义了一个generateHeartCoordinate函数,用于生成爱心上的一个点的坐标。

接下来,它定义了一个drawHeart函数,用于绘制爱心。这个函数首先清空画布,然后绘制爱心的光晕部分,再绘制爱心的主体部分。最后,它添加了一些文本到爱心中间。

在文档加载完成后,代码会获取画布和2d上下文,并定义一些变量,如力的大小比例和当前帧数。然后,它会调用animate函数开始动画。

这个函数会根据当前帧数计算力的大小比例,然后调用drawHeart函数绘制爱心,并请求下一帧的动画。通过不断调用animate函数,就可以实现爱心的跳动效果。

2、创建love.html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"> <!-- 指定文档使用UTF-8字符编码 -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- 设置视口,以适应不同设备屏幕大小 -->
    <title>Beating Heart</title> <!-- 文档标题 -->
    <style>
        /* 样式表定义 */
        body {
            background-color: black; /* 设置页面背景颜色为黑色 */
            margin: 0; /* 去除页面默认边距 */
            overflow: hidden; /* 隐藏超出画布的内容 */
        }
        canvas {
            display: block; /* 将画布作为块级元素显示 */
            margin: auto; /* 使画布在页面中居中 */
        }
        .text {
            position: absolute; /* 将文本绝对定位 */
            top: 50%; /* 使文本距离页面顶部50% */
            left: 50%; /* 使文本距离页面左侧50% */
            transform: translate(-50%, -50%); /* 将文本向左、向上平移自身宽度和高度的一半,实现在页面中居中 */
            color: #FF69B4; /* 设置文本颜色为浅粉色 */
            font-family: '宋体'; /* 设置文本字体为宋体 */
            font-size: 18px; /* 设置文本大小为18像素 */
            text-align: center; /* 使文本内容居中 */
        }
    </style>
</head>
<body>
    <!-- 页面内容定义 -->
    <canvas id="heartCanvas" width="640" height="480"></canvas> <!-- 创建一个宽640像素、高480像素的画布,并设置其ID为heartCanvas -->
    <div class="text" style="top: 5%;">点燃我 温暖你</div> <!-- 创建一个文本元素,内容为“点燃我 温暖你”,并设置其样式类为text,距离页面顶部5% -->
    <script src="heart.js"></script> <!-- 引入heart.js脚本文件 -->
</body>
</html>

3、总结

heart.jslove.html 文件放在同一个文件夹下,用浏览器打开 love.html 文件即可看到效果

转载请注明出处或者链接地址:https://www.qianduange.cn//article/6662.html
标签
评论
会员中心 联系我 留言建议 回顶部
复制成功!