如何为Phaser.js游戏添加与网页一致的滚动动画?
问题
我正在开发一个网站,通过hidden和show两个CSS类实现了滚动入场动画,同时集成了Phaser.js游戏。想让游戏也应用同样的滚动动画,但尝试将游戏脚本放入带有hidden类的div中并未生效。
现有代码
JS代码(app.js)
const observer = new IntersectionObserver((entries) =>{ entries.forEach((entry) => { console.log(entry) if(entry.isIntersecting){ entry.target.classList.add('show'); } else{ entry.target.classList.remove('show'); } }); }); const hiddenElements = document.querySelectorAll(".hidden"); hiddenElements.forEach((el)=> observer.observe(el)); function myfunction() { document.getElementById("Hacker1").style.color = "blue"; }; function myFunction1() { document.getElementById("Hacker1").style.color = "red"; } let pepole = prompt("Please enter your name"); if(pepole != null){ document.getElementById("demo").innerHTML = "Hello " + pepole + "! How are you today?"; }
Phaser.js代码(game.js)
function preload() { this.load.image('codey', 'https://content.codecademy.com/courses/learn-phaser/codey.png'); } function create() { this.add.sprite(50, 50, 'codey'); } const config = { type: Phaser.AUTO, width: 1300, height: 300, backgroundColor: "#5f2a55", scene: { create, preload } } const game = new Phaser.Game(config)
HTML代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <div class="scripts"> <script defer src="app.js"></script> <link rel="stylesheet" href="style.css"> </div> <body> <section> <h1 onmouseout="myFunction1()"onmouseover="myfunction()" style="font-size: 60px;"id="Hacker1"class="hidden">HackerXGames</h1> <p class="hidden">this is my way to play</p> </section> <section> <h1 style="font-size: 30px;" class="hidden" id="demo"></h1> </section> <section class="hidden"> <div class="hidden"> <script src="https://cdn.jsdelivr.net/npm/phaser@3.16.2/dist/phaser.js"></script> <script src="game.js"></script> </div> </section> </body> </html>
CSS代码(style.css)
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@200;400;700&display=swap"); body{ background-color: #131316; color: #ffffff; font-family: Poppins, sans-serif; padding: 0; margin: 0; } section { display: grid; place-items: center; align-content: center; min-height: 100vh; } .hidden{ opacity: 0; filter: blur(5px); transform: translateX(-100%); transition: all 1s; } .show { opacity: 1; filter: blur(0); transform: translateX(0); } .media{ display: flex; } .media:nth-child(2){ transition-delay: 200ms; } .media:nth-child(3){ transition-delay: 7s; }
解决方案
问题核心是Phaser的默认挂载行为:Phaser初始化时会把生成的canvas直接添加到body上,而非你加了hidden类的div里,导致滚动动画样式无法作用到游戏元素。按以下步骤修改即可:
1. 指定Phaser游戏挂载容器
修改game.js中的配置,添加parent属性指定游戏要挂载到的DOM元素ID:
const config = { type: Phaser.AUTO, width: 1300, height: 300, backgroundColor: "#5f2a55", parent: 'game-container', // 绑定到指定容器 scene: { create, preload } }
2. 调整HTML结构
- 移除包裹脚本的
hiddendiv,替换为一个空的游戏容器div并添加hidden类 - 修复HTML规范问题:将样式表链接放到
<head>内,脚本移到<body>末尾,确保DOM加载完成后再执行脚本
修改后的HTML:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="style.css"> </head> <body> <section> <h1 onmouseout="myFunction1()" onmouseover="myfunction()" style="font-size: 60px;" id="Hacker1" class="hidden">HackerXGames</h1> <p class="hidden">this is my way to play</p> </section> <section> <h1 style="font-size: 30px;" class="hidden" id="demo"></h1> </section> <section class="hidden"> <div id="game-container" class="hidden"></div> </section> <script src="https://cdn.jsdelivr.net/npm/phaser@3.16.2/dist/phaser.js"></script> <script src="game.js"></script> <script src="app.js"></script> </body> </html>
3. 验证效果
现在滚动到游戏所在的section时,IntersectionObserver会给section和游戏容器都加上show类,游戏就能和其他元素一样触发滚动入场动画了。
内容的提问来源于stack exchange,提问作者hackerhq
相关产品推荐
相关产品推荐

