import {Op, generate_id, html} from "@benev/slate"
import {styles} from "./styles.js"
import transitionSvg from "../../icons/transition.svg.js"
import {shadow_component} from "../../context/context.js"
import {StateHandler} from "../../views/state-handler/view.js"
import circleInfoSvg from "../../icons/gravity-ui/circle-info.svg.js"
import circlePlaySvg from "../../icons/gravity-ui/circle-play.svg.js"
import circlePauseSvg from "../../icons/gravity-ui/circle-pause.svg.js"
import {normalizeTransitionDuration} from "./utils/normalize-transition-duration.js"
import {calculateMaxTransitionDuration} from "./utils/calculate-max-transition-duration.js"
import {transitions} from "../../context/controllers/compositor/parts/transition-manager.js"
export const OmniTransitions = shadow_component(use => {
use.styles(styles)
use.watch(() => use.context.state)
const state = use.context.state
const manager = use.context.controllers.compositor.managers.transitionManager
const [isTutorialPlaying, setTutorialPlaying] = use.state(false)
use.mount(() => {
const dispose = manager.onChange(() => use.rerender())
return () => dispose()
})
const touchingPairs = manager.findTouchingClips(state.effects)
const renderTransitions = () => {
return transitions.map(transition => {
const selectedTransition = use.context.state.transitions.find(a => a.id === manager.selected)
const duration = selectedTransition?.duration ?? 520
return html`
manager.selectTransition({
incoming: selectedTransition?.incoming!,
outgoing: selectedTransition?.outgoing!,
duration: normalizeTransitionDuration(duration, 1000 / use.context.state.timebase),
transition,
id: selectedTransition?.id ?? generate_id()
})?.apply(use.context.state)}
class="transition"
>
${transition.name}
`
})
}
const renderAnimationNone = () => {
return html`
manager.removeSelectedTransition()}
class="transition"
>
none
`}
const renderDurationSlider = (id: string | null) => {
const transition = manager.getTransition(id)
const max = calculateMaxTransitionDuration(transition, use.context.state)
const frameDuration = 1000 / use.context.state.timebase
const duration = manager.getTransitionDuration(id) ?? 520
return html`
manager.updateTransition(
use.context.state,
{duration: +(e.target as HTMLInputElement).value}
)}
type="range"
min="500"
max=${max}
step=${frameDuration}
.value=${duration}
name="duration"
id="duration"
>
${duration / 1000}s
`
}
const tutorialVideo = use.once(() => {
const video = document.createElement("video")
video.src = "/assets/transition-tutorial.mp4"
video.loop = true
return video
})
const renderTutorialVideo = () => {
return html`
${circleInfoSvg} How to add transition
${tutorialVideo}
`
}
return StateHandler(Op.all(
use.context.helpers.ffmpeg.is_loading.value,
use.context.is_webcodecs_supported.value), () => html`
${transitionSvg} Transitions
${renderDurationSlider(manager.selected)}
${renderAnimationNone()}
${renderTransitions()}
`)
})