@ldelia/react-media 0.4.1 → 0.4.3
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/dist/components/__tests__/timeline/timeline.test.js +5 -10
- package/dist/components/index.js +2 -17
- package/dist/components/timeline/RangeSelectorCanvas/RangeSelectorCanvas.js +16 -44
- package/dist/components/timeline/Timeline.js +26 -56
- package/dist/components/timeline/TimelineCanvas/TickTime.js +5 -10
- package/dist/components/timeline/TimelineCanvas/TickTimeCollectionDisplay.js +9 -14
- package/dist/components/timeline/TimelineCanvas/TimelineCanvas.js +16 -44
- package/dist/components/timeline/TimelineCanvas/drawTimeBlocksOnCanvas.js +4 -8
- package/dist/components/timeline/TimelineValue/TimelineValue.js +24 -54
- package/dist/components/timeline/ZoomContext/ZoomContext.js +2 -8
- package/dist/components/timeline/constants.js +1 -4
- package/dist/components/timeline/index.js +1 -17
- package/dist/components/timeline/utils/utils.js +6 -15
- package/dist/index.js +1 -17
- package/dist/setupTests.js +1 -3
- package/dist/stories/timeline.stories.js +18 -24
- package/package.json +45 -35
- package/.bitmap +0 -48
- package/.eslintcache +0 -1
- package/.prettierignore +0 -3
- package/.prettierrc +0 -7
- package/.storybook/main.js +0 -38
- package/.storybook/preview.js +0 -4
- package/config/env.js +0 -104
- package/config/getHttpsConfig.js +0 -66
- package/config/jest/babelTransform.js +0 -29
- package/config/jest/cssTransform.js +0 -14
- package/config/jest/fileTransform.js +0 -40
- package/config/modules.js +0 -134
- package/config/paths.js +0 -77
- package/config/webpack/persistentCache/createEnvironmentHash.js +0 -9
- package/config/webpack.config.js +0 -755
- package/config/webpackDevServer.config.js +0 -127
- package/dist/components/__tests__/timeline/timeline.test.d.ts +0 -1
- package/dist/components/index.d.ts +0 -1
- package/dist/components/timeline/RangeSelectorCanvas/RangeSelectorCanvas.d.ts +0 -8
- package/dist/components/timeline/Timeline.d.ts +0 -12
- package/dist/components/timeline/TimelineCanvas/TickTime.d.ts +0 -7
- package/dist/components/timeline/TimelineCanvas/TickTimeCollectionDisplay.d.ts +0 -6
- package/dist/components/timeline/TimelineCanvas/TimelineCanvas.d.ts +0 -7
- package/dist/components/timeline/TimelineCanvas/drawTimeBlocksOnCanvas.d.ts +0 -2
- package/dist/components/timeline/TimelineValue/TimelineValue.d.ts +0 -7
- package/dist/components/timeline/ZoomContext/ZoomContext.d.ts +0 -7
- package/dist/components/timeline/constants.d.ts +0 -1
- package/dist/components/timeline/index.d.ts +0 -1
- package/dist/components/timeline/utils/utils.d.ts +0 -7
- package/dist/index.d.ts +0 -1
- package/dist/setupTests.d.ts +0 -1
- package/dist/stories/timeline.stories.d.ts +0 -9
- package/scripts/build.js +0 -217
- package/scripts/start.js +0 -154
- package/scripts/test.js +0 -52
- package/src/components/__tests__/timeline/timeline.test.js +0 -22
- package/src/components/__tests__/timeline/timeline.test.tsx +0 -26
- package/src/components/index.js +0 -2
- package/src/components/index.ts +0 -2
- package/src/components/reproduction-widget/README.md +0 -27
- package/src/components/reproduction-widget/ReproductionWidget.tsx +0 -68
- package/src/components/reproduction-widget/index.tsx +0 -1
- package/src/components/reproduction-widget/inner-players/PlayAlongInnerPlayer.tsx +0 -10
- package/src/components/reproduction-widget/inner-players/YouTubeInnerPlayer.tsx +0 -36
- package/src/components/reproduction-widget/models/Player/PlayAlongPlayer.ts +0 -129
- package/src/components/reproduction-widget/models/Player/PlayerEvents.ts +0 -4
- package/src/components/reproduction-widget/models/Player/YouTubePlayer.ts +0 -171
- package/src/components/reproduction-widget/models/Reproduction.ts +0 -272
- package/src/components/reproduction-widget/models/ReproductionBuilder.ts +0 -70
- package/src/components/timeline/README.md +0 -111
- package/src/components/timeline/RangeSelectorCanvas/RangeSelectorCanvas.js +0 -127
- package/src/components/timeline/RangeSelectorCanvas/RangeSelectorCanvas.tsx +0 -166
- package/src/components/timeline/Timeline.js +0 -77
- package/src/components/timeline/Timeline.tsx +0 -139
- package/src/components/timeline/TimelineCanvas/TickTime.js +0 -26
- package/src/components/timeline/TimelineCanvas/TickTime.tsx +0 -45
- package/src/components/timeline/TimelineCanvas/TickTimeCollectionDisplay.js +0 -19
- package/src/components/timeline/TimelineCanvas/TickTimeCollectionDisplay.tsx +0 -42
- package/src/components/timeline/TimelineCanvas/TimelineCanvas.js +0 -44
- package/src/components/timeline/TimelineCanvas/TimelineCanvas.tsx +0 -79
- package/src/components/timeline/TimelineCanvas/drawTimeBlocksOnCanvas.js +0 -28
- package/src/components/timeline/TimelineCanvas/drawTimeBlocksOnCanvas.ts +0 -43
- package/src/components/timeline/TimelineValue/TimelineValue.js +0 -50
- package/src/components/timeline/TimelineValue/TimelineValue.tsx +0 -87
- package/src/components/timeline/ZoomContext/ZoomContext.js +0 -2
- package/src/components/timeline/ZoomContext/ZoomContext.ts +0 -10
- package/src/components/timeline/constants.js +0 -13
- package/src/components/timeline/constants.ts +0 -13
- package/src/components/timeline/index.js +0 -1
- package/src/components/timeline/index.tsx +0 -1
- package/src/components/timeline/utils/utils.js +0 -28
- package/src/components/timeline/utils/utils.ts +0 -49
- package/src/index.js +0 -1
- package/src/index.ts +0 -1
- package/src/modules.d.ts +0 -1
- package/src/react-app-env.d.ts +0 -71
- package/src/react-docgen-types.d.ts +0 -37
- package/src/setupTests.js +0 -5
- package/src/setupTests.ts +0 -5
- package/src/stories/Configure.mdx +0 -364
- package/src/stories/reproduction-widget.stories.tsx +0 -23
- package/src/stories/timeline.stories.custom.css +0 -29
- package/src/stories/timeline.stories.js +0 -54
- package/src/stories/timeline.stories.tsx +0 -66
- package/storybook-static/favicon.svg +0 -1
- package/storybook-static/index.html +0 -173
- package/storybook-static/index.json +0 -1
- package/storybook-static/nunito-sans-bold-italic.woff2 +0 -0
- package/storybook-static/nunito-sans-bold.woff2 +0 -0
- package/storybook-static/nunito-sans-italic.woff2 +0 -0
- package/storybook-static/nunito-sans-regular.woff2 +0 -0
- package/storybook-static/project.json +0 -1
- package/storybook-static/sb-addons/essentials-actions-3/manager-bundle.js +0 -3
- package/storybook-static/sb-addons/essentials-actions-3/manager-bundle.js.LEGAL.txt +0 -0
- package/storybook-static/sb-addons/essentials-backgrounds-4/manager-bundle.js +0 -12
- package/storybook-static/sb-addons/essentials-backgrounds-4/manager-bundle.js.LEGAL.txt +0 -0
- package/storybook-static/sb-addons/essentials-controls-2/manager-bundle.js +0 -412
- package/storybook-static/sb-addons/essentials-controls-2/manager-bundle.js.LEGAL.txt +0 -0
- package/storybook-static/sb-addons/essentials-measure-7/manager-bundle.js +0 -3
- package/storybook-static/sb-addons/essentials-measure-7/manager-bundle.js.LEGAL.txt +0 -0
- package/storybook-static/sb-addons/essentials-outline-8/manager-bundle.js +0 -3
- package/storybook-static/sb-addons/essentials-outline-8/manager-bundle.js.LEGAL.txt +0 -0
- package/storybook-static/sb-addons/essentials-toolbars-6/manager-bundle.js +0 -3
- package/storybook-static/sb-addons/essentials-toolbars-6/manager-bundle.js.LEGAL.txt +0 -0
- package/storybook-static/sb-addons/essentials-viewport-5/manager-bundle.js +0 -3
- package/storybook-static/sb-addons/essentials-viewport-5/manager-bundle.js.LEGAL.txt +0 -0
- package/storybook-static/sb-addons/links-1/manager-bundle.js +0 -3
- package/storybook-static/sb-addons/links-1/manager-bundle.js.LEGAL.txt +0 -0
- package/storybook-static/sb-addons/storybook-core-core-server-presets-0/common-manager-bundle.js +0 -3
- package/storybook-static/sb-addons/storybook-core-core-server-presets-0/common-manager-bundle.js.LEGAL.txt +0 -0
- package/storybook-static/sb-common-assets/favicon.svg +0 -1
- package/storybook-static/sb-common-assets/nunito-sans-bold-italic.woff2 +0 -0
- package/storybook-static/sb-common-assets/nunito-sans-bold.woff2 +0 -0
- package/storybook-static/sb-common-assets/nunito-sans-italic.woff2 +0 -0
- package/storybook-static/sb-common-assets/nunito-sans-regular.woff2 +0 -0
- package/storybook-static/sb-manager/globals-module-info.js +0 -995
- package/storybook-static/sb-manager/globals-runtime.js +0 -53527
- package/storybook-static/sb-manager/globals.js +0 -48
- package/storybook-static/sb-manager/runtime.js +0 -11885
- package/storybook-static/sb-preview/globals.js +0 -33
- package/storybook-static/sb-preview/runtime.js +0 -9483
- package/tsconfig.json +0 -14
- /package/{src → dist}/components/reproduction-widget/ReproductionWidget.js +0 -0
- /package/{src → dist}/components/reproduction-widget/index.js +0 -0
- /package/{src → dist}/components/reproduction-widget/inner-players/PlayAlongInnerPlayer.js +0 -0
- /package/{src → dist}/components/reproduction-widget/inner-players/YouTubeInnerPlayer.js +0 -0
- /package/{src → dist}/components/reproduction-widget/models/Player/PlayAlongPlayer.js +0 -0
- /package/{src → dist}/components/reproduction-widget/models/Player/PlayerEvents.js +0 -0
- /package/{src → dist}/components/reproduction-widget/models/Player/YouTubePlayer.js +0 -0
- /package/{src → dist}/components/reproduction-widget/models/Reproduction.js +0 -0
- /package/{src → dist}/components/reproduction-widget/models/ReproductionBuilder.js +0 -0
- /package/{src → dist}/stories/reproduction-widget.stories.js +0 -0
|
@@ -1,272 +0,0 @@
|
|
|
1
|
-
import { PLAYER_EVENTS } from './Player/PlayerEvents';
|
|
2
|
-
import { ReproductionBuilder } from './ReproductionBuilder';
|
|
3
|
-
import { PlayAlongPlayer } from './Player/PlayAlongPlayer';
|
|
4
|
-
import { YouTubePlayer } from './Player/YouTubePlayer';
|
|
5
|
-
|
|
6
|
-
type Player = PlayAlongPlayer | YouTubePlayer;
|
|
7
|
-
|
|
8
|
-
const STATES = {
|
|
9
|
-
STOPPED: 0,
|
|
10
|
-
COUNTING_IN: 1,
|
|
11
|
-
PLAYING: 2,
|
|
12
|
-
PAUSED: 3,
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
const EVENTS = {
|
|
16
|
-
READY: 'READY',
|
|
17
|
-
START: 'START',
|
|
18
|
-
COUNTING_IN: 'COUNTING_IN',
|
|
19
|
-
PLAY: 'PLAY',
|
|
20
|
-
PLAYING: 'PLAYING',
|
|
21
|
-
PAUSED: 'PAUSED',
|
|
22
|
-
FINISH: 'FINISH',
|
|
23
|
-
} as const;
|
|
24
|
-
|
|
25
|
-
const dispatchOnReadyHandlers = Symbol();
|
|
26
|
-
const dispatchOnSongStartHandlers = Symbol();
|
|
27
|
-
const dispatchOnCountingInHandlers = Symbol();
|
|
28
|
-
const dispatchOnPlayHandlers = Symbol();
|
|
29
|
-
const dispatchOnPlayingHandlers = Symbol();
|
|
30
|
-
const dispatchOnPausedHandlers = Symbol();
|
|
31
|
-
const dispatchOnFinishHandlers = Symbol();
|
|
32
|
-
|
|
33
|
-
export class Reproduction {
|
|
34
|
-
private player: Player;
|
|
35
|
-
private requiresCountingIn: boolean;
|
|
36
|
-
|
|
37
|
-
private songTempo: number;
|
|
38
|
-
private state: number;
|
|
39
|
-
private ready: boolean;
|
|
40
|
-
private interval: ReturnType<typeof setInterval> | null;
|
|
41
|
-
private countingInCounter: number;
|
|
42
|
-
private [dispatchOnReadyHandlers]: (() => void)[];
|
|
43
|
-
private [dispatchOnSongStartHandlers]: (() => void)[];
|
|
44
|
-
private [dispatchOnCountingInHandlers]: (() => void)[];
|
|
45
|
-
private [dispatchOnPlayHandlers]: (() => void)[];
|
|
46
|
-
private [dispatchOnPlayingHandlers]: (() => void)[];
|
|
47
|
-
private [dispatchOnPausedHandlers]: (() => void)[];
|
|
48
|
-
private [dispatchOnFinishHandlers]: (() => void)[];
|
|
49
|
-
|
|
50
|
-
static get EVENTS() {
|
|
51
|
-
return EVENTS;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
static get STATES() {
|
|
55
|
-
return STATES;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
constructor(player: Player, requiresCountingIn: boolean, songTempo: number) {
|
|
59
|
-
this[dispatchOnReadyHandlers] = [];
|
|
60
|
-
this[dispatchOnSongStartHandlers] = [];
|
|
61
|
-
this[dispatchOnCountingInHandlers] = [];
|
|
62
|
-
this[dispatchOnPlayHandlers] = [];
|
|
63
|
-
this[dispatchOnPlayingHandlers] = [];
|
|
64
|
-
this[dispatchOnPausedHandlers] = [];
|
|
65
|
-
this[dispatchOnFinishHandlers] = [];
|
|
66
|
-
|
|
67
|
-
this.songTempo = songTempo;
|
|
68
|
-
this.player = player;
|
|
69
|
-
this.ready = false;
|
|
70
|
-
|
|
71
|
-
this.state = Reproduction.STATES.STOPPED;
|
|
72
|
-
this.interval = null;
|
|
73
|
-
|
|
74
|
-
this.requiresCountingIn = requiresCountingIn;
|
|
75
|
-
this.countingInCounter = 0;
|
|
76
|
-
|
|
77
|
-
this.player.on(PLAYER_EVENTS.READY, () => {
|
|
78
|
-
this.ready = true;
|
|
79
|
-
this.dispatch(Reproduction.EVENTS.READY);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
this.player.on(PLAYER_EVENTS.FINISH, () => {
|
|
83
|
-
this.state = Reproduction.STATES.STOPPED;
|
|
84
|
-
clearInterval(this.interval as NodeJS.Timeout);
|
|
85
|
-
this.dispatch(Reproduction.EVENTS.FINISH);
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
on(eventName: keyof typeof Reproduction.EVENTS, handler: () => void) {
|
|
90
|
-
switch (eventName) {
|
|
91
|
-
case Reproduction.EVENTS.READY:
|
|
92
|
-
return this[dispatchOnReadyHandlers].push(handler);
|
|
93
|
-
case Reproduction.EVENTS.START:
|
|
94
|
-
return this[dispatchOnSongStartHandlers].push(handler);
|
|
95
|
-
case Reproduction.EVENTS.COUNTING_IN:
|
|
96
|
-
return this[dispatchOnCountingInHandlers].push(handler);
|
|
97
|
-
case Reproduction.EVENTS.PLAY:
|
|
98
|
-
return this[dispatchOnPlayHandlers].push(handler);
|
|
99
|
-
case Reproduction.EVENTS.PLAYING:
|
|
100
|
-
return this[dispatchOnPlayingHandlers].push(handler);
|
|
101
|
-
case Reproduction.EVENTS.PAUSED:
|
|
102
|
-
return this[dispatchOnPausedHandlers].push(handler);
|
|
103
|
-
case Reproduction.EVENTS.FINISH:
|
|
104
|
-
return this[dispatchOnFinishHandlers].push(handler);
|
|
105
|
-
default:
|
|
106
|
-
break;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
dispatch(eventName: keyof typeof Reproduction.EVENTS) {
|
|
111
|
-
let handler, i, len;
|
|
112
|
-
|
|
113
|
-
let ref: (() => void)[] = [];
|
|
114
|
-
|
|
115
|
-
switch (eventName) {
|
|
116
|
-
case Reproduction.EVENTS.READY:
|
|
117
|
-
ref = this[dispatchOnReadyHandlers];
|
|
118
|
-
break;
|
|
119
|
-
case Reproduction.EVENTS.START:
|
|
120
|
-
ref = this[dispatchOnSongStartHandlers];
|
|
121
|
-
break;
|
|
122
|
-
case Reproduction.EVENTS.COUNTING_IN:
|
|
123
|
-
ref = this[dispatchOnCountingInHandlers];
|
|
124
|
-
break;
|
|
125
|
-
case Reproduction.EVENTS.PLAY:
|
|
126
|
-
ref = this[dispatchOnPlayHandlers];
|
|
127
|
-
break;
|
|
128
|
-
case Reproduction.EVENTS.PLAYING:
|
|
129
|
-
ref = this[dispatchOnPlayingHandlers];
|
|
130
|
-
break;
|
|
131
|
-
case Reproduction.EVENTS.PAUSED:
|
|
132
|
-
ref = this[dispatchOnPausedHandlers];
|
|
133
|
-
break;
|
|
134
|
-
case Reproduction.EVENTS.FINISH:
|
|
135
|
-
ref = this[dispatchOnFinishHandlers];
|
|
136
|
-
break;
|
|
137
|
-
default:
|
|
138
|
-
break;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
for (i = 0, len = ref.length; i < len; i++) {
|
|
142
|
-
handler = ref[i];
|
|
143
|
-
handler();
|
|
144
|
-
// setTimeout(handler, 0);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
private countIn(timeout: number, limit: number) {
|
|
149
|
-
// the initial count starts instantly, no waiting
|
|
150
|
-
this.countingInCounter++;
|
|
151
|
-
this.dispatch(Reproduction.EVENTS.COUNTING_IN);
|
|
152
|
-
|
|
153
|
-
const interval = setInterval(() => {
|
|
154
|
-
this.countingInCounter++;
|
|
155
|
-
if (this.countingInCounter === limit) {
|
|
156
|
-
clearInterval(interval);
|
|
157
|
-
this.countingInCounter = 0;
|
|
158
|
-
if (limit !== 5) {
|
|
159
|
-
this.countIn(this.getBPMInterval(), 5);
|
|
160
|
-
} else {
|
|
161
|
-
this.play();
|
|
162
|
-
}
|
|
163
|
-
} else {
|
|
164
|
-
this.dispatch(Reproduction.EVENTS.COUNTING_IN);
|
|
165
|
-
}
|
|
166
|
-
}, timeout);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
start() {
|
|
170
|
-
if (this.state === Reproduction.STATES.STOPPED) {
|
|
171
|
-
this.dispatch(Reproduction.EVENTS.START);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
if (this.requiresCountingIn && this.getCurrentTime() === 0) {
|
|
175
|
-
this.state = Reproduction.STATES.COUNTING_IN;
|
|
176
|
-
this.countIn(this.getBPMInterval() * 2, 3);
|
|
177
|
-
} else {
|
|
178
|
-
this.play();
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
play() {
|
|
183
|
-
this.state = Reproduction.STATES.PLAYING;
|
|
184
|
-
this.dispatch(Reproduction.EVENTS.PLAY);
|
|
185
|
-
this.player.play();
|
|
186
|
-
|
|
187
|
-
const intervalTimeout = 200;
|
|
188
|
-
|
|
189
|
-
this.interval = setInterval(() => {
|
|
190
|
-
if (this.isPlaying()) {
|
|
191
|
-
this.dispatch(Reproduction.EVENTS.PLAYING);
|
|
192
|
-
}
|
|
193
|
-
}, intervalTimeout);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
pause() {
|
|
197
|
-
this.state = Reproduction.STATES.PAUSED;
|
|
198
|
-
this.player.pause();
|
|
199
|
-
clearInterval(this.interval as NodeJS.Timeout);
|
|
200
|
-
|
|
201
|
-
this.dispatch(Reproduction.EVENTS.PAUSED);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
stop() {
|
|
205
|
-
this.state = Reproduction.STATES.STOPPED;
|
|
206
|
-
this.player.stop();
|
|
207
|
-
clearInterval(this.interval as NodeJS.Timeout);
|
|
208
|
-
this.dispatch(Reproduction.EVENTS.FINISH);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
isReady() {
|
|
212
|
-
// It's necessary to avoid play the reproduction-widget when the player is not ready
|
|
213
|
-
return this.ready;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
isPlaying() {
|
|
217
|
-
return this.state === Reproduction.STATES.PLAYING;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
isStopped() {
|
|
221
|
-
return this.state === Reproduction.STATES.STOPPED;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
isPaused() {
|
|
225
|
-
return this.state === Reproduction.STATES.PAUSED;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
isCountingIn() {
|
|
229
|
-
return this.state === Reproduction.STATES.COUNTING_IN;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
getPlayer() {
|
|
233
|
-
return this.player;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
getTempo() {
|
|
237
|
-
return this.songTempo;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
getCurrentTime() {
|
|
241
|
-
// in seconds with milliseconds.
|
|
242
|
-
return this.player.getCurrentTime();
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
getDuration() {
|
|
246
|
-
return this.player.getDuration();
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
seekTo(seconds: number) {
|
|
250
|
-
this.player.seekTo(seconds);
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
getAvailablePlaybackRates() {
|
|
254
|
-
return this.player.getAvailablePlaybackRates();
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
setPlaybackRate(playbackRate: number) {
|
|
258
|
-
this.player.setPlaybackRate(playbackRate);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
isAvailable() {
|
|
262
|
-
return this.player.isAvailable();
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
getBPMInterval() {
|
|
266
|
-
return 60000 / this.getTempo();
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
static newBuilder() {
|
|
270
|
-
return new ReproductionBuilder();
|
|
271
|
-
}
|
|
272
|
-
}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { YouTubePlayer } from './Player/YouTubePlayer';
|
|
2
|
-
import { PlayAlongPlayer } from './Player/PlayAlongPlayer';
|
|
3
|
-
import { Reproduction } from './Reproduction';
|
|
4
|
-
import { YouTubePlayer as InnerYouTubePlayer } from 'react-youtube';
|
|
5
|
-
|
|
6
|
-
export class ReproductionBuilder {
|
|
7
|
-
private trainingMode: boolean;
|
|
8
|
-
private requiresCountingIn: boolean;
|
|
9
|
-
private songDuration: number | null;
|
|
10
|
-
private songTempo: number | null;
|
|
11
|
-
private innerPlayer: InnerYouTubePlayer | string;
|
|
12
|
-
|
|
13
|
-
constructor() {
|
|
14
|
-
this.trainingMode = false;
|
|
15
|
-
this.requiresCountingIn = false;
|
|
16
|
-
this.songDuration = null;
|
|
17
|
-
this.songTempo = null;
|
|
18
|
-
this.innerPlayer = null;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
withSongDuration(songDuration: number) {
|
|
22
|
-
this.songDuration = songDuration;
|
|
23
|
-
return this;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
withSongTempo(songTempo: number) {
|
|
27
|
-
this.songTempo = songTempo;
|
|
28
|
-
return this;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
withTrainingMode(trainingMode: boolean) {
|
|
32
|
-
this.trainingMode = trainingMode;
|
|
33
|
-
return this;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
withCountingIn(requiresCountingIn: boolean) {
|
|
37
|
-
this.requiresCountingIn = requiresCountingIn;
|
|
38
|
-
return this;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
withInnerPlayer(innerPlayer: InnerYouTubePlayer | string) {
|
|
42
|
-
this.innerPlayer = innerPlayer;
|
|
43
|
-
return this;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
createReproduction() {
|
|
47
|
-
if (this.requiresCountingIn && this.songTempo === null) {
|
|
48
|
-
throw new Error('The song tempo is mandatory');
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (this.innerPlayer === null) {
|
|
52
|
-
throw new Error('The inner player was not provided.');
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
let player;
|
|
56
|
-
if (this.trainingMode) {
|
|
57
|
-
player = new YouTubePlayer(this.innerPlayer);
|
|
58
|
-
} else {
|
|
59
|
-
if (this.songDuration === null) {
|
|
60
|
-
throw new Error('The song duration is mandatory');
|
|
61
|
-
}
|
|
62
|
-
player = new PlayAlongPlayer(this.songDuration, this.innerPlayer);
|
|
63
|
-
}
|
|
64
|
-
return new Reproduction(
|
|
65
|
-
player,
|
|
66
|
-
this.requiresCountingIn,
|
|
67
|
-
this.songTempo || 0
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
# Timeline
|
|
2
|
-
|
|
3
|
-
<!-- STORY -->
|
|
4
|
-
|
|
5
|
-
<hr>
|
|
6
|
-
|
|
7
|
-
A component for displaying the duration of a media file (mp3, mp4, etc.) and the current reproduction position. It also allows selecting a range for reproduction looping purposes.
|
|
8
|
-
|
|
9
|
-
## Installation
|
|
10
|
-
|
|
11
|
-
### NPM
|
|
12
|
-
|
|
13
|
-
```
|
|
14
|
-
npm i @bit/ldelia.react-media.timeline
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
### YARN
|
|
18
|
-
|
|
19
|
-
```
|
|
20
|
-
yarn add @bit/ldelia.react-media.timeline
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
### BIT
|
|
24
|
-
|
|
25
|
-
```
|
|
26
|
-
bit import ldelia.react-media/timeline
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## Import
|
|
30
|
-
|
|
31
|
-
```js
|
|
32
|
-
import Timeline from '@bit/ldelia.react-media.timeline';
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## Usage
|
|
36
|
-
|
|
37
|
-
```jsx
|
|
38
|
-
<Timeline
|
|
39
|
-
duration={301}
|
|
40
|
-
value={15}
|
|
41
|
-
onChange={() => 'Do something'}
|
|
42
|
-
onRangeChange={() => 'Do something'}
|
|
43
|
-
/>
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
##### Required props
|
|
47
|
-
|
|
48
|
-
| Name | Type | Description |
|
|
49
|
-
| ---------- | -------- | --------------------------------- |
|
|
50
|
-
| `duration` | `number` | The media file duration |
|
|
51
|
-
| `value` | `number` | The current reproduction position |
|
|
52
|
-
|
|
53
|
-
##### Optional props
|
|
54
|
-
|
|
55
|
-
| Name | Type | Default | Description |
|
|
56
|
-
| --------------- | ---------- | ---------- | -------------------------------------------------- |
|
|
57
|
-
| `onChange` | `function` | `() => {}` | Fired when the user double-clicks on the timeline |
|
|
58
|
-
| `onRangeChange` | `function` | `() => {}` | Fired when the user select a range in the timeline |
|
|
59
|
-
| `selectedRange` | `array` | `[]` | The current selected range |
|
|
60
|
-
| `zoomLevel` | `number` | `0` | `The current timeline zoom level` |
|
|
61
|
-
|
|
62
|
-
## Customization
|
|
63
|
-
|
|
64
|
-
#### Timeline widget
|
|
65
|
-
|
|
66
|
-
```
|
|
67
|
-
const StyledTimeline = styled(Timeline)`
|
|
68
|
-
background-color: green;
|
|
69
|
-
`;
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
#### Value bar
|
|
73
|
-
|
|
74
|
-
```
|
|
75
|
-
const StyledTimeline = styled(Timeline)`
|
|
76
|
-
.media-timeline-value-line {
|
|
77
|
-
background-color: red;
|
|
78
|
-
width: 5px;
|
|
79
|
-
}
|
|
80
|
-
`;
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
#### Tick-time labels
|
|
84
|
-
|
|
85
|
-
```
|
|
86
|
-
const StyledTimeline = styled(Timeline)`
|
|
87
|
-
.media-timeline-tick-time {
|
|
88
|
-
color: red;
|
|
89
|
-
}
|
|
90
|
-
`;
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
#### Tick-time/Value bar container
|
|
94
|
-
|
|
95
|
-
```
|
|
96
|
-
const StyledTimeline = styled(Timeline)`
|
|
97
|
-
.media-timeline-value-line-canvas {
|
|
98
|
-
color: red;
|
|
99
|
-
}
|
|
100
|
-
`;
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
#### Range selector
|
|
104
|
-
|
|
105
|
-
```
|
|
106
|
-
const StyledTimeline = styled(Timeline)`
|
|
107
|
-
.media-timeline-range-selector-canvas {
|
|
108
|
-
color: red;
|
|
109
|
-
}
|
|
110
|
-
`;
|
|
111
|
-
```
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import React, { useContext, useEffect, useMemo, useRef } from 'react';
|
|
2
|
-
import styled from 'styled-components';
|
|
3
|
-
import { ZoomContext } from '../ZoomContext/ZoomContext';
|
|
4
|
-
import { pixelToSeconds, secondsToPixel } from '../utils/utils';
|
|
5
|
-
const OverlayCanvas = styled.canvas `
|
|
6
|
-
position: absolute;
|
|
7
|
-
top: 0;
|
|
8
|
-
left: 0;
|
|
9
|
-
width: 100%;
|
|
10
|
-
height: 100%;
|
|
11
|
-
color: cadetblue;
|
|
12
|
-
`;
|
|
13
|
-
const RangeSelectorCanvas = ({ selectedRange, onChange, onRangeChange, }) => {
|
|
14
|
-
const canvasRef = useRef(null);
|
|
15
|
-
const zoomContextValue = useContext(ZoomContext);
|
|
16
|
-
let isSelectingRange = false;
|
|
17
|
-
let selectedRangeInPixels = useMemo(() => [], []);
|
|
18
|
-
if (selectedRange.length === 2) {
|
|
19
|
-
selectedRangeInPixels = [
|
|
20
|
-
secondsToPixel(zoomContextValue, selectedRange[0]),
|
|
21
|
-
secondsToPixel(zoomContextValue, selectedRange[1]),
|
|
22
|
-
];
|
|
23
|
-
}
|
|
24
|
-
let lastValidSelectedRangeInPixels = [];
|
|
25
|
-
const getMousePointerPixelPosition = (e) => {
|
|
26
|
-
const canvas = canvasRef.current;
|
|
27
|
-
let rect = canvas.getBoundingClientRect();
|
|
28
|
-
return e.clientX - rect.left;
|
|
29
|
-
};
|
|
30
|
-
const drawRect = (pixelX0, pixelX1) => {
|
|
31
|
-
const canvas = canvasRef.current;
|
|
32
|
-
const context = canvas.getContext('2d');
|
|
33
|
-
context.globalAlpha = 0.3;
|
|
34
|
-
context.fillStyle = window
|
|
35
|
-
.getComputedStyle(canvas)
|
|
36
|
-
.getPropertyValue('color');
|
|
37
|
-
context.fillRect(pixelX0, 0, pixelX1 - pixelX0, context.canvas.height);
|
|
38
|
-
context.globalAlpha = 1.0;
|
|
39
|
-
};
|
|
40
|
-
const onCanvasDoubleClick = (e) => {
|
|
41
|
-
const x0 = getMousePointerPixelPosition(e);
|
|
42
|
-
onChange(pixelToSeconds(zoomContextValue, x0));
|
|
43
|
-
selectedRangeInPixels = lastValidSelectedRangeInPixels;
|
|
44
|
-
};
|
|
45
|
-
const isPixelNearSelectedRange = (x0) => {
|
|
46
|
-
if (selectedRangeInPixels.length === 2) {
|
|
47
|
-
const diff = Math.min(Math.abs(selectedRangeInPixels[0] - x0), Math.abs(selectedRangeInPixels[1] - x0));
|
|
48
|
-
return diff <= zoomContextValue.pixelsInSecond / 2;
|
|
49
|
-
}
|
|
50
|
-
return false;
|
|
51
|
-
};
|
|
52
|
-
const onCanvasMouseDown = (e) => {
|
|
53
|
-
const mouseCurrentPosition = getMousePointerPixelPosition(e);
|
|
54
|
-
if (!isPixelNearSelectedRange(mouseCurrentPosition)) {
|
|
55
|
-
// Keep track of the first position of the new range.
|
|
56
|
-
selectedRangeInPixels = [mouseCurrentPosition, mouseCurrentPosition];
|
|
57
|
-
}
|
|
58
|
-
isSelectingRange = true;
|
|
59
|
-
};
|
|
60
|
-
const onCanvasMouseMove = (e) => {
|
|
61
|
-
const canvas = canvasRef.current;
|
|
62
|
-
const context = canvas.getContext('2d');
|
|
63
|
-
const mouseCurrentPosition = getMousePointerPixelPosition(e);
|
|
64
|
-
if (selectedRangeInPixels.length === 2) {
|
|
65
|
-
const diff = Math.min(Math.abs(selectedRangeInPixels[0] - mouseCurrentPosition), Math.abs(selectedRangeInPixels[1] - mouseCurrentPosition));
|
|
66
|
-
// Change the mouse's cursor if it's near a selected range.
|
|
67
|
-
canvas.style.cursor =
|
|
68
|
-
diff <= zoomContextValue.pixelsInSecond / 2 ? 'col-resize' : 'default';
|
|
69
|
-
if (!isSelectingRange)
|
|
70
|
-
return;
|
|
71
|
-
if (mouseCurrentPosition < selectedRangeInPixels[0]) {
|
|
72
|
-
// The left side must be enlarged.
|
|
73
|
-
selectedRangeInPixels[0] = mouseCurrentPosition;
|
|
74
|
-
}
|
|
75
|
-
else if (mouseCurrentPosition > selectedRangeInPixels[1]) {
|
|
76
|
-
// The right side must be enlarged.
|
|
77
|
-
selectedRangeInPixels[1] = mouseCurrentPosition;
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
const diffX0 = mouseCurrentPosition - selectedRangeInPixels[0];
|
|
81
|
-
const diffX1 = selectedRangeInPixels[1] - mouseCurrentPosition;
|
|
82
|
-
if (diffX0 < diffX1) {
|
|
83
|
-
// The left side must be shrunk.
|
|
84
|
-
selectedRangeInPixels[0] = mouseCurrentPosition;
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
// The right side must be shrunk.
|
|
88
|
-
selectedRangeInPixels[1] = mouseCurrentPosition;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
context.clearRect(0, 0, canvas.width, canvas.height);
|
|
92
|
-
drawRect(selectedRangeInPixels[0], selectedRangeInPixels[1]);
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
const onCanvasMouseUp = (e) => {
|
|
96
|
-
if (selectedRangeInPixels.length !== 2)
|
|
97
|
-
return;
|
|
98
|
-
isSelectingRange = false;
|
|
99
|
-
const mouseCurrentPosition = getMousePointerPixelPosition(e);
|
|
100
|
-
const pixelRange = [
|
|
101
|
-
Math.min(selectedRangeInPixels[0], mouseCurrentPosition),
|
|
102
|
-
Math.max(selectedRangeInPixels[1], mouseCurrentPosition),
|
|
103
|
-
];
|
|
104
|
-
if (pixelRange[1] - pixelRange[0] <= 1) {
|
|
105
|
-
// It was just a click
|
|
106
|
-
selectedRangeInPixels = lastValidSelectedRangeInPixels;
|
|
107
|
-
}
|
|
108
|
-
else {
|
|
109
|
-
lastValidSelectedRangeInPixels = pixelRange;
|
|
110
|
-
onRangeChange([
|
|
111
|
-
pixelToSeconds(zoomContextValue, pixelRange[0]),
|
|
112
|
-
pixelToSeconds(zoomContextValue, pixelRange[1]),
|
|
113
|
-
]);
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
useEffect(() => {
|
|
117
|
-
const canvas = canvasRef.current;
|
|
118
|
-
// https://stackoverflow.com/questions/8696631/canvas-drawings-like-lines-are-blurry
|
|
119
|
-
canvas.width = canvas.offsetWidth;
|
|
120
|
-
canvas.height = canvas.offsetHeight;
|
|
121
|
-
if (selectedRangeInPixels.length === 0)
|
|
122
|
-
return;
|
|
123
|
-
drawRect(selectedRangeInPixels[0], selectedRangeInPixels[1]);
|
|
124
|
-
}, [selectedRangeInPixels]);
|
|
125
|
-
return (React.createElement(OverlayCanvas, { ref: canvasRef, onDoubleClick: onCanvasDoubleClick, onMouseDown: onCanvasMouseDown, onMouseMove: onCanvasMouseMove, onMouseUp: onCanvasMouseUp, className: 'media-timeline-range-selector-canvas' }));
|
|
126
|
-
};
|
|
127
|
-
export default React.memo(RangeSelectorCanvas);
|