You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Codepen移植的CSS与JavaScript动画无法运行问题排查

Why the Animation Isn't Working & How to Fix It

Let's break down the issues stopping your animation from running and walk through the fixes:

1. Missing GSAP Library Dependency

The biggest issue is that your code uses TweenLite (from the GSAP animation library) to animate the floating points, but you haven't included GSAP in your HTML page. Without this library, the browser doesn't recognize TweenLite, so the shiftPoint function (which drives the core movement) fails silently (or throws an error in the console).

Fix: Add GSAP to Your Page

Include the GSAP Core library via CDN in your <head> section. This gives you access to TweenLite and the Circ easing function needed for the animation:

<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>

(Note: Newer GSAP versions still support TweenLite as an alias, so this works seamlessly with your existing code.)

2. Unclosed HTML Tags

Your <h1> element has mismatched <span> tags, which can cause DOM parsing issues that might indirectly affect script behavior:

<!-- Before (broken) -->
<h1 class="main-title"><span class="thin">TitleGoes <span class="thin">.here</h1>

<!-- After (fixed) -->
<h1 class="main-title"><span class="thin">TitleGoes</span> <span class="thin">.here</span></h1>

3. Missing Initial active Property in Circle Class

The Circle class's draw method checks for an active property, but this isn't initialized in the constructor. Adding it prevents potential undefined value warnings:

// Inside the Circle constructor function
(function() {
    _this.pos = pos || null;
    _this.radius = rad || null;
    _this.color = color || null;
    _this.active = 0; // Add this line to initialize the active property
})();

Full Fixed Code

Here's the complete corrected HTML with all fixes applied:

