npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@projectleo/tickerjs

v1.2.1

Published

A more easier way to request animation frames.

Downloads

8

Readme

Tickerjs @ProjectLeo · GitHub license npm version npm type definitions bundle size

Tickerjs provides a more easier way to request animation frames.

Installation

npm install @projectleo/tickerjs

Examples

Basic example:

import { requestAnimationFrames } from '@projectleo/tickerjs'

const cancelAnimationFrames = requestAnimationFrames({
    actionOnFrame() {
        console.log(performance.now())
    },
})

setTimeout(cancelAnimationFrames, 5000)

Complicated example:

import {
    twentyFour,
    thirty,
    requestAnimationFrames,
    getStructuredTime,
} from '@projectleo/tickerjs'

/* some code */

const { minute: totalMinutes, second: totalSeconds } = getStructuredTime(
    thirty.second,
    'minute',
)

requestAnimationFrames({
    totalTime: thirty.second,
    frameRate: twentyFour.fps,
    actionOnStart() {
        audioElement.play()
    },
    actionOnFrame({ remainingTime, frameCount }) {
        /* some code */

        const { minute: remainingMinutes, second: remainingSeconds } =
            getStructuredTime(remainingTime, 'minute')

        ctx.drawImage(imageFrames[frameCount], 0, 0)
        ctx.fillText(
            `${remainingMinutes}:${remainingSeconds} / ${totalMinutes}:${totalSeconds}`,
            4,
            20,
        )

        /* some code */
    },
    actionOnEnd() {
        audioElement.pause()
    },
})

APIs

Core function

/**
 * @throws {RangeError} `NaN`, `0`, negative numbers and non-integers are not valid for `totalTime` and `frameRate`.
 * @throws {RangeError} `Infinity` is not valid for `frameRate`.
 */
const requestAnimationFrames: (args: {
    totalTime?:⁰ number;
    frameRate?:¹ number;
    actionOnStart?:² () => void;
    actionOnFrame:³ (args: {
        remainingTime:⁴ number;
        frameCount:⁵ number;
        time:⁶ number;
    }) =>⁷ void | {
        continueHandleFrames: boolean;
    };
    actionOnEnd?:⁸ () => void;
}) =>⁹ (never | (() => void));
  • ⁰ [totalTime]: Total time of animation, in milliseconds, if it is not specified, its value is Infinity.
  • ¹ [frameRate]: Frame rate of animation, if it is not specified, the value of it is usually 60 (fps), but will generally match the display refresh rate in most web browsers as per W3C recommendation.
  • ² [actionOnStart]: Called when the animation starts.
  • ³ [actionOnFrame]: Called at every valid frames, it means that not every logical frames could call it if the specified frame rate is higher than display refresh rate.
  • ⁴ [remainingTime]: Remaining time of animation, in milliseconds.
  • ⁵ [frameCount]: Frame counts calculated from one, it doesn't always increase one by one if the specified frame rate is higher than display refresh rate.
  • ⁶ [time]: Same as the parameter of callback for requestAnimationFrame.
  • ⁷ [actionOnFrame()]: It could return a value to end the animation in advance, and actionOnEnd would be called.
  • ⁸ [actionOnEnd]: Called when the animation ends.
  • ⁹ [requestAnimationFrames()]: It would return a function used to cancel remaining animation frames, if use this function, actionOnEnd would not be called.

Configuration function

You may use polyfill if you need your application to run in any runtime that doesn't support requestAnimationFrame and cancelAnimationFrame. Tickerjs provides a function to help you to let them work with requestAnimationFrames without affecting the global variable.

const specifyAnimationFrameManager: (args: {
    requestAnimationFrame:⁰ (callback: (time: number) => void) => number;
    cancelAnimationFrame:¹ (handle: number) => void;
}) => void;

Utility function

type StructuredTimeWithDayUnit = {
    day: number;
    hour: number;
    minute: number;
    second: number;
    millisecond: number;
};

type StructuredTimeWithHourUnit = {
    hour: number;
    minute: number;
    second: number;
    millisecond: number;
};

