cor*_*zza 63 html javascript fullscreen webgl three.js
我正在使用带有WebGL渲染器的Three.js来创建一个在play
点击链接时全屏显示的游戏.对于动画,我用requestAnimationFrame
.
我这样发起:
self.animate = function()
{
self.camera.lookAt(self.scene.position);
self.renderer.render(self.scene, self.camera);
if (self.willAnimate)
window.requestAnimationFrame(self.animate, self.renderer.domElement);
}
self.startAnimating = function()
{
self.willAnimate = true;
self.animate();
}
self.stopAnimating = function()
{
self.willAnimate = false;
}
Run Code Online (Sandbox Code Playgroud)
当我想,我称之为startAnimating
方法,是的,它确实按预期工作.但是,当我调用该stopAnimating
函数时,事情就会破裂!没有报告错误,但......
设置基本上是这样的:
play
页面上有一个链接domElement
应全屏显示,并且确实如此startAnimating
调用该方法,渲染器开始渲染内容fullscreenchange
事件并执行该stopAnimating
方法我很确定我的其他代码是好的,而且我以某种方式requestAnimationFrame
以错误的方式停止.我的解释可能很糟糕,所以我将代码上传到我的网站,你可以在这里看到它:http://banehq.com/Placeholdername/main.html.
这是我不试图调用动画方法的版本,以及完整的屏幕内外工作:http://banehq.com/Correct/Placeholdername/main.html.
一旦play
第一次点击,游戏就会初始化并start
执行它的方法.一旦全屏退出,stop
就会执行游戏的方法.每隔一次play
点击一次,游戏只执行它的start
方法,因为不需要再次初始化它.
以下是它的外观:
var playLinkHasBeenClicked = function()
{
if (!started)
{
started = true;
game = new Game(container); //"container" is an empty div
}
game.start();
}
Run Code Online (Sandbox Code Playgroud)
以下是这些start
和stop
方法的样子:
self.start = function()
{
self.container.appendChild(game.renderer.domElement); //Add the renderer's domElement to an empty div
THREEx.FullScreen.request(self.container); //Request fullscreen on the div
self.renderer.setSize(screen.width, screen.height); //Adjust screensize
self.startAnimating();
}
self.stop = function()
{
self.container.removeChild(game.renderer.domElement); //Remove the renderer from the div
self.renderer.setSize(0, 0); //I guess this isn't needed, but welp
self.stopAnimating();
}
Run Code Online (Sandbox Code Playgroud)
这和工作版本之间的唯一区别是,startAnimating
和stopAnimating
方法调用中start
和stop
方法被注释掉.
gma*_*man 113
启动/停止的一种方法是这样的
var requestId;
function loop(time) {
requestId = undefined;
...
// do stuff
...
start();
}
function start() {
if (!requestId) {
requestId = window.requestAnimationFrame(loop);
}
}
function stop() {
if (requestId) {
window.cancelAnimationFrame(requestId);
requestId = undefined;
}
}
Run Code Online (Sandbox Code Playgroud)
工作范例:
const timeElem = document.querySelector("#time");
var requestId;
function loop(time) {
requestId = undefined;
doStuff(time)
start();
}
function start() {
if (!requestId) {
requestId = window.requestAnimationFrame(loop);
}
}
function stop() {
if (requestId) {
window.cancelAnimationFrame(requestId);
requestId = undefined;
}
}
function doStuff(time) {
timeElem.textContent = (time * 0.001).toFixed(2);
}
document.querySelector("#start").addEventListener('click', function() {
start();
});
document.querySelector("#stop").addEventListener('click', function() {
stop();
});
Run Code Online (Sandbox Code Playgroud)
<button id="start">start</button>
<button id="stop">stop</button>
<div id="time"></div>
Run Code Online (Sandbox Code Playgroud)
小智 18
停止就像不再调用requestAnimationFrame一样简单,重新启动就是再次调用它.EX)
var pause = false;
function loop(){
//... your stuff;
if(pause) return;
window.requestionAnimationFrame(loop);
}
loop(); //to start it off
pause = true; //to stop it
loop(); //to restart it
Run Code Online (Sandbox Code Playgroud)
var myAnim //your requestId
function anim()
{
//bla bla bla
//it's important to update the requestId each time you're calling reuestAnimationFrame
myAnim=requestAnimationFrame(anim)
}
Run Code Online (Sandbox Code Playgroud)
让我们开始吧
myAnim=requestAnimationFrame(anim)
Run Code Online (Sandbox Code Playgroud)
让我们阻止它
//the cancelation uses the last requestId
cancelAnimationFrame(myAnim)
Run Code Online (Sandbox Code Playgroud)
因此,在做了更多测试之后,我发现确实是我的其他代码造成了问题,而不是动画停止(毕竟这是一个简单的递归)。问题在于从页面动态添加和删除渲染器的 domElement。在我停止这样做之后,因为确实没有理由这样做,并且在初始化发生时将其包含在内,一切都开始正常工作。