From 681c14ffa9c540c279b06ca88a7cbf9383e4c7c6 Mon Sep 17 00:00:00 2001 From: ktmblueskyarb Date: Sat, 25 Mar 2017 12:16:38 +0100 Subject: [PATCH 1/3] Added type definitions for web-animations-js --- web-animations-js/tsconfig.json | 24 +++++ web-animations-js/web-animations-js-tests.ts | 60 ++++++++++++ web-animations-js/web-animations-js.d.ts | 96 ++++++++++++++++++++ 3 files changed, 180 insertions(+) create mode 100644 web-animations-js/tsconfig.json create mode 100644 web-animations-js/web-animations-js-tests.ts create mode 100644 web-animations-js/web-animations-js.d.ts diff --git a/web-animations-js/tsconfig.json b/web-animations-js/tsconfig.json new file mode 100644 index 0000000000..dbf76f478e --- /dev/null +++ b/web-animations-js/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es5", + "es6", + "dom" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": false, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "web-animations-js.d.ts", + "web-animations-js-tests.ts" + ] +} \ No newline at end of file diff --git a/web-animations-js/web-animations-js-tests.ts b/web-animations-js/web-animations-js-tests.ts new file mode 100644 index 0000000000..977bc403ac --- /dev/null +++ b/web-animations-js/web-animations-js-tests.ts @@ -0,0 +1,60 @@ +// From the documentation +function test_doc() { + var elem = document.createElement('div'); + var animation = elem.animate({ + opacity: [0.5, 1], + transform: ['scale(0.5)', 'scale(1)'] + }, { + direction: 'alternate', + duration: 500, + iterations: Infinity + }); +} +// From https://io2015codelabs.appspot.com/codelabs/web-animations-transitions-playbackcontrol +// To test KeyframeEffect, SequenceEffect and GroupEffect +function test_AnimationsApiNext() { + function buildFadeIn(target : HTMLElement) { + var steps = [ + { opacity: 0, transform: 'translate(0, 20em)' }, + { opacity: 1, transform: 'translate(0)' } + ]; + return new KeyframeEffect(target, steps, { + duration: 500, + delay: -1000, + fill: 'backwards', + easing: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)' + }); + } + function buildFadeOut(target: HTMLElement) { + var angle = Math.pow((Math.random() * 16) - 6, 3); + var offset = (Math.random() * 20) - 10; + var transform = 'translate(' + offset + 'em, 20em) ' + + 'rotate(' + angle + 'deg) ' + + 'scale(0)'; + var steps = [ + { visibility: 'visible', opacity: 1, transform: 'none' }, + { visibility: 'visible', opacity: 0, transform: transform } + ]; + return new KeyframeEffect(target, steps, { + duration: 1500, + easing: 'ease-in' + }); + } + var effectNode = document.createElement('div'); + effectNode.className = 'circleEffect'; + var bounds = document.documentElement.getBoundingClientRect(); + effectNode.style.left = bounds.left + bounds.width / 2 + 'px'; + effectNode.style.top = bounds.top + bounds.height / 2 + 'px'; + var header = document.querySelector('header'); + header.appendChild(effectNode); + var newColor = 'hsl(' + Math.round(Math.random() * 255) + ', 46%, 42%)'; + effectNode.style.background = newColor; + var scaleSteps = [{ transform: 'scale(0)' }, { transform: 'scale(1)' }]; + var timing = { duration: 2500, easing: 'ease-in-out' }; + var scaleEffect = new KeyframeEffect(effectNode, scaleSteps, timing); + var fadeEffect = new SequenceEffect([buildFadeOut(effectNode), buildFadeIn(effectNode)]); + var allEffects = [scaleEffect, fadeEffect]; + // Play all animations within this group. + var groupEffect = new GroupEffect(allEffects); + var anim = document.timeline.play(groupEffect); +} diff --git a/web-animations-js/web-animations-js.d.ts b/web-animations-js/web-animations-js.d.ts new file mode 100644 index 0000000000..80c98a555a --- /dev/null +++ b/web-animations-js/web-animations-js.d.ts @@ -0,0 +1,96 @@ +// Type definitions for web-animations-js v2.2.2 +// Project: https://github.com/web-animations/web-animations-js +// Definitions by: Kristian Moerch +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +declare type FillMode = "none" | "forwards" | "backwards" | "both" | "auto"; +declare type PlaybackDirection = "normal" | "reverse" | "alternate" | "alternate-reverse"; +declare type AnimationPlayState = "idle" | "pending" | "running" | "paused" | "finished"; + +interface AnimationPlaybackEvent extends Event { + currentTime: number; + timelineTime: number; +} + +interface AnimationKeyFrame { + easing?: string; + offset?: number; + [key: string]: string | number | number[] | string[]; +} + +interface AnimationTimeline { + currentTime: number; + getAnimations(): any; + play(a: any): any; +} +interface AnimationEffectTiming { + delay?: number; + direction?: PlaybackDirection; + duration?: number; + easing?: string; + endDelay?: number; + fill?: FillMode |  string; + iterationStart?: number; + iterations?: number; + playbackRate?: number; +} +declare class KeyframeEffect { + constructor(target: HTMLElement, effect: AnimationKeyFrame | AnimationKeyFrame[], timing: number | AnimationEffectTiming); + activeDuration: number; + onsample: any; + parent: any; + target: any; + timing: AnimationEffectTiming; + getFrames(): AnimationKeyFrame[]; +} + +interface Animation extends Element { + currentTime: number; + id: string; + oncancel: EventListener; + onfinish: EventListener; + readonly playState: AnimationPlayState; + playbackRate: number; + startTime: number; + cancel(): void; + finish(): void; + pause(): void; + play(): void; + reverse(): void; + effect: KeyframeEffect; + readonly finished: Promise; + readonly ready: Promise; + timeline: AnimationTimeline; +} +declare class Animation extends Element { + currentTime: number; + id: string; + oncancel: EventListener; + onfinish: EventListener; + readonly playState: AnimationPlayState; + playbackRate: number; + startTime: number; + cancel(): void; + finish(): void; + pause(): void; + play(): void; + reverse(): void; + effect: KeyframeEffect; + readonly finished: Promise; + readonly ready: Promise; + timeline: AnimationTimeline; +} + +declare class SequenceEffect extends KeyframeEffect { + constructor(effects: KeyframeEffect[]); +} +declare class GroupEffect extends KeyframeEffect { + constructor(effects: KeyframeEffect[]); +} +interface Element { + animate(effect: AnimationKeyFrame | AnimationKeyFrame[], timing: number | AnimationEffectTiming): Animation; + getAnimations(): Animation[]; +} +interface Document { + timeline: AnimationTimeline; +} \ No newline at end of file From d4b98e705fe434c31efd1ab72a0dd196aa71ed0d Mon Sep 17 00:00:00 2001 From: ktmblueskyarb Date: Sun, 26 Mar 2017 01:24:55 +0100 Subject: [PATCH 2/3] Added Animation constructor and test for that --- web-animations-js/web-animations-js-tests.ts | 71 ++++++++++++++------ web-animations-js/web-animations-js.d.ts | 33 +++------ 2 files changed, 60 insertions(+), 44 deletions(-) diff --git a/web-animations-js/web-animations-js-tests.ts b/web-animations-js/web-animations-js-tests.ts index 977bc403ac..3072c936a0 100644 --- a/web-animations-js/web-animations-js-tests.ts +++ b/web-animations-js/web-animations-js-tests.ts @@ -1,7 +1,7 @@ // From the documentation function test_doc() { - var elem = document.createElement('div'); - var animation = elem.animate({ + const elem = document.createElement('div'); + const animation = elem.animate({ opacity: [0.5, 1], transform: ['scale(0.5)', 'scale(1)'] }, { @@ -13,8 +13,8 @@ function test_doc() { // From https://io2015codelabs.appspot.com/codelabs/web-animations-transitions-playbackcontrol // To test KeyframeEffect, SequenceEffect and GroupEffect function test_AnimationsApiNext() { - function buildFadeIn(target : HTMLElement) { - var steps = [ + function buildFadeIn(target: HTMLElement) { + const steps = [ { opacity: 0, transform: 'translate(0, 20em)' }, { opacity: 1, transform: 'translate(0)' } ]; @@ -26,12 +26,12 @@ function test_AnimationsApiNext() { }); } function buildFadeOut(target: HTMLElement) { - var angle = Math.pow((Math.random() * 16) - 6, 3); - var offset = (Math.random() * 20) - 10; - var transform = 'translate(' + offset + 'em, 20em) ' + + const angle = Math.pow((Math.random() * 16) - 6, 3); + const offset = (Math.random() * 20) - 10; + const transform = 'translate(' + offset + 'em, 20em) ' + 'rotate(' + angle + 'deg) ' + 'scale(0)'; - var steps = [ + const steps = [ { visibility: 'visible', opacity: 1, transform: 'none' }, { visibility: 'visible', opacity: 0, transform: transform } ]; @@ -40,21 +40,54 @@ function test_AnimationsApiNext() { easing: 'ease-in' }); } - var effectNode = document.createElement('div'); + const effectNode = document.createElement('div'); effectNode.className = 'circleEffect'; - var bounds = document.documentElement.getBoundingClientRect(); + const bounds = document.documentElement.getBoundingClientRect(); effectNode.style.left = bounds.left + bounds.width / 2 + 'px'; effectNode.style.top = bounds.top + bounds.height / 2 + 'px'; - var header = document.querySelector('header'); + const header = document.querySelector('header'); header.appendChild(effectNode); - var newColor = 'hsl(' + Math.round(Math.random() * 255) + ', 46%, 42%)'; + const newColor = 'hsl(' + Math.round(Math.random() * 255) + ', 46%, 42%)'; effectNode.style.background = newColor; - var scaleSteps = [{ transform: 'scale(0)' }, { transform: 'scale(1)' }]; - var timing = { duration: 2500, easing: 'ease-in-out' }; - var scaleEffect = new KeyframeEffect(effectNode, scaleSteps, timing); - var fadeEffect = new SequenceEffect([buildFadeOut(effectNode), buildFadeIn(effectNode)]); - var allEffects = [scaleEffect, fadeEffect]; + const scaleSteps = [{ transform: 'scale(0)' }, { transform: 'scale(1)' }]; + const timing: AnimationEffectTiming = { duration: 2500, easing: 'ease-in-out', fill: "backwards" }; + const scaleEffect = new KeyframeEffect(effectNode, scaleSteps, timing); + const fadeEffect = new SequenceEffect([buildFadeOut(effectNode), buildFadeIn(effectNode)]); + const allEffects = [scaleEffect, fadeEffect]; // Play all animations within this group. - var groupEffect = new GroupEffect(allEffects); - var anim = document.timeline.play(groupEffect); + const groupEffect = new GroupEffect(allEffects); + const anim = document.timeline.play(groupEffect); +} + +// https://developer.mozilla.org/en-US/docs/Web/API/Animation/Animation +// http://codepen.io/rachelnabors/pen/eJyWzm/?editors=0010 +function test_whiteRabbit() { + var whiteRabbit = document.getElementById("rabbit"); + + var rabbitDownKeyframes = new KeyframeEffect( + whiteRabbit, + [ + { transform: 'translateY(0%)' }, + { transform: 'translateY(100%)' } + ], + { duration: 3000, fill: 'forwards' } + ); + + var rabbitDownAnimation = new Animation(rabbitDownKeyframes, document.timeline); + + // On tap or click, + whiteRabbit.addEventListener("mousedown", downHeGoes, false); + whiteRabbit.addEventListener("touchstart", downHeGoes, false); + + // Trigger a single-fire animation + function downHeGoes(event: Event) { + + // Remove those event listeners + whiteRabbit.removeEventListener("mousedown", downHeGoes, false); + whiteRabbit.removeEventListener("touchstart", downHeGoes, false); + + // Play rabbit animation + rabbitDownAnimation.play(); + + } } diff --git a/web-animations-js/web-animations-js.d.ts b/web-animations-js/web-animations-js.d.ts index 80c98a555a..f570e423ba 100644 --- a/web-animations-js/web-animations-js.d.ts +++ b/web-animations-js/web-animations-js.d.ts @@ -3,8 +3,8 @@ // Definitions by: Kristian Moerch // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -declare type FillMode = "none" | "forwards" | "backwards" | "both" | "auto"; -declare type PlaybackDirection = "normal" | "reverse" | "alternate" | "alternate-reverse"; +declare type AnimationEffectTimingFillMode = "none" | "forwards" | "backwards" | "both" | "auto"; +declare type AnimationEffectTimingPlaybackDirection = "normal" | "reverse" | "alternate" | "alternate-reverse"; declare type AnimationPlayState = "idle" | "pending" | "running" | "paused" | "finished"; interface AnimationPlaybackEvent extends Event { @@ -15,21 +15,21 @@ interface AnimationPlaybackEvent extends Event { interface AnimationKeyFrame { easing?: string; offset?: number; - [key: string]: string | number | number[] | string[]; + [key: string]: string | string[] | number | number[]; } interface AnimationTimeline { currentTime: number; - getAnimations(): any; - play(a: any): any; + getAnimations(): Animation[]; + play(effect: KeyframeEffect): Animation; } interface AnimationEffectTiming { delay?: number; - direction?: PlaybackDirection; + direction?: AnimationEffectTimingPlaybackDirection; duration?: number; easing?: string; endDelay?: number; - fill?: FillMode |  string; + fill?: AnimationEffectTimingFillMode; iterationStart?: number; iterations?: number; playbackRate?: number; @@ -44,25 +44,8 @@ declare class KeyframeEffect { getFrames(): AnimationKeyFrame[]; } -interface Animation extends Element { - currentTime: number; - id: string; - oncancel: EventListener; - onfinish: EventListener; - readonly playState: AnimationPlayState; - playbackRate: number; - startTime: number; - cancel(): void; - finish(): void; - pause(): void; - play(): void; - reverse(): void; - effect: KeyframeEffect; - readonly finished: Promise; - readonly ready: Promise; - timeline: AnimationTimeline; -} declare class Animation extends Element { + constructor(effect: KeyframeEffect, timeline?: AnimationTimeline); currentTime: number; id: string; oncancel: EventListener; From 0ccb171334bb98d64e6f0f0533bc233286081ca7 Mon Sep 17 00:00:00 2001 From: ktmblueskyarb Date: Mon, 27 Mar 2017 10:02:42 +0200 Subject: [PATCH 3/3] AnimationPlaybackEvent, Corrected Animation class --- web-animations-js/web-animations-js.d.ts | 25 ++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/web-animations-js/web-animations-js.d.ts b/web-animations-js/web-animations-js.d.ts index f570e423ba..a151ef73b3 100644 --- a/web-animations-js/web-animations-js.d.ts +++ b/web-animations-js/web-animations-js.d.ts @@ -7,9 +7,18 @@ declare type AnimationEffectTimingFillMode = "none" | "forwards" | "backwards" | declare type AnimationEffectTimingPlaybackDirection = "normal" | "reverse" | "alternate" | "alternate-reverse"; declare type AnimationPlayState = "idle" | "pending" | "running" | "paused" | "finished"; -interface AnimationPlaybackEvent extends Event { +declare class AnimationPlaybackEvent { + constructor(target: Animation, currentTime: number, timelineTime: number); + target: Animation; currentTime: number; timelineTime: number; + type: string; + bubbles: boolean; + cancelable: boolean; + currentTarget: Animation; + defaultPrevented: boolean; + eventPhase: number; + timeStamp: number; } interface AnimationKeyFrame { @@ -35,7 +44,7 @@ interface AnimationEffectTiming { playbackRate?: number; } declare class KeyframeEffect { - constructor(target: HTMLElement, effect: AnimationKeyFrame | AnimationKeyFrame[], timing: number | AnimationEffectTiming); + constructor(target: HTMLElement, effect: AnimationKeyFrame | AnimationKeyFrame[], timing: number | AnimationEffectTiming, id?: string); activeDuration: number; onsample: any; parent: any; @@ -43,13 +52,15 @@ declare class KeyframeEffect { timing: AnimationEffectTiming; getFrames(): AnimationKeyFrame[]; } - -declare class Animation extends Element { +interface AnimationEventListener { + (evt: AnimationPlaybackEvent): void; +} +declare class Animation { constructor(effect: KeyframeEffect, timeline?: AnimationTimeline); currentTime: number; id: string; - oncancel: EventListener; - onfinish: EventListener; + oncancel: AnimationEventListener; + onfinish: AnimationEventListener; readonly playState: AnimationPlayState; playbackRate: number; startTime: number; @@ -58,6 +69,8 @@ declare class Animation extends Element { pause(): void; play(): void; reverse(): void; + addEventListener(type: number, handler: AnimationEventListener): void; + removeEventListener(type: number, handler: AnimationEventListener): void; effect: KeyframeEffect; readonly finished: Promise; readonly ready: Promise;