The old mouse track function used a list of several windows in the form of cursors that updated their positions with each frame. In fact, he had a list of “cursors”, and each subsequent “cursor” of a frame in the list moved to the current cursor position, as a result of which each fake cursor updated its own position with a frame delay of fake cursors - 1 .
Smooth on-demand delayed movement for a single object can be modeled using requestAnimationFrame , performance.now and Event.timeStamp . The idea is to store mouse events in an internal list and only use them after a certain time after they are created.
function DelayLine(delay, action){ capacity = Math.round(delay / 1000 * 200); this.ring = new Array(capacity); this.delay = delay; this.action = action; this._s = 0; this._e = 0; this._raf = null; this._af = this._animationFrame.bind(this); this._capacity = capacity; } DelayLine.prototype.put = function(value){ this.ring[this._e++] = value; if (this._e >= this._capacity) this._e = 0; if (this._e == this._s) this._get(); cancelAnimationFrame(this._raf); this._raf = requestAnimationFrame(this._af); } DelayLine.prototype._get = function(){ var value = this.ring[this._s++]; if (this._s == this._capacity) this._s = 0; return value; } DelayLine.prototype._peek = function(){ return this.ring[this._s]; } DelayLine.prototype._animationFrame = function(){ if (this._length > 0){ if (performance.now() - this._peek().timeStamp > this.delay) this.action(this._get()); this._raf = requestAnimationFrame(this._af); } } Object.defineProperty(DelayLine.prototype, "_length", { get: function() { var size = this._e - this._s; return size >= 0 ? size : size + this._capacity; } }); var delayLine = new DelayLine(100, function(e){ pointer.style.left = ex - pointer.offsetWidth/2 + "px"; pointer.style.top = ey - pointer.offsetHeight/2 + "px"; }); document.addEventListener("mousemove", function(e){ delayLine.put(e); }, false);
https://jsfiddle.net/os8r7c20/2/
weaknespase
source share