当我尝试使用以下代码移动图像时(当从typescrpt编译为js时),图像会闪烁。
注意:this.image是在父级中设置的,画布ID和尺寸也是如此。还将图像的起始坐标设置为0、0。
const Tool = require('../tools');
interface Coords {
x : number;
y : number;
}
class MoveTool extends Tool {
button: HTMLElement;
canvas: HTMLCanvasElement;
isDraggable: boolean;
public constructor(element : MouseEvent) {
if(!__states.activeLayer) return;
super(element);
this.canvasEditMode();
this.run();
}
private canvasEditMode() : void {
if(!this.canvas) return;
this.canvas.style.cursor = 'crosshair';
}
public run() : void {
this.isDraggable = false;
this.mouseEvents();
}
public mouseEvents() {
this.mouseD = this.mouseDown.bind(this);
this.mouseM = this.mouseMove.bind(this);
this.mouseU = this.mouseUp.bind(this);
this.canvas.addEventListener('mousedown', this.mouseD);
this.canvas.addEventListener('mousemove', this.mouseM);
this.canvas.addEventListener('mouseup', this.mouseU);
}
public tick() {
this.clearCanvas();
this.context.drawImage(this.image, this.currentX, this.currentY);
this.requestId = window.requestAnimationFrame(() => this.tick());
}
public quit() : void {
document.getElementById(__states.activeLayer).style.cursor = 'pointer';
this.canvas.removeEventListener('mousedown', this.mouseD);
this.canvas.removeEventListener('mousemove', this.mouseM);
this.canvas.removeEventListener('mouseup', this.mouseU);
}
public mouseDown(event : MouseEvent) : void {
event.preventDefault();
this.isDraggable = true;
this.startCur = this.getCursorPosition(event);
}
public mouseUp(event : MouseEvent) : void {
event.preventDefault();
__states.layer.layers[__states.activeLayer].x = this.currentX;
__states.layer.layers[__states.activeLayer].y = this.currentY;
this.isDraggable = false;
window.cancelAnimationFrame(this.requestId);
}
public mouseMove(event: MouseEvent) {
event.preventDefault();
if (!this.isDraggable) return;
this.cursor = this.getCursorPosition(event);
this.currentX = this.calcCurrent(this.currentX, this.cursor.x, this.coordsDist(this.startCur.x, this.cursor.x));
this.currentY = this.calcCurrent(this.currentY, this.cursor.y, this.coordsDist(this.startCur.y, this.cursor.y));
this.requestId = window.requestAnimationFrame(() => this.tick());
}
// srt : start co-ordinate, cnt : current co-ordinate
private coordsDist(srt : number, cnt : number) : number {
return srt === cnt ? 0 : srt > cnt ? srt - cnt : cnt - srt;
}
// distance between cursor at mousedown and current position
private calcCurrent(origCoord : number , currentCoord : number, cursorTravel : number) : number {
return origCoord > currentCoord ? origCoord - cursorTravel : origCoord + cursorTravel;
}
}
任何解决问题的想法都将受到赞赏,因为我已经在此上浪费了一天,谢谢
答案 0 :(得分:0)
您将在每个mousemove
事件中启动一个新的rAF循环(在最新的浏览器中每帧一个,通常在较旧的浏览器中更多)。
您的浏览器在移动图像时可能难以按每帧绘制呈指数级增长的图像。
cancelAnimationFrame
中的mouseUp
调用只会停止最后一个创建的调用,但是从mouseDown
创建的所有调用仍将无休止地运行。
快速解决方案:在您的cancelAnimationFrame( this.requestId );
处理程序中调用mouseMove
(在调用下一个this.requestId = requestAnimationFrame(...
之前。)
其他解决方案:高举一个标志,让您知道是否已请求新框架。