@kieransimkin/dancemoves 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +338 -0
- package/README.md +893 -0
- package/RUDIMENTS-API.md +394 -0
- package/docs/README.md +73 -0
- package/docs/api/adapters.md +400 -0
- package/docs/api/downloads.md +158 -0
- package/docs/api/effects.md +463 -0
- package/docs/api/javascript.md +500 -0
- package/docs/api/paper-planes.md +167 -0
- package/docs/api/styling.md +292 -0
- package/docs/api/surface.json +446 -0
- package/docs/api/wordpress.md +365 -0
- package/docs/clay-transform-validation.md +84 -0
- package/docs/development.md +254 -0
- package/docs/guide.md +288 -0
- package/docs/javascript-api.md +292 -0
- package/docs/javascript-server.md +150 -0
- package/docs/react-next.md +185 -0
- package/docs/releasing-shared.md +162 -0
- package/docs/rudiments-source-integrity.md +80 -0
- package/docs/shared-feature-coverage.md +34 -0
- package/docs/shared-runtime-migration.md +111 -0
- package/docs/source-audit.md +120 -0
- package/docs/validation-setup.md +102 -0
- package/docs/wordpress-examples.md +206 -0
- package/docs/wordpress-shared-runtime.md +133 -0
- package/lib/admin.min.js +1 -0
- package/lib/assets/DanceRudiments-LICENSE +21 -0
- package/lib/assets/DanceRudiments-build-manifest.json +21 -0
- package/lib/assets/paper-dreams-plane-atlas.png +0 -0
- package/lib/build-manifest.json +117 -0
- package/lib/dancemoves.css +9 -0
- package/lib/dancemoves.min.js +5 -0
- package/lib/index.cjs +4802 -0
- package/lib/index.d.ts +71 -0
- package/lib/index.mjs +4780 -0
- package/lib/react.cjs +154 -0
- package/lib/react.d.ts +12 -0
- package/lib/react.mjs +135 -0
- package/lib/rudiments.d.ts +124 -0
- package/lib/server.cjs +411 -0
- package/lib/server.d.ts +11 -0
- package/lib/server.mjs +367 -0
- package/lib/styles/clay-stars-effects.css +1 -0
- package/lib/styles/clay-stars-rudiments.css +1 -0
- package/lib/styles/dance-moves-core.css +1 -0
- package/lib/styles/ks-epk-device-orientation.css +1 -0
- package/lib/styles/paper-dreams-flight.css +1 -0
- package/lib/wordpress.js +5 -0
- package/package.json +101 -0
package/lib/react.cjs
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// .build/modules/react.mjs
|
|
22
|
+
var react_exports = {};
|
|
23
|
+
__export(react_exports, {
|
|
24
|
+
DanceMovesProvider: () => DanceMovesProvider,
|
|
25
|
+
PageMetadataEditor: () => PageMetadataEditor,
|
|
26
|
+
Rudiment: () => Rudiment,
|
|
27
|
+
useCue: () => useCue,
|
|
28
|
+
useDanceMoves: () => useDanceMoves,
|
|
29
|
+
useDanceMovesContext: () => useDanceMovesContext,
|
|
30
|
+
useLyric: () => useLyric,
|
|
31
|
+
useRudiment: () => useRudiment
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(react_exports);
|
|
34
|
+
var import_react = require("react");
|
|
35
|
+
var import_index = require("./index.cjs");
|
|
36
|
+
var EMPTY = Object.freeze({});
|
|
37
|
+
var Context = (0, import_react.createContext)(null);
|
|
38
|
+
function useDanceMoves(rootRef, options = EMPTY) {
|
|
39
|
+
const [result, setResult] = (0, import_react.useState)({ runtime: null, error: null });
|
|
40
|
+
(0, import_react.useEffect)(() => {
|
|
41
|
+
if (!rootRef.current) return;
|
|
42
|
+
let active = true, runtime;
|
|
43
|
+
try {
|
|
44
|
+
runtime = (0, import_index.createDanceMoves)({ ...options, root: rootRef.current });
|
|
45
|
+
setResult({ runtime, error: null });
|
|
46
|
+
runtime.ready.catch((error) => {
|
|
47
|
+
if (active) setResult({ runtime, error });
|
|
48
|
+
});
|
|
49
|
+
} catch (error) {
|
|
50
|
+
setResult({ runtime: null, error });
|
|
51
|
+
}
|
|
52
|
+
return () => {
|
|
53
|
+
active = false;
|
|
54
|
+
runtime?.destroy();
|
|
55
|
+
};
|
|
56
|
+
}, [rootRef, options]);
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
function DanceMovesProvider({ options = EMPTY, children, className = "", ...attributes }) {
|
|
60
|
+
const root = (0, import_react.useRef)(null);
|
|
61
|
+
const result = useDanceMoves(root, options);
|
|
62
|
+
return (0, import_react.createElement)("div", { ...attributes, ref: root, className: `ks-epk ${className}`.trim() }, (0, import_react.createElement)(Context.Provider, { value: result }, children));
|
|
63
|
+
}
|
|
64
|
+
function useDanceMovesContext() {
|
|
65
|
+
const value = (0, import_react.useContext)(Context);
|
|
66
|
+
if (!value) throw new Error("useDanceMovesContext requires DanceMovesProvider");
|
|
67
|
+
return value;
|
|
68
|
+
}
|
|
69
|
+
function useCue(runtime, name, callback) {
|
|
70
|
+
const latest = (0, import_react.useRef)(callback);
|
|
71
|
+
latest.current = callback;
|
|
72
|
+
(0, import_react.useEffect)(() => runtime?.onCue(name, (detail) => latest.current(detail)), [runtime, name]);
|
|
73
|
+
}
|
|
74
|
+
function useLyric(runtime) {
|
|
75
|
+
const [lyric, setLyric] = (0, import_react.useState)(null);
|
|
76
|
+
(0, import_react.useEffect)(() => {
|
|
77
|
+
setLyric(null);
|
|
78
|
+
if (!runtime) return;
|
|
79
|
+
const remove = runtime.onLyric(setLyric);
|
|
80
|
+
const clear = () => setLyric(null);
|
|
81
|
+
const events = ["pause", "ended", "seeking"];
|
|
82
|
+
events.forEach((type) => runtime.root.addEventListener(type, clear, true));
|
|
83
|
+
return () => {
|
|
84
|
+
remove();
|
|
85
|
+
events.forEach((type) => runtime.root.removeEventListener(type, clear, true));
|
|
86
|
+
};
|
|
87
|
+
}, [runtime]);
|
|
88
|
+
return lyric;
|
|
89
|
+
}
|
|
90
|
+
function useRudiment(runtime, targetRef, options) {
|
|
91
|
+
const [result, setResult] = (0, import_react.useState)({ controller: null, error: null });
|
|
92
|
+
(0, import_react.useEffect)(() => {
|
|
93
|
+
if (!runtime || !targetRef.current) return;
|
|
94
|
+
let active = true, controller;
|
|
95
|
+
try {
|
|
96
|
+
controller = runtime.rudiments.animate({ ...options, root: runtime.root, target: targetRef.current });
|
|
97
|
+
setResult({ controller, error: null });
|
|
98
|
+
controller.ready.catch((error) => {
|
|
99
|
+
if (active) setResult({ controller, error });
|
|
100
|
+
});
|
|
101
|
+
} catch (error) {
|
|
102
|
+
setResult({ controller: null, error });
|
|
103
|
+
}
|
|
104
|
+
return () => {
|
|
105
|
+
active = false;
|
|
106
|
+
controller?.destroy();
|
|
107
|
+
};
|
|
108
|
+
}, [runtime, targetRef, options]);
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
function Rudiment({ runtime, options, children, ...attributes }) {
|
|
112
|
+
const ref = (0, import_react.useRef)(null);
|
|
113
|
+
useRudiment(runtime, ref, options);
|
|
114
|
+
return (0, import_react.createElement)("div", { ...attributes, ref }, children);
|
|
115
|
+
}
|
|
116
|
+
function PageMetadataEditor({ value = EMPTY, onSave }) {
|
|
117
|
+
const [draft, setDraft] = (0, import_react.useState)(() => ({ ...value })), [message, setMessage] = (0, import_react.useState)(""), [busy, setBusy] = (0, import_react.useState)(false);
|
|
118
|
+
(0, import_react.useEffect)(() => setDraft({ ...value }), [value]);
|
|
119
|
+
const input = (key, label, type = "text") => (0, import_react.createElement)("label", { key }, label, (0, import_react.createElement)("input", {
|
|
120
|
+
type,
|
|
121
|
+
value: draft[key] ?? "",
|
|
122
|
+
step: type === "number" ? "0.001" : void 0,
|
|
123
|
+
onChange: (e) => setDraft({ ...draft, [key]: type === "number" ? e.target.value === "" ? void 0 : Number(e.target.value) : e.target.value })
|
|
124
|
+
}));
|
|
125
|
+
return (0, import_react.createElement)(
|
|
126
|
+
"form",
|
|
127
|
+
{ onSubmit: async (event) => {
|
|
128
|
+
event.preventDefault();
|
|
129
|
+
setBusy(true);
|
|
130
|
+
setMessage("");
|
|
131
|
+
try {
|
|
132
|
+
await onSave((0, import_index.validatePageConfig)(draft));
|
|
133
|
+
setMessage("Saved");
|
|
134
|
+
} catch (error) {
|
|
135
|
+
setMessage(error.message);
|
|
136
|
+
} finally {
|
|
137
|
+
setBusy(false);
|
|
138
|
+
}
|
|
139
|
+
} },
|
|
140
|
+
input("bpm", "BPM", "number"),
|
|
141
|
+
input("lyricTimingUrl", "Lyric timing URL"),
|
|
142
|
+
input("cueTimingUrl", "Cue timing URL"),
|
|
143
|
+
input("masterDurationMilliseconds", "Master duration (milliseconds)", "number"),
|
|
144
|
+
(0, import_react.createElement)("label", null, (0, import_react.createElement)("input", { type: "checkbox", checked: !!draft.lyricPopupsEnabled, onChange: (e) => setDraft({ ...draft, lyricPopupsEnabled: e.target.checked }) }), "Timed lyric pop-ups"),
|
|
145
|
+
(0, import_react.createElement)("label", null, "Ambient effect", (0, import_react.createElement)(
|
|
146
|
+
"select",
|
|
147
|
+
{ value: draft.effect || "", onChange: (e) => setDraft({ ...draft, effect: e.target.value }) },
|
|
148
|
+
(0, import_react.createElement)("option", { value: "" }, "None"),
|
|
149
|
+
(0, import_react.createElement)("option", { value: "paper-planes" }, "Paper planes")
|
|
150
|
+
)),
|
|
151
|
+
(0, import_react.createElement)("button", { type: "submit", disabled: busy }, busy ? "Saving\u2026" : "Save metadata"),
|
|
152
|
+
(0, import_react.createElement)("output", { "aria-live": "polite" }, message)
|
|
153
|
+
);
|
|
154
|
+
}
|
package/lib/react.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type {ReactNode,RefObject,HTMLAttributes} from 'react';
|
|
2
|
+
import type {DanceMoves,Options,PageConfig,Cue,Lyric} from './index';
|
|
3
|
+
import type {RudimentOptions,RudimentAnimation} from './rudiments';
|
|
4
|
+
export interface MountState {runtime:DanceMoves|null;error:Error|null}
|
|
5
|
+
export function useDanceMoves(root:RefObject<HTMLElement|null>,options?:Omit<Options,'root'>):MountState;
|
|
6
|
+
export function DanceMovesProvider(props:HTMLAttributes<HTMLDivElement> & {options?:Omit<Options,'root'>;children?:ReactNode}):ReactNode;
|
|
7
|
+
export function useDanceMovesContext():MountState;
|
|
8
|
+
export function useCue(runtime:DanceMoves|null,name:string,callback:(cue:Cue)=>void):void;
|
|
9
|
+
export function useLyric(runtime:DanceMoves|null):Lyric|null;
|
|
10
|
+
export function useRudiment(runtime:DanceMoves|null,target:RefObject<HTMLElement|null>,options:Omit<RudimentOptions,'root'|'target'>):{controller:RudimentAnimation|null;error:Error|null};
|
|
11
|
+
export function Rudiment(props:HTMLAttributes<HTMLDivElement> & {runtime:DanceMoves|null;options:Omit<RudimentOptions,'root'|'target'>;children?:ReactNode}):ReactNode;
|
|
12
|
+
export function PageMetadataEditor(props:{value?:PageConfig;onSave:(config:PageConfig)=>void|Promise<unknown>}):ReactNode;
|
package/lib/react.mjs
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
|
|
4
|
+
// .build/modules/react.mjs
|
|
5
|
+
import { createContext, createElement as h, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
6
|
+
import { createDanceMoves, validatePageConfig } from "./index.mjs";
|
|
7
|
+
var EMPTY = Object.freeze({});
|
|
8
|
+
var Context = createContext(null);
|
|
9
|
+
function useDanceMoves(rootRef, options = EMPTY) {
|
|
10
|
+
const [result, setResult] = useState({ runtime: null, error: null });
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (!rootRef.current) return;
|
|
13
|
+
let active = true, runtime;
|
|
14
|
+
try {
|
|
15
|
+
runtime = createDanceMoves({ ...options, root: rootRef.current });
|
|
16
|
+
setResult({ runtime, error: null });
|
|
17
|
+
runtime.ready.catch((error) => {
|
|
18
|
+
if (active) setResult({ runtime, error });
|
|
19
|
+
});
|
|
20
|
+
} catch (error) {
|
|
21
|
+
setResult({ runtime: null, error });
|
|
22
|
+
}
|
|
23
|
+
return () => {
|
|
24
|
+
active = false;
|
|
25
|
+
runtime?.destroy();
|
|
26
|
+
};
|
|
27
|
+
}, [rootRef, options]);
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
function DanceMovesProvider({ options = EMPTY, children, className = "", ...attributes }) {
|
|
31
|
+
const root = useRef(null);
|
|
32
|
+
const result = useDanceMoves(root, options);
|
|
33
|
+
return h("div", { ...attributes, ref: root, className: `ks-epk ${className}`.trim() }, h(Context.Provider, { value: result }, children));
|
|
34
|
+
}
|
|
35
|
+
function useDanceMovesContext() {
|
|
36
|
+
const value = useContext(Context);
|
|
37
|
+
if (!value) throw new Error("useDanceMovesContext requires DanceMovesProvider");
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
function useCue(runtime, name, callback) {
|
|
41
|
+
const latest = useRef(callback);
|
|
42
|
+
latest.current = callback;
|
|
43
|
+
useEffect(() => runtime?.onCue(name, (detail) => latest.current(detail)), [runtime, name]);
|
|
44
|
+
}
|
|
45
|
+
function useLyric(runtime) {
|
|
46
|
+
const [lyric, setLyric] = useState(null);
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
setLyric(null);
|
|
49
|
+
if (!runtime) return;
|
|
50
|
+
const remove = runtime.onLyric(setLyric);
|
|
51
|
+
const clear = () => setLyric(null);
|
|
52
|
+
const events = ["pause", "ended", "seeking"];
|
|
53
|
+
events.forEach((type) => runtime.root.addEventListener(type, clear, true));
|
|
54
|
+
return () => {
|
|
55
|
+
remove();
|
|
56
|
+
events.forEach((type) => runtime.root.removeEventListener(type, clear, true));
|
|
57
|
+
};
|
|
58
|
+
}, [runtime]);
|
|
59
|
+
return lyric;
|
|
60
|
+
}
|
|
61
|
+
function useRudiment(runtime, targetRef, options) {
|
|
62
|
+
const [result, setResult] = useState({ controller: null, error: null });
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
if (!runtime || !targetRef.current) return;
|
|
65
|
+
let active = true, controller;
|
|
66
|
+
try {
|
|
67
|
+
controller = runtime.rudiments.animate({ ...options, root: runtime.root, target: targetRef.current });
|
|
68
|
+
setResult({ controller, error: null });
|
|
69
|
+
controller.ready.catch((error) => {
|
|
70
|
+
if (active) setResult({ controller, error });
|
|
71
|
+
});
|
|
72
|
+
} catch (error) {
|
|
73
|
+
setResult({ controller: null, error });
|
|
74
|
+
}
|
|
75
|
+
return () => {
|
|
76
|
+
active = false;
|
|
77
|
+
controller?.destroy();
|
|
78
|
+
};
|
|
79
|
+
}, [runtime, targetRef, options]);
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
function Rudiment({ runtime, options, children, ...attributes }) {
|
|
83
|
+
const ref = useRef(null);
|
|
84
|
+
useRudiment(runtime, ref, options);
|
|
85
|
+
return h("div", { ...attributes, ref }, children);
|
|
86
|
+
}
|
|
87
|
+
function PageMetadataEditor({ value = EMPTY, onSave }) {
|
|
88
|
+
const [draft, setDraft] = useState(() => ({ ...value })), [message, setMessage] = useState(""), [busy, setBusy] = useState(false);
|
|
89
|
+
useEffect(() => setDraft({ ...value }), [value]);
|
|
90
|
+
const input = (key, label, type = "text") => h("label", { key }, label, h("input", {
|
|
91
|
+
type,
|
|
92
|
+
value: draft[key] ?? "",
|
|
93
|
+
step: type === "number" ? "0.001" : void 0,
|
|
94
|
+
onChange: (e) => setDraft({ ...draft, [key]: type === "number" ? e.target.value === "" ? void 0 : Number(e.target.value) : e.target.value })
|
|
95
|
+
}));
|
|
96
|
+
return h(
|
|
97
|
+
"form",
|
|
98
|
+
{ onSubmit: async (event) => {
|
|
99
|
+
event.preventDefault();
|
|
100
|
+
setBusy(true);
|
|
101
|
+
setMessage("");
|
|
102
|
+
try {
|
|
103
|
+
await onSave(validatePageConfig(draft));
|
|
104
|
+
setMessage("Saved");
|
|
105
|
+
} catch (error) {
|
|
106
|
+
setMessage(error.message);
|
|
107
|
+
} finally {
|
|
108
|
+
setBusy(false);
|
|
109
|
+
}
|
|
110
|
+
} },
|
|
111
|
+
input("bpm", "BPM", "number"),
|
|
112
|
+
input("lyricTimingUrl", "Lyric timing URL"),
|
|
113
|
+
input("cueTimingUrl", "Cue timing URL"),
|
|
114
|
+
input("masterDurationMilliseconds", "Master duration (milliseconds)", "number"),
|
|
115
|
+
h("label", null, h("input", { type: "checkbox", checked: !!draft.lyricPopupsEnabled, onChange: (e) => setDraft({ ...draft, lyricPopupsEnabled: e.target.checked }) }), "Timed lyric pop-ups"),
|
|
116
|
+
h("label", null, "Ambient effect", h(
|
|
117
|
+
"select",
|
|
118
|
+
{ value: draft.effect || "", onChange: (e) => setDraft({ ...draft, effect: e.target.value }) },
|
|
119
|
+
h("option", { value: "" }, "None"),
|
|
120
|
+
h("option", { value: "paper-planes" }, "Paper planes")
|
|
121
|
+
)),
|
|
122
|
+
h("button", { type: "submit", disabled: busy }, busy ? "Saving\u2026" : "Save metadata"),
|
|
123
|
+
h("output", { "aria-live": "polite" }, message)
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
export {
|
|
127
|
+
DanceMovesProvider,
|
|
128
|
+
PageMetadataEditor,
|
|
129
|
+
Rudiment,
|
|
130
|
+
useCue,
|
|
131
|
+
useDanceMoves,
|
|
132
|
+
useDanceMovesContext,
|
|
133
|
+
useLyric,
|
|
134
|
+
useRudiment
|
|
135
|
+
};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/** DanceMoves rudiment animation API v1; available on WordPress Page requests. */
|
|
2
|
+
export type RudimentName = 'bounce' | 'sway' | 'circle' | 'figure_eight' | 'step_touch' |
|
|
3
|
+
'box_step' | 'helix' | 'clay_background' | 'single_stroke_roll' | 'double_stroke_roll' |
|
|
4
|
+
'multiple_bounce_roll' | 'single_paradiddle' | 'flam' | 'drag' | 'five_stroke_roll';
|
|
5
|
+
export type Offset3 = Readonly<{ x: number; y: number; z: number }>;
|
|
6
|
+
export type RudimentClock = 'page' | 'audio' | 'auto';
|
|
7
|
+
export type RudimentStatus = 'loading' | 'running' | 'paused' | 'disabled' | 'hidden' |
|
|
8
|
+
'offscreen' | 'reduced-motion' | 'forced-colors' | 'audio-paused' | 'seeking' |
|
|
9
|
+
'ended' | 'error' | 'destroyed';
|
|
10
|
+
export interface RudimentInfo {
|
|
11
|
+
readonly name: RudimentName;
|
|
12
|
+
readonly description: string;
|
|
13
|
+
readonly periodPips: number;
|
|
14
|
+
readonly dimensions: 1 | 2 | 3;
|
|
15
|
+
/** Internal order in this pinned catalogue, not a stable cross-version ID. */
|
|
16
|
+
readonly index: number;
|
|
17
|
+
}
|
|
18
|
+
export interface RudimentFrame {
|
|
19
|
+
readonly id: string;
|
|
20
|
+
readonly root: Element;
|
|
21
|
+
readonly target: Element;
|
|
22
|
+
readonly audio: HTMLAudioElement | null;
|
|
23
|
+
readonly rudiment: RudimentName;
|
|
24
|
+
readonly clock: 'page' | 'audio';
|
|
25
|
+
readonly sourceBeats: number;
|
|
26
|
+
readonly bpm: number;
|
|
27
|
+
readonly rate: number;
|
|
28
|
+
/** Wrapped integer pip; null for a neutral disabled/accessibility pose. */
|
|
29
|
+
readonly pip: number | null;
|
|
30
|
+
readonly positionPips: number | null;
|
|
31
|
+
/** Continuous clock phase; positions themselves remain integer-pip samples. */
|
|
32
|
+
readonly loopProgress: number;
|
|
33
|
+
/** Loop duration at playbackRate=1, derived from page BPM and rudiment rate. */
|
|
34
|
+
readonly durationMilliseconds: number;
|
|
35
|
+
readonly offset: Offset3;
|
|
36
|
+
/** Pixel-scaled offset for the default CSS renderer. */
|
|
37
|
+
readonly position: Offset3;
|
|
38
|
+
readonly reason: RudimentStatus | 'frame';
|
|
39
|
+
}
|
|
40
|
+
export interface RudimentOptions {
|
|
41
|
+
readonly id: string;
|
|
42
|
+
readonly rudiment: RudimentName;
|
|
43
|
+
readonly target: Element | string;
|
|
44
|
+
readonly root?: Element | string;
|
|
45
|
+
readonly clock?: RudimentClock;
|
|
46
|
+
readonly audio?: HTMLAudioElement | string;
|
|
47
|
+
readonly rate?: number;
|
|
48
|
+
readonly phasePips?: number;
|
|
49
|
+
readonly amplitude?: number | Partial<Offset3>;
|
|
50
|
+
readonly enabled?: boolean;
|
|
51
|
+
readonly css?: boolean;
|
|
52
|
+
readonly cssPrefix?: string;
|
|
53
|
+
readonly offscreen?: boolean;
|
|
54
|
+
readonly resetOnCue?: boolean | string;
|
|
55
|
+
readonly renderEveryFrame?: boolean;
|
|
56
|
+
readonly render?: (detail: RudimentFrame) => void;
|
|
57
|
+
}
|
|
58
|
+
export interface RudimentAnimationSnapshot {
|
|
59
|
+
readonly id: string;
|
|
60
|
+
readonly rudiment: RudimentName;
|
|
61
|
+
readonly status: RudimentStatus;
|
|
62
|
+
readonly enabled: boolean;
|
|
63
|
+
readonly clock: RudimentClock;
|
|
64
|
+
readonly rate: number;
|
|
65
|
+
readonly phasePips: number;
|
|
66
|
+
readonly destroyed: boolean;
|
|
67
|
+
readonly loaded: boolean;
|
|
68
|
+
readonly error: string | null;
|
|
69
|
+
readonly updates: number;
|
|
70
|
+
readonly pip: number | null;
|
|
71
|
+
readonly sourceClock: 'page' | 'audio' | null;
|
|
72
|
+
readonly position: Offset3 | null;
|
|
73
|
+
readonly framePending: boolean;
|
|
74
|
+
}
|
|
75
|
+
export interface RudimentAnimation {
|
|
76
|
+
readonly id: string;
|
|
77
|
+
readonly ready: Promise<RudimentAnimation>;
|
|
78
|
+
pause(): void;
|
|
79
|
+
resume(): void;
|
|
80
|
+
setEnabled(enabled: boolean): void;
|
|
81
|
+
reset(): void;
|
|
82
|
+
refresh(): void;
|
|
83
|
+
snapshot(): RudimentAnimationSnapshot;
|
|
84
|
+
destroy(): void;
|
|
85
|
+
teardown(): void;
|
|
86
|
+
}
|
|
87
|
+
export interface RudimentApi {
|
|
88
|
+
readonly version: '1.0.0';
|
|
89
|
+
readonly upstreamVersion: string;
|
|
90
|
+
readonly upstreamCommit: string;
|
|
91
|
+
readonly pipsPerBeat: 64;
|
|
92
|
+
readonly ticksPerBeat: 16;
|
|
93
|
+
readonly pipsPerTick: 4;
|
|
94
|
+
ready(): Promise<RudimentApi>;
|
|
95
|
+
catalogue(): readonly RudimentInfo[];
|
|
96
|
+
describe(name: string): RudimentInfo | null;
|
|
97
|
+
sample(name: RudimentName, pip: number): Offset3;
|
|
98
|
+
pipsFromTicks(ticks: number): number;
|
|
99
|
+
pipsFromSeconds(seconds: number, bpm?: number): number;
|
|
100
|
+
animate(options: RudimentOptions): RudimentAnimation;
|
|
101
|
+
get(id: string): RudimentAnimation | null;
|
|
102
|
+
snapshot(): Readonly<{ version: '1.0.0'; upstreamVersion: string; loaded: boolean;
|
|
103
|
+
error: string | null; framePending: boolean; instances: readonly RudimentAnimationSnapshot[] }>;
|
|
104
|
+
destroyAll(): void;
|
|
105
|
+
}
|
|
106
|
+
export interface ClayRudimentApi {
|
|
107
|
+
readonly root: Element;
|
|
108
|
+
teardown(): void;
|
|
109
|
+
snapshot(): Readonly<{ status: 'loading' | 'active' | 'suspended' | 'fallback' | 'destroyed';
|
|
110
|
+
error: string | null; destroyed: boolean; loaded: boolean; rudiment: 'clay_background';
|
|
111
|
+
cycleBeats: 8; rate: 0.5; controller: RudimentAnimationSnapshot | null }>;
|
|
112
|
+
}
|
|
113
|
+
declare global {
|
|
114
|
+
interface Window {
|
|
115
|
+
DanceMovesRudiments?: RudimentApi;
|
|
116
|
+
DanceMovesClayRudiment?: ClayRudimentApi;
|
|
117
|
+
}
|
|
118
|
+
interface DocumentEventMap {
|
|
119
|
+
'dance-moves-rudiments-ready': CustomEvent<{
|
|
120
|
+
api: RudimentApi; version: string; upstreamVersion: string; upstreamCommit: string;
|
|
121
|
+
}>;
|
|
122
|
+
'dance-moves-rudiments-error': CustomEvent<{ id: string | null; message: string }>;
|
|
123
|
+
}
|
|
124
|
+
}
|