Skip to content

Commit dc92e4d

Browse files
committed
feat: add parallax
1 parent 492a9cb commit dc92e4d

File tree

12 files changed

+163
-1
lines changed

12 files changed

+163
-1
lines changed

.changeset/poor-geese-mix.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@casual-ui/svelte': minor
3+
---
4+
5+
feat: add parallax

packages/docs/config/sidebar.ts

+4
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ export default {
133133
title: 'Skeleton',
134134
to: '/features/components/interact/skeleton/',
135135
},
136+
{
137+
title: 'Parallax',
138+
to: '/features/components/interact/parallax/',
139+
},
136140
],
137141
},
138142
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
---
2+
title: Parallax
3+
componentName: CParallax
4+
---
5+
6+
## Basic usage
7+
8+
```svelte live
9+
<script>
10+
import { CParallax } from '@casual-ui/svelte'
11+
12+
</script>
13+
14+
<CParallax src="/rabbit.jpg">
15+
<div class="text-white text-6xl absolute inset-0 flex items-center justify-center">
16+
Rabbit
17+
</div>
18+
19+
</CParallax>
20+
```
21+
22+
23+
## Custom height & speed
24+
25+
```svelte live
26+
<script>
27+
import { CParallax } from '@casual-ui/svelte'
28+
29+
</script>
30+
31+
<CParallax src="/sunset.png" speed={0.5} height="300px">
32+
<div class="text-white text-6xl absolute inset-0 flex items-center justify-center">
33+
Sunset
34+
</div>
35+
</CParallax>
36+
```
37+
38+
## Using video with slots
39+
40+
```svelte live
41+
<script>
42+
import { CParallax } from '@casual-ui/svelte'
43+
44+
</script>
45+
46+
<CParallax src="/rabbit.jpg" speed={0.2} height="300px">
47+
<div class="text-white text-6xl absolute inset-0 flex items-center justify-center">
48+
Cats playing
49+
</div>
50+
<video slot="bg" width="100%" height="800" autoplay loop muted>
51+
<source type="video/mp4" src="/cat.mp4">
52+
</video>
53+
</CParallax>
54+
55+
<style>
56+
video {
57+
}
58+
</style>
59+
```

packages/docs/static/cat.mp4

5.63 MB
Binary file not shown.

packages/docs/static/cat.mp4:Zone.Identifier

Whitespace-only changes.

packages/docs/static/rabbit.jpg

1 MB
Loading

packages/docs/static/rabbit.jpg:Zone.Identifier

Whitespace-only changes.

packages/docs/static/sunset.png

54.1 KB
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[ZoneTransfer]
2+
ZoneId=3
3+
ReferrerUrl=http://static.simpledesktops.com/uploads/desktops/2015/03/02/mountains-on-mars.png
4+
HostUrl=http://static.simpledesktops.com/uploads/desktops/2015/03/02/mountains-on-mars.png
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<script>
2+
import { onMount } from 'svelte'
3+
import bem from '../utils/bem'
4+
5+
/**
6+
* The background image
7+
* @type {string}
8+
*/
9+
export let src
10+
11+
/**
12+
* The height of container.
13+
* @type {string}
14+
*/
15+
export let height = '400px'
16+
17+
/**
18+
* The background scroll speed. Value between 0 and 1
19+
* @type {number}
20+
*/
21+
export let speed = 1
22+
23+
/**
24+
* @type {HTMLDivElement}
25+
*/
26+
let container
27+
28+
/**
29+
* @type {HTMLDivElement}
30+
*/
31+
let imageContainer
32+
33+
let top = '0'
34+
35+
const classPrefix = bem('parallax')
36+
37+
onMount(() => {
38+
if (!container || !imageContainer) return
39+
let isIntersecting = false
40+
const observer = new IntersectionObserver(
41+
entires => {
42+
const [target] = entires
43+
isIntersecting = target.isIntersecting
44+
},
45+
{
46+
root: null,
47+
rootMargin: '0px',
48+
threshold: [0, 1],
49+
}
50+
)
51+
52+
observer.observe(container)
53+
54+
const scrollHandler = () => {
55+
if (!isIntersecting) return
56+
const imageHeight = imageContainer.offsetHeight
57+
const containerHeight = container.offsetHeight
58+
const total = imageHeight - containerHeight
59+
const next = (speed * document.documentElement.scrollTop) / total
60+
top = `-${next > 1 ? total : next * total}px`
61+
}
62+
63+
window.addEventListener('scroll', scrollHandler)
64+
65+
return () => {
66+
window.removeEventListener('scroll', scrollHandler)
67+
observer.unobserve(container)
68+
observer.disconnect()
69+
}
70+
})
71+
</script>
72+
73+
<div
74+
class={classPrefix}
75+
style:height
76+
bind:this={container}
77+
style:--c-parallax-top={top}
78+
>
79+
<div bind:this={imageContainer} class={`${classPrefix}--image`}>
80+
<!-- Customize the bg content -->
81+
<slot name="bg">
82+
<img {src} alt="" />
83+
</slot>
84+
</div>
85+
<div class={`${classPrefix}--front`}>
86+
<slot />
87+
</div>
88+
</div>

packages/ui/src/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,15 @@ import CCarousel from './components/carousel/CCarousel.svelte'
5151
import CCarouselSlider from './components/carousel/CCarouselSlider.svelte'
5252
import CTree from './components/tree/CTree.svelte'
5353
import CSkeleton from './components/skeleton/CSkeleton.svelte'
54+
import CParallax from './components/CParallax.svelte'
5455
import { attributeAtom } from './utils/attributeAtom'
5556

5657
export { useFormProps } from './hooks/useForm'
5758

5859
export {
5960
attributeAtom,
6061
CTree,
62+
CParallax,
6163
CAjaxBar,
6264
CSkeleton,
6365
CCarouselSlider,

0 commit comments

Comments
 (0)