Skip to content

Commit

Permalink
Fixes and updates in preparation for new sequence code
Browse files Browse the repository at this point in the history
All HTMLElement css styles are now set/get via a normalization instead of by fallback code
Tweens are now an interface (object) instead of an enum indexed array
Normalization function is now cached in tween at animation start for performance and consistency
Internal version number is now set directly instead of indirectly

Fixes #849 - SVG attribute initialisation was crashing
Fixes #845 - Inconsistent handling of colour codes, now force rgba()
Fixes #839 - - Possibly mis-identification of lineHeight
  • Loading branch information
Rycochet committed Feb 24, 2018
1 parent 9118352 commit 92f6981
Show file tree
Hide file tree
Showing 40 changed files with 666 additions and 664 deletions.
86 changes: 70 additions & 16 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,26 @@ type VelocityActionFn = (args?: any[], elements?: VelocityResult, promiseHandler
* @param propertyValue The value to set. If <code>undefined</code> then this is
* a get action and must return a string value for that element.
*
* @returns If a set action then returning any truthy value will prevent it
* trying to set the <code>element.style[propertyName]</code> value afterward
* returning.
* @returns When getting a value it must return a string, otherwise the return
* value is ignored.
*/
type VelocityNormalizationsFn = ((element: HTMLorSVGElement, propertyValue: string) => boolean) & ((element: HTMLorSVGElement) => string);
type VelocityNormalizationsFn = ((element: HTMLorSVGElement, propertyValue: string) => void) & ((element: HTMLorSVGElement) => string);

/**
* All easings. This is used for "easing:true" mapping, so that they can be
* recognised for auto-completion and type-safety with custom builds of
* Velocity.
*/
interface VelocityEasingsType {} // TODO: This needs to be auto-generated

/**
* List of all easing types for easy code completion in TypeScript
*/
type VelocityEasingType = VelocityEasingFn
| "linear" | "swing" | "spring"
| "ease" | "easeIn" | "easeOut" | "easeInOut" | "easeInSine" | "easeOutSine"
| "easeInOutSine" | "easeInQuad" | "easeOutQuad" | "easeInOutQuad"
| "easeInCubic" | "easeOutCubic" | "easeInOutCubic" | "easeInQuart"
| "easeOutQuart" | "easeInOutQuart" | "easeInQuint" | "easeOutQuint"
| "easeInOutQuint" | "easeInExpo" | "easeOutExpo" | "easeInOutExpo"
| "easeInCirc" | "easeOutCirc" | "easeInOutCirc"
| "ease-in" | "ease-out" | "ease-in-out"
| "at-start" | "at-end" | "during"
| string
| number[];
| keyof VelocityEasingsType
| string // Need to leave in to prevent errors.
| [number] | [number, number] | [number, number, number, number]
| number[]; // Need to leave in to prevent errors.

/**
* The return type of any velocity call. If this is called via a "utility"
Expand Down Expand Up @@ -446,7 +445,61 @@ interface ElementData {
lastFinishList: {[name: string]: number};
}

type VelocityTween = [(string | number)[], VelocityEasingFn, (string | number)[], (string | number)[], boolean[]];
type TweenPattern = ReadonlyArray<string | boolean>;
type TweenValues = ReadonlyArray<string | number>;

interface TweenStep extends ReadonlyArray<TweenValues> {
/**
* Percent of animation.
*/
percent?: number;
/**
* Easing function.
*/
easing?: VelocityEasingFn | null;
/**
* Values to tween and insert into pattern.
*/
[index: number]: TweenValues;
}

interface VelocitySequence {
/**
* Pattern to use for tweening.
*/
pattern: TweenPattern;
/**
* Step value.
*/
[index: number]: TweenStep;
}

interface VelocityTween {
/**
* Pattern to use for tweening (excludes sequence).
*/
pattern?: TweenPattern;
/**
* Normalization function - cached at animation creation time.
*/
fn: VelocityNormalizationsFn;
/**
* Sequence to use for tweening (excludes pattern).
*/
sequence?: VelocitySequence;
/**
* Easing function to use for entire tween.
*/
easing?: VelocityEasingFn;
/**
* Start value.
*/
start?: TweenValues;
/**
* End value.
*/
end: TweenValues;
}

