https://github.com/bethropolis/svelte-film-countdown
A vintage-style film countdown component for Svelte 5.
https://github.com/bethropolis/svelte-film-countdown
Last synced: 3 months ago
JSON representation
A vintage-style film countdown component for Svelte 5.
- Host: GitHub
- URL: https://github.com/bethropolis/svelte-film-countdown
- Owner: bethropolis
- Created: 2024-12-31T22:29:51.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-12-29T23:51:12.000Z (6 months ago)
- Last Synced: 2026-01-02T07:11:42.724Z (5 months ago)
- Language: Svelte
- Homepage: https://bethropolis.github.io/svelte-film-countdown/
- Size: 372 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# svelte-film-countdown
[](https://github.com/bethropolis/svelte-film-countdown/actions/workflows/pages.yaml)
A vintage-style film countdown component for your Svelte 5 applications, built with runes.

## Features
* **Authentic Vintage Aesthetic:** Provides a visually compelling retro film countdown experience reminiscent of classic cinema.
* **Highly Customizable:** Tailor the countdown's behavior and appearance with props and CSS variables. Control duration, initial count, styling of circles, numbers, and visual effects.
* **Programmatic Control:** Imperatively manage the countdown's state using exported functions: `start`, `pause`, `resume`, and `reset`.
* **Event Callbacks:** Execute custom logic when the countdown completes (`onComplete`) or after each decrement (`onEachCount`).
* **Looping Functionality:** Enable continuous countdown loops with the `loop` prop.
* **CSS Variable Theming:** Achieve consistent branding and easily adjust the visual theme using CSS variables.
## Installation
Install `svelte-film-countdown` using your preferred package manager:
```bash
npm install svelte-film-countdown
```
```bash
yarn add svelte-film-countdown
```
```bash
pnpm add svelte-film-countdown
```
```bash
bun add svelte-film-countdown
```
## Usage
Import the `FilmCountdown` component into your Svelte component:
```svelte
import FilmCountdown from 'svelte-film-countdown';
let countdownInstance;
function handleComplete() {
alert('Countdown finished!');
}
function handleEachCount(currentCount) {
console.log('Current count:', currentCount);
}
function startCountdown() {
countdownInstance?.start();
}
function pauseCountdown() {
countdownInstance?.pause();
}
function resumeCountdown() {
countdownInstance?.resume();
}
function resetCountdown() {
countdownInstance?.reset();
}
Start
Pause
Resume
Reset
```
### Basic Example
Render the countdown with default settings:
```svelte
import FilmCountdown from 'svelte-film-countdown';
```
### Custom Initial Count and Duration
Configure the starting number and the duration of each count:
```svelte
import FilmCountdown from 'svelte-film-countdown';
```
### Utilizing Event Callbacks
Execute functions when the countdown finishes or after each count:
```svelte
import FilmCountdown from 'svelte-film-countdown';
function handleComplete() {
console.log('Countdown finished!');
}
function handleEachCount(currentCount) {
console.log('Current count:', currentCount);
}
```
### Configuration Options via `config` Prop
Customize the visual appearance of the countdown through the `config` prop:
```svelte
import FilmCountdown from 'svelte-film-countdown';
```
### Enabling Looping
Make the countdown restart automatically after reaching zero. Note that you need to manually trigger `start()` to begin the countdown:
```svelte
import FilmCountdown from 'svelte-film-countdown';
let countdownInstance;
function startLoopingCountdown() {
countdownInstance?.start();
}
Start Looping Countdown
```
## Props
| Prop Name | Type | Default Value | Description |
| ------------------ | ----------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------- |
| `initialCount` | `number` | `5` | The number from which the countdown begins. |
| `countdownDuration`| `number` | `1000` | The time in milliseconds for each count decrement. |
| `onComplete` | `() => void` | `() => {}` | A callback function that is executed when the countdown reaches 0. |
| `onEachCount` | `(count: number) => void` | `() => {}` | A callback function executed after each count, receiving the current count as an argument. |
| `config` | `object` | `{}` | An object containing properties to customize the visual aspects of the countdown. See the `config` details below. |
| `loop` | `boolean` | `false` | If `true`, the countdown will automatically reset to `initialCount` and stop at 0, ready to be started again. |
### `config` Object Properties
| Property Name | Type | Default Value | Description |
| ----------------------- | -------- | ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `numberColor` | `string` | `'var(--countdown-number-color)'` | The color of the number displayed in the center of the countdown. |
| `numCircles` | `number` | `2` | The number of concentric circles animating around the central number. |
| `circleRadius` | `number` | `64` | The radius of the outermost circle in pixels. |
| `circleSpacing` | `number` | `8` | The space in pixels between each concentric circle. |
| `strokeRatio` | `number` | `1 / 40` | The ratio of the circle's radius that determines the thickness of the circle's stroke. |
| `canvasSize` | `number` | `256` | The width and height of the SVG canvas (viewBox dimensions). The component will maintain a 16:9 aspect ratio. |
| `circleGradientStart` | `string` | `'var(--circle-gradient-start)'` | The starting color of the gradient applied to the circles. |
| `circleGradientMiddle` | `string` | `'var(--circle-gradient-middle)'` | The middle color of the gradient applied to the circles. |
| `circleGradientMiddleOpacity` | `number` | `0.8` | The opacity of the middle color in the circle gradient. |
| `circleGradientEnd` | `string` | `'var(--circle-gradient-end)'` | The ending color of the gradient applied to the circles. |
## Exported Functions
To control the countdown programmatically, you need to bind a reference to the `FilmCountdown` component using `bind:this`.
* **`start()`:** Initiates the countdown sequence.
* **`pause()`:** Temporarily halts the countdown.
* **`resume()`:** Continues the countdown from the paused state.
* **`reset()`:** Stops the countdown and resets it to the `initialCount`.
## Theming with CSS Variables
Customize the visual theme of the `FilmCountdown` component by overriding these CSS variables in your global stylesheet or within a specific component's `` block.
```css
:root {
--countdown-number-color: black;
--countdown-button-color: rgba(0, 0, 0, 0.8);
--countdown-button-text-color: white;
--film-hole-width: 20px;
--film-hole-rect-width: 8px;
--film-hole-rect-height: 12px;
--film-hole-y-top: 10px;
--film-hole-y-bottom: 22px;
--film-hole-color: black;
--sweeping-background-color: rgba(0, 0, 0, 0.15);
--circle-gradient-start: black;
--circle-gradient-middle: black;
--circle-gradient-middle-opacity: 0.8;
--circle-gradient-end: black;
--grid-line-color: rgba(255, 255, 255, 0.3);
--film-grain-opacity: 0.1;
--flicker-duration: 0.15s;
--vignette-strength: 0.4;
--center-vignette-strength: 0.15;
--scratch-color: rgba(255, 255, 255, 0.2);
--scratch-opacity: 0.15;
--number-font: monospace;
--number-text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
--film-grain-pattern: linear-gradient(to bottom, rgba(156, 163, 175, 0.05), transparent, rgba(156, 163, 175, 0.05));
}
```
**Example of Applying a Theme:**
```svelte
<style>
:root {
--countdown-number-color: lightyellow;
--sweeping-background-color: rgba(100, 0, 0, 0.25);
--film-grain-opacity: 0.2;
}
```
## Contributing
Contributions are highly appreciated! If you find a bug, have an idea for an improvement, or want to add a new feature, please don't hesitate to open an issue or submit a pull request.
## License
[MIT License](LICENSE)