@retro-crt/svelte 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 retro-crt contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # retro-crt
2
+
3
+ A CRT monitor effect your content renders *inside*. Curvature, bloom and chromatic aberration apply
4
+ to the real pixels of whatever you wrap, not a scanline sticker on top.
5
+
6
+ Zero runtime dependencies. 9.3 KB gzipped.
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ npm install retro-crt # plain JS
12
+ npm install retro-crt @retro-crt/react # or /vue, /svelte, /solid, /angular
13
+ ```
14
+
15
+ ## Use it
16
+
17
+ ```js
18
+ import { CRT } from 'retro-crt'
19
+ import 'retro-crt/styles.css'
20
+
21
+ const screen = CRT.mount('#app', { curvature: 0.4 })
22
+
23
+ screen.update({ curvature: 0.7 })
24
+ screen.activeRenderer // 'webgl' | 'svg' | 'css'
25
+ screen.destroy()
26
+ ```
27
+
28
+ ```jsx
29
+ import { CRTScreen } from '@retro-crt/react'
30
+ import 'retro-crt/styles.css'
31
+
32
+ <CRTScreen curvature={0.4} scanlines={{ intensity: 0.6 }}>
33
+ <App />
34
+ </CRTScreen>
35
+ ```
36
+
37
+ Every adapter takes the same plain `CRTOptions` object. All adapters are SSR-safe. To wrap a whole
38
+ page, call `CRT.mountFullPage()`.
39
+
40
+ > **Wrapping content breaks `position: fixed` inside it.** A CSS filter makes its element the
41
+ > containing block for every fixed descendant. Use `CRT.mountFullPage()` for a whole page, which the
42
+ > spec exempts.
43
+
44
+ ## Renderers
45
+
46
+ `renderer: 'auto'` picks one of three tiers from measured facts, never the user-agent string.
47
+
48
+ | | `webgl` | `svg` | `css` |
49
+ |---|---|---|---|
50
+ | Curvature | true barrel | approximation | edge shading |
51
+ | Chromatic aberration | yes | yes | no |
52
+ | Persistence | yes | no | no |
53
+ | Content stays interactive | **no** | yes | yes |
54
+ | Picked for | a lone image, video or canvas | Chrome and Firefox on desktop | Safari over animating content, low-end devices |
55
+
56
+ The WebGL tier is a separate chunk that loads only when something uses it.
57
+
58
+ ## Options
59
+
60
+ ```ts
61
+ interface CRTOptions {
62
+ renderer?: 'auto' | 'webgl' | 'svg' | 'css' // 'auto'
63
+ background?: string // '#000000'
64
+ curvature?: number // 0-1, 0.3
65
+ vignette?: number // 0-1, 0.5
66
+ scanlines?: { intensity?: number; gap?: number; flicker?: boolean } // 0.5, 3px, false
67
+ tint?: { preset?: 'default' | 'green' | 'amber' | 'blue' | 'violet' | 'lime' | 'pink' | 'red'
68
+ strength?: number } // 'default', 0.35
69
+ bloom?: { enabled?: boolean; radius?: number; strength?: number; threshold?: number }
70
+ chromaticAberration?: { intensity?: number } // 0-6px, 0.6
71
+ noise?: { enabled?: boolean; static?: number } // true, 0.04
72
+ persistence?: { strength?: number } // 0-0.5, 0 (webgl only)
73
+ bezel?: { enabled?: boolean; thickness?: number; radius?: { outer?: number; screen?: number }
74
+ color?: string; bevel?: number; lightAngle?: number; innerLip?: number
75
+ screenSpill?: number; glare?: number; shadow?: boolean }
76
+ quality?: 'auto' | 'high' | 'balanced' | 'low' // 'auto'
77
+ maxPixelRatio?: number // 2
78
+ pauseWhenOffscreen?: boolean // true
79
+ respectReducedMotion?: boolean // true
80
+ respectSaveData?: boolean // true
81
+ }
82
+ ```
83
+
84
+ Out-of-range numbers clamp. Unknown values fall back to the default. `background` and `bezel.color`
85
+ accept `#rgb`, `#rrggbb` and `rgb()` only. When a renderer cannot honour an option you set, it
86
+ ignores it and warns once in development.
87
+
88
+ `prefers-reduced-motion` stops flicker, grain and persistence. `prefers-reduced-transparency` halves
89
+ tint and bloom. Save-Data forces the CSS tier. Effect layers are `aria-hidden` and
90
+ `pointer-events: none`.
91
+
92
+ ## License
93
+
94
+ MIT
@@ -0,0 +1,36 @@
1
+ <script lang="ts">
2
+ import { untrack, type Snippet } from 'svelte'
3
+ import { CRT, type CRTOptions, type CRTScreen as Screen, type Quality, type Renderer } from 'retro-crt'
4
+
5
+ interface Props extends CRTOptions {
6
+ children?: Snippet
7
+ class?: string
8
+ style?: string
9
+ onrendererchange?: (renderer: Renderer, quality: Quality) => void
10
+ }
11
+
12
+ let { children, class: className, style, onrendererchange, ...options }: Props = $props()
13
+ let host: HTMLDivElement
14
+ let screen: Screen | undefined = $state()
15
+
16
+ $effect(() => {
17
+ const s = CRT.mount(host, untrack(() => $state.snapshot(options)))
18
+ const notify = () => untrack(() => onrendererchange?.(s.activeRenderer, s.activeQuality))
19
+ const unsubscribe = s.subscribe(notify)
20
+ notify()
21
+ screen = s
22
+ return () => {
23
+ unsubscribe()
24
+ s.destroy()
25
+ }
26
+ })
27
+
28
+ $effect(() => {
29
+ const next = $state.snapshot(options)
30
+ untrack(() => screen)?.set(next)
31
+ })
32
+ </script>
33
+
34
+ <div bind:this={host} class={className} {style}>
35
+ <div data-rcrt-content="">{@render children?.()}</div>
36
+ </div>
@@ -0,0 +1,11 @@
1
+ import { type Snippet } from 'svelte';
2
+ import { type CRTOptions, type Quality, type Renderer } from 'retro-crt';
3
+ interface Props extends CRTOptions {
4
+ children?: Snippet;
5
+ class?: string;
6
+ style?: string;
7
+ onrendererchange?: (renderer: Renderer, quality: Quality) => void;
8
+ }
9
+ declare const CRTScreen: import("svelte").Component<Props, {}, "">;
10
+ type CRTScreen = ReturnType<typeof CRTScreen>;
11
+ export default CRTScreen;
@@ -0,0 +1,2 @@
1
+ export { default as CRTScreen } from './CRTScreen.svelte';
2
+ export type { CRTOptions } from 'retro-crt';
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export { default as CRTScreen } from './CRTScreen.svelte';
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@retro-crt/svelte",
3
+ "version": "1.0.0",
4
+ "description": "Svelte adapter for retro-crt",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "sideEffects": false,
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "svelte": "./dist/index.js",
12
+ "types": "./dist/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "svelte": "./dist/index.js",
17
+ "import": "./dist/index.js"
18
+ }
19
+ },
20
+ "scripts": {
21
+ "build": "svelte-package -i src/lib -o dist"
22
+ },
23
+ "peerDependencies": {
24
+ "svelte": ">=5.8",
25
+ "retro-crt": "^1.0.0"
26
+ },
27
+ "devDependencies": {
28
+ "@sveltejs/package": "^2.5.0",
29
+ "svelte": "^5.8.0",
30
+ "retro-crt": "*"
31
+ },
32
+ "author": "pixelyokai",
33
+ "homepage": "https://github.com/pixelyokai/retro-crt/tree/main/packages/svelte#readme",
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/pixelyokai/retro-crt.git",
37
+ "directory": "packages/svelte"
38
+ },
39
+ "bugs": {
40
+ "url": "https://github.com/pixelyokai/retro-crt/issues"
41
+ },
42
+ "publishConfig": {
43
+ "access": "public"
44
+ },
45
+ "keywords": [
46
+ "crt",
47
+ "retro",
48
+ "scanlines",
49
+ "effect",
50
+ "svelte"
51
+ ]
52
+ }