Skip to content

Commit

Permalink
Animate slide transition
Browse files Browse the repository at this point in the history
  • Loading branch information
SheepTester committed Jun 13, 2024
1 parent ebe6377 commit e755c28
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 41 deletions.
39 changes: 22 additions & 17 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
Fragment,
MutableRefObject,
PointerEvent,
useEffect,
useMemo,
Expand Down Expand Up @@ -52,6 +53,18 @@ export type DraggedAnnotation = {
insert: number | null
}

/**
* Enforces the following rules:
* - The script must always start and end with text.
* - Adjacent text parts must be merged.
*/
function normalizeParts (
parts: Part[],
nextId: MutableRefObject<number>
): Part[] {
return parts
}

export function App () {
const ref = useRef<HTMLDivElement>(null)
const nextId = useRef(0)
Expand Down Expand Up @@ -178,11 +191,14 @@ export function App () {
if (dragState.current?.pointerId === e.pointerId) {
if (dragState.current.insert !== null) {
setParts(
parts.toSpliced(dragState.current.insert, 0, {
id: nextId.current++,
type: 'annotation',
annotation: dragState.current.annotation
})
normalizeParts(
parts.toSpliced(dragState.current.insert, 0, {
id: nextId.current++,
type: 'annotation',
annotation: dragState.current.annotation
}),
nextId
)
)
}
dragState.current = null
Expand Down Expand Up @@ -394,18 +410,7 @@ export function App () {
const before = parts[i - 1]
const after = parts[i + 1]
setParts(parts =>
before?.type === 'text' && after?.type === 'text'
? parts.toSpliced(i - 1, 3, {
...before,
content:
before.content.trimEnd() +
(before.content.trim() !== '' &&
after.content.trim() !== ''
? '\n\n'
: '') +
after.content.trimStart()
})
: parts.toSpliced(i, 1)
normalizeParts(parts.toSpliced(i, 1), nextId)
)
}}
refCallback={elem => {
Expand Down
67 changes: 43 additions & 24 deletions src/render/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export function render (
let previousLayout: Layout | undefined
let currentLayout: { layout: Layout; time: number } | undefined
let previousSlide: HTMLImageElement | undefined
let currentSlide: HTMLImageElement | undefined
let currentSlide: { image: HTMLImageElement; time: number } | undefined
for (const action of strategy.actions) {
if (time < action.time) {
break
Expand All @@ -93,37 +93,45 @@ export function render (
currentLayout = action
}
if (action.type === 'set-slide') {
previousSlide = currentSlide
currentSlide = action.image
previousSlide = currentSlide?.image
currentSlide = action
}
}
previousLayout ??= defaultLayout
currentLayout ??= { layout: defaultLayout, time: -Infinity }
previousLayout ??=
currentLayout.time === 0 ? currentLayout.layout : defaultLayout

const slideT = easeInOutCubic(
clamp((time - (currentSlide?.time ?? -Infinity)) / TRANSITION_DURATION)
)
const aspect = v(
slideT,
previousSlide
? previousSlide.width / previousSlide.height || undefined
: undefined,
currentSlide
? currentSlide.image.width / currentSlide.image.height || undefined
: undefined,
1
)
const layoutStyles: Record<Layout, Partial<Style>> = {
'avatar-only': { opacity: 0 },
'slide-avatar': {
...contain(
currentSlide ? currentSlide.width / currentSlide.height || null : null,
{
x: PADDING,
y: PADDING,
width: (WIDTH * 2) / 3 - PADDING * 2,
height: HEIGHT - PADDING * 2 - 40
}
),
...contain(aspect, {
x: PADDING,
y: PADDING,
width: (WIDTH * 2) / 3 - PADDING * 2,
height: HEIGHT - PADDING * 2 - 40
}),
opacity: 1
},
'slide-only': {
...contain(
currentSlide ? currentSlide.width / currentSlide.height || null : null,
{
x: PADDING,
y: PADDING,
width: WIDTH - PADDING * 2,
height: HEIGHT - PADDING * 2 - 40
}
),
...contain(aspect, {
x: PADDING,
y: PADDING,
width: WIDTH - PADDING * 2,
height: HEIGHT - PADDING * 2 - 40
}),
opacity: 1
}
}
Expand Down Expand Up @@ -192,9 +200,9 @@ export function render (

c.closePath()
c.clip()
if (currentSlide) {
if (currentSlide?.image) {
c.drawImage(
currentSlide,
currentSlide.image,
layoutStyle.x,
layoutStyle.y,
layoutStyle.width,
Expand All @@ -209,6 +217,17 @@ export function render (
layoutStyle.height
)
}
if (slideT < 1 && previousSlide) {
c.globalAlpha = 1 - slideT
c.drawImage(
previousSlide,
layoutStyle.x,
layoutStyle.y,
layoutStyle.width,
layoutStyle.height
)
c.globalAlpha = 1
}
c.restore()
}

Expand Down

0 comments on commit e755c28

Please sign in to comment.