/**
* AnimationFlags are used internally. These are subject to change as they are
Expand Down Expand Up @@ -616,6 +669,7 @@ interface Velocity {
}

CSS: {
ColorNames: {[name: string]: string};
getPropertyValue(element: HTMLorSVGElement, property: string, rootPropertyValue?: string, forceStyleLookup?: boolean): string;
getUnit(str: string, start?: number): string;
fixColors(str: string): string;
Expand Down
6 changes: 3 additions & 3 deletions src/Velocity/actions/finish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,18 @@ namespace VelocityStatic {
}
for (const property in animation.tweens) {
const tween = animation.tweens[property],
pattern = tween[Tween.PATTERN];
pattern = tween.pattern;
let currentValue = "",
i = 0;

if (pattern) {
for (; i < pattern.length; i++) {
const endValue = tween[Tween.END][i];
const endValue = tween.end[i];

currentValue += endValue == null ? pattern[i] : endValue;
}
}
CSS.setPropertyValue(animation.element, property, currentValue);
CSS.setPropertyValue(animation.element, property, currentValue, tween.fn);
}
completeCall(animation);
}
Expand Down
4 changes: 2 additions & 2 deletions src/Velocity/actions/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ namespace VelocityStatic {
// If only a single animation is found and we're only targetting a
// single element, then return the value directly
if (elements.length === 1) {
return CSS.getPropertyValue(elements[0], property);
return CSS.fixColors(CSS.getPropertyValue(elements[0], property));
}
const result = [];

for (let i = 0; i < elements.length; i++) {
result.push(CSS.getPropertyValue(elements[i], property));
result.push(CSS.fixColors(CSS.getPropertyValue(elements[i], property)));
}
return result;
}
Expand Down
11 changes: 5 additions & 6 deletions src/Velocity/actions/tween.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,22 +85,21 @@ namespace VelocityStatic {
for (const property in fakeAnimation.tweens) {
// For every element, iterate through each property.
const tween = fakeAnimation.tweens[property],
easing = tween[Tween.EASING] || activeEasing,
pattern = tween[Tween.PATTERN],
rounding = tween[Tween.ROUNDING];
easing = tween.easing || activeEasing,
pattern = tween.pattern;
let currentValue = "";

count++;
if (pattern) {
for (let i = 0; i < pattern.length; i++) {
const startValue = tween[Tween.START][i];
const startValue = tween.start[i];

if (startValue == null) {
currentValue += pattern[i];
} else {
const result = easing(percentComplete, startValue as number, tween[Tween.END][i] as number, property)
const result = easing(percentComplete, startValue as number, tween.end[i] as number, property)

currentValue += rounding && rounding[i] ? Math.round(result) : result;
currentValue += pattern[i] === true ? Math.round(result) : result;
}
}
}
Expand Down
1 change: 0 additions & 1 deletion src/Velocity/css/_all.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@
///<reference path="fixColors.ts" />
///<reference path="getPropertyValue.ts" />
///<reference path="getUnit.ts" />
///<reference path="regex.ts" />
///<reference path="setPropertyValue.ts" />
6 changes: 2 additions & 4 deletions src/Velocity/css/camelCase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ namespace VelocityStatic.CSS {
if (fixed) {
return fixed;
}
return cache[property] = property.replace(/-([a-z])/g, function(match: string, subMatch: string) {
return subMatch.toUpperCase();
})
return cache[property] = property.replace(/-([a-z])/g, ($: string, letter: string) => letter.toUpperCase());
}
}
}
6 changes: 3 additions & 3 deletions src/Velocity/css/fixColors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace VelocityStatic.CSS {
const rxColor6 = /#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})/gi,
rxColor3 = /#([a-f\d])([a-f\d])([a-f\d])/gi,
rxColorName = /(rgba?\(\s*)?(\b[a-z]+\b)/g,
rxRGB = /rgba?\([^\)]+\)/gi,
rxRGB = /rgb(a?)\(([^\)]+)\)/gi,
rxSpaces = /\s+/g;

/**
Expand All @@ -41,8 +41,8 @@ namespace VelocityStatic.CSS {
}
return $0;
})
.replace(rxRGB, function($0) {
return $0.replace(rxSpaces, "");
.replace(rxRGB, function($0, $1, $2: string) {
return "rgba(" + $2.replace(rxSpaces, "") + ($1 ? "" : ",1") + ")";
});
}
}
36 changes: 7 additions & 29 deletions src/Velocity/css/getPropertyValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ namespace VelocityStatic.CSS {
Also, in all browsers, when border colors aren't all the same, a compound value is returned that Velocity isn't setup to parse.
So, as a polyfill for querying individual border side colors, we just return the top border's color and animate all borders from that value. */
/* TODO: There is a borderColor normalisation in legacy/ - figure out where this is needed... */
// if (property === "borderColor") {
// property = "borderTopColor";
// }

