Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

animar

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

animar - npm Package Compare versions

Comparing version 0.4.4 to 0.5.1

.istanbul.yml

451

lib/animar.js

@@ -1,262 +0,281 @@

var EasingFactory = require("./ease"),
Helper = require("./helper"),
Constants = require("./constants");
/* @flow */
/* global __DEV__ */
import Animation from './animation';
import Attribute from './attribute';
import Element from './element';
var Animar = function() {
this.elementMap = new Map();
this.ticking = false;
if (__DEV__) {
var Helpers = require('./helpers');
var getStartValue = Helpers.getStartValue;
}
type ElementMap = Map<HTMLElement, Element>;
type AnimationOptions = { // user-provided so can't assume correct type or existance
delay: ?any,
easingFunction: ?any,
duration: ?any,
loop: ?any
};
type AttributesOptions = { [key: string]: number | Array<number> };
type ChainOptions = {
delay: number,
currentDuration: number,
totalDuration: number
}
type FullChainObject = {
start: Function,
loop: Function,
add: Function,
then: Function
};
type ThenChainObject = {
add: Function
};
type LoopChainObject = {
start: Function
}
type AddChainObject = FullChainObject;
Animar.prototype.add = function(element, attributes, options) {
return this._add(element, attributes, options, { delay: 0, currentDuration: 0, totalDuration: 0, animationList: [] });
const EMPTY_ANIMATION_OPTIONS = {
delay: null,
easingFunction: null,
duration: null,
loop: null
};
Animar.prototype._add = function(element, attributes, options, chainOptions) {
var self = this;
module.exports = class Animar {
ticking: boolean;
elementMap: ElementMap;
defaults: { delay: number, easingFunction: Function, duration: number, loop: boolean };
timescale: number;
// manage options defaults
options = options || {};
options.delay = options.delay || 0;
options.easing = options.easing || 'linear';
constructor() {
this.ticking = false;
this.elementMap = new Map();
this.defaults = {
delay: 0,
easingFunction: (t, b, c, d) => { return c * t / d + b; }, // linear easing function
duration: 60,
loop: false
};
this.timescale = 1;
}
options.easing = typeof options.easing === 'string' ? EasingFactory[options.easing]() : options.easing;
add(element: HTMLElement, attributes: AttributesOptions, options: AnimationOptions): FullChainObject {
let resolvedOptions = options == null ? EMPTY_ANIMATION_OPTIONS : options;
options.duration = options.duration || 60;
options.loop = options.loop || false;
if (__DEV__) {
if (element == null) {
throw 'Missing or null parameter: element';
}
if (!element instanceof HTMLElement) {
throw "Parameter 'element' should be of type HTMLElement";
}
if (typeof attributes === 'undefined') {
throw 'Missing or null parameter: attribtues';
}
if (typeof attributes !== 'object') {
throw "Parameter 'attributes' should be of type Object";
}
// TODO: Validate attributes contents
}
for (var attribute in attributes) {
/* istanbul ignore else */
if (attributes.hasOwnProperty(attribute)) {
var start, destination;
var attributeValue = attributes[attribute];
return this._add(
element,
attributes,
resolvedOptions,
{
delay: 0,
currentDuration: 0,
totalDuration: 0
},
new Map()
);
}
if (typeof attributeValue === 'number') {
destination = attributeValue;
mergeElementMaps(src: ElementMap, target: ElementMap): ElementMap {
let result = new Map(src);
target.forEach((element, elementRef) => {
let mergedElement;
if (result.has(elementRef)) {
mergedElement = result.get(elementRef).merge(element);
} else {
start = attributeValue[0];
destination = attributeValue[1];
mergedElement = element;
}
result.set(elementRef, mergedElement);
});
var attrOptions = {
start: start,
duration: options.duration,
easing: options.easing,
delay: options.delay + chainOptions.delay,
loop: options.loop,
wait: 0
};
return result;
}
var currentAnimation = this._addAnimation(element, attribute, destination, attrOptions);
chainOptions.animationList.push(currentAnimation);
resolveStartValue(start: ?number, element: HTMLElement, attribute: string, currentChain: ElementMap): ?number {
if (currentChain.has(element) && currentChain.get(element).hasAttribute(attribute)) {
start = currentChain.get(element).getModelFromAttribute(attribute);
} else if (this.elementMap.has(element) && this.elementMap.get(element).hasAttribute(attribute)) {
start = this.elementMap.get(element).getModelFromAttribute(attribute);
} else {
if (__DEV__) {
start = getStartValue(element, attribute);
}
}
return start;
}
chainOptions.currentDuration = Math.max(chainOptions.currentDuration, options.delay + options.duration);
_add(element: HTMLElement,
attributes: { [key: string]: number | Array<number> },
options: AnimationOptions,
chainOptions: ChainOptions,
currentChain: ElementMap): FullChainObject
{
const resolvedOptions = {
delay: options.delay == null ?
this.defaults.delay : options.delay,
easingFunction: options.easingFunction == null ?
this.defaults.easingFunction : options.easingFunction,
duration: options.duration == null ?
this.defaults.duration : options.duration,
loop: options.loop == null ?
this.defaults.loop : options.loop
};
return this._chainFunctions(chainOptions);
};
for (const attribute in attributes) {
if (attributes.hasOwnProperty(attribute)) {
const attributeValue = attributes[attribute];
let start, destination;
Animar.prototype._chainFunctions = function(chainOptions) {
return {
and: this._andChainFunction(chainOptions),
then: this._thenChainFunction(chainOptions),
loop: this._loopChainFunction(chainOptions),
wait: this._waitChainFunction(chainOptions)
};
};
if (typeof attributeValue === 'number') {
destination = attributeValue;
} else {
start = attributeValue[0];
destination = attributeValue[1];
}
Animar.prototype._andChainFunction = function(chainOptions) {
var self = this;
return function(element, attributes, options) {
return self._add(element, attributes, options, chainOptions);
};
};
start = this.resolveStartValue(start, element, attribute, currentChain);
Animar.prototype._thenChainFunction = function(chainOptions) {
var self = this;
return function(element, attributes, options) {
chainOptions.totalDuration = chainOptions.totalDuration + chainOptions.currentDuration;
chainOptions.currentDuration = 0;
chainOptions.delay = chainOptions.totalDuration;
return self._add(element, attributes, options, chainOptions);
};
};
if (start == null) {
throw 'Animation start value is not provided and cannot be infered';
} else {
start -= destination;
let newAnimation = new Animation(
0 - (resolvedOptions.delay + chainOptions.delay),
start,
0 - start,
resolvedOptions.duration,
resolvedOptions.easingFunction,
resolvedOptions.loop,
resolvedOptions.delay + chainOptions.delay,
0
);
Animar.prototype._loopChainFunction = function(chainOptions) {
var self = this;
return function() {
chainOptions.totalDuration = chainOptions.totalDuration + chainOptions.currentDuration;
for (var i = 0; i < chainOptions.animationList.length; i++) {
var anim = chainOptions.animationList[i];
anim.loop = true;
anim.wait = chainOptions.totalDuration - anim.delay - anim.totalIterations;
}
self._requestTick();
};
};
let newAttribute = new Attribute(attribute, destination);
newAttribute.addAnimation(newAnimation);
Animar.prototype._waitChainFunction = function(chainOptions) {
var self = this;
return function(numFrames) {
chainOptions.totalDuration = chainOptions.totalDuration + chainOptions.currentDuration + numFrames;
chainOptions.currentDuration = 0;
chainOptions.delay = chainOptions.totalDuration;
return self._chainFunctions(chainOptions);
};
};
let newElement = new Element(element);
newElement.addAttribute(attribute, newAttribute);
Animar.prototype._addAnimation = function(element, attribute, destination, options) {
var newAnimation = {
element: element,
attribute: attribute,
start: options.start,
destination: destination,
duration: options.duration,
ease: options.easing,
delay: options.delay,
loop: options.loop,
wait: options.wait
};
var currentAnimation = this._addAnimationToMap(newAnimation);
this._requestTick();
return currentAnimation;
};
let tempEMap = new Map();
tempEMap.set(element, newElement);
Animar.prototype._addAnimationToMap = function(args) {
if (!this.elementMap.has(args.element)) {
this.elementMap.set(args.element, new Map());
currentChain = this.mergeElementMaps(currentChain, tempEMap);
}
}
}
chainOptions.currentDuration = Math.max(chainOptions.currentDuration, resolvedOptions.delay + resolvedOptions.duration);
return this.fullChainObjectFactory(chainOptions, currentChain);
}
return this._addAnimationToElement(this.elementMap.get(args.element), args);
};
fullChainObjectFactory(chainOptions: ChainOptions, chain: ElementMap): FullChainObject {
return {
start: this.startChainFunctionFactory(chain),
loop: this.loopChainFunctionFactory(chainOptions, chain),
add: this.addChainFunctionFactory(chainOptions, chain),
then: this.thenChainFunctionFactory(chainOptions, chain)
};
}
Animar.prototype._addAnimationToElement = function(attributeMap, args) {
if (!attributeMap.has(args.attribute)) {
attributeMap = this._createAttribute(attributeMap, args);
thenChainFunctionFactory(chainOptions: ChainOptions, chain: ElementMap): Function {
return (wait=0) => {
chainOptions.totalDuration += (chainOptions.currentDuration + wait);
chainOptions.currentDuration = 0;
chainOptions.delay = chainOptions.totalDuration;
return {
add: this.addChainFunctionFactory(chainOptions, chain)
};
};
}
var currentAttribute = attributeMap.get(args.attribute),
startValue = currentAttribute.model - args.destination,
changeInValue = 0 - startValue;
currentAttribute.model = args.destination;
addChainFunctionFactory(chainOptions: ChainOptions, chain: ElementMap): Function {
return (element, attributes, options) => {
let resolvedOptions = typeof options === 'undefined' ? EMPTY_ANIMATION_OPTIONS : options;
return this._add(element, attributes, resolvedOptions, chainOptions, chain);
};
}
var currentAnimation = {
currentIteration: 0 - args.delay,
startValue: startValue,
changeInValue: changeInValue,
totalIterations: args.duration,
easingFunction: args.ease,
loop: args.loop,
delay: args.delay,
wait: args.wait
};
currentAttribute.animations.push(currentAnimation);
return currentAnimation;
};
loopChainFunctionFactory(chainOptions: ChainOptions, chain: ElementMap): Function {
return () => {
chainOptions.totalDuration += chainOptions.currentDuration;
Animar.prototype._createAttribute = function(attributeMap, args) {
var start = (args.start === undefined ? Helper.getStartValue([args.element, args.attribute]) : args.start);
var newAttributeObject = {
model: start,
animations: []
};
let newElementMap = new Map();
attributeMap.set(args.attribute, newAttributeObject);
return attributeMap;
};
chain.forEach((element, elementRef) => {
element.forEachAnimationInAttribute(animation => {
if (animation != null) {
animation.loop = true;
animation.wait = chainOptions.totalDuration - animation.delay - animation.totalIterations;
return animation;
}
});
newElementMap.set(elementRef, element);
});
Animar.prototype._update = function() {
var animationsRemaining = this._renderDOM();
this._stepFrame();
this.ticking = false;
if (animationsRemaining) {
this._requestTick();
chain = newElementMap;
return {
start: this.startChainFunctionFactory(chain)
};
};
}
};
Animar.prototype._requestTick = function() {
if (!this.ticking) {
window.requestAnimationFrame(this._update.bind(this));
this.ticking = true;
startChainFunctionFactory(chain: ElementMap): Function {
return () => {
console.log(chain);
this.elementMap = this.mergeElementMaps(this.elementMap, chain);
this.requestTick();
};
}
};
Animar.prototype._calculateAnimationValue = function(animations) {
var result = 0;
animations.forEach(function(value) {
var currentIteration = value.currentIteration;
if (value.currentIteration < 0) {
currentIteration = 0;
requestTick() {
if (!this.ticking) {
window.requestAnimationFrame(this.update.bind(this));
this.ticking = true;
}
if (value.currentIteration >= value.totalIterations) {
currentIteration = value.totalIterations;
}
update() {
this.ticking = false;
var hasChanged = this.step();
if (hasChanged) {
this.render();
this.requestTick();
}
result += value.easingFunction(currentIteration, value.startValue, value.changeInValue, value.totalIterations);
});
return result;
};
}
Animar.prototype._applyStyle = function(element, attribute, value) {
switch(attribute) {
case("transform"):
Helper.setTransform(element, value);
break;
case("opacity"):
element.style.opacity = value;
break;
case("perspective"):
element.style.perspective = value;
element.style.webkitPerspective = value;
break;
render() {
this.elementMap.forEach((element, domElement) => {
element.render(domElement);
});
}
};
Animar.prototype._renderDOM = function() {
var self = this;
var animated = false;
self.elementMap.forEach(function(value, key) {
var targetElement = key;
var transformValue = "";
value.forEach(function(value, key) {
var targetAttribute = String(key);
if ( value.animations.length !== 0 ) {
animated = true;
var targetValue = value.model + self._calculateAnimationValue(value.animations),
pxRegex = /(perspective)|(translate[XYZ])/,
degRegex = /rotate[XYZ]?/;
if (Constants.TRANSFORM_ATTRIBUTES.indexOf(targetAttribute) !== -1) {
var unit = ((pxRegex.test(targetAttribute)) ? "px" : (degRegex.test(targetAttribute) ? "deg" : ""));
transformValue += targetAttribute + "(" + targetValue + unit + ") ";
} else {
self._applyStyle(targetElement, targetAttribute, targetValue);
}
step(): boolean {
let somethingChanged = false;
this.elementMap.forEach(element => {
if (element.step(this.timescale)) {
somethingChanged = true;
}
});
if (transformValue !== "") {
transformValue += "translateZ(0)";
self._applyStyle(targetElement, "transform", transformValue);
}
});
return animated;
return somethingChanged;
}
};
Animar.prototype._stepFrame = function() {
var elementMap = this.elementMap;
elementMap.forEach(function(value) {
value.forEach(function(value) {
var updatedAnimations = [];
value.animations.forEach(function(value) {
if (value.currentIteration < (value.totalIterations + value.wait)) {
value.currentIteration += 1;
updatedAnimations.push(value);
} else if (value.loop) {
value.currentIteration = 0 - value.delay;
updatedAnimations.push(value);
}
});
value.animations = updatedAnimations;
});
});
};
module.exports = Animar;
The MIT License (MIT)
Copyright (c) <year> <copyright holders>
Copyright (c) 2015 Vincent Riemer

@@ -5,0 +5,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy

{
"name": "animar",
"version": "0.4.4",
"version": "0.5.1",
"description": "a modern, focused, flexible javascript animation library.",

@@ -26,23 +26,11 @@ "keywords": [

"scripts": {
"clean": "rimraf dist",
"clean-coverage": "rimraf coverage",
"clean-dist": "rimraf dist",
"clean": "npm run clean-coverage && npm run clean-dist",
"lint": "jshint **.js",
"build": "./scripts/build.sh",
"test": "jest",
"pretest": "npm run clean-coverage && npm run lint",
"prebuild": "npm run clean-dist"
"lint": "eslint lib",
"typecheck": "./node_modules/.bin/flow check",
"prebuild": "npm run clean",
"test": "./node_modules/babel-cli/bin/babel-node.js ./node_modules/.bin/isparta cover ./node_modules/.bin/_mocha",
"pretest": "npm run clean-coverage && npm run lint && npm run typecheck"
},
"jest": {
"collectCoverage": true,
"testFileExtensions": [
"js"
],
"moduleFileExtensions": [
"js"
],
"testPathDirs": [
"lib"
]
},
"directories": {

@@ -53,9 +41,25 @@ "lib": "lib"

"devDependencies": {
"compression-webpack-plugin": "^0.1.2",
"jest-cli": "^0.4.0",
"jshint": "^2.6.0",
"babel-cli": "^6.2.0",
"babel-core": "^6.2.1",
"babel-eslint": "^4.1.5",
"babel-loader": "^6.2.0",
"babel-plugin-transform-class-properties": "^6.2.2",
"babel-plugin-transform-es2015-modules-commonjs": "^6.2.0",
"babel-plugin-transform-flow-strip-types": "^6.1.18",
"babel-preset-es2015": "^6.1.18",
"chai": "^3.4.1",
"compression-webpack-plugin": "^0.2.0",
"eslint": "^1.10.1",
"eslint-plugin-flow-vars": "0.0.1",
"flow-bin": "^0.18.1",
"isparta": "^4.0.0",
"jsdom": "^7.0.2",
"lodash": "^3.3.1",
"mocha": "^2.3.4",
"rimraf": "^2.3.1",
"webpack": "^1.6.0"
"sinon": "^1.15.4",
"travis-weigh-in": "^1.0.2",
"tsd": "^0.6.3",
"webpack": "^1.12.8"
}
}

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

[![Build Status](https://img.shields.io/travis/vincentriemer/animar/master.svg?style=flat)](https://travis-ci.org/vincentriemer/animar) [![Dependency Status](https://img.shields.io/david/vincentriemer/animar.svg?style=flat)](https://david-dm.org/vincentriemer/animar) [![devDependency Status](https://img.shields.io/david/dev/vincentriemer/animar.svg?style=flat)](https://david-dm.org/vincentriemer/animar#info=devDependencies) [![npm version](https://img.shields.io/npm/v/animar.js.svg?style=flat)](http://badge.fury.io/js/animar) [![Code Climate](https://img.shields.io/codeclimate/github/vincentriemer/animar.svg?style=flat)](https://codeclimate.com/github/vincentriemer/animar) [![Test Coverage](https://img.shields.io/codeclimate/coverage/github/vincentriemer/animar.svg?style=flat)](https://codeclimate.com/github/vincentriemer/animar)
[![Build Status](https://img.shields.io/travis/vincentriemer/animar/master.svg?style=flat)](https://travis-ci.org/vincentriemer/animar) [![Dependency Status](https://img.shields.io/david/vincentriemer/animar.svg?style=flat)](https://david-dm.org/vincentriemer/animar) [![devDependency Status](https://img.shields.io/david/dev/vincentriemer/animar.svg?style=flat)](https://david-dm.org/vincentriemer/animar#info=devDependencies) [![npm version](https://img.shields.io/npm/v/animar.js.svg?style=flat)](http://badge.fury.io/js/animar) [![Test Coverage](https://img.shields.io/codeclimate/coverage/github/vincentriemer/animar.svg?style=flat)](https://codeclimate.com/github/vincentriemer/animar)

@@ -3,0 +3,0 @@ # Animar

Sorry, the diff of this file is not supported yet

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