Nebulous Program Mechanic

    timrjs
    TypeScript icon, indicating that this package has built-in type declarations

    3.2.1 • Public • Published

    TimrJS

    Timr is a simple utility for creating timers in JavaScript.
    It can create a simple countdown timer, a stopwatch style counter and a dynamic timer that counts down to a specific day that will be up to date no matter when you start it.

    Compatible with Browsers and Node.js.

    build status coverage status npm version npm downloads npm license Commitizen friendly

    Examples

    Here are a few different ways you could use Timr.

    Installation

    Install with npm or Bower.

    npm install timrjs --save
    

    Then import it into your project.

    // ES6 imports, using a transpiler like Babel.
    import { create } from 'timrjs'
    
    // Regular old ES5
    var create = require('timrjs').create

    You can also include the following CDN:

    https://unpkg.com/timrjs@latest/dist/timr.js
    https://unpkg.com/timrjs@latest/dist/timr.min.js

    These versions will expose a single global method: Timr.

    Syntax

    create(startTime[, options])
    

    Parameters

    startTime [type: string | number | Date | object]

    This accepts two types of syntax.

    1. It takes a time. [type: string | number]. The following will create a simple countdown timer:

      • '10:00' - Creates a 10 minute timer.
      • '01:00:00' - Creates a 1 hour timer.
      • 600 - Equivalent to 10:00.
      • '25m' - Equivalent to 25:00. (minutes)
      • '25h' - Equivalent to 25:00:00. (hours)
      • '25d' - Equivalent to 600:00:00. (days)

      The provided time must follow the above patterns or an error will be thrown.

    2. It takes a future date/time [type: string | Date]. This will create a countdown timer to that point in time. The time will be local to the user.

      • '2021-12-25' - Creates a countdown timer to midnight on Christmas Day.
      • '2021-12-25 10:00' - Creates a countdown timer to 10am on Christmas Day.

      Internally this uses the individual date/time components of the Date constructor as described here for maximum compatibility.

      You can also provide a Date object, allowing the use of custom timezones if required.

      • new Date('2021-12-25 10:00-08:00') - Creates a countdown timer to 10am on Christmas Day, Pacific Standard ime.
      • new Date('2021-12-25 10:00Z') - Creates a countdown timer to 10am on Christmas Day, UTC Time.

      The provided date must follow the above patterns or an error will be thrown.

      If a date provided is in the past, it will also throw an error. See options.backupStartTime for an easy solution to handle this.

    Alternatively you can pass an object to startTime that contains a startTime property, allowing you to pass both startTime and options in one object.

    create({
      startTime: 600,
      countdown: true,
      etc...
    })

    options [type: object]

    Optional. Object which accepts:

    • countdown [type: boolean] [default: true]

      This dictates whether the timer should countdown or up. If countdown is false and startTime is 0, it will act as a stopwatch.

      Setting startTime to 0 with countdown as true will throw an error.

    • formatOutput [type: string] [default: 'DD hh:{mm:ss}']

      This dictates how the formatted string will look. See below for further explanation. Also see examples for different uses.

    • formatValues [type: { [key: string]: (number) => string | number }] [default: { [key]: zeroPad }]

      This dictates how each value in the formattedString is formatted. By default they are all padded with a 0. See below for further explanation.

    • backupStartTime [type: string | Date]

      If startTime is in the past, it will attempt to use the backupStartTime instead. Same rules apply to this as they do to startTime. See Christmas Countdown for an example on how this might be used.

    formatOutput

    It takes the string you provide, injects the correct value in and returns that string, custom formatting included. See the formatOutput example for some ideas of how you can use this.

    The placeholders used to make up the string are below.

    // Assume today is 17th Dec 2021.
    const timer = create('2021-12-25', { formatOutput: 'DD days hh:mm:ss' })
    
    timer.formatTime()
    {
      formattedTime: '07 days 00:57:58',
      raw: {
        ss: 58,
        mm: 57,
        hh: 0,
        dd: 7,
        SS: 608278,
        MM: 10137,
        HH: 168,
        DD: 7,
      },
    }

    You can use curly braces to denote 'protected values', essentially this means that the values inside the braces won't be removed as the string is formatted. See the Protected Values example for an idea of what this does.

    If the string doesn't contain any braces, than it will be formatted as is.

    Note: For the protected values to work correctly, Timr assumes that you write the formatOutput string with the placeholder values in the following order: DDdd HHhh MMmm SSss.

    formatValues

    Each placeholder value can be customised individually in the final formatted string.

    Each entry in the formatValues object accepts a function that can return a number or string.

    import { create, zeroPad } from 'timrjs'
    
    const timer = create({
      startTime: '72:05:34',
      formatOutput: 'DD hh:mm:ss',
      formatValues: {
        // default applies to all placeholders that aren't customised explicitly. Defaults to the zeroPad function if not specified.
        default: (num) => `<${num}>`, 
        ss: zeroPad,
        mm: (num) => num,
        // hh: (num) => num,
        // dd: (num) => num,
        // SS: (num) => num,
        // MM: (num) => num,
        // HH: (num) => num,
        DD: (num) => num > 1 ? `${num} days` : `${num} day`,
      }
    })
    
    timer.getFt()
    // 3 days <0>:5:34

    This example is contrived but it gives you an idea of what you can do with it.

    Usage

    Start by calling the Timr function with the desired startTime and any options. This will return a new Timr Object.

    const timer = create('10:00');

    Events

    Timr is event based, it's primary events are ticker and finish.

    ticker is called every second and emits an object with the following properties:

    • formattedTime

      The current time formatted into a time string. Customised with formatOutput and formatValues option.

    • raw

      An object with the raw values used to calculate the current time. See here for available properties.

    • percentDone

      The elapsed time in percent. Useful for making something like a progress bar.

    • currentTime

      The current time in seconds.

    • startTime

      The starting time in seconds.

    • self

      The original timr object.

    The first call will be 1 second after the timer has started. In the below example, it will emit '09:59'.

    To display the timers startTime initially, you can call timer.getFt() which will return '10:00' as in the case below.

    If the countdown option has been set to false, ticker will omit percentDone from the provided object.

    /** 
     * We can use ES6 destructuring syntax here to cherry pick the values we need.
     */
    timer.ticker(({ formattedTime, percentDone }) => {
      // formattedTime: '09:59'
      // percentDone:   0
    });

    finish is called once, when the timer hits 0. It only emits the original timr object.

    timer.finish((self) => {
      console.log('Countdown Finished!');
    
      // ticker: '00:00'
      // finish: 'Countdown Finished!'
    });

    Five other events are provided, all of them emit the original Timr object as the first argument and are called after their operation:

    • onStart

      If the timer has already been started and start() is called again, this won't emit. Instead use, onAlreadyStarted

    • onAlreadyStarted

      If the timer has started and start() is called again this will emit.

    • onPause

    • onStop

    • onDestroy

      This is the only event that emits BEFORE it carries out its operation. This is because part of that operation is to remove all event listeners from the timr.

    Controls

    To control the Timr, you use the start, pause and stop methods.

    /**
     * Start takes an optional number (in ms) argument that will
     * delay the start of the timer.
     */
    timer.start([delay: number]);
    timer.pause();
    timer.stop();
    
    /**
     * Because Timr is class based, to ensure the this variable is correct,
     * you'll need to bind it's functions if you want to pass them in to be called later.
     *
     * Or you can use ES6 arrow syntax which doesn't alter the this value.
     */
    $('button').on('click', timer.start.bind(timer));
    
    setTImeout(() => timer.start(), 1000);

    Full API

    The following methods are available on all timrs. Unless they return a specific value, they return the original timer object so calls can be chained.

    • start(delay: number): Timr

      Starts the timer. Optionally delays starting by the provided ms. If a future date was used, start will update the startTime to ensure its in sync with the current time.

    • pause(): Timr

      Pauses the timer.

    • stop(): Timr

      Stops the timer.

    • destroy(): Timr

      Stops the timer, removes all event listeners and removes the timr from the store (if it's in one).

    • ticker(fn: ({ formattedTime: string, raw: Raw, percentDone?: number, currentTime: number, startTime: number, self: Timr }) => void): Timr

      Executes every second the timer ticks down. percentDone omitted if countdown set to false.

    • finish(fn: (self: Timr) => void): Timr

      Executes once the timer finishes.

    • onStart(fn: (self: Timr) => void): Timr

      Executes after the timer starts, unless its already started.

    • onAlreadyStarted(fn: (self: Timr) => void): Timr

      Executes if the timer has already started and start() is called again.

    • onPause(fn: (self: Timr) => void): Timr

      Executes after the timer is paused.

    • onStop(fn: (self: Timr) => void): Timr

      Executes after the timer is stopped.

    • onDestroy(fn: (self: Timr) => void): Timr

      Executes before the timer is destroyed.

    • formatTime(time: 'currentTime' | 'startTime' [default='currentTime']): string

      Returns an object with the formattedTime and raw values. Optionally accepts 'startTime', which will return the startTime formatted.

    • percentDone(): number

      Returns the time elapsed in percent.

    • changeOptions(options): Timr

      Merges the provided options into the existing ones. See: here for available options.

    • setStartTime(newStartTime[, backupStartTime]): Timr

      Changes the startTime to the one provided. Will stop the timer if its already started. It's also subject to validation, so will throw an error if the provided time is invalid. Optionally accepts a backupStartTime for futureDates, will default to the one provided by options if omitted.

    • getFt(time: 'currentTime' | 'startTime' [default='currentTime']): string

      Shorthand for formatTime(time).formattedTime.

    • getRaw(time: 'currentTime' | 'startTime' [default='currentTime']): Raw

      Shorthand for formatTime(time).raw.

    • getStartTime(): number

      Returns the startTime in seconds.

    • getCurrentTime(): number

      Returns the currentTime in seconds.

    • getStatus(statusName?: Status): Status | boolean

      Returns the current status of the timer with the following available:

      • Status.initialized - Status representing when the Timr object is created.
      • Status.started - Status representing when the Timr has started.
      • Status.paused - Status representing when the Timr has been paused.
      • Status.stopped - Status representing when the Timr has stopped.
      • Status.finished - Status representing when the Timr has finished.
      • Status.destroyed - Status representing when the Timr has been destroyed.

      Alternatively if a Status argument is provided, will return a boolean confirming if the current status matches the provided one.

      Status is a Typescript Enum and is available as a top-level export.

      import { Status } from 'timrjs'

    Top Level API

    createStore

    The createStore function provides a way to easily store multiple timrs together and perform various operations on all of them at the same time.

    It is available as a top-level export.

    import { createStore } from 'timrjs'
    
    const store = createStore();

    It also accepts Timr objects.

    If any non-Timr arguments are provided, or they exist in another store, an error is thrown.

    const timer1 = create('20:00');
    const timer2 = create('15:00');
    const timer3 = create('10:00');
    const timer4 = create('5:00');
    
    const store1 = createStore(timer1, timer2);
    const store2 = createStore(timer2, timer3, timer4);
    // Because timer2 already exists in store1, an error will be thrown

    Store API

    When createStore is called, it will return an object with the following methods:

    • store.add(timr): Timr

      Adds the provided Timr to the store. If it already exits in a store, then it won't add it. Returns the provided store.

    • store.getAll(): Timr[]

      Returns the array of all stored Timrs.

    • store.startAll(): void

      Starts all stored Timrs.

    • store.pauseAll(): void

      Pauses all stored Timrs.

    • store.stopAll(): void

      Stops all stored Timrs.

    • store.getStatus(statusName: Status): Timr[]

      Returns a new array of all the timrs that match the provided status.

    • store.started(): Timr[]

      Returns a new array of all stored Timrs that are running.

    • store.removeFromStore(timr): void

      Removes the provided Timr from the store.

    • store.destroyAll(): void

      Destroys all stored Timrs.

    Each store is isolated, so methods run on one won't affect another.

    Utilities

    The following methods are also available as top-level exports.

    import {   
      formatTime,
      timeToSeconds,
      dateToSeconds,
      zeroPad
    } from 'timrjs
    • formatTime(seconds: number, options: Options, toBuild: boolean [default=true])

      Converts seconds into a time string. Used by Timrs when outputting their formattedTime and raw values. See here for more info.

      • seconds - Required. The seconds to be converted.
      • options - See: options
      • toBuild - Mostly for internal use. Specifies whether to build the options object or not.
    • timeToSeconds(startTime: string | number): number

      Converts a time string into seconds. Used when passing startTime to create() so is subject to the same validity checks. Alternatively returns the argument if a positive number is passed in.

      See Start Delay Examples for some ideas on where you could use this.

    • dateToSeconds(startTime: string | date, backupStartTime?: string | date): number Converts a date string into seconds until that date from now. Used when passing startTime to create() so is subject to the same validity checks. Alternatively if a date object is passed it returns the seconds until that date from now.

      If the parsed date is in the passed, it will look for the backUpStartTime and try to use that instead.

      See Start Delay Examples for some ideas on where you could use this.

    • zeroPad(num: number): string | number

      Pads a number with a 0, for example:

      zeroPad(1)
      // 01
      zeroPad(11)
      // 11

    Bugs

    If you find any and fancy helping me out, create an issue, or submit a pull request.

    License

    MIT

    Install

    npm i timrjs

    DownloadsWeekly Downloads

    19

    Version

    3.2.1

    License

    MIT

    Unpacked Size

    269 kB

    Total Files

    37

    Last publish

    Collaborators

    • joecastle