Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
formatting, structuring, plugin system
- Loading branch information
1 parent
de75254
commit 73133a3
Showing
41 changed files
with
1,225 additions
and
1,235 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,64 +0,0 @@ | ||
import * as types from '../types'; | ||
import { RUNNING, CANCEL, PAUSE, FINISH, SEEK, UPDATE, inRange, minMax, _, lazy } from '../utils'; | ||
|
||
const framePadding = 0 | ||
|
||
export interface IAnimationController { | ||
(type: string, time: number, playbackRate: number): void | ||
} | ||
|
||
export function createWebAnimation({ keyframes, from, to, target }: types.Effect): IAnimationController { | ||
const getAnimator = lazy(() => { | ||
const a = (target as any).animate(keyframes, { | ||
duration: to - from, | ||
fill: 'both' | ||
}) | ||
a.pause() | ||
return a | ||
}) | ||
|
||
return (type: string, time: number, playbackRate: number) => { | ||
const animator = getAnimator(); | ||
|
||
if (animator.playbackRate !== playbackRate) { | ||
// set playbackRate direction/speed | ||
animator.playbackRate = playbackRate | ||
} | ||
|
||
if (type === CANCEL) { | ||
animator.cancel() | ||
return | ||
} | ||
if (type === FINISH) { | ||
// without pause() WAAPI appears to play the animation again on seek | ||
animator.finish() | ||
animator.pause() | ||
return | ||
} | ||
|
||
if (type === PAUSE) { | ||
animator.pause() | ||
} | ||
|
||
const isForwards = (playbackRate || 0) >= 0 | ||
const duration = to - from | ||
const currentTime = (time !== _ ? time : isForwards ? 0 : duration) - from | ||
if (type === PAUSE || type === SEEK) { | ||
// sync if paused or seeking | ||
animator.currentTime = minMax(currentTime, 0, duration) | ||
} | ||
|
||
if (type === UPDATE && animator.playState !== RUNNING) { | ||
const sign = isForwards ? 1 : -1 | ||
const isActive = inRange(currentTime + (framePadding * sign), 0, duration) | ||
|
||
if (isActive) { | ||
// sync time | ||
animator.currentTime = minMax(currentTime, 0, duration) | ||
|
||
// start if ticking and animator is not running | ||
animator.play() | ||
} | ||
} | ||
} | ||
} | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
import * as types from '../types' | ||
import { isFunction, convertToMs, isDefined, indexOf } from '../utils' | ||
import { resolve } from '../transformers' | ||
import { getPlugins } from './plugins' | ||
|
||
export function toEffects( | ||
targets: types.TargetConfiguration[] | ||
): types.Effect[] { | ||
const result: types.Effect[] = [] | ||
|
||
for (var i = 0, ilen = targets.length; i < ilen; i++) { | ||
const targetConfig = targets[i] | ||
const { from, to, duration, keyframes, target } = targetConfig | ||
|
||
// construct property animation options | ||
var effects: types.PropertyEffects = {} | ||
for (var j = 0, jlen = keyframes.length; j < jlen; j++) { | ||
const p = keyframes[j] | ||
const propName = p.prop | ||
const offset = (p.time - from) / (duration || 1) | ||
const value = isFunction(p.value) | ||
? (p.value as Function)(target, p.index) | ||
: p.value as string | number | ||
|
||
// get or create property | ||
const effect = effects[propName] || (effects[propName] = []) | ||
effect.push({ offset, value }) | ||
} | ||
|
||
// process handlers | ||
var plugins = getPlugins() | ||
for (var q = 0, qlen = plugins.length; q < qlen; q++) { | ||
var plugin = plugins[q] | ||
if (plugin.transform) { | ||
plugin.transform(targetConfig, effects) | ||
} | ||
} | ||
|
||
for (var propName in effects) { | ||
var effect = effects[propName] | ||
if (!effect) { | ||
continue | ||
} | ||
|
||
// remap the keyframes field to remove multiple values | ||
var effect2 = { | ||
target, | ||
from, | ||
to, | ||
keyframes: effect.map(({ offset, value }) => ({ | ||
offset, | ||
[propName]: value | ||
})) | ||
} | ||
|
||
// add to list of Effects | ||
result.push(effect2) | ||
} | ||
} | ||
return result | ||
} | ||
|
||
export function addKeyframes( | ||
target: types.TargetConfiguration, | ||
index: number, | ||
options: types.AnimationOptions | ||
) { | ||
const { css } = options | ||
const staggerMs = convertToMs( | ||
resolve(options.stagger, target, index, true) || 0 | ||
) as number | ||
const delayMs = convertToMs( | ||
resolve(options.delay, target, index) || 0 | ||
) as number | ||
const endDelayMs = convertToMs( | ||
resolve(options.endDelay, target, index) || 0 | ||
) as number | ||
|
||
// todo: incorporate WAAPI delay/endDelay | ||
const from = staggerMs + delayMs + options.from | ||
const to = staggerMs + delayMs + options.to + endDelayMs | ||
const duration = to - from | ||
|
||
for (var i = 0, ilen = css.length; i < ilen; i++) { | ||
var keyframe = css[i] | ||
var time = Math.floor(duration * keyframe.offset + from) | ||
addKeyframe(target, time, index, keyframe) | ||
} | ||
} | ||
|
||
function addKeyframe( | ||
target: types.TargetConfiguration, | ||
time: number, | ||
index: number, | ||
keyframe: types.KeyframeOptions | ||
) { | ||
var { keyframes } = target | ||
for (var name in keyframe) { | ||
if (name === 'offset') { | ||
continue | ||
} | ||
|
||
var value = keyframe[name] as string | number | ||
if (!isDefined(value)) { | ||
continue | ||
} | ||
|
||
var indexOfFrame = indexOf( | ||
keyframes, | ||
k => k.prop === name && k.time === time | ||
) | ||
if (indexOfFrame !== -1) { | ||
keyframes[indexOfFrame].value = value | ||
continue | ||
} | ||
|
||
keyframes.push({ | ||
index, | ||
prop: name, | ||
time, | ||
order: 0, // fixme | ||
value | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
export * from './animator' | ||
export * from './keyframes' | ||
export * from './effects' | ||
export * from './plugins' | ||
export * from './split-text' | ||
export * from './timeline' | ||
export * from './timeloop' |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import * as types from '../types' | ||
|
||
const plugins: types.Plugin[] = [] | ||
|
||
export const getPlugins = () => plugins | ||
export const addPlugin = (plugin: types.Plugin) => plugins.push(plugin) |
Oops, something went wrong.