Socket
Socket
Sign inDemoInstall

crossani

Package Overview
Dependencies
Maintainers
2
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

crossani - npm Package Compare versions

Comparing version 1.2.1 to 1.3.0

dist/cjs/transCssManager.js

56

dist/bundle.js
(() => {
// src/generator.ts
// src/transCssManager.ts
var EASE = {

@@ -20,7 +20,12 @@ cubicBezier: (...points) => `cubic-bezier(${points.map((p) => p.toString()).reduce((curr, next) => curr + "," + next)})`,

};
var generateTransition = (prevState, transition) => distinct([
...Object.keys(transition.state ?? {}),
...Object.keys(prevState.curr)
]).map((p) => `${p} ${transition.ms ?? prevState.lastMs}ms ${transition.easing ?? prevState.lastEase}`).join(",");
var distinct = (arr) => Array.from(new Set(arr));
function updateTransition(state, trans) {
for (const prop in trans.state)
if (!state.running.has(prop))
state.running.set(prop, [
trans.ms ?? state.lastMs,
prop,
trans.easing ?? state.lastEase
]);
}
var generateTransition = (state) => Array.from(state.running.values()).map(([ms, prop, ease]) => `${prop} ${ms ?? state.lastMs}ms ${ease ?? state.lastEase}`).join(",");

@@ -49,5 +54,6 @@ // src/shared.ts

queue: [],
transitionPromises: [],
transitionPromises: /* @__PURE__ */ new Map(),
lastEase: EASE.ease,
lastMs: 100
lastMs: 100,
running: /* @__PURE__ */ new Map()
};

@@ -65,6 +71,9 @@ sanitiseStyleObject(newState.orig);

const state = getOrInitStore(elem);
state.queue.push(transition);
if (transition.detached)
startAnimating(elem, transition);
else
state.queue.push(transition);
let resolve;
const promise = new Promise((res) => resolve = res);
state.transitionPromises.push([transition, promise, () => resolve()]);
state.transitionPromises.set(transition, [promise, () => resolve()]);
return [state.queue.length === 1, promise];

@@ -119,3 +128,4 @@ }

Object.assign(state.curr, transition.state);
state.transitionPromises.shift()?.[2]();
state.transitionPromises.get(transition)?.[1]();
state.transitionPromises.delete(transition);
return true;

@@ -129,8 +139,9 @@ }

