HTML&CSS&JS:赛博木鱼

用 HTML + CSS + JS 打造一个禅意十足的互动小应用------赛博木鱼, 本文将拆解其核心实现逻辑,带你从 0 到 1 理解 "敲木鱼" 背后的技术细节。


大家复制代码时,可能会因格式转换出现错乱,导致样式失效。建议先少量复制代码进行测试,若未能解决问题,私信回复源码两字,我会发送完整的压缩包给你。

演示效果

HTML&CSS

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>赛博木鱼</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            background-color: #121212;
            color: #FFFFFF;
            font-family: 'Kaiti SC', 'PingFang SC', sans-serif;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            min-height: 100vh;
            overflow: hidden;
        }

        .title-container {
            text-align: center;
            margin-bottom: 20px;
        }

        .main-title {
            color: #FFFFFF;
            font-size: 6vw;
            font-family: 'Kaiti SC', sans-serif;
            background: linear-gradient(180deg,
                rgba(255, 176, 103, 0.05) 0%,
                rgba(115, 55, 0, 0.02) 100%);
            background-clip: text;
            margin: 0;
            line-height: 1;
        }

        .score-container {
            text-align: center;
            margin: 20px 0;
        }

        .score {
            font-size: 10vh;
            font-family: 'PingFang SC', sans-serif;
            font-weight: 900;
            margin: 0;
        }

        .description {
            font-size: 5vh;
            font-family: 'PingFang SC', sans-serif;
            margin-top: 10px;
        }

        .wooden-fish-container {
            position: relative;
            width: 300px;
            height: 250px;
            display: flex;
            justify-content: center;
            align-items: center;
            margin: 30px 0;
        }

        .wooden-fish {
            width: 284px;
            height: 236px;
            transition: transform 0.1s ease;
        }

        .mallet {
            position: absolute;
            top: 20px;
            right: 20px;
            width: 119px;
            height: 69px;
            transition: transform 0.1s ease;
            z-index: 10;
        }

        .floating-text {
            position: absolute;
            top: -50px;
            left: 50%;
            transform: translateX(-50%);
            font-family: 'PingFang SC', sans-serif;
            font-size: 1.5em;
            color: #FFFFFF;
            opacity: 0;
            pointer-events: none;
            animation: floatUp 0.4s ease-out forwards;
        }

        @keyframes floatUp {
            0% {
                opacity: 1;
                transform: translateX(-50%) translateY(0);
            }
            100% {
                opacity: 0;
                transform: translateX(-50%) translateY(-60px);
            }
        }

        .bottom-text {
            font-family: 'Kaiti SC', sans-serif;
            font-size: 1.2em;
            text-align: center;
            margin-top: 30px;
        }
    </style>
</head>
<body>
    <div class="title-container">
        <div class="main-title">赛博木鱼</div>
    </div>

    <div class="score-container">
        <div class="score" id="score">0</div>
        <div class="description">功德</div>
    </div>

    <div class="wooden-fish-container" id="fishContainer">
        <img src="https://img.alicdn.com/imgextra/i3/O1CN012CO0YU1VSfNs506ZS_!!6000000002652-2-tps-284-236.png"
             alt="木鱼" class="wooden-fish" id="woodenFish">
        <img src="https://img.alicdn.com/imgextra/i1/O1CN01tKb5Et1aSjWRjCHK3_!!6000000003329-2-tps-119-69.png"
             alt="锤子" class="mallet" id="mallet">
    </div>

    <div class="bottom-text">轻敲木鱼,细悟赛博真经。</div>

    <audio id="clickSound" preload="auto">
        <source src="https://qianwen.alicdn.com/resource/qiaomuyu.mp3" type="audio/mpeg">
    </audio>

    <script>
        let score = 0;
        const scoreElement = document.getElementById('score');
        const woodenFish = document.getElementById('woodenFish');
        const mallet = document.getElementById('mallet');
        const fishContainer = document.getElementById('fishContainer');
        const clickSound = document.getElementById('clickSound');

        fishContainer.addEventListener('click', function(e) {
            // 播放音效
            clickSound.currentTime = 0;
            clickSound.play();

            // 锤子旋转动画
            mallet.style.transform = 'rotate(-25deg)';
            setTimeout(() => {
                mallet.style.transform = 'rotate(0deg)';
            }, 100);

            // 木鱼放大动画
            woodenFish.style.transform = 'scale(1.1)';
            setTimeout(() => {
                woodenFish.style.transform = 'scale(1)';
            }, 100);

            // 增加分数
            score++;
            scoreElement.textContent = score;

            // 创建漂浮文字
            const floatingText = document.createElement('div');
            floatingText.className = 'floating-text';
            floatingText.textContent = '功德+1';
            fishContainer.appendChild(floatingText);

            // 移除漂浮文字
            setTimeout(() => {
                floatingText.remove();
            }, 400);
        });
    </script>
