Skip to content

Instantly share code, notes, and snippets.

@Teemwu
Last active January 13, 2023 03:37
Show Gist options
  • Save Teemwu/33321373ce590cb11757e86f412bb1ae to your computer and use it in GitHub Desktop.
Save Teemwu/33321373ce590cb11757e86f412bb1ae to your computer and use it in GitHub Desktop.
requestAnimationFrame instead of setTimeout and setInterval
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