Untitled

 avatar
unknown
plain_text
22 days ago
28 kB
6
Indexable
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <title>粉色梦幻·巨型爱心 | 心动合成与回归</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            user-select: none;
        }

        body {
            min-height: 100vh;
            background: radial-gradient(circle at 30% 10%, #ffb7c5, #ff7a95);
            display: flex;
            justify-content: center;
            align-items: center;
            font-family: 'Segoe UI', 'Quicksand', 'Poppins', system-ui, sans-serif;
            overflow: hidden;
            position: relative;
            cursor: default;
        }

        /* 主舞台容器 */
        .heart-stage {
            position: relative;
            width: 100vw;
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        /* 画布: 粒子与核心大爱心绘制 */
        canvas {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            display: block;
            pointer-events: none;
        }

        /* 封面层 (一开始的梦幻小爱心界面) */
        .cover {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: radial-gradient(ellipse at center, #ffc0d0, #ff8aab);
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            z-index: 30;
            backdrop-filter: blur(2px);
            transition: opacity 0.8s cubic-bezier(0.2, 0.9, 0.4, 1.2), visibility 0.8s;
            cursor: pointer;
            text-align: center;
        }

        .cover.hide {
            opacity: 0;
            visibility: hidden;
            pointer-events: none;
        }

        /* 返回按钮 (合成爱心后显示) */
        .back-button {
            position: absolute;
            bottom: 8%;
            left: 50%;
            transform: translateX(-50%);
            background: rgba(255, 240, 245, 0.9);
            backdrop-filter: blur(12px);
            border: none;
            padding: 12px 32px;
            border-radius: 60px;
            font-size: 1.2rem;
            font-weight: 600;
            color: #ff4370;
            letter-spacing: 1px;
            cursor: pointer;
            z-index: 40;
            box-shadow: 0 8px 20px rgba(255, 80, 120, 0.5);
            transition: all 0.3s ease;
            font-family: inherit;
            display: flex;
            align-items: center;
            gap: 8px;
            opacity: 0;
            visibility: hidden;
            pointer-events: none;
            border: 1px solid #ffb7c5;
        }

        .back-button.show {
            opacity: 1;
            visibility: visible;
            pointer-events: auto;
            animation: gentleRise 0.5s ease-out;
        }

        .back-button:hover {
            background: #ffebf0;
            transform: translateX(-50%) scale(1.03);
            box-shadow: 0 12px 28px #ff6085;
            color: #ff2a5c;
        }

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

        /* 封面浮动小爱心区域 */
        .floating-hearts {
            position: absolute;
            width: 100%;
            height: 100%;
            overflow: hidden;
            pointer-events: none;
            z-index: 1;
        }

        .float-heart {
            position: absolute;
            font-size: 26px;
            filter: drop-shadow(0 6px 12px rgba(255, 50, 90, 0.4));
            opacity: 0.85;
            animation: floatUp 7s linear infinite;
            bottom: -60px;
            left: calc(10% + 80% * var(--random-x, 0.5));
            animation-delay: calc(var(--delay, 0) * 1s);
            transform: scale(var(--scale, 1));
        }

        @keyframes floatUp {
            0% {
                transform: translateY(0) rotate(0deg) scale(var(--scale, 1));
                opacity: 0.9;
            }
            75% {
                opacity: 0.7;
            }
            100% {
                transform: translateY(-120vh) rotate(12deg) scale(0.5);
                opacity: 0;
            }
        }

        /* 封面文字内容 */
        .cover-content {
            position: relative;
            z-index: 12;
            text-align: center;
            transform: translateY(-8%);
        }

        .cover-title {
            font-size: 3.6rem;
            font-weight: 700;
            color: #fffaf2;
            text-shadow: 0 10px 25px #ff4d70;
            letter-spacing: 3px;
            margin-bottom: 20px;
            background: rgba(255, 200, 210, 0.4);
            padding: 12px 32px;
            border-radius: 100px;
            display: inline-block;
            backdrop-filter: blur(8px);
        }

        .cover-sub {
            font-size: 1.5rem;
            color: #fff5f0;
            background: rgba(255, 110, 135, 0.5);
            padding: 8px 28px;
            border-radius: 50px;
            backdrop-filter: blur(6px);
            margin-top: 18px;
            font-weight: 500;
        }

        .click-hint {
            position: absolute;
            bottom: 12%;
            left: 0;
            right: 0;
            font-size: 1.2rem;
            font-weight: 500;
            color: #fff0e6;
            background: #ff7f9a90;
            width: fit-content;
            margin: 0 auto;
            padding: 8px 28px;
            border-radius: 60px;
            backdrop-filter: blur(10px);
            animation: softPulse 1.4s infinite;
            pointer-events: none;
        }

        @keyframes softPulse {
            0% { transform: scale(1); background: #ff7f9a90; }
            50% { transform: scale(1.05); background: #ff6685b0; }
            100% { transform: scale(1); background: #ff7f9a90; }
        }

        /* 合成结束后的温馨悬浮语(非必要,装饰) */
        .heart-tip {
            position: absolute;
            bottom: 20%;
            left: 0;
            right: 0;
            text-align: center;
            font-size: 1.1rem;
            color: #fff3e6;
            background: rgba(255, 100, 130, 0.5);
            backdrop-filter: blur(6px);
            width: fit-content;
            margin: 0 auto;
            padding: 5px 18px;
            border-radius: 40px;
            z-index: 15;
            opacity: 0;
            transition: opacity 0.6s;
            pointer-events: none;
            white-space: nowrap;
        }

        .heart-tip.show {
            opacity: 0.85;
        }

        @media (max-width: 650px) {
            .cover-title { font-size: 2rem; padding: 6px 20px; }
            .cover-sub { font-size: 1rem; }
            .click-hint { font-size: 0.85rem; bottom: 10%;}
            .back-button { padding: 8px 24px; font-size: 1rem; bottom: 6%;}
            .heart-tip { font-size: 0.7rem; white-space: nowrap; bottom: 18%;}
        }
    </style>
</head>
<body>
<div class="heart-stage">
    <!-- 背景画布(粒子+巨型爱心) -->
    <canvas id="heartCanvas" width="800" height="800"></canvas>

    <!-- 封面层,内含浮动小爱心 -->
    <div class="cover" id="coverLayer">
        <div class="floating-hearts" id="floatHeartsContainer"></div>
        <div class="cover-content">
            <div class="cover-title">💗 粉色梦境 💗</div>
            <div class="cover-sub">✨ 轻触 · 凝聚永恒之心 ✨</div>
        </div>
        <div class="click-hint">🌸 点击任意位置 · 巨型爱心诞生 🌸</div>
    </div>

    <!-- 返回封页按钮(爱心合成后展示) -->
    <button class="back-button" id="backBtn">💞 重返梦幻扉页 💞</button>
    <div class="heart-tip" id="heartTip">❤️ 巨型爱心 · 为你跳动 ❤️</div>
</div>

<script>
    (function(){
        // ---------------- DOM 元素 ----------------
        const canvas = document.getElementById('heartCanvas');
        const ctx = canvas.getContext('2d');
        const coverDiv = document.getElementById('coverLayer');
        const backBtn = document.getElementById('backBtn');
        const heartTipDiv = document.getElementById('heartTip');
        const heartsContainer = document.getElementById('floatHeartsContainer');

        let width, height;
        let particles = [];          // 粒子系统
        let animationId = null;
        
        // 状态机
        let synthesizing = false;     // 正在合成
        let heartFormed = false;      // 巨型爱心已经完成
        let synthesisProgress = 0;    // 0..1 (主要用于过渡)
        
        // 心形目标点集合 (巨型爱心轮廓)
        let targetPoints = [];
        let heartbeatTime = 0;
        
        // ---------------- 巨型爱心参数 (更大,更饱满) ----------------
        // 经典心形曲线: x = 16 * sin(t)^3 , y = 13cos(t) - 5 cos(2t) - 2cos(3t) - cos(4t)
        // 为了显示更大爱心,大幅放大 (scaleFactor 从2.8提升到3.5左右,且偏移中心)
        function getHeartPoint(t, scaleFactor = 3.55, offsetX, offsetY) {
            const xRaw = 16 * Math.pow(Math.sin(t), 3);
            const yRaw = 13 * Math.cos(t) - 5 * Math.cos(2*t) - 2*Math.cos(3*t) - Math.cos(4*t);
            let px = xRaw * scaleFactor;
            let py = -yRaw * scaleFactor;   // 翻转Y轴让爱心正立
            px += offsetX;
            py += offsetY;
            return { x: px, y: py };
        }

        // 生成巨型爱心轮廓点 (增加密度,爱心更饱满)
        function generateGiantHeartPoints(numPoints = 240, scale = 3.65, centerX, centerY) {
            const points = [];
            for (let i = 0; i < numPoints; i++) {
                const t = (i / numPoints) * Math.PI * 2;
                const { x, y } = getHeartPoint(t, scale, centerX, centerY);
                points.push({ x, y, t });
            }
            return points;
        }

        // ----- 粒子系统初始化 (封面阶段 小粒子四处飘散) -----
        function initParticlesForCover(count = 400) {
            const newParticles = [];
            for (let i = 0; i < count; i++) {
                newParticles.push({
                    x: Math.random() * width,
                    y: Math.random() * height,
                    vx: (Math.random() - 0.5) * 1.0,
                    vy: (Math.random() - 0.5) * 0.8 - 0.2,
                    size: 3 + Math.random() * 9,
                    alpha: 0.6 + Math.random() * 0.4,
                    originalColor: `hsl(${340 + Math.random() * 25}, 85%, 68%)`,
                    targetX: null,
                    targetY: null,
                    isMovingToHeart: false
                });
            }
            return newParticles;
        }

        // 为所有粒子分配巨型爱心上的目标点 (合成时调用)
        function assignGiantHeartTargets() {
            if (!targetPoints.length) return;
            for (let i = 0; i < particles.length; i++) {
                // 随机从心形点集里选取一个目标,保证爱心轮廓被填满,视觉密集成巨型爱心
                const randomTarget = targetPoints[ Math.floor(Math.random() * targetPoints.length) ];
                particles[i].targetX = randomTarget.x;
                particles[i].targetY = randomTarget.y;
                particles[i].isMovingToHeart = true;
                // 停止随机飘移速度
                particles[i].vx = 0;
                particles[i].vy = 0;
            }
        }

        // 合成动画:逐渐移动到目标巨型爱心位置
        function updateSynthesisAnimation(speed = 0.058) {
            let allArrived = true;
            for (let p of particles) {
                if (p.isMovingToHeart && p.targetX !== null && p.targetY !== null) {
                    const dx = p.targetX - p.x;
                    const dy = p.targetY - p.y;
                    const distance = Math.hypot(dx, dy);
                    if (distance > 1.5) {
                        allArrived = false;
                        // 优雅移动, 先快后慢 效果自然
                        const moveX = dx * speed;
                        const moveY = dy * speed;
                        p.x += moveX;
                        p.y += moveY;
                        // 逐渐缩小粒子使爱心更精致
                        p.size *= 0.99;
                        if (p.size < 2.2) p.size = 2.2;
                    } else {
                        p.x = p.targetX;
                        p.y = p.targetY;
                    }
                }
            }
            if (allArrived && particles.length > 0 && !heartFormed) {
                // 合成完毕 巨型爱心凝聚完成
                synthesizing = false;
                heartFormed = true;
                // 显示返回按钮 + 温馨tip
                backBtn.classList.add('show');
                heartTipDiv.classList.add('show');
                // 过几秒tip淡一点但保留
                setTimeout(() => {
                    if(heartTipDiv) heartTipDiv.style.opacity = '0.6';
                }, 3000);
            }
        }

        // 心跳脉动效果: 让已经成型的爱心微微缩放 (模拟跳动)
        function applyHeartbeatToParticles() {
            if (!heartFormed) return;
            heartbeatTime += 0.028;
            const beatScale = 1 + Math.sin(heartbeatTime * 9) * 0.022;
            const centerX = width / 2;
            const centerY = height / 2 - 18;  // 视觉中心微调
            
            for (let p of particles) {
                if (p.targetX && p.targetY) {
                    const dx = p.targetX - centerX;
                    const dy = p.targetY - centerY;
                    const originalDist = Math.hypot(dx, dy);
                    if (originalDist > 0.1) {
                        const angle = Math.atan2(dy, dx);
                        const newDist = originalDist * beatScale;
                        p.x = centerX + Math.cos(angle) * newDist;
                        p.y = centerY + Math.sin(angle) * newDist;
                    } else {
                        p.x = p.targetX;
                        p.y = p.targetY;
                    }
                }
            }
        }

        // 绘制所有粒子 (爱心形状或漂浮粒子)
        function drawParticles() {
            for (let p of particles) {
                ctx.beginPath();
                // 使用粉红/亮粉色径向渐变
                const grad = ctx.createRadialGradient(p.x-2, p.y-2, 2, p.x, p.y, p.size);
                grad.addColorStop(0, '#ffe0e8');
                grad.addColorStop(0.6, '#ff5f89');
                grad.addColorStop(1, '#ff2f60');
                ctx.fillStyle = grad;
                ctx.shadowBlur = 8;
                ctx.shadowColor = '#ff7f9f';
                ctx.arc(p.x, p.y, p.size * 0.72, 0, Math.PI * 2);
                ctx.fill();
                // 高光小白点
                ctx.beginPath();
                ctx.fillStyle = '#fff9fc';
                ctx.arc(p.x-1.5, p.y-1.5, p.size*0.22, 0, Math.PI*2);
                ctx.fill();
            }
            ctx.shadowBlur = 0;
        }

        // 封面阶段 自然飘动的粒子更新
        function updateFloatingParticles() {
            for (let p of particles) {
                p.x += p.vx;
                p.y += p.vy;
                // 柔和边界环绕 (避免消失)
                if (p.x < -30) p.x = width + 20;
                if (p.x > width + 30) p.x = -20;
                if (p.y < -40) p.y = height + 30;
                if (p.y > height + 40) p.y = -30;
                // 随机微飘
                p.vx += (Math.random() - 0.5) * 0.08;
                p.vy += (Math.random() - 0.5) * 0.06;
                let maxSpeed = 1.1;
                p.vx = Math.min(maxSpeed, Math.max(-maxSpeed, p.vx));
                p.vy = Math.min(maxSpeed, Math.max(-maxSpeed, p.vy));
            }
        }

        // 绘制额外巨型爱心光晕轮廓(增强大爱心视觉)
        function drawGiantHeartGlow() {
            if (!heartFormed) return;
            if (targetPoints.length === 0) return;
            ctx.save();
            ctx.beginPath();
            const step = Math.PI * 2 / 220;
            for (let i = 0; i <= 220; i++) {
                const t = i * step;
                const pt = getHeartPoint(t, 3.7, width/2, height/2 - 18);
                if (i === 0) ctx.moveTo(pt.x, pt.y);
                else ctx.lineTo(pt.x, pt.y);
            }
            ctx.closePath();
            ctx.shadowBlur = 22;
            ctx.shadowColor = '#ff4870';
            ctx.strokeStyle = '#ffb0ca';
            ctx.lineWidth = 6;
            ctx.stroke();
            ctx.shadowBlur = 8;
            ctx.strokeStyle = '#fff9ef';
            ctx.lineWidth = 2.5;
            ctx.stroke();
            // 增加内发光
            ctx.beginPath();
            for (let i = 0; i <= 220; i++) {
                const t = i * step;
                const pt = getHeartPoint(t, 3.68, width/2, height/2 - 18);
                if (i === 0) ctx.moveTo(pt.x, pt.y);
                else ctx.lineTo(pt.x, pt.y);
            }
            ctx.strokeStyle = '#ff80a2';
            ctx.lineWidth = 2;
            ctx.stroke();
            ctx.restore();
        }
        
        // 额外增加满屏飘浮小光晕(爱心形成时背景浪漫)
        function drawBackgroundSparkles() {
            if (!heartFormed) return;
            for (let i = 0; i < 80; i++) {
                if (i % 2 === 0) continue; // 轻量点缀
                const fx = (Math.sin(heartbeatTime * 2 + i) * 0.2 + 0.5) * width;
                const fy = (Math.cos(heartbeatTime * 1.7 + i) * 0.15 + 0.5) * height;
                ctx.beginPath();
                ctx.fillStyle = `rgba(255, 200, 210, ${0.2 + Math.sin(heartbeatTime * 3 + i) * 0.1})`;
                ctx.arc(fx, fy, 3, 0, Math.PI*2);
                ctx.fill();
            }
        }

        // ----- 主渲染循环 (状态机) -----
        function render() {
            if (!ctx) return;
            ctx.clearRect(0, 0, width, height);
            // 梦幻粉色渐变背景
            const gradBack = ctx.createLinearGradient(0, 0, width, height);
            gradBack.addColorStop(0, '#ffb8ca');
            gradBack.addColorStop(1, '#ff90ad');
            ctx.fillStyle = gradBack;
            ctx.fillRect(0, 0, width, height);
            
            ctx.globalCompositeOperation = 'lighter';
            
            if (synthesizing) {
                // 合成动画:粒子向巨型爱心聚集
                drawParticles();
                updateSynthesisAnimation(0.062);
            } 
            else if (heartFormed) {
                // 巨型爱心已形成: 呼吸脉动 + 光效 + 粒子精美跳动
                applyHeartbeatToParticles();
                drawParticles();
                drawGiantHeartGlow();
                drawBackgroundSparkles();
            } 
            else {
                // 初始封面模式: 自由飘浮粒子 + 轻盈背景
                drawParticles();
                updateFloatingParticles();
            }
            
            ctx.globalCompositeOperation = 'source-over';
            // 增加一层柔光
            ctx.fillStyle = '#ffb7c520';
            ctx.fillRect(0, 0, width, height);
            requestAnimationFrame(render);
        }

        // ---------- 重置所有状态,回到粉色封面 (保留返回功能) ----------
        function resetToCover() {
            // 重置状态变量
            synthesizing = false;
            heartFormed = false;
            synthesisProgress = 0;
            heartbeatTime = 0;
            // 重新生成粒子 (新的大批量漂浮小爱心粒子)
            particles = initParticlesForCover(440);
            // 清除爱心目标点引用
            targetPoints = [];
            for(let p of particles) {
                p.isMovingToHeart = false;
                p.targetX = null;
                p.targetY = null;
            }
            // 隐藏返回按钮 和提示语
            backBtn.classList.remove('show');
            heartTipDiv.classList.remove('show');
            heartTipDiv.style.opacity = '';
            // 让封面层重新出现 (移除hide)
            coverDiv.classList.remove('hide');
            // 重新生成封面浮动小爱心 (丰富视觉效果)
            regenerateCoverFloatingHearts();
            // 重新适应画布目标 (确保所有粒子在尺寸内)
            resizeAndAlignParticles();
        }

        // 辅助:让浮动小爱心封面重新丰盈
        function regenerateCoverFloatingHearts() {
            if(heartsContainer) {
                heartsContainer.innerHTML = '';
                const newCount = 48;
                for(let i=0;i<newCount;i++) {
                    const heartDiv = document.createElement('div');
                    heartDiv.className = 'float-heart';
                    const scale = 0.6 + Math.random() * 1.3;
                    heartDiv.style.setProperty('--scale', scale);
                    heartDiv.style.left = Math.random() * 100 + '%';
                    heartDiv.style.animationDuration = 4 + Math.random() * 6 + 's';
                    heartDiv.style.animationDelay = Math.random() * 8 + 's';
                    heartDiv.style.fontSize = (18 + Math.random() * 30) + 'px';
                    const icons = ['💖','🌸','💗','💕','💓','✨','💞','🌷','💘'];
                    heartDiv.innerHTML = icons[Math.floor(Math.random() * icons.length)];
                    heartsContainer.appendChild(heartDiv);
                }
                // 动态补充
                setInterval(() => {
                    if(coverDiv && !coverDiv.classList.contains('hide') && heartsContainer.children.length < 70) {
                        const extraHeart = document.createElement('div');
                        extraHeart.className = 'float-heart';
                        extraHeart.style.left = Math.random()*100+'%';
                        extraHeart.style.animationDuration = 3+Math.random()*6+'s';
                        extraHeart.style.fontSize = (16+Math.random()*28)+'px';
                        extraHeart.innerHTML = ['💖','🌸','💗','💞','💓','✨'][Math.floor(Math.random()*6)];
                        heartsContainer.appendChild(extraHeart);
                        setTimeout(()=> extraHeart.remove(), 7500);
                    }
                }, 2000);
            }
        }
        
        // 尺寸变更时调整粒子位置并重新生成心形轮廓时不影响已合成状态
        function resizeAndAlignParticles() {
            if(!heartFormed && !synthesizing) {
                // 封面或未合成,重新随机分布粒子 适配新窗口
                particles = initParticlesForCover(420);
            } else if(heartFormed) {
                // 如果已经合成爱心但改变窗口大小,重新映射巨型爱心位置,保持爱心展示
                const centerX = width/2;
                const centerY = height/2 - 18;
                const newGiantTargets = generateGiantHeartPoints(260, 3.72, centerX, centerY);
                targetPoints = newGiantTargets;
                for(let i=0; i<particles.length && i<targetPoints.length; i++) {
                    if(particles[i]) {
                        particles[i].targetX = targetPoints[i % targetPoints.length].x;
                        particles[i].targetY = targetPoints[i % targetPoints.length].y;
                        particles[i].x = particles[i].targetX;
                        particles[i].y = particles[i].targetY;
                        particles[i].isMovingToHeart = true;
                    }
                }
            }
        }

        // 开启合成(封面点击时调用)
        function startGiantHeartSynthesis() {
            if(synthesizing || heartFormed) return;
            synthesizing = true;
            // 生成巨型爱心目标点(更大更明显)
            const centerX = width/2;
            const centerY = height/2 - 18;
            targetPoints = generateGiantHeartPoints(280, 3.78, centerX, centerY);
            assignGiantHeartTargets();
        }

        // ----- 封面点击触发合成 -----
        function onCoverClick(e) {
            if(heartFormed || synthesizing) return;
            coverDiv.classList.add('hide');
            startGiantHeartSynthesis();
        }
        
        // 返回按钮逻辑:重置所有,回到封面页
        function onBackToCover() {
            if(synthesizing) return; // 合成中不能打断过于生硬,但可以稍后重置
            resetToCover();
        }

        // ----- 窗口自适应 -----
        function resizeCanvas() {
            width = window.innerWidth;
            height = window.innerHeight;
            canvas.width = width;
            canvas.height = height;
            if(!heartFormed && !synthesizing) {
                particles = initParticlesForCover(430);
            } else if(heartFormed) {
                const centerX = width/2;
                const centerY = height/2 - 18;
                const newTargets = generateGiantHeartPoints(280, 3.75, centerX, centerY);
                targetPoints = newTargets;
                for(let i=0; i<particles.length && i<targetPoints.length; i++) {
                    if(particles[i]) {
                        particles[i].targetX = targetPoints[i % targetPoints.length].x;
                        particles[i].targetY = targetPoints[i % targetPoints.length].y;
                        particles[i].x = particles[i].targetX;
                        particles[i].y = particles[i].targetY;
                    }
                }
            } else if(synthesizing) {
                // 合成中调整尺寸需谨慎: 重新生成目标且粒子重新映射
                const centerX = width/2;
                const centerY = height/2 - 18;
                const freshTargets = generateGiantHeartPoints(280, 3.75, centerX, centerY);
                targetPoints = freshTargets;
                for(let i=0; i<particles.length; i++) {
                    if(particles[i].isMovingToHeart) {
                        const randTarget = targetPoints[Math.floor(Math.random() * targetPoints.length)];
                        particles[i].targetX = randTarget.x;
                        particles[i].targetY = randTarget.y;
                    }
                }
            }
        }

        // 事件绑定
        coverDiv.addEventListener('click', onCoverClick);
        backBtn.addEventListener('click', onBackToCover);
        window.addEventListener('resize', () => {
            resizeCanvas();
        });
        
        // 初始化
        resizeCanvas();
        regenerateCoverFloatingHearts();
        particles = initParticlesForCover(440);
        // 启动动画循环
        animationId = requestAnimationFrame(render);
    })();
</script>
</body>
</html>
Editor is loading...
Leave a Comment