blocks-dusted 0.1.9 → 0.1.11
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/README.md +35 -0
- package/package.json +1 -1
- package/src/utils/paths.js +13 -13
- package/templates/blocks/DD-Accordion/Component.tsx +229 -0
- package/templates/blocks/DD-Accordion/README.md +3 -0
- package/templates/blocks/DD-Accordion/config.ts +73 -0
- package/templates/blocks/DD-Accordion/manifest.json +75 -0
- package/templates/blocks/DD-AnimText/Component.tsx +788 -0
- package/templates/blocks/DD-AnimText/README.md +3 -0
- package/templates/blocks/DD-AnimText/config.ts +295 -0
- package/templates/blocks/DD-AnimText/manifest.json +85 -0
- package/templates/blocks/DD-AsideNav/Component.tsx +321 -0
- package/templates/blocks/DD-AsideNav/config.ts +204 -0
- package/templates/blocks/DD-AsideNav/manifest.json +80 -0
- package/templates/blocks/DD-Banner/Component.tsx +51 -0
- package/templates/blocks/DD-Banner/config.ts +57 -0
- package/templates/blocks/DD-Banner/manifest.json +72 -0
- package/templates/blocks/DD-BgLightning/Component.tsx +44 -0
- package/templates/blocks/DD-BgLightning/README.md +3 -0
- package/templates/blocks/DD-BgLightning/config.ts +97 -0
- package/templates/blocks/DD-BgLightning/manifest.json +79 -0
- package/templates/blocks/DD-BookCall/Component.tsx +10 -11
- package/templates/blocks/DD-BookCall/config.ts +238 -238
- package/templates/blocks/DD-ButtonPop/Component.tsx +117 -0
- package/templates/blocks/DD-ButtonPop/config.ts +105 -0
- package/templates/blocks/DD-ButtonPop/manifest.json +88 -0
- package/templates/blocks/DD-ButtonPop/svg-icons/Dust2.tsx +167 -0
- package/templates/blocks/DD-Card/Component.tsx +251 -0
- package/templates/blocks/DD-Card/README.md +4 -0
- package/templates/blocks/DD-Card/config.ts +154 -0
- package/templates/blocks/DD-Card/manifest.json +82 -0
- package/templates/blocks/DD-CardTemplate01/Component.tsx +5 -6
- package/templates/blocks/DD-CardTemplate01/config.ts +106 -106
- package/templates/blocks/DD-Carousel-A/Component.tsx +249 -249
- package/templates/blocks/DD-Carousel-B/Component.tsx +403 -403
- package/templates/blocks/DD-Chip/Component.tsx +250 -0
- package/templates/blocks/DD-Chip/EXAMPLES.md +313 -0
- package/templates/blocks/DD-Chip/README.md +202 -0
- package/templates/blocks/DD-Chip/config.ts +369 -0
- package/templates/blocks/DD-Chip/manifest.json +74 -0
- package/templates/blocks/DD-ComparisonTable/Component.tsx +256 -256
- package/templates/blocks/DD-Contact/Component.tsx +434 -434
- package/templates/blocks/DD-Contact/config.ts +22 -22
- package/templates/blocks/DD-Counter/Component.tsx +190 -0
- package/templates/blocks/DD-Counter/README.md +4 -0
- package/templates/blocks/DD-Counter/config.ts +291 -0
- package/templates/blocks/DD-Counter/manifest.json +74 -0
- package/templates/blocks/DD-CustomCSS/Component.tsx +8 -0
- package/templates/blocks/DD-CustomCSS/README.md +4 -0
- package/templates/blocks/DD-CustomCSS/addToLayout.md +5 -0
- package/templates/blocks/DD-CustomCSS/config.ts +22 -0
- package/templates/blocks/DD-CustomCSS/manifest.json +72 -0
- package/templates/blocks/DD-CustomCSS/renderCustomCSS.md +7 -0
- package/templates/blocks/DD-FeatCat/Component.tsx +302 -302
- package/templates/blocks/DD-FeatCat/config.ts +201 -201
- package/templates/blocks/DD-FeatStrip/Component.tsx +585 -585
- package/templates/blocks/DD-FeatStrip/config.ts +134 -134
- package/templates/blocks/DD-FluidBtn/ButtonsEyeCatching.tsx +628 -0
- package/templates/blocks/DD-FluidBtn/Component.tsx +43 -0
- package/templates/blocks/DD-FluidBtn/README.md +6 -0
- package/templates/blocks/DD-FluidBtn/config.ts +102 -0
- package/templates/blocks/DD-FluidBtn/manifest.json +86 -0
- package/templates/blocks/DD-GooeyInfo/Component.tsx +149 -0
- package/templates/blocks/DD-GooeyInfo/config.ts +135 -0
- package/templates/blocks/DD-GooeyInfo/manifest.json +72 -0
- package/templates/blocks/DD-Hero/Component.tsx +40 -17
- package/templates/blocks/DD-Hero/config.ts +267 -267
- package/templates/blocks/DD-HorizontalScroll/Component.tsx +4 -2
- package/templates/blocks/DD-HorizontalScroll/config.ts +231 -231
- package/templates/blocks/DD-Icon/Component.tsx +287 -0
- package/templates/blocks/DD-Icon/README.md +4 -0
- package/templates/blocks/DD-Icon/config.ts +258 -0
- package/templates/blocks/DD-Icon/hooks/revalidateBlockIds.ts +66 -0
- package/templates/blocks/DD-Icon/manifest.json +82 -0
- package/templates/blocks/DD-IconButton/Component.tsx +455 -0
- package/templates/blocks/DD-IconButton/README.md +326 -0
- package/templates/blocks/DD-IconButton/config.ts +239 -0
- package/templates/blocks/DD-IconButton/manifest.json +85 -0
- package/templates/blocks/DD-IdTag/Component.tsx +21 -0
- package/templates/blocks/DD-IdTag/README.md +4 -0
- package/templates/blocks/DD-IdTag/config.ts +41 -0
- package/templates/blocks/DD-IdTag/manifest.json +72 -0
- package/templates/blocks/DD-Iframe/Component.tsx +45 -0
- package/templates/blocks/DD-Iframe/README.md +4 -0
- package/templates/blocks/DD-Iframe/config.ts +47 -0
- package/templates/blocks/DD-Iframe/manifest.json +72 -0
- package/templates/blocks/DD-IframeMedia/Component.tsx +129 -0
- package/templates/blocks/DD-IframeMedia/README.md +4 -0
- package/templates/blocks/DD-IframeMedia/config.ts +79 -0
- package/templates/blocks/DD-IframeMedia/manifest.json +72 -0
- package/templates/blocks/DD-LineAnim/Component.tsx +36 -0
- package/templates/blocks/DD-LineAnim/README.md +4 -0
- package/templates/blocks/DD-LineAnim/config.ts +90 -0
- package/templates/blocks/DD-LineAnim/manifest.json +80 -0
- package/templates/blocks/DD-LinkGrid/Component.tsx +119 -0
- package/templates/blocks/DD-LinkGrid/README.md +4 -0
- package/templates/blocks/DD-LinkGrid/config.ts +51 -0
- package/templates/blocks/DD-LinkGrid/manifest.json +74 -0
- package/templates/blocks/DD-LogoMarq/Component.tsx +132 -0
- package/templates/blocks/DD-LogoMarq/README.md +4 -0
- package/templates/blocks/DD-LogoMarq/config.ts +264 -0
- package/templates/blocks/DD-LogoMarq/manifest.json +82 -0
- package/templates/blocks/DD-Lottie/Component.tsx +459 -0
- package/templates/blocks/DD-Lottie/README.md +4 -0
- package/templates/blocks/DD-Lottie/config.ts +379 -0
- package/templates/blocks/DD-Lottie/index.tsx +28 -0
- package/templates/blocks/DD-Lottie/manifest.json +83 -0
- package/templates/blocks/DD-MagicBento/Component.tsx +777 -0
- package/templates/blocks/DD-MagicBento/README.md +4 -0
- package/templates/blocks/DD-MagicBento/config.ts +264 -0
- package/templates/blocks/DD-MagicBento/manifest.json +74 -0
- package/templates/blocks/DD-MasonaryMedia/Component.tsx +547 -545
- package/templates/blocks/DD-MasonaryMedia/config.ts +2 -2
- package/templates/blocks/DD-MasonaryMedia/vendor.d.ts +2 -2
- package/templates/blocks/DD-Masonry/Component.tsx +645 -0
- package/templates/blocks/DD-Masonry/README.md +4 -0
- package/templates/blocks/DD-Masonry/config.ts +475 -0
- package/templates/blocks/DD-Masonry/manifest.json +82 -0
- package/templates/blocks/DD-Pricing/Component.tsx +372 -372
- package/templates/blocks/DD-Process/Component.tsx +149 -149
- package/templates/blocks/DD-Process/config.ts +150 -150
- package/templates/blocks/DD-Progress/Component.tsx +141 -0
- package/templates/blocks/DD-Progress/README.md +4 -0
- package/templates/blocks/DD-Progress/config.ts +175 -0
- package/templates/blocks/DD-Progress/manifest.json +74 -0
- package/templates/blocks/DD-ProjHeader/Component.tsx +91 -0
- package/templates/blocks/DD-ProjHeader/README.md +4 -0
- package/templates/blocks/DD-ProjHeader/config.ts +96 -0
- package/templates/blocks/DD-ProjHeader/manifest.json +72 -0
- package/templates/blocks/DD-ProjSlider/Component.tsx +123 -0
- package/templates/blocks/DD-ProjSlider/README.md +4 -0
- package/templates/blocks/DD-ProjSlider/config.ts +64 -0
- package/templates/blocks/DD-ProjSlider/manifest.json +72 -0
- package/templates/blocks/DD-ScrollText/Component.tsx +114 -0
- package/templates/blocks/DD-ScrollText/README.md +4 -0
- package/templates/blocks/DD-ScrollText/config.ts +58 -0
- package/templates/blocks/DD-ScrollText/manifest.json +72 -0
- package/templates/blocks/DD-Section/Component.tsx +266 -266
- package/templates/blocks/DD-Separator/Component.tsx +66 -0
- package/templates/blocks/DD-Separator/README.md +4 -0
- package/templates/blocks/DD-Separator/config.ts +58 -0
- package/templates/blocks/DD-Separator/manifest.json +72 -0
- package/templates/blocks/DD-Services/Component.tsx +176 -176
- package/templates/blocks/DD-Services/config.ts +149 -149
- package/templates/blocks/DD-ShowcaseGrid/Component.tsx +307 -307
- package/templates/blocks/DD-Slider-A/Component.tsx +237 -237
- package/templates/blocks/DD-StackCards/Component.tsx +473 -473
- package/templates/blocks/DD-StackCards/config.ts +399 -399
- package/templates/blocks/DD-Team/Component.tsx +247 -247
- package/templates/blocks/DD-Team/config.ts +173 -173
- package/templates/blocks/DD-TeamCards/Component.tsx +251 -0
- package/templates/blocks/DD-TeamCards/README.md +4 -0
- package/templates/blocks/DD-TeamCards/config.ts +302 -0
- package/templates/blocks/DD-TeamCards/manifest.json +74 -0
- package/templates/blocks/DD-TechStack/Component.tsx +168 -162
- package/templates/blocks/DD-TechStack/config.ts +153 -153
- package/templates/blocks/DD-TestMarq/Component.tsx +132 -0
- package/templates/blocks/DD-TestMarq/README.md +4 -0
- package/templates/blocks/DD-TestMarq/RowLabel.tsx +9 -0
- package/templates/blocks/DD-TestMarq/config.ts +88 -0
- package/templates/blocks/DD-TestMarq/manifest.json +72 -0
- package/templates/blocks/DD-Testim/Component.tsx +247 -0
- package/templates/blocks/DD-Testim/README.md +4 -0
- package/templates/blocks/DD-Testim/config.ts +101 -0
- package/templates/blocks/DD-Testim/manifest.json +75 -0
- package/templates/blocks/DD-Testim2/Component.tsx +256 -0
- package/templates/blocks/DD-Testim2/README.md +4 -0
- package/templates/blocks/DD-Testim2/config.ts +100 -0
- package/templates/blocks/DD-Testim2/manifest.json +74 -0
- package/templates/blocks/DD-Testimonials/Component.tsx +147 -147
- package/templates/blocks/DD-Testimonials/config.ts +120 -120
- package/templates/blocks/DD-TextMarq/Component.tsx +157 -0
- package/templates/blocks/DD-TextMarq/README.md +4 -0
- package/templates/blocks/DD-TextMarq/config.ts +237 -0
- package/templates/blocks/DD-TextMarq/manifest.json +82 -0
- package/templates/blocks/DD-Thanks/Component.tsx +500 -0
- package/templates/blocks/DD-Thanks/README.md +4 -0
- package/templates/blocks/DD-Thanks/config.ts +224 -0
- package/templates/blocks/DD-Thanks/manifest.json +72 -0
- package/templates/blocks/DD-VertMarq/Component.tsx +154 -0
- package/templates/blocks/DD-VertMarq/README.md +4 -0
- package/templates/blocks/DD-VertMarq/config.ts +236 -0
- package/templates/blocks/DD-VertMarq/dist/index.css +6 -0
- package/templates/blocks/DD-VertMarq/dist/index.min.css +1 -0
- package/templates/blocks/DD-VertMarq/manifest.json +74 -0
- package/templates/blocks/DD-Work/Component.tsx +318 -315
- package/templates/blocks/DD-Work/config.ts +165 -165
- package/templates/blocks/DD-Work-B/Component.tsx +294 -294
- package/templates/blocks/DDHG-CTASection2/Component.tsx +185 -0
- package/templates/blocks/DDHG-CTASection2/config.ts +140 -0
- package/templates/blocks/DDHG-CTASection2/manifest.json +45 -0
- package/templates/blocks/DDHG-HighlightArc/Component.tsx +243 -0
- package/templates/blocks/DDHG-HighlightArc/config.ts +85 -0
- package/templates/blocks/DDHG-HighlightArc/manifest.json +46 -0
- package/templates/blocks/DDHG-LogoMarquee/Component.tsx +93 -0
- package/templates/blocks/DDHG-LogoMarquee/config.ts +66 -0
- package/templates/blocks/DDHG-LogoMarquee/manifest.json +39 -0
- package/templates/blocks/DDHG-NavCodeGrid/Component.tsx +213 -0
- package/templates/blocks/DDHG-NavCodeGrid/config.ts +64 -0
- package/templates/blocks/DDHG-NavCodeGrid/manifest.json +45 -0
- package/templates/blocks/DDHG-ProcessSec/Component.tsx +575 -0
- package/templates/blocks/DDHG-ProcessSec/config.ts +170 -0
- package/templates/blocks/DDHG-ProcessSec/manifest.json +56 -0
- package/templates/blocks/DDHG-ServiceDetails/Component.tsx +164 -0
- package/templates/blocks/DDHG-ServiceDetails/ServiceDetailCard.tsx +394 -0
- package/templates/blocks/DDHG-ServiceDetails/config.ts +77 -0
- package/templates/blocks/DDHG-ServiceDetails/manifest.json +50 -0
- package/templates/blocks/DDHG-ServiceHero/Component.tsx +234 -0
- package/templates/blocks/DDHG-ServiceHero/config.ts +49 -0
- package/templates/blocks/DDHG-ServiceHero/manifest.json +26 -0
- package/templates/blocks/DDHG-ServiceOverview/Component.tsx +277 -0
- package/templates/blocks/DDHG-ServiceOverview/config.ts +64 -0
- package/templates/blocks/DDHG-ServiceOverview/manifest.json +44 -0
- package/templates/blocks/DDHG-StatsFAQ/Component.tsx +389 -0
- package/templates/blocks/DDHG-StatsFAQ/config.ts +204 -0
- package/templates/blocks/DDHG-StatsFAQ/manifest.json +45 -0
- package/templates/blocks/DDHG-TeamCards/Component.tsx +131 -0
- package/templates/blocks/DDHG-TeamCards/config.ts +48 -0
- package/templates/blocks/DDHG-TeamCards/manifest.json +29 -0
- package/templates/components/HeaderDD02/MobileBottomNav/index.tsx +352 -257
- package/templates/components/HeaderDD02/index.tsx +313 -229
- package/templates/shared/src/components/BgLightning/index.tsx +242 -0
- package/templates/shared/src/components/ui/ShareButton/index.tsx +80 -0
- package/templates/shared/src/components/ui/anims/FadeOnScroll.tsx +48 -0
- package/templates/shared/src/components/ui/anims/FadeUpOnInView.tsx +63 -0
- package/templates/shared/src/components/ui/anims/GlareHover.tsx +111 -0
- package/templates/shared/src/components/ui/anims/LineAnims.tsx +81 -0
- package/templates/shared/src/components/ui/anims/TitleAnims01.tsx +54 -0
- package/templates/shared/src/components/ui/anims/animation-container.tsx +29 -0
- package/templates/shared/src/components/ui/anims/blur-in.tsx +26 -0
- package/templates/shared/src/components/ui/anims/counter.tsx +53 -0
- package/templates/shared/src/components/ui/anims/fade.tsx +83 -0
- package/templates/shared/src/components/ui/anims/gradual-spacing.tsx +39 -0
- package/templates/shared/src/components/ui/anims/pull-up.tsx +93 -0
- package/templates/shared/src/components/ui/anims/reveal-text.tsx +76 -0
- package/templates/shared/src/components/ui/anims/rotate-words.tsx +43 -0
- package/templates/shared/src/components/ui/anims/shiny-text.tsx +58 -0
- package/templates/shared/src/components/ui/anims/shuffle-text.tsx +85 -0
- package/templates/shared/src/components/ui/anims/split-text.tsx +211 -0
- package/templates/shared/src/components/ui/anims/staggered-fade.tsx +133 -0
- package/templates/shared/src/components/ui/anims/text-scroll.tsx +111 -0
- package/templates/shared/src/components/ui/anims/typing-effect.tsx +112 -0
- package/templates/shared/src/components/ui/button-dusted-fluid/index.tsx +1521 -0
- package/templates/shared/src/components/ui/separator.tsx +85 -0
- package/templates/shared/src/hooks/useBodyScrollLock.ts +97 -0
- package/templates/shared/src/hooks/useClickOutside.ts +28 -0
- package/templates/shared/src/utilities/renderCustomCSS.ts +5 -0
- package/templates/shared/src/utilities/smoothScroll.ts +65 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React, { useRef, useEffect } from 'react'
|
|
4
|
+
|
|
5
|
+
interface BgLightningProps {
|
|
6
|
+
hue?: number
|
|
7
|
+
xOffset?: number
|
|
8
|
+
speed?: number
|
|
9
|
+
intensity?: number
|
|
10
|
+
size?: number
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const BgLightning: React.FC<BgLightningProps> = ({
|
|
14
|
+
hue = 230,
|
|
15
|
+
xOffset = 0,
|
|
16
|
+
speed = 1,
|
|
17
|
+
intensity = 1,
|
|
18
|
+
size = 1
|
|
19
|
+
}) => {
|
|
20
|
+
const canvasRef = useRef<HTMLCanvasElement>(null)
|
|
21
|
+
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
const canvas = canvasRef.current
|
|
24
|
+
if (!canvas) return
|
|
25
|
+
|
|
26
|
+
let frameId = 0
|
|
27
|
+
let disposed = false
|
|
28
|
+
|
|
29
|
+
const gl = canvas.getContext('webgl', {
|
|
30
|
+
alpha: true,
|
|
31
|
+
premultipliedAlpha: false
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
if (!gl) {
|
|
35
|
+
console.error('WebGL not supported')
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const resizeCanvas = () => {
|
|
40
|
+
const width = canvas.clientWidth
|
|
41
|
+
const height = canvas.clientHeight
|
|
42
|
+
|
|
43
|
+
if (canvas.width !== width || canvas.height !== height) {
|
|
44
|
+
canvas.width = width
|
|
45
|
+
canvas.height = height
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
resizeCanvas()
|
|
50
|
+
window.addEventListener('resize', resizeCanvas)
|
|
51
|
+
|
|
52
|
+
const vertexShaderSource = `
|
|
53
|
+
attribute vec2 aPosition;
|
|
54
|
+
|
|
55
|
+
void main() {
|
|
56
|
+
gl_Position = vec4(aPosition, 0.0, 1.0);
|
|
57
|
+
}
|
|
58
|
+
`
|
|
59
|
+
|
|
60
|
+
const fragmentShaderSource = `
|
|
61
|
+
precision mediump float;
|
|
62
|
+
|
|
63
|
+
uniform vec2 iResolution;
|
|
64
|
+
uniform float iTime;
|
|
65
|
+
uniform float uHue;
|
|
66
|
+
uniform float uXOffset;
|
|
67
|
+
uniform float uSpeed;
|
|
68
|
+
uniform float uIntensity;
|
|
69
|
+
uniform float uSize;
|
|
70
|
+
|
|
71
|
+
#define OCTAVE_COUNT 10
|
|
72
|
+
|
|
73
|
+
vec3 hsv2rgb(vec3 c) {
|
|
74
|
+
vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0,4.0,2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);
|
|
75
|
+
return c.z * mix(vec3(1.0), rgb, c.y);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
float hash11(float p) {
|
|
79
|
+
p = fract(p * .1031);
|
|
80
|
+
p *= p + 33.33;
|
|
81
|
+
p *= p + p;
|
|
82
|
+
return fract(p);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
float hash12(vec2 p) {
|
|
86
|
+
vec3 p3 = fract(vec3(p.xyx) * .1031);
|
|
87
|
+
p3 += dot(p3, p3.yzx + 33.33);
|
|
88
|
+
return fract((p3.x + p3.y) * p3.z);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
mat2 rotate2d(float theta) {
|
|
92
|
+
float c = cos(theta);
|
|
93
|
+
float s = sin(theta);
|
|
94
|
+
return mat2(c, -s, s, c);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
float noise(vec2 p) {
|
|
98
|
+
vec2 ip = floor(p);
|
|
99
|
+
vec2 fp = fract(p);
|
|
100
|
+
|
|
101
|
+
float a = hash12(ip);
|
|
102
|
+
float b = hash12(ip + vec2(1.0, 0.0));
|
|
103
|
+
float c = hash12(ip + vec2(0.0, 1.0));
|
|
104
|
+
float d = hash12(ip + vec2(1.0, 1.0));
|
|
105
|
+
|
|
106
|
+
vec2 t = smoothstep(0.0, 1.0, fp);
|
|
107
|
+
|
|
108
|
+
return mix(mix(a, b, t.x), mix(c, d, t.x), t.y);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
float fbm(vec2 p) {
|
|
112
|
+
float value = 0.0;
|
|
113
|
+
float amplitude = 0.5;
|
|
114
|
+
|
|
115
|
+
for (int i = 0; i < OCTAVE_COUNT; ++i) {
|
|
116
|
+
value += amplitude * noise(p);
|
|
117
|
+
p *= rotate2d(0.45);
|
|
118
|
+
p *= 2.0;
|
|
119
|
+
amplitude *= 0.5;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return value;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
|
126
|
+
vec2 uv = fragCoord / iResolution.xy;
|
|
127
|
+
uv = 2.0 * uv - 1.0;
|
|
128
|
+
uv.x *= iResolution.x / iResolution.y;
|
|
129
|
+
uv.x += uXOffset;
|
|
130
|
+
|
|
131
|
+
uv += 2.0 * fbm(uv * uSize + 0.8 * iTime * uSpeed) - 1.0;
|
|
132
|
+
|
|
133
|
+
float dist = max(abs(uv.x), 0.001);
|
|
134
|
+
vec3 baseColor = hsv2rgb(vec3(uHue / 360.0, 0.7, 0.8));
|
|
135
|
+
vec3 col = baseColor * pow(mix(0.0, 0.07, hash11(iTime * uSpeed)) / dist, 1.0) * uIntensity;
|
|
136
|
+
|
|
137
|
+
float a = clamp(max(col.r, max(col.g, col.b)), 0.0, 1.0);
|
|
138
|
+
fragColor = vec4(col, a);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
void main() {
|
|
142
|
+
mainImage(gl_FragColor, gl_FragCoord.xy);
|
|
143
|
+
}
|
|
144
|
+
`
|
|
145
|
+
|
|
146
|
+
const compileShader = (source: string, type: number) => {
|
|
147
|
+
const shader = gl.createShader(type)
|
|
148
|
+
if (!shader) return null
|
|
149
|
+
|
|
150
|
+
gl.shaderSource(shader, source)
|
|
151
|
+
gl.compileShader(shader)
|
|
152
|
+
|
|
153
|
+
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
154
|
+
console.error('Shader compile error:', gl.getShaderInfoLog(shader))
|
|
155
|
+
gl.deleteShader(shader)
|
|
156
|
+
return null
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return shader
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const vertexShader = compileShader(vertexShaderSource, gl.VERTEX_SHADER)
|
|
163
|
+
const fragmentShader = compileShader(fragmentShaderSource, gl.FRAGMENT_SHADER)
|
|
164
|
+
|
|
165
|
+
if (!vertexShader || !fragmentShader) return
|
|
166
|
+
|
|
167
|
+
const program = gl.createProgram()
|
|
168
|
+
if (!program) return
|
|
169
|
+
|
|
170
|
+
gl.attachShader(program, vertexShader)
|
|
171
|
+
gl.attachShader(program, fragmentShader)
|
|
172
|
+
gl.linkProgram(program)
|
|
173
|
+
|
|
174
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
175
|
+
console.error('Program linking error:', gl.getProgramInfoLog(program))
|
|
176
|
+
gl.deleteProgram(program)
|
|
177
|
+
return
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const vertices = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1])
|
|
181
|
+
|
|
182
|
+
const vertexBuffer = gl.createBuffer()
|
|
183
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer)
|
|
184
|
+
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)
|
|
185
|
+
|
|
186
|
+
const aPosition = gl.getAttribLocation(program, 'aPosition')
|
|
187
|
+
|
|
188
|
+
if (aPosition >= 0) {
|
|
189
|
+
gl.useProgram(program)
|
|
190
|
+
gl.enableVertexAttribArray(aPosition)
|
|
191
|
+
gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const iResolutionLocation = gl.getUniformLocation(program, 'iResolution')
|
|
195
|
+
const iTimeLocation = gl.getUniformLocation(program, 'iTime')
|
|
196
|
+
const uHueLocation = gl.getUniformLocation(program, 'uHue')
|
|
197
|
+
const uXOffsetLocation = gl.getUniformLocation(program, 'uXOffset')
|
|
198
|
+
const uSpeedLocation = gl.getUniformLocation(program, 'uSpeed')
|
|
199
|
+
const uIntensityLocation = gl.getUniformLocation(program, 'uIntensity')
|
|
200
|
+
const uSizeLocation = gl.getUniformLocation(program, 'uSize')
|
|
201
|
+
|
|
202
|
+
const startTime = performance.now()
|
|
203
|
+
|
|
204
|
+
const render = () => {
|
|
205
|
+
if (disposed) return
|
|
206
|
+
|
|
207
|
+
resizeCanvas()
|
|
208
|
+
|
|
209
|
+
gl.useProgram(program)
|
|
210
|
+
gl.viewport(0, 0, canvas.width, canvas.height)
|
|
211
|
+
|
|
212
|
+
if (iResolutionLocation) gl.uniform2f(iResolutionLocation, canvas.width, canvas.height)
|
|
213
|
+
if (iTimeLocation) gl.uniform1f(iTimeLocation, (performance.now() - startTime) / 1000)
|
|
214
|
+
if (uHueLocation) gl.uniform1f(uHueLocation, hue)
|
|
215
|
+
if (uXOffsetLocation) gl.uniform1f(uXOffsetLocation, xOffset)
|
|
216
|
+
if (uSpeedLocation) gl.uniform1f(uSpeedLocation, speed)
|
|
217
|
+
if (uIntensityLocation) gl.uniform1f(uIntensityLocation, intensity)
|
|
218
|
+
if (uSizeLocation) gl.uniform1f(uSizeLocation, size)
|
|
219
|
+
|
|
220
|
+
gl.drawArrays(gl.TRIANGLES, 0, 6)
|
|
221
|
+
|
|
222
|
+
frameId = requestAnimationFrame(render)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
frameId = requestAnimationFrame(render)
|
|
226
|
+
|
|
227
|
+
return () => {
|
|
228
|
+
disposed = true
|
|
229
|
+
cancelAnimationFrame(frameId)
|
|
230
|
+
window.removeEventListener('resize', resizeCanvas)
|
|
231
|
+
|
|
232
|
+
gl.deleteBuffer(vertexBuffer)
|
|
233
|
+
gl.deleteShader(vertexShader)
|
|
234
|
+
gl.deleteShader(fragmentShader)
|
|
235
|
+
gl.deleteProgram(program)
|
|
236
|
+
}
|
|
237
|
+
}, [hue, xOffset, speed, intensity, size])
|
|
238
|
+
|
|
239
|
+
return <canvas ref={canvasRef} className="relative h-full w-full" />
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export default BgLightning
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React, { useState } from 'react'
|
|
4
|
+
import { LucideIcon } from 'lucide-react'
|
|
5
|
+
|
|
6
|
+
import { cn } from '@/utilities/ui'
|
|
7
|
+
import { Button } from '@/components/ui/button'
|
|
8
|
+
|
|
9
|
+
interface ShareLink {
|
|
10
|
+
icon: LucideIcon
|
|
11
|
+
href?: string
|
|
12
|
+
onClick?: () => void
|
|
13
|
+
label?: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface ShareButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
17
|
+
links: ShareLink[]
|
|
18
|
+
children: React.ReactNode
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const ShareButton = ({ className, links, children, ...props }: ShareButtonProps) => {
|
|
22
|
+
const [isHovered, setIsHovered] = useState(false)
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<div
|
|
26
|
+
className="relative"
|
|
27
|
+
onMouseEnter={() => setIsHovered(true)}
|
|
28
|
+
onMouseLeave={() => setIsHovered(false)}
|
|
29
|
+
>
|
|
30
|
+
<Button
|
|
31
|
+
className={cn(
|
|
32
|
+
'relative min-w-40 rounded-3xl ',
|
|
33
|
+
'bg-white dark:bg-black',
|
|
34
|
+
'hover:bg-gray-50 dark:hover:bg-gray-950',
|
|
35
|
+
'text-stone-200 dark:text-stone-200',
|
|
36
|
+
'border border-black/10 dark:border-white/10',
|
|
37
|
+
'transition-all duration-300',
|
|
38
|
+
isHovered ? 'opacity-0' : 'opacity-100',
|
|
39
|
+
className
|
|
40
|
+
)}
|
|
41
|
+
{...props}
|
|
42
|
+
>
|
|
43
|
+
<span className="flex items-center gap-2">{children}</span>
|
|
44
|
+
</Button>
|
|
45
|
+
|
|
46
|
+
<div className="absolute left-0 top-0 flex h-10">
|
|
47
|
+
{links.map((link, index) => {
|
|
48
|
+
const Icon = link.icon
|
|
49
|
+
return (
|
|
50
|
+
<button
|
|
51
|
+
type="button"
|
|
52
|
+
key={index}
|
|
53
|
+
onClick={link.onClick}
|
|
54
|
+
className={cn(
|
|
55
|
+
'h-10',
|
|
56
|
+
'w-10',
|
|
57
|
+
'flex items-center justify-center',
|
|
58
|
+
'bg-black dark:bg-white',
|
|
59
|
+
'text-white dark:text-black',
|
|
60
|
+
'transition-all duration-300',
|
|
61
|
+
index === 0 && 'rounded-l-3xl',
|
|
62
|
+
index === links.length - 1 && 'rounded-r-3xl',
|
|
63
|
+
'border-r border-white/10 last:border-r-0 dark:border-black/10',
|
|
64
|
+
'hover:bg-gray-900 dark:hover:bg-gray-100',
|
|
65
|
+
'',
|
|
66
|
+
isHovered ? 'translate-x-0 opacity-100' : '-translate-x-full opacity-0',
|
|
67
|
+
index === 0 && 'transition-all duration-200',
|
|
68
|
+
index === 1 && 'delay-\\[50ms\\] transition-all duration-200',
|
|
69
|
+
index === 2 && 'transition-all delay-100 duration-200',
|
|
70
|
+
index === 3 && 'transition-all delay-150 duration-200'
|
|
71
|
+
)}
|
|
72
|
+
>
|
|
73
|
+
<Icon className="size-4" />
|
|
74
|
+
</button>
|
|
75
|
+
)
|
|
76
|
+
})}
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
)
|
|
80
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React, { useEffect, useRef, useState } from 'react'
|
|
4
|
+
import { motion, useScroll, useTransform } from 'framer-motion'
|
|
5
|
+
|
|
6
|
+
interface FadeOnScrollProps {
|
|
7
|
+
children: React.ReactNode
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const FadeOnScroll: React.FC<FadeOnScrollProps> = ({ children }) => {
|
|
11
|
+
const containerRef = useRef<HTMLDivElement>(null)
|
|
12
|
+
const [targetRef, setTargetRef] = useState<HTMLElement | null>(null)
|
|
13
|
+
|
|
14
|
+
// Bind scroll tracking only when ready
|
|
15
|
+
const scrollSetupRef = useRef(false)
|
|
16
|
+
const { scrollYProgress } = useScroll({
|
|
17
|
+
target: targetRef ? { current: targetRef } : undefined,
|
|
18
|
+
offset: ['start 50%', 'start 0%'],
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
const opacity = useTransform(scrollYProgress, [0, 1], [1, 0])
|
|
22
|
+
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (typeof window === 'undefined') return
|
|
25
|
+
|
|
26
|
+
const container = containerRef.current
|
|
27
|
+
if (!container) return
|
|
28
|
+
|
|
29
|
+
const parent = container.closest('.renderblock-container')
|
|
30
|
+
if (!parent) return
|
|
31
|
+
|
|
32
|
+
let sibling = parent.nextElementSibling as HTMLElement | null
|
|
33
|
+
while (sibling && !sibling.classList.contains('renderblock-container')) {
|
|
34
|
+
sibling = sibling.nextElementSibling as HTMLElement | null
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (sibling && !scrollSetupRef.current) {
|
|
38
|
+
setTargetRef(sibling)
|
|
39
|
+
scrollSetupRef.current = true
|
|
40
|
+
}
|
|
41
|
+
}, [])
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<motion.div ref={containerRef} style={{ opacity }}>
|
|
45
|
+
{children}
|
|
46
|
+
</motion.div>
|
|
47
|
+
)
|
|
48
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import React, { useRef, useEffect, useState, ReactNode } from 'react'
|
|
3
|
+
import { motion } from 'framer-motion'
|
|
4
|
+
import { cn } from '@/utilities/ui'
|
|
5
|
+
|
|
6
|
+
interface FadeUpOnInViewProps {
|
|
7
|
+
children: ReactNode
|
|
8
|
+
delay?: number
|
|
9
|
+
className?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const FadeUpOnInView: React.FC<FadeUpOnInViewProps> = ({ children, delay, className }) => {
|
|
13
|
+
const ref = useRef<HTMLDivElement | null>(null)
|
|
14
|
+
const [isVisible, setIsVisible] = useState(false)
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (!ref.current) return
|
|
18
|
+
const target = ref.current
|
|
19
|
+
const observer = new IntersectionObserver(
|
|
20
|
+
(entries) => {
|
|
21
|
+
if (entries && entries.length > 0 && entries[0]) {
|
|
22
|
+
setIsVisible(!!entries[0].isIntersecting)
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
root: null,
|
|
27
|
+
rootMargin: '0px',
|
|
28
|
+
threshold: 0.5
|
|
29
|
+
}
|
|
30
|
+
)
|
|
31
|
+
observer.observe(target)
|
|
32
|
+
return () => {
|
|
33
|
+
observer.disconnect()
|
|
34
|
+
}
|
|
35
|
+
}, [])
|
|
36
|
+
|
|
37
|
+
// Defensive: Only allow number and >= 0 for delay
|
|
38
|
+
const animationDelay = typeof delay === 'number' && !isNaN(delay) && delay >= 0 ? delay : 0
|
|
39
|
+
|
|
40
|
+
// Defensive: Only render children if defined
|
|
41
|
+
const safeChildren = children === undefined || children === null ? null : children
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<motion.div
|
|
45
|
+
className={cn('fadeupInView', className)}
|
|
46
|
+
ref={ref}
|
|
47
|
+
initial={{ opacity: 0, y: 40 }}
|
|
48
|
+
animate={{
|
|
49
|
+
opacity: isVisible ? 1 : 0,
|
|
50
|
+
y: isVisible ? 0 : 40
|
|
51
|
+
}}
|
|
52
|
+
exit={{ opacity: 0, y: 40 }}
|
|
53
|
+
transition={{
|
|
54
|
+
duration: 0.3,
|
|
55
|
+
delay: animationDelay
|
|
56
|
+
}}
|
|
57
|
+
>
|
|
58
|
+
{safeChildren}
|
|
59
|
+
</motion.div>
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export default FadeUpOnInView
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
2
|
+
'use client'
|
|
3
|
+
import React, { useRef } from 'react'
|
|
4
|
+
|
|
5
|
+
interface GlareHoverProps {
|
|
6
|
+
width?: string
|
|
7
|
+
height?: string
|
|
8
|
+
background?: string
|
|
9
|
+
borderRadius?: string
|
|
10
|
+
borderColor?: string
|
|
11
|
+
children?: React.ReactNode
|
|
12
|
+
glareColor?: string
|
|
13
|
+
glareOpacity?: number
|
|
14
|
+
glareAngle?: number
|
|
15
|
+
glareSize?: number
|
|
16
|
+
transitionDuration?: number
|
|
17
|
+
playOnce?: boolean
|
|
18
|
+
className?: string
|
|
19
|
+
style?: React.CSSProperties
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const GlareHover: React.FC<GlareHoverProps> = ({
|
|
23
|
+
width = 'auto',
|
|
24
|
+
height = 'auto',
|
|
25
|
+
background = 'transparent',
|
|
26
|
+
borderRadius = '0',
|
|
27
|
+
borderColor = 'transparent',
|
|
28
|
+
children,
|
|
29
|
+
glareColor = '#ffffff69',
|
|
30
|
+
glareOpacity = 0.5,
|
|
31
|
+
glareAngle = -45,
|
|
32
|
+
glareSize = 250,
|
|
33
|
+
transitionDuration = 650,
|
|
34
|
+
playOnce = false,
|
|
35
|
+
className = '',
|
|
36
|
+
style = {},
|
|
37
|
+
}) => {
|
|
38
|
+
const hex = glareColor.replace('#', '')
|
|
39
|
+
let rgba = glareColor
|
|
40
|
+
if (/^[\dA-Fa-f]{6}$/.test(hex)) {
|
|
41
|
+
const r = parseInt(hex.slice(0, 2), 16)
|
|
42
|
+
const g = parseInt(hex.slice(2, 4), 16)
|
|
43
|
+
const b = parseInt(hex.slice(4, 6), 16)
|
|
44
|
+
rgba = `rgba(${r}, ${g}, ${b}, ${glareOpacity})`
|
|
45
|
+
} else if (/^[\dA-Fa-f]{3}$/.test(hex) && hex.length === 3) {
|
|
46
|
+
const r = parseInt(hex[0]! + hex[0]!, 16)
|
|
47
|
+
const g = parseInt(hex[1]! + hex[1]!, 16)
|
|
48
|
+
const b = parseInt(hex[2]! + hex[2]!, 16)
|
|
49
|
+
rgba = `rgba(${r}, ${g}, ${b}, ${glareOpacity})`
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const overlayRef = useRef<HTMLDivElement | null>(null)
|
|
53
|
+
|
|
54
|
+
const animateIn = () => {
|
|
55
|
+
const el = overlayRef.current
|
|
56
|
+
if (!el) return
|
|
57
|
+
|
|
58
|
+
el.style.transition = 'none'
|
|
59
|
+
el.style.backgroundPosition = '-100% -100%, 0 0'
|
|
60
|
+
el.offsetHeight
|
|
61
|
+
el.style.transition = `${transitionDuration}ms ease`
|
|
62
|
+
el.style.backgroundPosition = '100% 100%, 0 0'
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const animateOut = () => {
|
|
66
|
+
const el = overlayRef.current
|
|
67
|
+
if (!el) return
|
|
68
|
+
|
|
69
|
+
if (playOnce) {
|
|
70
|
+
el.style.transition = 'none'
|
|
71
|
+
el.style.backgroundPosition = '-100% -100%, 0 0'
|
|
72
|
+
} else {
|
|
73
|
+
el.style.transition = `${transitionDuration}ms ease`
|
|
74
|
+
el.style.backgroundPosition = '-100% -100%, 0 0'
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const overlayStyle: React.CSSProperties = {
|
|
79
|
+
position: 'absolute',
|
|
80
|
+
inset: 0,
|
|
81
|
+
background: `linear-gradient(${glareAngle}deg,
|
|
82
|
+
hsla(0,0%,0%,0) 60%,
|
|
83
|
+
${rgba} 70%,
|
|
84
|
+
hsla(0,0%,0%,0) 100%)`,
|
|
85
|
+
backgroundSize: `${glareSize}% ${glareSize}%, 100% 100%`,
|
|
86
|
+
backgroundRepeat: 'no-repeat',
|
|
87
|
+
backgroundPosition: '-100% -100%, 0 0',
|
|
88
|
+
pointerEvents: 'none',
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<div
|
|
93
|
+
className={`relative grid place-items-center overflow-hidden border cursor-pointer ${className}`}
|
|
94
|
+
style={{
|
|
95
|
+
width,
|
|
96
|
+
height,
|
|
97
|
+
background,
|
|
98
|
+
borderRadius,
|
|
99
|
+
borderColor,
|
|
100
|
+
...style,
|
|
101
|
+
}}
|
|
102
|
+
onMouseEnter={animateIn}
|
|
103
|
+
onMouseLeave={animateOut}
|
|
104
|
+
>
|
|
105
|
+
<div ref={overlayRef} style={overlayStyle} />
|
|
106
|
+
{children}
|
|
107
|
+
</div>
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export default GlareHover
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import React, { useEffect, useRef } from 'react'
|
|
3
|
+
import { gsap } from 'gsap'
|
|
4
|
+
import { ScrollTrigger } from 'gsap/ScrollTrigger'
|
|
5
|
+
|
|
6
|
+
gsap.registerPlugin(ScrollTrigger)
|
|
7
|
+
|
|
8
|
+
interface LineAnimProps {
|
|
9
|
+
direction: 'left-to-right' | 'right-to-left' | 'top-to-bottom' | 'bottom-to-top'
|
|
10
|
+
className?: string
|
|
11
|
+
trigger?: 'scroll' | 'immediate'
|
|
12
|
+
duration?: number
|
|
13
|
+
delay?: number
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const LineAnim: React.FC<LineAnimProps> = ({
|
|
17
|
+
direction,
|
|
18
|
+
className = '',
|
|
19
|
+
trigger = 'scroll',
|
|
20
|
+
duration = 1,
|
|
21
|
+
delay = 0
|
|
22
|
+
}) => {
|
|
23
|
+
const lineRef = useRef<HTMLDivElement>(null)
|
|
24
|
+
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (!lineRef.current) return
|
|
27
|
+
|
|
28
|
+
const isVertical = direction.includes('top') || direction.includes('bottom')
|
|
29
|
+
const scale = isVertical ? 'scaleY' : 'scaleX'
|
|
30
|
+
|
|
31
|
+
const animation = gsap.fromTo(
|
|
32
|
+
lineRef.current,
|
|
33
|
+
{ [scale]: 0, opacity: 1 },
|
|
34
|
+
{
|
|
35
|
+
[scale]: 1,
|
|
36
|
+
opacity: 1,
|
|
37
|
+
duration,
|
|
38
|
+
delay,
|
|
39
|
+
ease: 'power2.out',
|
|
40
|
+
...(trigger === 'scroll' && {
|
|
41
|
+
scrollTrigger: {
|
|
42
|
+
trigger: lineRef.current,
|
|
43
|
+
start: 'top 100%'
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
return () => {
|
|
50
|
+
animation.kill()
|
|
51
|
+
ScrollTrigger.getAll().forEach((trigger) => trigger.kill())
|
|
52
|
+
}
|
|
53
|
+
}, [direction, trigger, duration, delay])
|
|
54
|
+
|
|
55
|
+
const getLineClasses = () => {
|
|
56
|
+
const baseClasses = 'bg-transparent opacity-0'
|
|
57
|
+
|
|
58
|
+
switch (direction) {
|
|
59
|
+
case 'left-to-right':
|
|
60
|
+
return `h-[1px] w-screen origin-left ${baseClasses}`
|
|
61
|
+
case 'right-to-left':
|
|
62
|
+
return `h-[1px] w-screen origin-right ${baseClasses}`
|
|
63
|
+
case 'top-to-bottom':
|
|
64
|
+
return `w-[1px] h-screen origin-top ${baseClasses}`
|
|
65
|
+
case 'bottom-to-top':
|
|
66
|
+
return `w-[1px] h-screen origin-bottom ${baseClasses}`
|
|
67
|
+
default:
|
|
68
|
+
return baseClasses
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<div
|
|
74
|
+
ref={lineRef}
|
|
75
|
+
className={`${getLineClasses()} ${className}`}
|
|
76
|
+
style={{ transition: 'all 0.3s' }}
|
|
77
|
+
/>
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export default LineAnim
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React, { useEffect, useRef, ReactNode } from 'react'
|
|
2
|
+
import { motion } from 'framer-motion'
|
|
3
|
+
|
|
4
|
+
interface TitleAnims01Props {
|
|
5
|
+
children: ReactNode
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const TitleAnims01: React.FC<TitleAnims01Props> = ({ children }) => {
|
|
9
|
+
const ref = useRef<HTMLDivElement>(null)
|
|
10
|
+
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
const spanText = (text: HTMLElement) => {
|
|
13
|
+
const string = text.innerText
|
|
14
|
+
let spaned = ''
|
|
15
|
+
for (let i = 0; i < string.length; i++) {
|
|
16
|
+
if (string.substring(i, i + 1) === ' ') spaned += string.substring(i, i + 1)
|
|
17
|
+
else spaned += '<span>' + string.substring(i, i + 1) + '</span>'
|
|
18
|
+
}
|
|
19
|
+
text.innerHTML = spaned
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const headline = ref.current
|
|
23
|
+
if (!headline) return
|
|
24
|
+
spanText(headline)
|
|
25
|
+
|
|
26
|
+
const animations = headline.querySelectorAll('.animation')
|
|
27
|
+
|
|
28
|
+
animations.forEach((animation) => {
|
|
29
|
+
const letters = animation.querySelectorAll('span')
|
|
30
|
+
letters.forEach((letter, i) => {
|
|
31
|
+
;(letter as HTMLElement).style.animationDelay = i * 0.1 + 's'
|
|
32
|
+
})
|
|
33
|
+
})
|
|
34
|
+
}, [])
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<motion.div
|
|
38
|
+
ref={ref}
|
|
39
|
+
initial={{ opacity: 0, y: 50 }}
|
|
40
|
+
animate={{
|
|
41
|
+
opacity: 1,
|
|
42
|
+
y: 0,
|
|
43
|
+
}}
|
|
44
|
+
transition={{
|
|
45
|
+
duration: 0.3,
|
|
46
|
+
delay: 0.2,
|
|
47
|
+
}}
|
|
48
|
+
>
|
|
49
|
+
{children}
|
|
50
|
+
</motion.div>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export default TitleAnims01
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
import { Button } from '@/components/ui/button'
|
|
5
|
+
import { FaPlay } from 'react-icons/fa'
|
|
6
|
+
import { cn } from '@/utilities/ui'
|
|
7
|
+
|
|
8
|
+
export const AnimationContainer = ({
|
|
9
|
+
children,
|
|
10
|
+
className = ''
|
|
11
|
+
}: {
|
|
12
|
+
children: React.ReactNode
|
|
13
|
+
className?: string
|
|
14
|
+
}) => {
|
|
15
|
+
const [key, setKey] = React.useState(0)
|
|
16
|
+
const onClick = () => {
|
|
17
|
+
setKey((prv) => prv + 1)
|
|
18
|
+
}
|
|
19
|
+
return (
|
|
20
|
+
<div className={cn('pb-12 pt-4 border-b dark:border-stone-900', className)}>
|
|
21
|
+
<div className="flex-row-end w-full mb-2">
|
|
22
|
+
<Button onClick={onClick} size="icon" className="rounded-md size-9" variant="outline">
|
|
23
|
+
<FaPlay className="size-3" />
|
|
24
|
+
</Button>
|
|
25
|
+
</div>
|
|
26
|
+
<div key={key}>{children}</div>
|
|
27
|
+
</div>
|
|
28
|
+
)
|
|
29
|
+
}
|