computedValue = computedStyle[property];
/* Fall back to the property's style value (if defined) when computedValue returns nothing,
Expand Down Expand Up @@ -88,9 +85,9 @@ namespace VelocityStatic.CSS {

/**
* Get a property value. This will grab via the cache if it exists, then
* via any normalisations, then it will check the css values directly.
* via any normalisations.
*/
export function getPropertyValue(element: HTMLorSVGElement, propertyName: string, skipNormalisation?: boolean, skipCache?: boolean): string {
export function getPropertyValue(element: HTMLorSVGElement, propertyName: string, fn?: VelocityNormalizationsFn, skipCache?: boolean): string {
const data = Data(element);
let propertyValue: string;

Expand All @@ -99,37 +96,18 @@ namespace VelocityStatic.CSS {
}
if (!skipCache && data && data.cache[propertyName] != null) {
propertyValue = data.cache[propertyName];
if (debug >= 2) {
console.info("Get " + propertyName + ": " + propertyValue);
}
return propertyValue;
} else {
let types = data.types,
best: VelocityNormalizationsFn;

for (let index = 0; types; types >>= 1, index++) {
if (types & 1) {
best = Normalizations[index][propertyName] || best;
fn = fn || getNormalization(element, propertyName);
if (fn) {
propertyValue = fn(element);
if (data) {
data.cache[propertyName] = propertyValue;
}
}
if (best) {
propertyValue = best(element);
} else {
// Note: Retrieving the value of a CSS property cannot simply be
// performed by checking an element's style attribute (which
// only reflects user-defined values). Instead, the browser must
// be queried for a property's *computed* value. You can read
// more about getComputedStyle here:
// https://developer.mozilla.org/en/docs/Web/API/window.getComputedStyle
propertyValue = computePropertyValue(element, propertyName);
}
}
if (debug >= 2) {
console.info("Get " + propertyName + ": " + propertyValue);
}
if (data) {
data.cache[propertyName] = propertyValue;
}
return propertyValue;
}
}
19 changes: 0 additions & 19 deletions src/Velocity/css/regex.ts

This file was deleted.

17 changes: 5 additions & 12 deletions src/Velocity/css/setPropertyValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
namespace VelocityStatic.CSS {
/**
* The singular setPropertyValue, which routes the logic for all
* normalizations, hooks, and standard CSS properties.
* normalizations.
*/
export function setPropertyValue(element: HTMLorSVGElement, propertyName: string, propertyValue: any) {
export function setPropertyValue(element: HTMLorSVGElement, propertyName: string, propertyValue: any, fn?: VelocityNormalizationsFn) {
const data = Data(element);

if (isString(propertyValue)
Expand All @@ -27,16 +27,9 @@ namespace VelocityStatic.CSS {
if (data && data.cache[propertyName] !== propertyValue) {
// By setting it to undefined we force a true "get" later
data.cache[propertyName] = propertyValue || undefined;
let types = data.types,
best: VelocityNormalizationsFn;

for (let index = 0; types; types >>= 1, index++) {
if (types & 1) {
best = Normalizations[index][propertyName] || best;
}
}
if (!best || !best(element, propertyValue)) {
element.style[propertyName] = propertyValue;
fn = fn || getNormalization(element, propertyName);
if (fn) {
fn(element, propertyValue);
}
if (debug >= 2) {
console.info("Set " + propertyName + ": " + propertyValue, element);
Expand Down
6 changes: 6 additions & 0 deletions src/Velocity/easing/back.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
* Back easings, based on code from https://github.com/yuichiroharai/easeplus-velocity
*/

interface VelocityEasingsType {
"easeInBack": true;
"easeOutBack": true;
"easeInOutBack": true;
}

namespace VelocityStatic.Easing {
export function registerBackIn(name: string, amount: number) {
registerEasing([name, function(percentComplete: number, startValue: number, endValue: number): number {
Expand Down
31 changes: 31 additions & 0 deletions src/Velocity/easing/bezier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,37 @@
* Bezier curve function generator. Copyright Gaetan Renaudeau. MIT License: http://en.wikipedia.org/wiki/MIT_License
*/

interface VelocityEasingsType {
"ease": true;
"easeIn": true;
"ease-in": true;
"easeOut": true;
"ease-out": true;
"easeInOut": true;
"ease-in-out": true;
"easeInSine": true;
"easeOutSine": true;
"easeInOutSine": true;
"easeInQuad": true;
"easeOutQuad": true;
"easeInOutQuad": true;
"easeInCubic": true;
"easeOutCubic": true;
"easeInOutCubic": true;
"easeInQuart": true;
"easeOutQuart": true;
"easeInOutQuart": true;
"easeInQuint": true;
"easeOutQuint": true;
"easeInOutQuint": true;
"easeInExpo": true;
"easeOutExpo": true;
"easeInOutExpo": true;
"easeInCirc": true;
"easeOutCirc": true;
"easeInOutCirc": true;
}

namespace VelocityStatic.Easing {
/**
* Fix to a range of <code>0 <= num <= 1</code>.
Expand Down
6 changes: 6 additions & 0 deletions src/Velocity/easing/bounce.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
* Bounce easings, based on code from https://github.com/yuichiroharai/easeplus-velocity
*/

interface VelocityEasingsType {
"easeInBounce": true;
"easeOutBounce": true;
"easeInOutBounce": true;
}

namespace VelocityStatic.Easing {
function easeOutBounce(percentComplete: number): number {
if (percentComplete < 1 / 2.75) {
Expand Down
Loading

0 comments on commit 92f6981

Please sign in to comment.