<html>
<head>
    <style>
        /* Header */
        .large-header {
            position: relative;
            width: 100%;
            background: #333;
            overflow: hidden;
            background-size: cover;
            background-position: center center;
            z-index: 1;
        }

        #large-header {
            background-image: url("https://www.marcoguglie.it/Codepen/AnimatedHeaderBg/demo-1/img/demo-1-bg.jpg");
        }

        .main-title {
            position: absolute;
            margin: 0;
            padding: 0;
            color: #f9f1e9;
            text-align: center;
            top: 50%;
            left: 50%;
            -webkit-transform: translate3d(-50%, -50%, 0);
            transform: translate3d(-50%, -50%, 0);
        }

        .demo-1 .main-title {
            text-transform: uppercase;
            font-size: 4.2em;
            letter-spacing: 0.1em;
        }

        .main-title .thin {
            font-weight: 200;
        }

        @media only screen and (max-width: 768px) {
            .demo-1 .main-title {
                font-size: 3em;
            }
        }
    </style>
    <!-- Add GSAP Library -->
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>
</head>
<body>
    <div id="large-header" class="large-header">
        <canvas id="demo-canvas"></canvas>
        <!-- Fixed span tags -->
        <h1 class="main-title"><span class="thin">TitleGoes</span> <span class="thin">.here</span></h1>
    </div>
    <script>
        (function() {
            var width, height, largeHeader, canvas, ctx, points, target, animateHeader = true;

            // Main
            initHeader();
            initAnimation();
            addListeners();

            function initHeader() {
                width = window.innerWidth;
                height = window.innerHeight;
                target = {x: width/2, y: height/2};

                largeHeader = document.getElementById('large-header');
                largeHeader.style.height = height+'px';

                canvas = document.getElementById('demo-canvas');
                canvas.width = width;
                canvas.height = height;
                ctx = canvas.getContext('2d');

                // create points
                points = [];
                for(var x = 0; x < width; x = x + width/20) {
                    for(var y = 0; y < height; y = y + height/20) {
                        var px = x + Math.random()*width/20;
                        var py = y + Math.random()*height/20;
                        var p = {x: px, originX: px, y: py, originY: py };
                        points.push(p);
                    }
                }

                // for each point find the 5 closest points
                for(var i = 0; i < points.length; i++) {
                    var closest = [];
                    var p1 = points[i];
                    for(var j = 0; j < points.length; j++) {
                        var p2 = points[j]
                        if(!(p1 == p2)) {
                            var placed = false;
                            for(var k = 0; k < 5; k++) {
                                if(!placed) {
                                    if(closest[k] == undefined) {
                                        closest[k] = p2;
                                        placed = true;
                                    }
                                }
                            }
                            for(var k = 0; k < 5; k++) {
                                if(!placed) {
                                    if(getDistance(p1, p2) < getDistance(p1, closest[k])) {
                                        closest[k] = p2;
                                        placed = true;
                                    }
                                }
                            }
                        }
                    }
                    p1.closest = closest;
                }

                // assign a circle to each point
                for(var i in points) {
                    var c = new Circle(points[i], 2+Math.random()*2, 'rgba(255,255,255,0.3)');
                    points[i].circle = c;
                }
            }

            // Event handling
            function addListeners() {
                if(!('ontouchstart' in window)) {
                    window.addEventListener('mousemove', mouseMove);
                }
                window.addEventListener('scroll', scrollCheck);
                window.addEventListener('resize', resize);
            }

            function mouseMove(e) {
                var posx = posy = 0;
                if (e.pageX || e.pageY) {
                    posx = e.pageX;
                    posy = e.pageY;
                }
                else if (e.clientX || e.clientY)    {
                    posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
                    posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
                }
                target.x = posx;
                target.y = posy;
            }

            function scrollCheck() {
                if(document.body.scrollTop > height) animateHeader = false;
                else animateHeader = true;
            }

            function resize() {
                width = window.innerWidth;
                height = window.innerHeight;
                largeHeader.style.height = height+'px';
                canvas.width = width;
                canvas.height = height;
            }

            // animation
            function initAnimation() {
                animate();
                for(var i in points) {
                    shiftPoint(points[i]);
                }
            }

            function animate() {
                if(animateHeader) {
                    ctx.clearRect(0,0,width,height);
                    for(var i in points) {
                        // detect points in range
                        if(Math.abs(getDistance(target, points[i])) < 4000) {
                            points[i].active = 0.3;
                            points[i].circle.active = 0.6;
                        } else if(Math.abs(getDistance(target, points[i])) < 20000) {
                            points[i].active = 0.1;
                            points[i].circle.active = 0.3;
                        } else if(Math.abs(getDistance(target, points[i])) < 40000) {
                            points[i].active = 0.02;
                            points[i].circle.active = 0.1;
                        } else {
                            points[i].active = 0;
                            points[i].circle.active = 0;
                        }

                        drawLines(points[i]);
                        points[i].circle.draw();
                    }
                }
                requestAnimationFrame(animate);
            }

            function shiftPoint(p) {
                TweenLite.to(p, 1+1*Math.random(), {x:p.originX-50+Math.random()*100, y: p.originY-50+Math.random()*100, ease:Circ.easeInOut, onComplete: function() {
                    shiftPoint(p);
                }});
            }

            // Canvas manipulation
            function drawLines(p) {
                if(!p.active) return;
                for(var i in p.closest) {
                    ctx.beginPath();
                    ctx.moveTo(p.x, p.y);
                    ctx.lineTo(p.closest[i].x, p.closest[i].y);
                    ctx.strokeStyle = 'rgba(156,217,249,'+ p.active+')';
                    ctx.stroke();
                }
            }

            function Circle(pos,rad,color) {
                var _this = this;

                // constructor
                (function() {
                    _this.pos = pos || null;
                    _this.radius = rad || null;
                    _this.color = color || null;
                    _this.active = 0; // Initialize active property
                })();

                this.draw = function() {
                    if(!_this.active) return;
                    ctx.beginPath();
                    ctx.arc(_this.pos.x, _this.pos.y, _this.radius, 0, 2 * Math.PI, false);
                    ctx.fillStyle = 'rgba(156,217,249,'+ _this.active+')';
                    ctx.fill();
                };
            }

            // Util
            function getDistance(p1, p2) {
                return Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2);
            }

        })();
    </script>
</body>
</html>

After applying these fixes, the animation will work exactly as it does on Codepen: points will float randomly, and connecting lines will appear when your mouse moves near them.

内容的提问来源于stack exchange,提问作者Compoot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:48:53