var abortAnimation = (elem) => elem.style.transition = "none";
function startAnimating(elem) {
function startAnimating(elem, transition) {
const state = getOrInitStore(elem);
const transition = state.queue[0];
if (!transition?.detached)
transition = state.queue[0];
if (!transition)
return;
const transitionString = generateTransition(state, transition);
updateTransition(state, transition);
if (transition.reset)

@@ -140,9 +151,12 @@ state.curr = { ...transition.state };

Object.assign(state.curr, transition.state);
elem.style.transition = generateTransition(state);
updateStyles(elem);
state.lastMs = transition.ms ?? state.lastMs;
state.lastEase = transition.easing ?? state.lastEase;
elem.style.transition = transitionString;
updateStyles(elem);
enqueue(() => {
state.transitionPromises.get(transition)?.[1]();
state.transitionPromises.delete(transition);
if (transition.detached)
return;
state.queue.shift();
state.transitionPromises.shift()?.[2]();
startAnimating(elem);

@@ -171,2 +185,5 @@ }, state.lastMs + 1);

};
SVGElement.prototype.forcePop = HTMLElement.prototype.forcePop = function() {
popAll(this);
};
SVGElement.prototype.removeCrossAni = HTMLElement.prototype.removeCrossAni = function() {

@@ -180,7 +197,2 @@ const store = getOrInitStore(this);

};
var orig = Element.prototype.remove;
Element.prototype.remove = function() {
stateStore.delete(this);
orig.call(this);
};
var unload = () => {

@@ -187,0 +199,0 @@ for (const elem of stateStore.keys())

@@ -25,3 +25,3 @@ var __defProp = Object.defineProperty;

module.exports = __toCommonJS(animator_exports);
var import_generator = require("./generator");
var import_transCssManager = require("./transCssManager");
var import_util = require("./util");

@@ -38,3 +38,4 @@ var import_queue = require("./queue");

Object.assign(state.curr, transition.state);
state.transitionPromises.shift()?.[2]();
state.transitionPromises.get(transition)?.[1]();
state.transitionPromises.delete(transition);
return true;

@@ -48,8 +49,9 @@ }

const abortAnimation = (elem) => elem.style.transition = "none";
function startAnimating(elem) {
function startAnimating(elem, transition) {
const state = (0, import_util.getOrInitStore)(elem);
const transition = state.queue[0];
if (!transition?.detached)
transition = state.queue[0];
if (!transition)
return;
const transitionString = (0, import_generator.generateTransition)(state, transition);
(0, import_transCssManager.updateTransition)(state, transition);
if (transition.reset)

@@ -59,11 +61,14 @@ state.curr = { ...transition.state };

Object.assign(state.curr, transition.state);
elem.style.transition = (0, import_transCssManager.generateTransition)(state);
(0, import_util.updateStyles)(elem);
state.lastMs = transition.ms ?? state.lastMs;
state.lastEase = transition.easing ?? state.lastEase;
elem.style.transition = transitionString;
(0, import_util.updateStyles)(elem);
(0, import_queue.enqueue)(() => {
state.transitionPromises.get(transition)?.[1]();
state.transitionPromises.delete(transition);
if (transition.detached)
return;
state.queue.shift();
state.transitionPromises.shift()?.[2]();
startAnimating(elem);
}, state.lastMs + 1);
}
var import__ = require(".");
var import_generator = require("./generator");
window.EASE = import_generator.EASE;
window.JUMP = import_generator.JUMP;
var import_transCssManager = require("./transCssManager");
window.EASE = import_transCssManager.EASE;
window.JUMP = import_transCssManager.JUMP;
window.unloadCrossani = import__.unload;

@@ -20,4 +20,4 @@ var __defProp = Object.defineProperty;

__export(src_exports, {
EASE: () => import_generator.EASE,
JUMP: () => import_generator.JUMP,
EASE: () => import_transCssManager.EASE,
JUMP: () => import_transCssManager.JUMP,
unload: () => unload

@@ -29,3 +29,3 @@ });

var import_util = require("./util");
var import_generator = require("./generator");
var import_transCssManager = require("./transCssManager");
SVGElement.prototype.doTransition = HTMLElement.prototype.doTransition = function(transOrName) {

@@ -49,2 +49,5 @@ (0, import_util.sanitiseTransitions)(this);

};
SVGElement.prototype.forcePop = HTMLElement.prototype.forcePop = function() {
(0, import_animator.popAll)(this);
};
SVGElement.prototype.removeCrossAni = HTMLElement.prototype.removeCrossAni = function() {

@@ -58,7 +61,2 @@ const store = (0, import_util.getOrInitStore)(this);

};
const orig = Element.prototype.remove;
Element.prototype.remove = function() {
import_shared.stateStore.delete(this);
orig.call(this);
};
const unload = () => {

@@ -65,0 +63,0 @@ for (const elem of import_shared.stateStore.keys())

@@ -28,4 +28,5 @@ var __defProp = Object.defineProperty;

module.exports = __toCommonJS(util_exports);
var import_generator = require("./generator");
var import_transCssManager = require("./transCssManager");
var import_shared = require("./shared");
var import_animator = require("./animator");
function cloneStyles(styles) {

@@ -49,5 +50,6 @@ const cloned = {};

queue: [],
transitionPromises: [],
lastEase: import_generator.EASE.ease,
lastMs: 100
transitionPromises: /* @__PURE__ */ new Map(),
lastEase: import_transCssManager.EASE.ease,
lastMs: 100,
running: /* @__PURE__ */ new Map()
};

@@ -65,6 +67,9 @@ sanitiseStyleObject(newState.orig);

const state = getOrInitStore(elem);
state.queue.push(transition);
if (transition.detached)
(0, import_animator.startAnimating)(elem, transition);
else
state.queue.push(transition);
let resolve;
const promise = new Promise((res) => resolve = res);
state.transitionPromises.push([transition, promise, () => resolve()]);
state.transitionPromises.set(transition, [promise, () => resolve()]);
return [state.queue.length === 1, promise];

@@ -71,0 +76,0 @@ }

@@ -1,2 +0,2 @@

import { generateTransition } from "./generator";
import { generateTransition, updateTransition } from "./transCssManager";
import { getOrInitStore, updateStyles } from "./util";

@@ -16,3 +16,4 @@ import { enqueue } from "./queue";

// resolve
state.transitionPromises.shift()?.[2]();
state.transitionPromises.get(transition)?.[1]();
state.transitionPromises.delete(transition);
return true;

@@ -26,10 +27,9 @@ }

export const abortAnimation = (elem) => (elem.style.transition = "none");
export function startAnimating(elem) {
export function startAnimating(elem, transition) {
const state = getOrInitStore(elem);
const transition = state.queue[0];
if (!transition?.detached)
transition = state.queue[0];
if (!transition)
return;
// generates the style transition: property string
// needs to be run before updating state.curr or some values may not work correctly
const transitionString = generateTransition(state, transition);
updateTransition(state, transition);
// update styles

@@ -40,12 +40,15 @@ if (transition.reset)

Object.assign(state.curr, transition.state);
// run transition
elem.style.transition = generateTransition(state);
updateStyles(elem);
state.lastMs = transition.ms ?? state.lastMs;
state.lastEase = transition.easing ?? state.lastEase;
// run transition
elem.style.transition = transitionString;
updateStyles(elem);
enqueue(() => {
state.transitionPromises.get(transition)?.[1]();
state.transitionPromises.delete(transition);
if (transition.detached)
return;
state.queue.shift();
state.transitionPromises.shift()?.[2]();
startAnimating(elem);
}, state.lastMs + 1); // lmao
}
import { unload } from ".";
import { EASE, JUMP } from "./generator";
import { EASE, JUMP } from "./transCssManager";
// @ts-expect-error

@@ -4,0 +4,0 @@ window.EASE = EASE;

import { abortAnimation, popAll, startAnimating } from "./animator";
import { stateStore } from "./shared";
import { getOrInitStore, queueTransition, sanitiseTransitions, updateStyles, whenTransitionAborts, } from "./util";
export { EASE, JUMP } from "./generator";
export { EASE, JUMP } from "./transCssManager";
SVGElement.prototype.doTransition = HTMLElement.prototype.doTransition =

@@ -29,2 +29,6 @@ function (transOrName) {

};
SVGElement.prototype.forcePop = HTMLElement.prototype.forcePop =
function () {
popAll(this);
};
SVGElement.prototype.removeCrossAni = HTMLElement.prototype.removeCrossAni =

@@ -39,7 +43,2 @@ function () {

};
const orig = Element.prototype.remove;
Element.prototype.remove = function () {
stateStore.delete(this);
orig.call(this);
};
export const unload = () => {

@@ -46,0 +45,0 @@ for (const elem of stateStore.keys())

@@ -1,3 +0,4 @@

import { EASE } from "./generator";
import { EASE } from "./transCssManager";
import { stateStore } from "./shared";
import { startAnimating } from "./animator";
/** Converts a CSSStyleDeclaration to a Record<string, string> */

@@ -26,5 +27,6 @@ export function cloneStyles(styles) {

queue: [],
transitionPromises: [],
transitionPromises: new Map(),
lastEase: EASE.ease,
lastMs: 100,
running: new Map()
};

@@ -45,6 +47,9 @@ sanitiseStyleObject(newState.orig);

const state = getOrInitStore(elem);
state.queue.push(transition);
if (transition.detached)
startAnimating(elem, transition);
else
state.queue.push(transition);
let resolve;
const promise = new Promise((res) => (resolve = res));
state.transitionPromises.push([transition, promise, () => resolve()]);
state.transitionPromises.set(transition, [promise, () => resolve()]);
return [state.queue.length === 1, promise];

@@ -51,0 +56,0 @@ }

@@ -0,4 +1,5 @@

import { Transition } from "./types";
/** Pops all transitions off the queue instantly and applies relevant CSS */
export declare function popAll(elem: HTMLElement | SVGElement): void;
export declare const abortAnimation: (elem: HTMLElement | SVGElement) => string;
export declare function startAnimating(elem: HTMLElement | SVGElement): void;
export declare function startAnimating(elem: HTMLElement | SVGElement, transition?: Transition): void;

@@ -1,3 +0,3 @@

export { EASE, JUMP } from "./generator";
export { EASE, JUMP } from "./transCssManager";
export declare const unload: () => void;
export type { Transition } from "./types";

@@ -13,3 +13,6 @@ /** Represents a transition that may run on an element at any given time */

cutOff?: boolean;
/** Don't track and queue this */
detached?: boolean;
}
export declare type CssTransition = [number | undefined, string, string | undefined];
/** @internal */

@@ -24,3 +27,3 @@ export interface ElementState {

/** Stores promises for transition completion */
transitionPromises: [Transition, Promise<void>, () => void][];
transitionPromises: Map<Transition, [Promise<void>, () => void]>;
/** Stores the previous ms value of the element */

@@ -30,2 +33,4 @@ lastMs: number;

lastEase: string;
/** Current running transitions */
running: Map<string, CssTransition>;
}

@@ -37,6 +42,8 @@ declare global {

/** Runs transitions defined in Element.transitions by name */
doTransition(name: Transition | string): void;
doTransition(name: Transition | string): Promise<void>;
/** Removes CrossAni from this element */
removeCrossAni(): void;
/** Stops currently running animations */
forcePop(): void;
}
}
{
"name": "crossani",
"version": "1.2.1",
"version": "1.3.0",
"description": "A silky smooth declarative animation library for the web.",

@@ -15,4 +15,4 @@ "main": "dist/cjs/index.js",

"scripts": {
"build": "tsc && esbuild src/*.ts --format=cjs --outdir=dist/cjs && esbuild src/browser.ts --bundle --outfile=dist/bundle.js"
"prepublish": "tsc && esbuild src/*.ts --format=cjs --outdir=dist/cjs && esbuild src/browser.ts --bundle --outfile=dist/bundle.js"
}
}

