Pop
A short pop for an entrance or transition.
Customize
import {Scene, Video} from "odori";
import {Pop} from "../components/pop/pop";
<Video>
<Scene id="pop" duration="0.13s">
<Pop />
</Scene>
</Video>Installation
pnpm odori add audio popnpx odori add audio popbunx odori add audio popEdit the source in videos/components/pop/. Use odori diff to compare upstream changes and odori update to apply updates.
Copy these files into your project
videos/components/pop/pop.tsx
import {defineCue, gain, mix, normalize, note, shape, sine, sweep, type CueDefinition} from "odori";
export type PopOptions = {
/** The note the pop lands on. */
pitch?: string;
/** Peak level before the mix normalizes the whole track. */
peak?: number;
};
/**
* A small bubble of air: a tone that snaps up in pitch and dies immediately.
* Four frames, for a chip appearing, a card landing, an item entering a list.
*
* The upward sweep is the whole trick. A flat tone this short is a beep; a
* tone that rises through it is a pop.
*/
export const pop = ({pitch = "e5", peak = 0.7}: PopOptions = {}): CueDefinition => {
const samples = Math.round(48000 * 0.13);
const target = note(pitch);
return defineCue({
name: "ui.pop",
durationInFrames: 4,
params: {pitch, peak},
render: () =>
normalize(
mix(
gain(shape(sweep(samples, target * 0.55, target), {attack: 0.002, decay: 0.09, sustain: 0}), 0.9),
gain(shape(sine(samples, target * 2), {attack: 0.001, decay: 0.04, sustain: 0}), 0.25),
),
peak,
),
});
};
videos/components/pop/pop.preview.tsx
import {CueWave, defineComponentPreview} from "odori/preview";
import {pop, type PopOptions} from "./pop";
const Wave = ({pitch, peak}: PopOptions) => <CueWave cue={pop({pitch, peak})} />;
export default defineComponentPreview({
title: "Pop",
category: "Sound/Interface",
description: "A short pop for an entrance or transition.",
component: Wave,
canvas: {width: 1920, height: 1080, duration: "1s"},
controls: {
pitch: {type: "select", defaultValue: "e5", options: ["c5", "e5", "g5", "c6"]},
peak: {type: "number", defaultValue: 0.7, min: 0.1, max: 1, step: 0.05},
},
examples: [{name: "Default", props: {}}, {name: "Higher", props: {pitch: "c6"}}],
});
Add it to a scene
import {Scene, Video} from "odori";
import {Pop} from "../components/pop/pop";
<Video>
<Scene id="pop" duration="0.13s">
<Pop />
</Scene>
</Video>Timing contract
Use these durations and content limits when composing a scene. Run odori test to check your video.
- Family
- Sound
- Brand cue
- ui.pop
- Recommended duration
- 4 frames · 0.13s
- Minimum duration
- 4 frames · 0.13s
- Entrance
- 0 frames
- Exit
- 0 frames
- Reduced motion
- the waveform renders without a playhead
- Requires
- mono font
- Content limits
- none