Skip to content

Commit

Permalink
Merge pull request #417 from charlielee/issue-413
Browse files Browse the repository at this point in the history
Pause playback
  • Loading branch information
charlielee committed Aug 13, 2022
2 parents 5106185 + 7ff0d82 commit 31e9f82
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 68 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { useState } from "react";
import PlaybackContext from "../../../context/PlaybackContext/PlaybackContext";
import PlaybackContext, {
PlaybackFrameName,
} from "../../../context/PlaybackContext/PlaybackContext";
import IconName from "../../common/Icon/IconName";
import IconButton from "../../common/IconButton/IconButton";
import InputRange from "../../common/Input/InputRange/InputRange";
Expand All @@ -10,21 +12,17 @@ import ToolbarItem, {
import "./AnimationToolbar.css";

interface AnimationToolbarProps {
startPlayback: () => void;
startOrPausePlayback: () => void;
stopPlayback: () => void;
displayFirstFrame: () => void;
displayPreviousFrame: () => void;
displayNextFrame: () => void;
displayLastFrame: () => void;
displayFrame: (name: PlaybackFrameName) => void;
playing: boolean;
}

const AnimationToolbar = ({
startPlayback,
startOrPausePlayback,
stopPlayback,
displayFirstFrame,
displayPreviousFrame,
displayNextFrame,
displayLastFrame,
displayFrame,
playing,
}: AnimationToolbarProps): JSX.Element => {
const [onionSkinAmount, setOnionSkinAmount] = useState(0);
const [loopPlayback, setLoopPlayback] = useState(false);
Expand Down Expand Up @@ -57,17 +55,17 @@ const AnimationToolbar = ({
<IconButton
title="First Frame"
icon={IconName.PLAY_FIRST}
onClick={() => displayFirstFrame()}
onClick={() => displayFrame(PlaybackFrameName.FIRST)}
/>
<IconButton
title="Previous Frame"
icon={IconName.PLAY_PREVIOUS}
onClick={() => displayPreviousFrame()}
onClick={() => displayFrame(PlaybackFrameName.PREVIOUS)}
/>
<IconButton
title="Playback Frames"
icon={IconName.PLAY}
onClick={() => startPlayback()}
title={playing ? "Pause Playback" : "Playback Frames"}
icon={playing ? IconName.PLAY_PAUSE : IconName.PLAY}
onClick={() => startOrPausePlayback()}
/>
<IconButton
title="Stop Playback"
Expand All @@ -77,12 +75,12 @@ const AnimationToolbar = ({
<IconButton
title="Next Frame"
icon={IconName.PLAY_NEXT}
onClick={() => displayNextFrame()}
onClick={() => displayFrame(PlaybackFrameName.NEXT)}
/>
<IconButton
title="Last Frame"
icon={IconName.PLAY_LAST}
onClick={() => displayLastFrame()}
onClick={() => displayFrame(PlaybackFrameName.LAST)}
/>
</ToolbarItem>

Expand Down
8 changes: 4 additions & 4 deletions src/renderer/components/animator/Timeline/Timeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ interface TimelineWithContextProps {

interface TimelineProps extends TimelineWithContextProps {
timelineIndex: TimelineIndex | undefined;
displayFrame: (timelineIndex: TimelineIndex | undefined) => void;
stopPlayback: (timelineIndex?: TimelineIndex | undefined) => void;
}

const Timeline = ({
take,
timelineIndex,
displayFrame,
stopPlayback,
}: TimelineProps): JSX.Element => {
const frameTrack = take.frameTrack;
const timelineRef = useRef<HTMLDivElement>(null);
Expand All @@ -34,7 +34,7 @@ const Timeline = ({
}, [timelineIndex, frameTrack.trackItems]);

const onClickItem = (track: Track, trackItemIndex: number) =>
displayFrame(getTrackItemStartPosition(track, trackItemIndex));
stopPlayback(getTrackItemStartPosition(track, trackItemIndex));

return (
<div className="timeline" ref={timelineRef}>
Expand All @@ -50,7 +50,7 @@ const Timeline = ({
onClickItem={(trackItemIndex) =>
onClickItem(frameTrack, trackItemIndex)
}
onClickLiveView={() => displayFrame(undefined)}
onClickLiveView={() => stopPlayback()}
/>
</div>
</div>
Expand Down
25 changes: 13 additions & 12 deletions src/renderer/context/PlaybackContext/PlaybackContext.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
import { createContext } from "react";
import { TimelineIndex } from "../../../common/Flavors";

export const enum PlaybackFrameName {
FIRST = "FIRST",
PREVIOUS = "PREVIOUS",
NEXT = "NEXT",
LAST = "LAST",
}

export interface PlaybackContextProps {
startPlayback: () => void;
stopPlayback: () => void;
displayFrame: (i: TimelineIndex | undefined) => void;
displayFirstFrame: () => void;
displayPreviousFrame: () => void;
displayNextFrame: () => void;
displayLastFrame: () => void;
startOrPausePlayback: () => void;
stopPlayback: (i?: TimelineIndex | undefined, pause?: boolean) => void;
displayFrame: (name: PlaybackFrameName) => void;
timelineIndex: TimelineIndex | undefined;
liveViewVisible: boolean;
playing: boolean;
}

const defaultValue: PlaybackContextProps = {
startPlayback: () => undefined,
startOrPausePlayback: () => undefined,
stopPlayback: () => undefined,
displayFrame: () => undefined,
displayFirstFrame: () => undefined,
displayPreviousFrame: () => undefined,
displayNextFrame: () => undefined,
displayLastFrame: () => undefined,
timelineIndex: undefined,
liveViewVisible: true,
playing: false,
};

const PlaybackContext = createContext<PlaybackContextProps>(defaultValue);
Expand Down
81 changes: 47 additions & 34 deletions src/renderer/context/PlaybackContext/PlaybackContextProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import { TimelineIndex } from "../../../common/Flavors";
import { getTrackLength, Take } from "../../../common/Project";
import useRequestAnimationFrame from "../../hooks/useRequestAnimationFrame";
import * as rLogger from "../../services/rLogger/rLogger";
import PlaybackContext, { PlaybackContextProps } from "./PlaybackContext";
import PlaybackContext, {
PlaybackContextProps,
PlaybackFrameName,
} from "./PlaybackContext";

interface PlaybackContextProviderProps {
take: Take;
Expand All @@ -21,6 +24,7 @@ const PlaybackContextProvider = ({
undefined
);
const [liveViewVisible, setLiveViewVisible] = useState(true);
const [playing, setPlaying] = useState(false);

const delay = 1000 / take.frameRate;
const previousTime = useRef<number>(0);
Expand Down Expand Up @@ -48,68 +52,80 @@ const PlaybackContextProvider = ({
}
});

const startPlayback = () => {
const startOrPausePlayback = () =>
playing ? _pausePlayback() : _startPlayback();

const stopPlayback = (i?: TimelineIndex | undefined) => {
_logPlayback("playback.stopPlayback");
stop();
_updateFrameIndex(i === undefined ? undefined : i);
setLiveViewVisible(i === undefined);
setPlaying(false);
};

const displayFrame = (name: PlaybackFrameName) => {
switch (name) {
case PlaybackFrameName.FIRST:
return _displayFirstFrame();
case PlaybackFrameName.PREVIOUS:
return _displayPreviousFrame();
case PlaybackFrameName.NEXT:
return _displayNextFrame();
case PlaybackFrameName.LAST:
return _displayLastFrame();
}
};

const _startPlayback = () => {
_logPlayback("playback.startPlayback");
if (playForDuration > 0) {
lastFrameIndex.current = playForDuration - 1;
start();
setLiveViewVisible(false);
setPlaying(true);
}
};

const stopPlayback = () => {
_logPlayback("playback.stopPlayback");
stop();
_updateFrameIndex(undefined);
setLiveViewVisible(true);
};

const displayFrame = (i: TimelineIndex | undefined) => {
_logPlayback("playback.displayFrame");
if (i === undefined) {
stopPlayback();
} else {
stop();
_updateFrameIndex(i);
setLiveViewVisible(false);
}
const _pausePlayback = () => {
_logPlayback("playback.pausePlayback");
stopPlayback(timelineIndex);
};

const displayFirstFrame = () => {
const _displayFirstFrame = () => {
_logPlayback("playback.displayFirstFrame");
displayFrame(0);
stopPlayback(0);
};

const displayPreviousFrame = () => {
const _displayPreviousFrame = () => {
_logPlayback("playback.displayPreviousFrame");

if (timelineIndex === undefined) {
return displayFrame(playForDuration - 1);
return stopPlayback(playForDuration - 1);
}
if (timelineIndex > 0) {
return displayFrame(timelineIndex - 1);
return stopPlayback(timelineIndex - 1);
}
};

const displayNextFrame = () => {
const _displayNextFrame = () => {
_logPlayback("playback.displayNextFrame");

if (timelineIndex === playForDuration - 1) {
return displayFrame(undefined);
return stopPlayback(undefined);
}
if (timelineIndex !== undefined) {
return displayFrame(timelineIndex + 1);
return stopPlayback(timelineIndex + 1);
}
};

const displayLastFrame = () => {
const _displayLastFrame = () => {
_logPlayback("playback.displayLastFrame");

if (timelineIndex === playForDuration - 1) {
return displayFrame(undefined);
return stopPlayback(undefined);
}
if (timelineIndex !== undefined) {
return displayFrame(playForDuration - 1);
return stopPlayback(playForDuration - 1);
}
};

Expand All @@ -126,15 +142,12 @@ const PlaybackContextProvider = ({
});

const value: PlaybackContextProps = {
startPlayback,
startOrPausePlayback,
stopPlayback,
displayFrame,
displayFirstFrame,
displayPreviousFrame,
displayNextFrame,
displayLastFrame,
timelineIndex,
liveViewVisible,
playing,
};

return (
Expand Down

0 comments on commit 31e9f82

Please sign in to comment.