@@ -13,3 +13,3 @@ # CrossAni

However: this can have massive performance repurcussions.
However: this can have performance repurcussions.

@@ -20,3 +20,3 @@ CrossAni uses CSS transitions to fix this problem, using the browser's built in animating tools.

The main other way to achieve this is the Web Animations API (WAAPI).
The main other way to achieve this is the Web Animations API (WAAPI) like Motion One does.

@@ -60,12 +60,28 @@ ### Size Matters

Any element that should be animated needs a `transitions` property with a key-value record of strings to state objects.
Any element that should be animated can have a `transitions` property with a key-value record of strings to transition objects.
A state object contains the following things:
You may also pass transition objects directly to doTransition,
which is helpful for programmatically generated animations for example.
A transition object contains the following things:
- `ms`: the time it should take to finish transitioning to that state
- `easing`: An easing function to use, all exported on the `EASE` object.
- `state`: An object containing the CSS values to set on the element this state.
- `cutOff`: (OPTIONAL) see behaviour above
- `reset`: (OPTIONAL) see behaviour above
- `cutOff`: see behaviour above
- `reset`: see behaviour above
- `detached`: if true, this transition is completely independent of the global queue and runs instantly.
Transition objects allow all properties to be undefined, and will provide useful defaults:
```js
({
state: {},
ms: 100, // falls through from past transition, this value is for the first transition
easing: EASE.ease, // see above comment
cutOff: false,
reset: false,
detached: false
})
```
An example setup would be as follows:

