Last active
January 13, 2023 03:37
-
-
Save Teemwu/33321373ce590cb11757e86f412bb1ae to your computer and use it in GitHub Desktop.
requestAnimationFrame instead of setTimeout and setInterval
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export default class Ticker { | |
static RAF: any = null | |
static CAF: any = null | |
static prefixs = ['webkit', 'moz', 'o', 'ms'] | |
constructor() { | |
Ticker.RAF = this.getRequestAnimationFrame() | |
Ticker.CAF = this.getCancelAnimationFrame() | |
} | |
/** | |
* Get requestAnimationFrame | |
* @returns any | |
*/ | |
public getRequestAnimationFrame(): any { | |
if (!window) return null | |
const prefix = Ticker.prefixs.filter(pre => `${pre}RequestAnimationFrame` in window)[0] | |
window.requestAnimationFrame = window.requestAnimationFrame | |
|| window[`${prefix}RequestAnimationFrame`] | |
|| requestAnimationFrame | |
if (!!window.requestAnimationFrame) { | |
window.requestAnimationFrame = window.requestAnimationFrame.bind(window) | |
} | |
return window.requestAnimationFrame || null | |
} | |
/** | |
* Get cancelAnimationFrame | |
* @returns any | |
*/ | |
public getCancelAnimationFrame(): any { | |
if (!window) return null | |
const prefix = Ticker.prefixs.filter(pre => `${pre}RequestAnimationFrame` in window)[0] | |
window.cancelAnimationFrame = window.cancelAnimationFrame | |
|| window[`${prefix}CancelAnimationFrame`] | |
|| window[`${prefix}CancelRequestAnimationFrame`] | |
|| cancelAnimationFrame | |
if (!!window.cancelAnimationFrame) { | |
window.cancelAnimationFrame = window.cancelAnimationFrame.bind(window) | |
} | |
return window.cancelAnimationFrame || null | |
} | |
/** | |
* Clear timeout | |
* @param id number | |
* @returns void | |
*/ | |
static clearTimeout(id: number) { | |
return this.CAF ? this.CAF(id) : window.clearTimeout(id) | |
} | |
/** | |
* Clear interval | |
* @param id number | |
* @returns void | |
*/ | |
static clearInterval(id: number) { | |
return this.CAF ? this.CAF(id) : window.clearInterval(id) | |
} | |
/** | |
* Set timeout | |
* @param handler Function | string | |
* @param delay number | |
* @param args any | |
* @returns number | |
*/ | |
static setTimeout(handler: Function | string, delay = 100 / 60, ...args: any) { | |
if (!this.RAF) return window.setTimeout(handler, delay, ...args) | |
const now = Date.now | |
const start = now() | |
let id: any = null | |
const loop = () => { | |
const isEnd = now() - start >= delay | |
if (isEnd) { | |
const isFunc = typeof handler !== 'string' | |
isFunc ? handler(...args) : eval(handler) | |
clearTimeout(id) | |
} else { | |
id = this.RAF(loop) | |
} | |
} | |
id = this.RAF(loop) | |
return id | |
} | |
/** | |
* Set interval | |
* @param handler Function | string | |
* @param delay number | |
* @param args any | |
* @returns number | |
*/ | |
static setInterval(handler: Function | string, delay = 100 / 60, ...args: any) { | |
if (!this.RAF) return window.setInterval(handler, delay, ...args) | |
const now = Date.now | |
const start = now() | |
let end = start | |
let id = null | |
const loop = () => { | |
const _now = now() | |
const needCallback = _now - end >= delay | |
if (needCallback) { | |
end = _now | |
const isFunc = typeof handler !== 'string' | |
isFunc ? handler(...args) : eval(handler) | |
} | |
id = this.RAF(loop) | |
} | |
id = this.RAF(loop) | |
return id | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment