I'm tring to make a game and i want to use window.requestAnimationFrame() to make roles move, the movement seems to be right at first.
but there is problem that when i re-trigger move()
immediately after triggering pause()
, the movement will be faster and faster, i have code blow, move()
、pause()
and initListener()
are functions about movement
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()
});
}
}
I guess it's because when i re-trigger move()
, there are still some requestAnimationFrame()
running in javascript stack?
how can I fix this?
Via Active questions tagged javascript - Stack Overflow https://ift.tt/2FdjaAW
Comments
Post a Comment