我有一个app-object构造函数,如下所示:
var app = function(loadedsettings) {
return {
init: function() {
this.loop();
},
loop: function() {
this.update();
window.requestAnimationFrame(this.loop);
},
update: function() {
//loop through settings and call update on every object.
},
settings: [
//array of settings objects, all with update methods.
]
};
}
Run Code Online (Sandbox Code Playgroud)
然后,当我这样做:
var theApp = app(settings);
theApp.init();
Run Code Online (Sandbox Code Playgroud)
我明白了:
Uncaught TypeError: Object [object global] has no method 'update'
Run Code Online (Sandbox Code Playgroud)
因为当调用requestAnimationFrame时,循环函数内的this-value设置为window.
有没有人知道如何调用requestAnimatinFrame并将'theApp'对象设置为this-value?
我正在使用 Paul Irish 的以下片段:
// requestAnimationFrame shim & fallback
window.requestAnimFrame = (function () {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
Run Code Online (Sandbox Code Playgroud)
我也看到了一个 polyfill,但我还没有在所有浏览器中测试过这个 shim,所以我不确定我是否需要 polyfill。也许我不会,节省文件大小。
我想知道我是否真的需要打电话给cancelAnimationFrame某个地方,如果是这样,我想我需要另一个垫片。与上面相反的东西:
// cancelAnimationFrame shim & fallback
window.cancelAnimFrame = (function () {
return window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || function (callback) {
window.clearTimeout(callback);
};
})();
Run Code Online (Sandbox Code Playgroud)
基本上我尝试了console.log在其中运行的函数,requestAnimationFrame我可以看到日志何时停止,所以我猜动画帧不再使用......
我的功能step()是这样结束的:
if (progress == 1) return;
requestAnimFrame(step);
Run Code Online (Sandbox Code Playgroud)
我真的很关心这一点,而且我仍在全面学习动画。为我创建动画很痛苦,尤其是使用缓动方程。直接回答就可以了,如果需要取消,请给我举个例子如何?现在我相信 cancelAnimationFrame 仅用于手动取消或一些复杂的动画。嗯,这只是我的想法,我还不确定。
我正在将 requestAnimationFrame 循环用于秒表和其他一些动画。我使用从 rAF 返回的时间戳来获取时间,但是当我停止循环以暂停计时器,等待几秒钟,然后再次启动循环时,计时器将显示总时间。
我需要能够暂停计时器并从暂停的时间继续。有没有办法在暂停计时器后重置时间戳变量?如果您需要我发布一些代码,请告诉我,或者如果您需要我进一步解释自己,我会这样做。
编辑
var frames = 0,
startTime = null,
lastTime = null,
fps = 1000/120,
isRunning = false,
pTime = 0,
timeElapsed;
function loop(timeStamp){
if(!startTime) startTime = timeStamp;
var timeDiff = lastTime ? (timeStamp - lastTime) : fps,
timeScale = timeDiff / fps,
timeElapsed += (timeStamp - startTime)/1000,
lastTime = timeStamp;
if(isRunning){
requestAnimationFrame(loop);
gField.t.text = ++frames + "f / "+parseInt(timeElapsed - pTime)+"s = "+parseInt(frames/(timeElapsed-pTime)) + "fps\n"+(timeDiff).toFixed(2);
}
/*
canvas manipulation e.g.
particle.x += acc*timeElapsed;
*/ …Run Code Online (Sandbox Code Playgroud) 我正在努力克制requestanimationframe.
说这requestanimationframe是一个浏览器API 是否正确,它使得影响绘制的用户界面的逻辑能够在下一次到图形子系统的接口之前尽力完成,以避免浪费精力绘画由于物理屏幕刷新周期和应用程序渲染循环之间的相位差异,从未进入屏幕的帧?
在观看 Google IO17 时,我了解了双重 requestAnimationFrame 方法,但我无法真正理解它,也许是因为我几乎不参与网络动画。
但是,我认为很高兴知道它是如何工作的以及何时将事情加倍,就像 Addy Osmani 提出的 Twitter 选项卡示例一样。谢谢!
我想为使用requestAnimationFrame和的模块编写一个开玩笑的单元测试cancelAnimationFrame。
我尝试用我自己的模拟覆盖 window.requestAnimationFrame(如本答案中所建议的那样),但该模块继续使用 jsdom 提供的实现。
我目前的方法是使用requestAnimationFrame来自 jsdom的(以某种方式)内置实现,它似乎在幕后使用setTimeout,应该可以通过使用jest.useFakeTimers().
jest.useFakeTimers();
describe("fakeTimers", () => {
test.only("setTimeout and trigger", () => {
const order: number[] = [];
expect(order).toEqual([]);
setTimeout(t => order.push(1));
expect(order).toEqual([]);
jest.runAllTimers();
expect(order).toEqual([1]);
});
test.only("requestAnimationFrame and runAllTimers", () => {
const order: number[] = [];
expect(order).toEqual([]);
requestAnimationFrame(t => order.push(1));
expect(order).toEqual([]);
jest.runAllTimers();
expect(order).toEqual([1]);
});
});
Run Code Online (Sandbox Code Playgroud)
第一次测试成功,第二次失败,因为order是空的。
测试依赖于requestAnimationFrame(). 特别是如果我需要测试帧被取消的条件?
[answered]
我正在测试我的浏览器的fps为html5游戏.
我有这个代码:
var requestAnimationFrame = ( function() {
return window.requestAnimationFrame || //Chromium
window.webkitRequestAnimationFrame || //Webkit
window.mozRequestAnimationFrame || //Mozilla Geko
window.oRequestAnimationFrame || //Opera Presto
window.msRequestAnimationFrame || //IE Trident?
function(callback) { //Fallback function
window.setTimeout(callback, 1000/60);
}
})();
var hits = 0;
var last = new Date().getTime();
var step = (function(){
now = new Date().getTime();
hits += 1;
if( now - last >= 1000 ){
last += 1000;
console.log( "fps: "+ hits );
hits = 0;
}
requestAnimationFrame( step );
})();
Run Code Online (Sandbox Code Playgroud)
它在Chrome上出现以下错误: …
渲染画布的函数是类的原型方法,如下所示:
Engine.prototype.renderCameras = function() {
console.log('render ok');
}
当我尝试直接运行此代码时,它工作正常:
engine.renderCameras()
>>> render ok
Run Code Online (Sandbox Code Playgroud)
当我尝试使用requestAnimationFrame运行它时,在Chrome或Firefox中,我得到了这个:
window.requestAnimFrame(engine.renderCameras())
>>> render ok
>>> Error: Component returned failure code: 0x80570009 (NS_ERROR_XPC_BAD_CONVERT_JS) [nsIDOMWindow.mozRequestAnimationFrame]
Run Code Online (Sandbox Code Playgroud)
它运行,但它总是抛出一个错误.这不酷.
当我尝试像这样运行它:
window.requestAnimFrame(engine.renderCameras)
>>> 0
Run Code Online (Sandbox Code Playgroud)
它什么都不做.
我能够通过使用闭包来解决这个问题,但我仍然想知道为什么我不能将这样的函数传递给requestAnimationFrame.
我想知道如何只在真正需要时调用该animate函数requestAnimationFrame.目前,我animate一直在调用产生开销的东西.
我已经尝试在我的animate函数内部进行比较targetRadius和初始化radius并在它们相同时返回false.不幸的是,这根本不起作用.
有人可以解释我如何解决这个问题吗?
HTML:
<canvas id="ddayCanvas" width="288" height="288" data-image="http://www.topdesignmag.com/wp-content/uploads/2011/07/64.png">
<div>
<div class="product-image"></div>
<div class="product-box">...</div>
<a href="#" class="overlay">...</a>
</div>
</canvas>
Run Code Online (Sandbox Code Playgroud)
JS:
// Options
var maxImageWidth = 250,
maxImageHeight = 196;
var canvas = $('#ddayCanvas'),
canvasWidth = canvas.width(),
canvasHeight = canvas.height(),
sectorColor = $('.product-box').css('background-color'),
context = canvas[0].getContext('2d'),
imageSrc = canvas.data('image'),
imageObj = new Image(),
imageWidth, imageHeight,
mouseover = false;
imageObj.onload = function() {
imageWidth = this.width;
imageHeight = this.height; …Run Code Online (Sandbox Code Playgroud) 试着玩RXJS和Scheduler.最后,我希望在滚动事件上有一个请求动画帧.
问题:我遇到类型错误:属性animationFrame不存在于调度程序类型上
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/observable/of';
import 'rxjs/add/observable/timer';
import 'rxjs/add/operator/repeat';
import 'rxjs/add/operator/takeUntil';
import { Scheduler } from 'rxjs/Scheduler';
Observable
.of(0, Scheduler.animationFrame) // error here
.repeat()
.takeUntil(Observable.timer(1000))
.subscribe(() => console.log(x++));
Run Code Online (Sandbox Code Playgroud)
如何识别animationFrame?
javascript ×8
animation ×2
canvas ×2
html5-canvas ×2
css ×1
html ×1
html5 ×1
jestjs ×1
jquery ×1
jsdom ×1
observable ×1
rxjs ×1
scheduler ×1
settimeout ×1
timer ×1