UNPKG

pixi.js

Version:

<p align="center"> <a href="https://pixijs.com" target="_blank" rel="noopener noreferrer"> <img height="150" src="https://files.pixijs.download/branding/pixijs-logo-transparent-dark.svg?v=1" alt="PixiJS logo"> </a> </p> <br/> <p align="center">

1 lines 38.5 kB
{"version":3,"file":"Ticker.mjs","sources":["../../src/ticker/Ticker.ts"],"sourcesContent":["import { UPDATE_PRIORITY } from './const';\nimport { TickerListener } from './TickerListener';\n\n/**\n * A callback which can be added to a ticker.\n * ```js\n * ticker.add(() => {\n * // do something every frame\n * });\n * ```\n * @category ticker\n * @standard\n */\nexport type TickerCallback<T> = (this: T, ticker: Ticker) => any;\n\n/**\n * A Ticker class that runs an update loop that other objects listen to.\n * Used for managing animation frames and timing in a PixiJS application.\n *\n * It provides a way to add listeners that will be called on each frame,\n * allowing for smooth animations and updates.\n *\n * Animation frames are requested\n * only when necessary, e.g., when the ticker is started and the emitter has listeners.\n * @example\n * ```ts\n * // Basic ticker usage\n * const ticker = new Ticker();\n * ticker.add((ticker) => {\n * // Update every frame\n * sprite.rotation += 0.1 * ticker.deltaTime;\n * });\n * ticker.start();\n *\n * // Control update priority\n * ticker.add(\n * (ticker) => {\n * // High priority updates run first\n * physics.update(ticker.deltaTime);\n * },\n * undefined,\n * UPDATE_PRIORITY.HIGH\n * );\n *\n * // One-time updates\n * ticker.addOnce(() => {\n * console.log('Runs on next frame only');\n * });\n * ```\n * @see {@link TickerPlugin} For use with Application\n * @see {@link UPDATE_PRIORITY} For priority constants\n * @see {@link TickerCallback} For listener function type\n * @category ticker\n * @standard\n */\nexport class Ticker\n{\n /**\n * Target frame rate in frames per millisecond.\n * Used for converting deltaTime to a scalar time delta.\n * @example\n * ```ts\n * // Default is 0.06 (60 FPS)\n * console.log(Ticker.targetFPMS); // 0.06\n *\n * // Calculate target frame duration\n * const frameDuration = 1 / Ticker.targetFPMS; // ≈ 16.67ms\n *\n * // Use in custom timing calculations\n * const deltaTime = elapsedMS * Ticker.targetFPMS;\n * ```\n * @remarks\n * - Default is 0.06 (equivalent to 60 FPS)\n * - Used in deltaTime calculations\n * - Affects all ticker instances\n * @default 0.06\n * @see {@link Ticker#deltaTime} For time scaling\n * @see {@link Ticker#FPS} For actual frame rate\n */\n public static targetFPMS = 0.06;\n\n /** The private shared ticker instance */\n private static _shared: Ticker;\n /** The private system ticker instance */\n private static _system: Ticker;\n\n /**\n * Whether or not this ticker should invoke the method {@link Ticker#start|start}\n * automatically when a listener is added.\n * @example\n * ```ts\n * // Default behavior (manual start)\n * const ticker = new Ticker();\n * ticker.autoStart = false;\n * ticker.add(() => {\n * // Won't run until ticker.start() is called\n * });\n *\n * // Auto-start behavior\n * const autoTicker = new Ticker();\n * autoTicker.autoStart = true;\n * autoTicker.add(() => {\n * // Runs immediately when added\n * });\n * ```\n * @default false\n * @see {@link Ticker#start} For manually starting the ticker\n * @see {@link Ticker#stop} For manually stopping the ticker\n */\n public autoStart = false;\n /**\n * Scalar time value from last frame to this frame.\n * Used for frame-based animations and updates.\n *\n * This value is capped by setting {@link Ticker#minFPS|minFPS}\n * and is scaled with {@link Ticker#speed|speed}.\n * > [!NOTE] The cap may be exceeded by scaling.\n * @example\n * ```ts\n * // Basic animation\n * ticker.add((ticker) => {\n * // Rotate sprite by 0.1 radians per frame, scaled by deltaTime\n * sprite.rotation += 0.1 * ticker.deltaTime;\n * });\n * ```\n */\n public deltaTime = 1;\n /**\n * Scalar time elapsed in milliseconds from last frame to this frame.\n * Provides precise timing for animations and updates.\n *\n * This value is capped by setting {@link Ticker#minFPS|minFPS}\n * and is scaled with {@link Ticker#speed|speed}.\n *\n * If the platform supports DOMHighResTimeStamp,\n * this value will have a precision of 1 µs.\n *\n * Defaults to target frame time\n *\n * > [!NOTE] The cap may be exceeded by scaling.\n * @example\n * ```ts\n * // Animation timing\n * ticker.add((ticker) => {\n * // Use millisecond timing for precise animations\n * const progress = (ticker.deltaMS / animationDuration);\n * sprite.alpha = Math.min(1, progress);\n * });\n * ```\n * @default 16.66\n */\n public deltaMS: number;\n /**\n * Time elapsed in milliseconds from last frame to this frame.\n * Provides raw timing information without modifications.\n *\n * Opposed to what the scalar {@link Ticker#deltaTime|deltaTime}\n * is based, this value is neither capped nor scaled.\n *\n * If the platform supports DOMHighResTimeStamp,\n * this value will have a precision of 1 µs.\n *\n * Defaults to target frame time\n * @example\n * ```ts\n * // Basic timing information\n * ticker.add((ticker) => {\n * console.log(`Raw frame time: ${ticker.elapsedMS}ms`);\n * });\n * ```\n * @default 16.66\n */\n public elapsedMS: number;\n /**\n * The last time {@link Ticker#update|update} was invoked.\n * Used for calculating time deltas between frames.\n *\n * This value is also reset internally outside of invoking\n * update, but only when a new animation frame is requested.\n *\n * If the platform supports DOMHighResTimeStamp,\n * this value will have a precision of 1 µs.\n * @example\n * ```ts\n * // Basic timing check\n * ticker.add(() => {\n * const timeSinceStart = performance.now() - ticker.lastTime;\n * console.log(`Time running: ${timeSinceStart}ms`);\n * });\n * ```\n */\n public lastTime = -1;\n /**\n * Factor of current {@link Ticker#deltaTime|deltaTime}.\n * Used to scale time for slow motion or fast-forward effects.\n * @example\n * ```ts\n * // Basic speed adjustment\n * ticker.speed = 0.5; // Half speed (slow motion)\n * ticker.speed = 2.0; // Double speed (fast forward)\n *\n * // Temporary speed changes\n * function slowMotion() {\n * const normalSpeed = ticker.speed;\n * ticker.speed = 0.2;\n * setTimeout(() => {\n * ticker.speed = normalSpeed;\n * }, 1000);\n * }\n * ```\n */\n public speed = 1;\n /**\n * Whether or not this ticker has been started.\n *\n * `true` if {@link Ticker#start|start} has been called.\n * `false` if {@link Ticker#stop|Stop} has been called.\n *\n * While `false`, this value may change to `true` in the\n * event of {@link Ticker#autoStart|autoStart} being `true`\n * and a listener is added.\n * @example\n * ```ts\n * // Check ticker state\n * const ticker = new Ticker();\n * console.log(ticker.started); // false\n *\n * // Start and verify\n * ticker.start();\n * console.log(ticker.started); // true\n * ```\n */\n public started = false;\n\n /** The first listener. All new listeners added are chained on this. */\n private _head: TickerListener;\n /** Internal current frame request ID */\n private _requestId: number = null;\n /**\n * Internal value managed by minFPS property setter and getter.\n * This is the maximum allowed milliseconds between updates.\n */\n private _maxElapsedMS = 100;\n /**\n * Internal value managed by minFPS property setter and getter.\n * This is the minimum allowed milliseconds between updates.\n */\n private _minElapsedMS = 0;\n /** If enabled, deleting is disabled.*/\n private _protected = false;\n /** The last time keyframe was executed. Maintains a relatively fixed interval with the previous value. */\n private _lastFrame = -1;\n /**\n * Internal tick method bound to ticker instance.\n * This is because in early 2015, Function.bind\n * is still 60% slower in high performance scenarios.\n * Also separating frame requests from update method\n * so listeners may be called at any time and with\n * any animation API, just invoke ticker.update(time).\n * @param time - Time since last tick.\n */\n private readonly _tick: (time: number) => any;\n\n constructor()\n {\n this._head = new TickerListener(null, null, Infinity);\n this.deltaMS = 1 / Ticker.targetFPMS;\n this.elapsedMS = 1 / Ticker.targetFPMS;\n\n this._tick = (time: number): void =>\n {\n this._requestId = null;\n\n if (this.started)\n {\n // Invoke listeners now\n this.update(time);\n // Listener side effects may have modified ticker state.\n if (this.started && this._requestId === null && this._head.next)\n {\n this._requestId = requestAnimationFrame(this._tick);\n }\n }\n };\n }\n\n /**\n * Conditionally requests a new animation frame.\n * If a frame has not already been requested, and if the internal\n * emitter has listeners, a new frame is requested.\n */\n private _requestIfNeeded(): void\n {\n if (this._requestId === null && this._head.next)\n {\n // ensure callbacks get correct delta\n this.lastTime = performance.now();\n this._lastFrame = this.lastTime;\n this._requestId = requestAnimationFrame(this._tick);\n }\n }\n\n /** Conditionally cancels a pending animation frame. */\n private _cancelIfNeeded(): void\n {\n if (this._requestId !== null)\n {\n cancelAnimationFrame(this._requestId);\n this._requestId = null;\n }\n }\n\n /**\n * Conditionally requests a new animation frame.\n * If the ticker has been started it checks if a frame has not already\n * been requested, and if the internal emitter has listeners. If these\n * conditions are met, a new frame is requested. If the ticker has not\n * been started, but autoStart is `true`, then the ticker starts now,\n * and continues with the previous conditions to request a new frame.\n */\n private _startIfPossible(): void\n {\n if (this.started)\n {\n this._requestIfNeeded();\n }\n else if (this.autoStart)\n {\n this.start();\n }\n }\n\n /**\n * Register a handler for tick events. Calls continuously unless\n * it is removed or the ticker is stopped.\n * @example\n * ```ts\n * // Basic update handler\n * ticker.add((ticker) => {\n * // Update every frame\n * sprite.rotation += 0.1 * ticker.deltaTime;\n * });\n *\n * // With specific context\n * const game = {\n * update(ticker) {\n * this.physics.update(ticker.deltaTime);\n * }\n * };\n * ticker.add(game.update, game);\n *\n * // With priority\n * ticker.add(\n * (ticker) => {\n * // Runs before normal priority updates\n * physics.update(ticker.deltaTime);\n * },\n * undefined,\n * UPDATE_PRIORITY.HIGH\n * );\n * ```\n * @param fn - The listener function to be added for updates\n * @param context - The listener context\n * @param priority - The priority for emitting (default: UPDATE_PRIORITY.NORMAL)\n * @returns This instance of a ticker\n * @see {@link Ticker#addOnce} For one-time handlers\n * @see {@link Ticker#remove} For removing handlers\n */\n public add<T = any>(fn: TickerCallback<T>, context?: T, priority: number = UPDATE_PRIORITY.NORMAL): this\n {\n return this._addListener(new TickerListener(fn, context, priority));\n }\n\n /**\n * Add a handler for the tick event which is only executed once on the next frame.\n * @example\n * ```ts\n * // Basic one-time update\n * ticker.addOnce(() => {\n * console.log('Runs next frame only');\n * });\n *\n * // With specific context\n * const game = {\n * init(ticker) {\n * this.loadResources();\n * console.log('Game initialized');\n * }\n * };\n * ticker.addOnce(game.init, game);\n *\n * // With priority\n * ticker.addOnce(\n * () => {\n * // High priority one-time setup\n * physics.init();\n * },\n * undefined,\n * UPDATE_PRIORITY.HIGH\n * );\n * ```\n * @param fn - The listener function to be added for one update\n * @param context - The listener context\n * @param priority - The priority for emitting (default: UPDATE_PRIORITY.NORMAL)\n * @returns This instance of a ticker\n * @see {@link Ticker#add} For continuous updates\n * @see {@link Ticker#remove} For removing handlers\n */\n public addOnce<T = any>(fn: TickerCallback<T>, context?: T, priority: number = UPDATE_PRIORITY.NORMAL): this\n {\n return this._addListener(new TickerListener(fn, context, priority, true));\n }\n\n /**\n * Internally adds the event handler so that it can be sorted by priority.\n * Priority allows certain handler (user, AnimatedSprite, Interaction) to be run\n * before the rendering.\n * @private\n * @param listener - Current listener being added.\n * @returns This instance of a ticker\n */\n private _addListener(listener: TickerListener): this\n {\n // For attaching to head\n let current = this._head.next;\n let previous = this._head;\n\n // Add the first item\n if (!current)\n {\n listener.connect(previous);\n }\n else\n {\n // Go from highest to lowest priority\n while (current)\n {\n if (listener.priority > current.priority)\n {\n listener.connect(previous);\n break;\n }\n previous = current;\n current = current.next;\n }\n\n // Not yet connected\n if (!listener.previous)\n {\n listener.connect(previous);\n }\n }\n\n this._startIfPossible();\n\n return this;\n }\n\n /**\n * Removes any handlers matching the function and context parameters.\n * If no handlers are left after removing, then it cancels the animation frame.\n * @example\n * ```ts\n * // Basic removal\n * const onTick = () => {\n * sprite.rotation += 0.1;\n * };\n * ticker.add(onTick);\n * ticker.remove(onTick);\n *\n * // Remove with context\n * const game = {\n * update(ticker) {\n * this.physics.update(ticker.deltaTime);\n * }\n * };\n * ticker.add(game.update, game);\n * ticker.remove(game.update, game);\n *\n * // Remove all matching handlers\n * // (if same function was added multiple times)\n * ticker.add(onTick);\n * ticker.add(onTick);\n * ticker.remove(onTick); // Removes all instances\n * ```\n * @param fn - The listener function to be removed\n * @param context - The listener context to be removed\n * @returns This instance of a ticker\n * @see {@link Ticker#add} For adding handlers\n * @see {@link Ticker#addOnce} For one-time handlers\n */\n public remove<T = any>(fn: TickerCallback<T>, context?: T): this\n {\n let listener = this._head.next;\n\n while (listener)\n {\n // We found a match, lets remove it\n // no break to delete all possible matches\n // incase a listener was added 2+ times\n if (listener.match(fn, context))\n {\n listener = listener.destroy();\n }\n else\n {\n listener = listener.next;\n }\n }\n\n if (!this._head.next)\n {\n this._cancelIfNeeded();\n }\n\n return this;\n }\n\n /**\n * The number of listeners on this ticker, calculated by walking through linked list.\n * @example\n * ```ts\n * // Check number of active listeners\n * const ticker = new Ticker();\n * console.log(ticker.count); // 0\n *\n * // Add some listeners\n * ticker.add(() => {});\n * ticker.add(() => {});\n * console.log(ticker.count); // 2\n *\n * // Check after cleanup\n * ticker.destroy();\n * console.log(ticker.count); // 0\n * ```\n * @readonly\n * @see {@link Ticker#add} For adding listeners\n * @see {@link Ticker#remove} For removing listeners\n */\n get count(): number\n {\n if (!this._head)\n {\n return 0;\n }\n\n let count = 0;\n let current = this._head;\n\n while ((current = current.next))\n {\n count++;\n }\n\n return count;\n }\n\n /**\n * Starts the ticker. If the ticker has listeners a new animation frame is requested at this point.\n * @example\n * ```ts\n * // Basic manual start\n * const ticker = new Ticker();\n * ticker.add(() => {\n * // Animation code here\n * });\n * ticker.start();\n * ```\n * @see {@link Ticker#stop} For stopping the ticker\n * @see {@link Ticker#autoStart} For automatic starting\n * @see {@link Ticker#started} For checking ticker state\n */\n public start(): void\n {\n if (!this.started)\n {\n this.started = true;\n this._requestIfNeeded();\n }\n }\n\n /**\n * Stops the ticker. If the ticker has requested an animation frame it is canceled at this point.\n * @example\n * ```ts\n * // Basic stop\n * const ticker = new Ticker();\n * ticker.stop();\n * ```\n * @see {@link Ticker#start} For starting the ticker\n * @see {@link Ticker#started} For checking ticker state\n * @see {@link Ticker#destroy} For cleaning up the ticker\n */\n public stop(): void\n {\n if (this.started)\n {\n this.started = false;\n this._cancelIfNeeded();\n }\n }\n\n /**\n * Destroy the ticker and don't use after this. Calling this method removes all references to internal events.\n * @example\n * ```ts\n * // Clean up with active listeners\n * const ticker = new Ticker();\n * ticker.add(() => {});\n * ticker.destroy(); // Removes all listeners\n * ```\n * @see {@link Ticker#stop} For stopping without destroying\n * @see {@link Ticker#remove} For removing specific listeners\n */\n public destroy(): void\n {\n if (!this._protected)\n {\n this.stop();\n\n let listener = this._head.next;\n\n while (listener)\n {\n listener = listener.destroy(true);\n }\n\n this._head.destroy();\n this._head = null;\n }\n }\n\n /**\n * Triggers an update.\n *\n * An update entails setting the\n * current {@link Ticker#elapsedMS|elapsedMS},\n * the current {@link Ticker#deltaTime|deltaTime},\n * invoking all listeners with current deltaTime,\n * and then finally setting {@link Ticker#lastTime|lastTime}\n * with the value of currentTime that was provided.\n *\n * This method will be called automatically by animation\n * frame callbacks if the ticker instance has been started\n * and listeners are added.\n * @example\n * ```ts\n * // Basic manual update\n * const ticker = new Ticker();\n * ticker.update(performance.now());\n * ```\n * @param currentTime - The current time of execution (defaults to performance.now())\n * @see {@link Ticker#deltaTime} For frame delta value\n * @see {@link Ticker#elapsedMS} For raw elapsed time\n */\n public update(currentTime: number = performance.now()): void\n {\n let elapsedMS;\n\n // If the difference in time is zero or negative, we ignore most of the work done here.\n // If there is no valid difference, then should be no reason to let anyone know about it.\n // A zero delta, is exactly that, nothing should update.\n //\n // The difference in time can be negative, and no this does not mean time traveling.\n // This can be the result of a race condition between when an animation frame is requested\n // on the current JavaScript engine event loop, and when the ticker's start method is invoked\n // (which invokes the internal _requestIfNeeded method). If a frame is requested before\n // _requestIfNeeded is invoked, then the callback for the animation frame the ticker requests,\n // can receive a time argument that can be less than the lastTime value that was set within\n // _requestIfNeeded. This difference is in microseconds, but this is enough to cause problems.\n //\n // This check covers this browser engine timing issue, as well as if consumers pass an invalid\n // currentTime value. This may happen if consumers opt-out of the autoStart, and update themselves.\n\n if (currentTime > this.lastTime)\n {\n // Save uncapped elapsedMS for measurement\n elapsedMS = this.elapsedMS = currentTime - this.lastTime;\n\n // cap the milliseconds elapsed used for deltaTime\n if (elapsedMS > this._maxElapsedMS)\n {\n elapsedMS = this._maxElapsedMS;\n }\n\n elapsedMS *= this.speed;\n\n // If not enough time has passed, exit the function.\n // Get ready for next frame by setting _lastFrame, but based on _minElapsedMS\n // adjustment to ensure a relatively stable interval.\n if (this._minElapsedMS)\n {\n const delta = currentTime - this._lastFrame | 0;\n\n if (delta < this._minElapsedMS)\n {\n return;\n }\n\n this._lastFrame = currentTime - (delta % this._minElapsedMS);\n }\n\n this.deltaMS = elapsedMS;\n this.deltaTime = this.deltaMS * Ticker.targetFPMS;\n\n // Cache a local reference, in-case ticker is destroyed\n // during the emit, we can still check for head.next\n const head = this._head;\n\n // Invoke listeners added to internal emitter\n let listener = head.next;\n\n while (listener)\n {\n listener = listener.emit(this);\n }\n\n if (!head.next)\n {\n this._cancelIfNeeded();\n }\n }\n else\n {\n this.deltaTime = this.deltaMS = this.elapsedMS = 0;\n }\n\n this.lastTime = currentTime;\n }\n\n /**\n * The frames per second at which this ticker is running.\n * The default is approximately 60 in most modern browsers.\n * > [!NOTE] This does not factor in the value of\n * > {@link Ticker#speed|speed}, which is specific\n * > to scaling {@link Ticker#deltaTime|deltaTime}.\n * @example\n * ```ts\n * // Basic FPS monitoring\n * ticker.add(() => {\n * console.log(`Current FPS: ${Math.round(ticker.FPS)}`);\n * });\n * ```\n * @readonly\n */\n get FPS(): number\n {\n return 1000 / this.elapsedMS;\n }\n\n /**\n * Manages the maximum amount of milliseconds allowed to\n * elapse between invoking {@link Ticker#update|update}.\n *\n * This value is used to cap {@link Ticker#deltaTime|deltaTime},\n * but does not effect the measured value of {@link Ticker#FPS|FPS}.\n *\n * When setting this property it is clamped to a value between\n * `0` and `Ticker.targetFPMS * 1000`.\n * @example\n * ```ts\n * // Set minimum acceptable frame rate\n * const ticker = new Ticker();\n * ticker.minFPS = 30; // Never go below 30 FPS\n *\n * // Use with maxFPS for frame rate clamping\n * ticker.minFPS = 30;\n * ticker.maxFPS = 60;\n *\n * // Monitor delta capping\n * ticker.add(() => {\n * // Delta time will be capped based on minFPS\n * console.log(`Delta time: ${ticker.deltaTime}`);\n * });\n * ```\n * @default 10\n */\n get minFPS(): number\n {\n return 1000 / this._maxElapsedMS;\n }\n\n set minFPS(fps: number)\n {\n // Minimum must be below the maxFPS\n const minFPS = Math.min(this.maxFPS, fps);\n\n // Must be at least 0, but below 1 / Ticker.targetFPMS\n const minFPMS = Math.min(Math.max(0, minFPS) / 1000, Ticker.targetFPMS);\n\n this._maxElapsedMS = 1 / minFPMS;\n }\n\n /**\n * Manages the minimum amount of milliseconds required to\n * elapse between invoking {@link Ticker#update|update}.\n *\n * This will effect the measured value of {@link Ticker#FPS|FPS}.\n *\n * If it is set to `0`, then there is no limit; PixiJS will render as many frames as it can.\n * Otherwise it will be at least `minFPS`\n * @example\n * ```ts\n * // Set minimum acceptable frame rate\n * const ticker = new Ticker();\n * ticker.maxFPS = 60; // Never go above 60 FPS\n *\n * // Use with maxFPS for frame rate clamping\n * ticker.minFPS = 30;\n * ticker.maxFPS = 60;\n *\n * // Monitor delta capping\n * ticker.add(() => {\n * // Delta time will be capped based on maxFPS\n * console.log(`Delta time: ${ticker.deltaTime}`);\n * });\n * ```\n * @default 0\n */\n get maxFPS(): number\n {\n if (this._minElapsedMS)\n {\n return Math.round(1000 / this._minElapsedMS);\n }\n\n return 0;\n }\n\n set maxFPS(fps: number)\n {\n if (fps === 0)\n {\n this._minElapsedMS = 0;\n }\n else\n {\n // Max must be at least the minFPS\n const maxFPS = Math.max(this.minFPS, fps);\n\n this._minElapsedMS = 1 / (maxFPS / 1000);\n }\n }\n\n /**\n * The shared ticker instance used by {@link AnimatedSprite} and by\n * {@link VideoSource} to update animation frames / video textures.\n *\n * It may also be used by {@link Application} if created with the `sharedTicker` option property set to true.\n *\n * The property {@link Ticker#autoStart|autoStart} is set to `true` for this instance.\n * Please follow the examples for usage, including how to opt-out of auto-starting the shared ticker.\n * @example\n * import { Ticker } from 'pixi.js';\n *\n * const ticker = Ticker.shared;\n * // Set this to prevent starting this ticker when listeners are added.\n * // By default this is true only for the Ticker.shared instance.\n * ticker.autoStart = false;\n *\n * // FYI, call this to ensure the ticker is stopped. It should be stopped\n * // if you have not attempted to render anything yet.\n * ticker.stop();\n *\n * // Call this when you are ready for a running shared ticker.\n * ticker.start();\n * @example\n * import { autoDetectRenderer, Container } from 'pixi.js';\n *\n * // You may use the shared ticker to render...\n * const renderer = autoDetectRenderer();\n * const stage = new Container();\n * document.body.appendChild(renderer.view);\n * ticker.add((time) => renderer.render(stage));\n *\n * // Or you can just update it manually.\n * ticker.autoStart = false;\n * ticker.stop();\n * const animate = (time) => {\n * ticker.update(time);\n * renderer.render(stage);\n * requestAnimationFrame(animate);\n * };\n * animate(performance.now());\n * @type {Ticker}\n * @readonly\n */\n static get shared(): Ticker\n {\n if (!Ticker._shared)\n {\n const shared = Ticker._shared = new Ticker();\n\n shared.autoStart = true;\n shared._protected = true;\n }\n\n return Ticker._shared;\n }\n\n /**\n * The system ticker instance used by {@link PrepareBase} for core timing\n * functionality that shouldn't usually need to be paused, unlike the `shared`\n * ticker which drives visual animations and rendering which may want to be paused.\n *\n * The property {@link Ticker#autoStart|autoStart} is set to `true` for this instance.\n * @type {Ticker}\n * @readonly\n * @advanced\n */\n static get system(): Ticker\n {\n if (!Ticker._system)\n {\n const system = Ticker._system = new Ticker();\n\n system.autoStart = true;\n system._protected = true;\n }\n\n return Ticker._system;\n }\n}\n"],"names":[],"mappings":"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"}