</body>
</html>

HTML

  • title-container:标题容器:承载 "赛博木鱼" 主标题,通过居中布局突出视觉核心
  • score-container:分数展示区:包含 "功德数" 和 "功德" 描述,是用户交互的核心反馈载体
  • wooden-fish-container:交互核心容器
  • wooden-fish:木鱼图片:通过 CDN 引入资源,无需本地存储,是点击交互的视觉核心
  • mallet:锤子图片:绝对定位在木鱼右上方,点击时通过旋转动画模拟 "敲击" 动作
  • clickSound:音效载体:预加载木鱼敲击音效(preload="auto"),点击时触发播放,增强沉浸感
  • floating-text:动态生成元素:点击时创建 "功德 + 1" 漂浮文字,完成交互反馈闭环

CSS

  • .mallet:点击时锤子绕右上角旋转 25 度,模拟 "敲下去" 的动作,100 毫秒快速回弹
  • .wooden-fish:点击时木鱼轻微放大 1.1 倍,模拟 "被敲击后的震动",与锤子动作同步:
  • .floating-text:自动向上淡出,营造"功德升天"的视觉效果。

JavaScript

  1. 初始化变量:获取 DOM 元素与状态
javascript 复制代码
let score = 0; // 功德数初始值
const scoreElement = document.getElementById('score'); // 分数显示元素
const woodenFish = document.getElementById('woodenFish'); // 木鱼元素
const mallet = document.getElementById('mallet'); // 锤子元素
const fishContainer = document.getElementById('fishContainer'); // 交互容器
const clickSound = document.getElementById('clickSound'); // 音效元素

通过 getElementById 获取核心交互元素,提前定义功德数状态。

  1. 核心交互:点击事件处理
javascript 复制代码
fishContainer.addEventListener('click', function(e) {
    // 1. 播放敲击音效(每次点击从头播放,支持连续敲击)
    clickSound.currentTime = 0;
    clickSound.play();

    // 2. 锤子旋转动画:敲下→回弹
    mallet.style.transform = 'rotate(-25deg)';
    setTimeout(() => {
        mallet.style.transform = 'rotate(0deg)';
    }, 100);

    // 3. 木鱼缩放动画:放大→还原
    woodenFish.style.transform = 'scale(1.1)';
    setTimeout(() => {
        woodenFish.style.transform = 'scale(1)';
    }, 100);

    // 4. 功德数累加与更新
    score++;
    scoreElement.textContent = score;

    // 5. 生成"功德+1"漂浮文字
    const floatingText = document.createElement('div');
    floatingText.className = 'floating-text';
    floatingText.textContent = '功德+1';
    fishContainer.appendChild(floatingText);

    // 6. 动画结束后移除文字(避免DOM堆积)
    setTimeout(() => {
        floatingText.remove();
    }, 400);
});
  1. 关键技术点拆解

音效重置:clickSound.currentTime = 0 确保连续点击时音效不叠加,每次都是完整的 "敲击声";

动画同步:锤子旋转和木鱼缩放的过渡时长(0.1s)与定时器延迟(100ms)一致,动作协调;

DOM 优化:漂浮文字动画结束后通过 remove()移除,避免页面 DOM 元素过多导致性能问题;

无依赖设计:不使用任何框架,仅原生 API,兼容性覆盖所有现代浏览器。


各位互联网搭子,要是这篇文章成功引起了你的注意,别犹豫,关注、点赞、评论、分享走一波,让我们把这份默契延续下去,一起在知识的海洋里乘风破浪!

相关推荐
有点笨的蛋2 小时前
从值拷贝到深拷贝:彻底弄懂 JavaScript 的堆与栈
前端·javascript
BBB努力学习程序设计2 小时前
CSS3选项卡:纯CSS实现优雅的内容切换
前端·html
有点笨的蛋2 小时前
从零掌握 Ajax:一次请求带你读懂异步数据加载原理
前端·javascript·ajax
进击的野人2 小时前
JavaScript日期操作与DOM节点管理:构建动态网页的核心技术
前端·javascript
BBB努力学习程序设计2 小时前
Canvas入门指南:从零开始绘制你的第一个图形
前端·html
AAA简单玩转程序设计2 小时前
JS防抖:别再让按钮“手抖”连点了!
前端·javascript·html
晚夏_八月2 小时前
ES6 模块导出 export default 与 export 的区别?
前端
皮蛋瘦肉粥_1212 小时前
pink老师html5+css3day09
前端·css3·html5
Mintopia2 小时前
🧠 可定制化 AIGC:Web 用户个性化模型训练的技术门槛正在塌缩!
前端·人工智能·trae