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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@blakron/game

v0.3.0

Published

Game extensions for the Blakron engine — Tween, Ease, MovieClip, ScrollView, URLLoader

Readme

@blakron/game

Game extensions for the Blakron engine — Tween animation, MovieClip, ScrollView, and URLLoader.

Migrated from Egret's extension/tween and extension/game, rewritten in modern TypeScript.

Installation

pnpm add @blakron/game

Requires @blakron/core as a peer dependency.

Modules

Tween

Egret-compatible tween engine with object pooling and a chainable step queue.

import { Tween, Ease } from '@blakron/game';

// Basic animation
Tween.get(sprite)
	.to({ x: 200, alpha: 0 }, 500, Ease.cubicOut)
	.wait(100)
	.call(() => console.log('done'));

// Loop
Tween.get(sprite, { loop: true }).to({ scaleX: 1.2, scaleY: 1.2 }, 200, Ease.backOut).to({ scaleX: 1, scaleY: 1 }, 200);

// Start paused, then play later
const tween = Tween.get(sprite, { paused: true }).to({ x: 100 }, 300);
tween.setPaused(false);

// Jump to a specific time position
tween.setPosition(150); // seek to 150ms

// onChange callback — fires every tick
Tween.get(sprite, {
	onChange: t => console.log('progress'),
	onLoopComplete: t => console.log('loop done'),
});

// Manage tweens on a target
Tween.pauseTweens(sprite);
Tween.resumeTweens(sprite);
Tween.removeTweens(sprite);
Tween.removeAllTweens();

// Global pause
Tween.pauseAll();
Tween.resumeAll();

Ease functions:

Ease.linear;
Ease.cubicIn / Ease.cubicOut / Ease.cubicInOut;
Ease.backOut;
Ease.elasticOut;
Ease.bounceOut;
Ease.getPowOut(4); // quartOut equivalent
Ease.getElasticOut(1, 0.3);
Ease.cubicBezier(0.25, 0.1, 0.25, 1);

TweenGroup

Manage a named set of tweens together.

import { TweenGroup } from '@blakron/game';

const group = new TweenGroup('ui');
group.get(btnA).to({ alpha: 0 }, 300);
group.get(btnB).to({ alpha: 0 }, 300);

group.pause();
group.resume();
group.removeAll();

MovieClip

Sequence-frame animation display object. Extends Bitmap and drives frame changes via the engine ticker.

import { MovieClip, MovieClipData } from '@blakron/game';
import { Event } from '@blakron/core';

// Build frame data from textures
const data = MovieClipData.fromTextureArray([tex1, tex2, tex3], 12);

// From a SpriteSheet
const data2 = MovieClipData.fromSpriteSheet(sheet, ['run_01', 'run_02', 'run_03'], 24);

// Frame events — dispatched when a specific frame is reached
data.setFrameEvent(2, 'footstep'); // 0-based index

const mc = new MovieClip(data);
mc.addEventListener('footstep', () => playSound());

// Playback
mc.play(-1); // loop forever
mc.play(3); // play 3 times then stop
mc.play(0); // don't change current play count (Egret-compatible)
mc.stop();

mc.gotoAndPlay('attack'); // jump to label and play
mc.gotoAndStop(5); // jump to frame 5 (1-based) and stop
mc.prevFrame();
mc.nextFrame();

// Events
mc.addEventListener(Event.COMPLETE, () => console.log('done'));
mc.addEventListener(Event.LOOP_COMPLETE, () => console.log('loop'));

// Properties
console.log(mc.currentFrame); // 1-based frame number
console.log(mc.totalFrames);
console.log(mc.currentFrameLabel); // label of current frame, or undefined
console.log(mc.currentLabel); // nearest preceding label
console.log(mc.frameRate); // fps (override per-clip)
console.log(mc.isPlaying);

stage.addChild(mc);

ScrollView

Inertial scrolling container with bounce, scroll threshold, and animated scroll-to.

import { ScrollView, ScrollPolicy } from '@blakron/game';
import { Event } from '@blakron/core';

const sv = new ScrollView();
sv.width = 640;
sv.height = 960;
sv.bounces = true;
sv.scrollSpeed = 1;
sv.scrollBeginThreshold = 10;
sv.horizontalScrollPolicy = ScrollPolicy.OFF;
sv.verticalScrollPolicy = ScrollPolicy.AUTO;
sv.setContent(contentSprite);
stage.addChild(sv);

// Instant scroll
sv.scrollTop = 200;
sv.scrollLeft = 0;

// Animated scroll
sv.setScrollTop(200, 300); // scroll to y=200 over 300ms
sv.setScrollLeft(0, 300);

// Combined (instant)
sv.setScrollPosition(200, 0);
// Combined (delta)
sv.setScrollPosition(10, 0, true);

