我正在尝试制作一个游戏,我想使用window.requestAnimationFrame()来让角色移动,这个动作一开始似乎是正确的。
但是问题是,当我在触发后立即重新触发 move()时,移动会越来越快,我有代码blow,move()、pause()和initListener()都是关于运动的函数。
type state = "init" | "mount" | "moving" | "pause" | "end";
interface position {
left: number;
top: number;
}
interface elProps {
id: string;
text: string;
avatar: string;
}
export default class Bullet {
public el: HTMLElement;
public targetEl: HTMLElement;
public unit: string = "px";
private id:string;
private state: state;
private position: position;
private animationId: number | undefined;
constructor(props: elProps) {
if (!props) return;
this.el = document.createElement("div");
this.initEl(props);
}
initEl(props: elProps) {
const defaultStyle = {};
this.el.style["height"] = "40px";
this.el.style["background"] = "lightblue";
this.el.style["display"] = "inline-flex";
this.el.style["position"] = "absolute";
//
const { text, avatar, id } = props;
this.el.setAttribute("id", id);
this.id = id
const textEl = document.createElement("div");
textEl.innerText = text;
const avatarEl = document.createElement("img");
avatarEl.setAttribute("src", avatar);
//
this.el.appendChild(avatarEl);
this.el.appendChild(textEl);
//
this.state = "init";
}
mount(targetEl: HTMLElement, position: position, unit: string) {
//
this.position = position;
this.unit = unit;
this.targetEl = targetEl;
this.el.style["left"] = this.position.left + this.unit;
//
targetEl.appendChild(this.el);
//
this.state = "mount";
const domEl = document.querySelector(`#${SPECIAL_ID}`);
if (!domEl) {
throw new Error("mount bullet error");
}
this.el = domEl as HTMLElement;
}
move(duration: number) {
this.state = "moving";
this.initListener();
const animation = () => {
if (this.state !== "moving") return;
this.position.left -= 1.2;
this.el.style["left"] = this.position.left + this.unit;
this.animationId = requestAnimationFrame(animation);
};
animation();
}
pause() {
if(this.animationId){
cancelAnimationFrame(this.animationId)
this.animationId = undefined
}
}
initListener() {
this.el.addEventListener("mouseenter", () => {
this.state = "pause";
this.pause()
});
this.el.addEventListener("mouseover", () => {
this.state = "pause";
this.pause()
});
this.el.addEventListener("mouseout", () => {
this.state = "moving";
this.move()
});
}
}我想是因为当我重新触发move()时,javascript堆栈中仍然有一些requestAnimationFrame()在运行?
我怎么才能解决这个问题?
发布于 2021-10-31 18:58:30
您应该在执行暂停时取消事件侦听器的注册,或者在move()函数之外注册它们(例如,在mount()中)。
https://stackoverflow.com/questions/69787986
复制相似问题