type StructuredTimeWithMinuteUnit = {
    minute: number;
    second: number;
    millisecond: number;
};

type StructuredTimes = {
    day: StructuredTimeWithDayUnit;
    hour: StructuredTimeWithHourUnit;
    minute: StructuredTimeWithMinuteUnit;
};

const getStructuredTime:
    <T extends keyof StructuredTimes>(totalMilliseconds:⁰ number, highestUnit:¹ T) =>²
    StructuredTimes[T];
  • ⁰ [totalMilliseconds]: Total time to be structured, in milliseconds.
  • ¹ [highestUnit]: The highest unit to be used when structuring time, you can only choose one from 'day', 'hour' and 'minute'.
  • ² [getStructuredTime()]: It would return an object that contains structured time fields, fields are based on specified highestUnit.

Tickerjs provides a series of commonly used numerical constants:

|Number|Object|Property|Property|Property|Property|Property|Property| |:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:| |1|one|millisecond|second|minute|hour|day|fps| |2|two|millisecond|second|minute|hour|day|fps| |3|three|millisecond|second|minute|hour|day|fps| |5|five|millisecond|second|minute|hour|day|fps| |7|seven|millisecond|second|minute|hour|day|fps| |10|ten|millisecond|second|minute|hour|day|fps| |12|twelve|millisecond|second|minute|hour|day|fps| |14|fourteen|millisecond|second|minute|hour|day|fps| |15|fifteen|millisecond|second|minute|hour|day|fps| |20|twenty|millisecond|second|minute|hour|day|fps| |21|twentyOne|millisecond|second|minute|hour|day|fps| |24|twentyFour|millisecond|second|minute|hour|day|fps| |25|twentyFive|millisecond|second|minute|hour|day|fps| |28|twentyEight|millisecond|second|minute|hour|day|fps| |29|twentyNine|millisecond|second|minute|hour|day|fps| |30|thirty|millisecond|second|minute|hour|day|fps| |31|thirtyOne|millisecond|second|minute|hour|day|fps| |45|fortyFive|millisecond|second|minute|hour|day|fps| |48|fortyEight|millisecond|second|minute|hour|day|fps| |50|fifty|millisecond|second|minute|hour|day|fps| |60|sixty|millisecond|second|minute|hour|day|fps| |90|ninety|millisecond|second|minute|hour|day|fps| |120|oneHundredTwenty|millisecond|second|minute|hour|day|fps| |144|oneHundredFortyFour|millisecond|second|minute|hour|day|fps| |240|twoHundredForty|millisecond|second|minute|hour|day|fps| |300|threeHundred|millisecond|second|minute|hour|day|fps| |360|threeHundredSixty|millisecond|second|minute|hour|day|fps| |500|fiveHundred|millisecond|second|minute|hour|day|fps|

If you need other specific values for totalTime of requestAnimationFrames, these functions would be useful:

const second: (second: number) => number;
const minute: (minute: number) => number;
const hour: (hour: number) => number;
const day: (day: number) => number;

Troubleshooting

⚠️ After I unpacking values from time numbers, some strange errors are thrown.

Time numbers are proxy values, not pure objects, don't use destructuring assignment syntax on them.

⚠️ Animation sometimes would end before reaching expected frame counts.

If the total time of animation is specified, animation would always end when remaining time is exhausted. Depending on the refresh rate of display, if the specified frame rate is higher than display refresh rate, animation may end before reaching expected frame counts because of the runtime's calculation accuracy error.

⚠️ When I use tickerjs in some browsers directly, some errors are thrown.

Tickerjs uses some latest JavaScript features in source code, the exported bundle also has not been processed by JavaScript compiler like Babel, you need to handle it yourself.

FAQ

// without tickerjs

function callback(time) {
    doSomething(time)

    requestAnimationFrame(callback)
}

requestAnimationFrame(callback)

// with tickerjs

requestAnimationFrames({
    actionOnFrame({ time }) {
        doSomething(time)
    },
})

License

Tickerjs is MIT licensed.