sv.addEventListener(Event.CHANGE, () => console.log(sv.scrollTop));
sv.addEventListener(Event.COMPLETE, () => console.log('tween done'));

console.log(sv.getMaxScrollTop());
console.log(sv.getMaxScrollLeft());

URLLoader

High-level resource loader wrapping @blakron/core's HttpRequest, ImageLoader, and Sound.

import {
	URLLoader,
	URLRequest,
	URLLoaderDataFormat,
	URLRequestHeader,
	URLRequestMethod,
	URLVariables,
} from '@blakron/game';
import { Event, IOErrorEvent, Texture, Sound } from '@blakron/core';

// Load JSON
const loader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.JSON;
loader.addEventListener(Event.COMPLETE, () => {
	const config = loader.data as Record<string, unknown>;
});
loader.addEventListener(IOErrorEvent.IO_ERROR, () => console.error('failed'));
loader.load(new URLRequest('data/config.json'));

// Load texture
const texLoader = new URLLoader();
texLoader.dataFormat = URLLoaderDataFormat.TEXTURE;
texLoader.addEventListener(Event.COMPLETE, () => {
	const texture = texLoader.data as Texture;
});
texLoader.load(new URLRequest('assets/bg.png'));

// Load sound
const sndLoader = new URLLoader();
sndLoader.dataFormat = URLLoaderDataFormat.SOUND;
sndLoader.addEventListener(Event.COMPLETE, () => {
	const sound = sndLoader.data as Sound;
	sound.play();
});
sndLoader.load(new URLRequest('audio/bgm.mp3'));

// POST with URLVariables
const vars = new URLVariables();
vars.variables['key'] = 'value';
vars.variables['count'] = '3';

const req = new URLRequest('https://api.example.com/data');
req.method = URLRequestMethod.POST;
req.data = vars.toString();
req.requestHeaders.push(new URLRequestHeader('Content-Type', 'application/x-www-form-urlencoded'));
loader.load(req);

// Abort
loader.close();

API Reference

Tween static methods

| Method | Description | | ----------------------------- | ---------------------------------- | | Tween.get(target, options?) | Create or reuse a tween for target | | Tween.removeTweens(target) | Remove all tweens on target | | Tween.pauseTweens(target) | Pause all tweens on target | | Tween.resumeTweens(target) | Resume all tweens on target | | Tween.removeAllTweens() | Remove all active tweens | | Tween.pauseAll() | Global pause | | Tween.resumeAll() | Global resume |

Tween instance methods

| Method | Description | | ------------------------------- | ---------------------------------- | | .to(props, duration, ease?) | Animate to values | | .from(props, duration, ease?) | Animate from values | | .wait(duration) | Pause between steps | | .call(fn, thisObj?, params?) | Callback step | | .set(props) | Instant property set | | .setPaused(value) | Pause or resume (Egret-compatible) | | .setPosition(ms) | Seek to absolute time position | | .pause() / .resume() | Shorthand for setPaused |

TweenOptions

| Option | Type | Description | | ------------------- | ----------------- | ----------------------------------------------- | | loop | boolean | Loop the tween sequence | | ignoreGlobalPause | boolean | Ignore Tween.pauseAll() | | ease | EaseFunction | Default ease for all steps | | paused | boolean | Start in paused state | | position | number | Seek to this time (ms) immediately after create | | onChange | (tween) => void | Called every tick while running | | onLoopComplete | (tween) => void | Called each time a loop cycle completes |

MovieClip

| Member | Description | | ----------------------------- | -------------------------------------------------------------- | | play(playTimes?) | Play. -1 = loop, 0 = keep current setting, >=1 = N times | | stop() | Stop on current frame | | gotoAndPlay(frame) | Jump to frame/label and play | | gotoAndStop(frame) | Jump to frame/label and stop | | prevFrame() / nextFrame() | Step one frame | | currentFrame | Current frame number, 1-based (read-only) | | totalFrames | Total frame count (read-only) | | currentFrameLabel | Label of current frame, or undefined | | currentLabel | Nearest preceding labeled frame, or undefined | | frameRate | Per-clip fps override (NaN = use data's rate) | | isPlaying | Playback state (read-only) | | movieClipData | Frame data source |

MovieClipData

| Method | Description | | ------------------------------------------ | ------------------------------------ | | addFrame(texture, duration, label?) | Append a frame | | setFrameEvent(frameIndex, eventName) | Dispatch event when frame is reached | | fromTextureArray(textures, fps?) | Static factory from texture array | | fromSpriteSheet(sheet, frameNames, fps?) | Static factory from sprite sheet |

URLVariables

const vars = new URLVariables('key=value&count=3');
vars.decode('extra=data');
console.log(vars.toString()); // 'key=value&count=3&extra=data'

License

MIT