JavaScript 添加到 requestAnimationFrame 函数
JavaScript Adding to requestAnimationFrame function
问题可以参考Three.JS框架,但我认为是一般的JS问题。
animate();
function animate() {
{doSomething}
requestAnimationFrame( animate );
}
所以函数 animate() 运行每一帧并做一些事情。
问题是如何即时将 {doAnotherSomething}
添加到 animate()
?
function anEventHappened(){
//adding some methods to animate
}
有几种方法可以做到这一点。但是您将不得不以某种方式预见此动画函数中的某些内容,这些内容可以检测到需要完成更多工作。这个 "something" 可以是一个数组,其中包含作为额外执行的函数。最初该数组为空,但在某些情况下您可以向该列表添加一个函数(或从中删除一个函数)。
这是一个实际的例子:
let container = document.querySelector("pre");
let todoList = []; // <--- list of functions to execute also as extras
animate();
function animate() {
todoList.forEach(f => f()); // execute whatever is in the todo-list
moveText(container);
requestAnimationFrame(animate);
}
document.querySelector("button").onclick = function anEventHappened() {
let newContainer = document.createElement("pre");
newContainer.textContent = Math.random();
document.body.appendChild(newContainer);
todoList.push(() => moveText(newContainer)); // add something extra
}
// Helper function to perform some HTML-text manipulation
function moveText(what) {
what.textContent = what.textContent.includes("<") ? what.textContent.slice(1)
: what.textContent.length < 60 ? " " + what.textContent
: what.textContent.replace(/ (\S)/, "<");
}
<button>Do extra</button>
<pre>phrase</pre>
一旦您知道要寻找什么,就很容易了。
一个最简单的解决方案是保留每次调用的函数集合(策略集合)
为了不在整个代码库中共享此集合,您可以应用订阅者 - 发布者方法,其中包含 animate
的模块订阅系统中的事件,这些事件将更改要在屏幕上呈现的内容.
这里有一个关于基本设计模式的很好的参考:https://refactoring.guru/design-patterns/
所以...回到你原来的问题,你可以做的是发送一个带有回调的事件dispatchEvent({ type: 'render'; strategy: <some_function> })
,animate
的模块将监听这些事件.addEventListener('render', event => strategies.push(event.strategy))
.
备注:
- 不要忘记删除旧策略。
strategies
可以是字典而不是数组。在那种情况下,事件 render
也应该有某种键来防止多个相同的策略被推送到 "queue"
https://threejs.org/docs/index.html#api/en/core/EventDispatcher
问题可以参考Three.JS框架,但我认为是一般的JS问题。
animate();
function animate() {
{doSomething}
requestAnimationFrame( animate );
}
所以函数 animate() 运行每一帧并做一些事情。
问题是如何即时将 {doAnotherSomething}
添加到 animate()
?
function anEventHappened(){
//adding some methods to animate
}
有几种方法可以做到这一点。但是您将不得不以某种方式预见此动画函数中的某些内容,这些内容可以检测到需要完成更多工作。这个 "something" 可以是一个数组,其中包含作为额外执行的函数。最初该数组为空,但在某些情况下您可以向该列表添加一个函数(或从中删除一个函数)。
这是一个实际的例子:
let container = document.querySelector("pre");
let todoList = []; // <--- list of functions to execute also as extras
animate();
function animate() {
todoList.forEach(f => f()); // execute whatever is in the todo-list
moveText(container);
requestAnimationFrame(animate);
}
document.querySelector("button").onclick = function anEventHappened() {
let newContainer = document.createElement("pre");
newContainer.textContent = Math.random();
document.body.appendChild(newContainer);
todoList.push(() => moveText(newContainer)); // add something extra
}
// Helper function to perform some HTML-text manipulation
function moveText(what) {
what.textContent = what.textContent.includes("<") ? what.textContent.slice(1)
: what.textContent.length < 60 ? " " + what.textContent
: what.textContent.replace(/ (\S)/, "<");
}
<button>Do extra</button>
<pre>phrase</pre>
一旦您知道要寻找什么,就很容易了。
一个最简单的解决方案是保留每次调用的函数集合(策略集合)
为了不在整个代码库中共享此集合,您可以应用订阅者 - 发布者方法,其中包含 animate
的模块订阅系统中的事件,这些事件将更改要在屏幕上呈现的内容.
这里有一个关于基本设计模式的很好的参考:https://refactoring.guru/design-patterns/
所以...回到你原来的问题,你可以做的是发送一个带有回调的事件dispatchEvent({ type: 'render'; strategy: <some_function> })
,animate
的模块将监听这些事件.addEventListener('render', event => strategies.push(event.strategy))
.
备注:
- 不要忘记删除旧策略。
strategies
可以是字典而不是数组。在那种情况下,事件render
也应该有某种键来防止多个相同的策略被推送到 "queue"
https://threejs.org/docs/index.html#api/en/core/EventDispatcher