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