@@ -78,3 +94,2 @@

default: {
state: {},
ms: 500,

@@ -88,4 +103,3 @@ easing: EASE.inOut,

state: { transform: "scale(1.1)" },
ms: 250,
easing: EASE.inOut,
ms: 250
},

@@ -117,3 +131,3 @@ };

box.doTransition("moveright");
box.doTransition("slowgrop");
box.doTransition("slowgrow");
await box.doTransition("fadetextout");

@@ -132,4 +146,2 @@ box.innerText = "the text is now different";

Either way, you're doing much better with CrossAni than JS animations, even if you're not getting the most blazing speed!
Non `transform` _movements_ are slower as, although the browser is running the animation,

@@ -150,3 +162,3 @@ repaints and often reflows are necessary, which are expensive.

But also, SVG `d` attributes still cannot be animated with CSS transitions.
However, CrossAni does not support some SVG attributes such as `d`.

@@ -158,3 +170,3 @@ ### Bundle size

| Pkg | Raw | Gzip | Brotli |
| -------- | ------- | ------- | ------- |
|----------|---------|---------|---------|
| crossani | 2.5kb | 1.12kb | 1.05kb |

@@ -167,48 +179,48 @@ | motion | 15.07kb | 6.34kb | 6.17kb |

| | Feature | CrossAni | Motion | AnimeJS | Greensock |
| ------------ | -----------------: | :---------: | :-------: | :----------: | :-------: |
| **Values** | CSS `transform` | ✅ | ✅ | ❌ | ✅ |
| | Named colours | ✅ | ✅ | ❌ | Partial |
| | Colour type conv | ✅ | ✅ | Wrong interp | ✅ |
| | To/from CSS vars | ✅ | ✅ | ❌ | ❌ |
| | To/from CSS funcs | ✅ | ✅ | ❌ | ❌ |
| | Animate CSS vars | ❌ | ✅ | ❌ | ❌ |
| | Simple keyframes | ❌ Soon? | ✅ | ✅ | ❌ |
| | Wildcard keyframes | N/A | ✅ | ❌ | ❌ |
| | Relative values | ❌ | ✅ | ❌ | ❌ |
| **Output** | Element styles | ✅ | ✅ | ✅ | ✅ |
| | Element attrs | ❌ | ❌ | ✅ | ✅ |
| | Custom animations | ❌ | ✅ | ✅ | ✅ |
| **Options** | Duration | ✅ | ✅ | ✅ | ✅ |
| | Direction | ✅ | ✅ | ✅ | ✅ |
| | Repeat | ❌ | ✅ | ✅ | ✅ |
| | Delay | ❌ | ✅ | ✅ | ✅ |
| | End delay | ❌ | ✅ | ✅ | ✅ |
| | Repeat delay | ❌ | ✅ | ❌ | ✅ |
| **Stagger** | Stagger | ❌ | ✅ +.1kb | ✅ | ✅ |
| **Timeline** | Timeline | ❌ | ✅ +.6kb | ✅ | ✅ |
| **Controls** | Play | ✅ | ✅ | ✅ | ✅ |
| | Pause | ❌ | ✅ | ✅ | ✅ |
| | Finish | ❌ | ✅ | ✅ | ✅ |
| | Reverse | ❌ | ✅ | ✅ | ✅ |
| | Stop | ❌ | ✅ | ✅ | ✅ |
| | Playback rate | ❌ | ✅ | ✅ | ✅ |
| **Easing** | Linear | ✅ | ✅ | ✅ | ✅ |
| | Cubic bezier | ✅ | ✅ | ✅ | ✅ |
| | Steps | ✅ | ✅ | ✅ | ✅ |
| | Spring simulation | ❌ | ✅ +1kb | ❌ | ❌ |
| | Glide | ❌ | ✅ +1.3kb | ❌ | ✅ $99/yr |
| | Spring easing | ❌ | ❌ | ✅ | ❌ |
| | Custom easings | ❌ | ❌ | ✅ | ✅ |
| **Events** | Complete | ✅ | ✅ | ✅ | ✅ |
| | Cancel | Fires above | ✅ | ✅ | ✅ |
| | Start | ❌ | ❌ | ✅ | ✅ |
| | Update | ❌ | ❌ | ✅ | ✅ |
| | Repeat | N/A | ❌ | ✅ | ✅ |
| **Path** | Motion path | ❌ | ✅ | ✅ | ✅ +9.5kb |
| | Path morphing | ❌ | ✅ lib | ✅ = #points | ✅ $99/yr |
| | Path drawing | ✅ | ✅ | ✅ | ✅ $99/yr |
| **Other** | license | MIT | MIT | MIT | Custom |
| | GPU acceleration | ✅ | ✅ | ❌ | ❌ |
| | IE11 (ew) | ❌ | ❌ | ✅ | ✅ |
| | Frameworks | ✅ | ✅ | ❌ | ❌ |
| | Feature | CrossAni | Motion | AnimeJS | Greensock |
|--------------|-------------------:|:--------:|:--------:|:------------:|:---------:|
| **Values** | CSS `transform` | ✅ | ✅ | ❌ | ✅ |
| | Named colours | ✅ | ✅ | ❌ | Partial |
| | Colour type conv | ✅ | ✅ | Wrong interp | ✅ |
| | To/from CSS vars | ✅ | ✅ | ❌ | ❌ |
| | To/from CSS funcs | ✅ | ✅ | ❌ | ❌ |
| | Animate CSS vars | ❌ | ✅ | ❌ | ❌ |
| | Simple keyframes | ❌ Soon? | ✅ | ✅ | ❌ |
| | Wildcard keyframes | N/A | ✅ | ❌ | ❌ |
| | Relative values | ❌ | ✅ | ❌ | ❌ |
| **Output** | Element styles | ✅ | ✅ | ✅ | ✅ |
| | Element attrs | ❌ | ❌ | ✅ | ✅ |
| | Custom animations | ❌ | ✅ | ✅ | ✅ |
| **Options** | Duration | ✅ | ✅ | ✅ | ✅ |
| | Direction | ✅ | ✅ | ✅ | ✅ |
| | Repeat | ❌ | ✅ | ✅ | ✅ |
| | Delay | ❌ | ✅ | ✅ | ✅ |
| | End delay | ❌ | ✅ | ✅ | ✅ |
| | Repeat delay | ❌ | ✅ | ❌ | ✅ |
| **Stagger** | Stagger | ❌ | ✅ +.1kb | ✅ | ✅ |
| **Timeline** | Timeline | ❌ | ✅ +.6kb | ✅ | ✅ |
| **Controls** | Play | ✅ | ✅ | ✅ | ✅ |
| | Pause | ❌ | ✅ | ✅ | ✅ |
| | Finish | ❌ | ✅ | ✅ | ✅ |
| | Reverse | ❌ | ✅ | ✅ | ✅ |
| | Stop | ❌ | ✅ | ✅ | ✅ |
| | Playback rate | ❌ | ✅ | ✅ | ✅ |
| **Easing** | Linear | ✅ | ✅ | ✅ | ✅ |
| | Cubic bezier | ✅ | ✅ | ✅ | ✅ |
| | Steps | ✅ | ✅ | ✅ | ✅ |
| | Spring simulation | ❌ | ✅ +1kb | ❌ | ❌ |
| | Glide | ❌ | ✅ +1.3kb | ❌ | ✅ $99/yr |
| | Spring easing | ❌ | ❌ | ✅ | ❌ |
| | Custom easings | ❌ | ❌ | ✅ | ✅ |
| **Events** | Complete | ✅ | ✅ | ✅ | ✅ |
| | Cancel | ^ | ✅ | ✅ | ✅ |
| | Start | ❌ | ❌ | ✅ | ✅ |
| | Update | ❌ | ❌ | ✅ | ✅ |
| | Repeat | N/A | ❌ | ✅ | ✅ |
| **Path** | Motion path | ❌ | ✅ | ✅ | ✅ +9.5kb |
| | Path morphing | ❌ | ✅ lib | ✅ = #points | ✅ $99/yr |
| | Path drawing | ✅ | ✅ | ✅ | ✅ $99/yr |
| **Other** | license | MIT | MIT | MIT | Custom |
| | GPU acceleration | ✅ | ✅ | ❌ | ❌ |
| | IE11 (ew) | ❌ | ❌ | ✅ | ✅ |
| | Frameworks | ✅ | ✅ | ❌ | ❌ |
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc