kmcom-nuxt-layers 1.0.1
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/.claude/rules/nuxt-layers.md +23 -0
- package/.claude/rules/typescript.md +16 -0
- package/.claude/rules/vue-components.md +34 -0
- package/.claude/settings.local.json +81 -0
- package/.editorconfig +27 -0
- package/.github/workflows/npm-publish.yml +33 -0
- package/.oxlintrc.json +10 -0
- package/.prettierignore +87 -0
- package/CLAUDE.md +71 -0
- package/apps/playground/README.md +75 -0
- package/apps/playground/app/app.config.ts +10 -0
- package/apps/playground/app/app.vue +12 -0
- package/apps/playground/app/components/AmbientBackground.client.vue +795 -0
- package/apps/playground/app/components/ShaderDemoCanvas.client.vue +636 -0
- package/apps/playground/app/components/ShaderImageDemo.client.vue +211 -0
- package/apps/playground/app/pages/ambient.vue +387 -0
- package/apps/playground/app/pages/content.vue +200 -0
- package/apps/playground/app/pages/core.vue +560 -0
- package/apps/playground/app/pages/forms.vue +645 -0
- package/apps/playground/app/pages/index.vue +257 -0
- package/apps/playground/app/pages/layout.vue +591 -0
- package/apps/playground/app/pages/locomotive-scroll.vue +738 -0
- package/apps/playground/app/pages/motion.vue +848 -0
- package/apps/playground/app/pages/shader.vue +1701 -0
- package/apps/playground/app/pages/theme.vue +115 -0
- package/apps/playground/app/pages/ui.vue +656 -0
- package/apps/playground/content/blog/hello-world.md +127 -0
- package/apps/playground/content/blog/second-post.md +99 -0
- package/apps/playground/content/blog/third-post.md +33 -0
- package/apps/playground/content/gallery/autumn-collection.md +57 -0
- package/apps/playground/content/gallery/summer-collection.md +52 -0
- package/apps/playground/content/pages/index.md +132 -0
- package/apps/playground/content/portfolio/project-one.md +90 -0
- package/apps/playground/content/portfolio/project-two.md +96 -0
- package/apps/playground/content.config.ts +93 -0
- package/apps/playground/nuxt.config.ts +99 -0
- package/apps/playground/package.json +17 -0
- package/apps/playground/public/favicon.ico +0 -0
- package/apps/playground/public/robots.txt +2 -0
- package/apps/playground/tsconfig.json +25 -0
- package/eslint.config.mjs +223 -0
- package/eslint.configCOPY.mjs +216 -0
- package/eslintconfigCURRENT.mjs +244 -0
- package/eslintconfigOLD.mjs +178 -0
- package/files for claude/Scroller.vue +31 -0
- package/files for claude/TextMarquee.vue +255 -0
- package/files for claude/gsap.client.ts +18 -0
- package/files for claude/gsap.ts +10 -0
- package/files for claude/scroll.ts +28 -0
- package/layers/content/app/assets/css/main.css +1 -0
- package/layers/content/app/components/Blog/Article.vue +29 -0
- package/layers/content/app/components/Blog/Card.vue +40 -0
- package/layers/content/app/components/Blog/List.vue +35 -0
- package/layers/content/app/components/Gallery/AmbientImage.vue +52 -0
- package/layers/content/app/components/Gallery/Card.vue +39 -0
- package/layers/content/app/components/Gallery/Detail.vue +76 -0
- package/layers/content/app/components/Gallery/Grid.vue +48 -0
- package/layers/content/app/components/Gallery/ImageDetail.vue +92 -0
- package/layers/content/app/components/Gallery/Lightbox.vue +102 -0
- package/layers/content/app/components/NuxtContent/Detail.vue +53 -0
- package/layers/content/app/components/NuxtContent/List.vue +21 -0
- package/layers/content/app/components/NuxtContent/Renderer.vue +14 -0
- package/layers/content/app/components/NuxtContent/Surround.vue +15 -0
- package/layers/content/app/components/NuxtContent/Toc.vue +18 -0
- package/layers/content/app/components/Portfolio/Card.vue +39 -0
- package/layers/content/app/components/Portfolio/ColorPalette.vue +39 -0
- package/layers/content/app/components/Portfolio/Detail.vue +49 -0
- package/layers/content/app/components/Portfolio/List.vue +44 -0
- package/layers/content/app/components/Portfolio/Typography.vue +37 -0
- package/layers/content/app/components/content/Figure.vue +31 -0
- package/layers/content/app/composables/useBlogPost.ts +3 -0
- package/layers/content/app/composables/useBlogPosts.ts +23 -0
- package/layers/content/app/composables/useCollectionItem.ts +5 -0
- package/layers/content/app/composables/useCollectionSurround.ts +9 -0
- package/layers/content/app/composables/useContentPage.ts +3 -0
- package/layers/content/app/composables/useGalleryItem.ts +3 -0
- package/layers/content/app/composables/useGalleryItems.ts +19 -0
- package/layers/content/app/composables/usePortfolioItem.ts +3 -0
- package/layers/content/app/composables/usePortfolioItems.ts +23 -0
- package/layers/content/app/pages/blog/[slug].vue +10 -0
- package/layers/content/app/pages/blog/index.vue +15 -0
- package/layers/content/app/pages/gallery/[slug]/[imageId].vue +11 -0
- package/layers/content/app/pages/gallery/[slug]/index.vue +10 -0
- package/layers/content/app/pages/gallery/index.vue +15 -0
- package/layers/content/app/pages/portfolio/[slug].vue +10 -0
- package/layers/content/app/pages/portfolio/index.vue +15 -0
- package/layers/content/app/types/content.ts +84 -0
- package/layers/content/app.config.ts +12 -0
- package/layers/content/content.config.ts +93 -0
- package/layers/content/nuxt.config.ts +31 -0
- package/layers/content/package.json +31 -0
- package/layers/content/tsconfig.json +6 -0
- package/layers/core/app/assets/css/base.css +88 -0
- package/layers/core/app/assets/css/layout.css +36 -0
- package/layers/core/app/assets/css/main.css +7 -0
- package/layers/core/app/assets/css-backup.zip +0 -0
- package/layers/core/app/components/ErrorBoundary.vue +102 -0
- package/layers/core/app/components/LoadingScreen.vue +137 -0
- package/layers/core/app/composables/useBrowser.ts +161 -0
- package/layers/core/app/composables/useCache.ts +138 -0
- package/layers/core/app/composables/useDevice.ts +36 -0
- package/layers/core/app/composables/useEnv.ts +23 -0
- package/layers/core/app/composables/useErrorLog.ts +158 -0
- package/layers/core/app/composables/useFeatures.ts +269 -0
- package/layers/core/app/composables/useLoading.ts +109 -0
- package/layers/core/app/composables/useNetworkInfo.ts +83 -0
- package/layers/core/app/composables/usePWAInfo.ts +104 -0
- package/layers/core/app/composables/useRendering.ts +97 -0
- package/layers/core/app/composables/useScreen.ts +95 -0
- package/layers/core/app/composables/useScrollGuard.ts +266 -0
- package/layers/core/app/error.vue +103 -0
- package/layers/core/app/layouts/default.vue +4 -0
- package/layers/core/app/pages/[...slug].vue +168 -0
- package/layers/core/app/pages/diagnostics.vue +228 -0
- package/layers/core/app/plugins/error-handler.ts +47 -0
- package/layers/core/app/plugins/feature-detection.client.ts +32 -0
- package/layers/core/app/plugins/init.ts +188 -0
- package/layers/core/app/plugins/loading.client.ts +54 -0
- package/layers/core/app/plugins/scroll-guard.client.ts +53 -0
- package/layers/core/app/types/detection.ts +117 -0
- package/layers/core/app/types/index.ts +10 -0
- package/layers/core/app/types/loading.ts +47 -0
- package/layers/core/app/types/runtime-config.ts +31 -0
- package/layers/core/app/types/scroll-guard.ts +25 -0
- package/layers/core/app/utils/helpers.ts +246 -0
- package/layers/core/app/utils/index.ts +8 -0
- package/layers/core/app/utils/regex.ts +6 -0
- package/layers/core/app.config.ts +193 -0
- package/layers/core/nuxt.config.ts +84 -0
- package/layers/core/package.json +25 -0
- package/layers/core/tailwind.config.js +28 -0
- package/layers/core/tsconfig.json +6 -0
- package/layers/forms/app/components/Form/Contact.vue +78 -0
- package/layers/forms/app/components/Form/Field.vue +85 -0
- package/layers/forms/app/composables/useFormSchema.ts +35 -0
- package/layers/forms/app/config/fields.ts +104 -0
- package/layers/forms/app/types/fields.ts +60 -0
- package/layers/forms/app.config.ts +12 -0
- package/layers/forms/nuxt.config.ts +17 -0
- package/layers/forms/package.json +17 -0
- package/layers/forms/tsconfig.json +6 -0
- package/layers/layout/.nuxtrc +1 -0
- package/layers/layout/CLAUDE.MD +186 -0
- package/layers/layout/GRID_SYSTEM.md +993 -0
- package/layers/layout/README.md +73 -0
- package/layers/layout/app/assets/css/layout/grids.css +180 -0
- package/layers/layout/app/assets/css/main.css +1 -0
- package/layers/layout/app/components/Layout/Grid/Debug.vue +79 -0
- package/layers/layout/app/components/Layout/Grid/Item.vue +180 -0
- package/layers/layout/app/components/Layout/Page/Container.vue +100 -0
- package/layers/layout/app/components/Layout/Page/Header.vue +33 -0
- package/layers/layout/app/components/Layout/Section/Gallery.vue +68 -0
- package/layers/layout/app/components/Layout/Section/Hero.vue +71 -0
- package/layers/layout/app/components/Layout/Section/Split.vue +56 -0
- package/layers/layout/app/components/Layout/Section/index.vue +39 -0
- package/layers/layout/app/composables/GridPlacement.ts +31 -0
- package/layers/layout/app/composables/useGridConfig.ts +27 -0
- package/layers/layout/app/types/layouts.ts +37 -0
- package/layers/layout/app.config.ts +97 -0
- package/layers/layout/nuxt.config.ts +14 -0
- package/layers/layout/package.json +14 -0
- package/layers/layout/tailwind.config.js +28 -0
- package/layers/layout/tsconfig.json +6 -0
- package/layers/motion/README.md +107 -0
- package/layers/motion/TASKS.MD +16 -0
- package/layers/motion/app/assets/css/main.css +111 -0
- package/layers/motion/app/components/Motion/Marquee.vue +171 -0
- package/layers/motion/app/components/Motion/Parallax.vue +75 -0
- package/layers/motion/app/components/Motion/ScrollLink.vue +49 -0
- package/layers/motion/app/components/Motion/ScrollProgress.vue +127 -0
- package/layers/motion/app/components/Motion/ScrollStats.vue +102 -0
- package/layers/motion/app/components/Motion/Staggered.vue +73 -0
- package/layers/motion/app/components/Motion/TextReveal.vue +101 -0
- package/layers/motion/app/components/Motion/Transition.vue +89 -0
- package/layers/motion/app/components/Motion/VelocityEffect.vue +139 -0
- package/layers/motion/app/components/Motion/index.vue +16 -0
- package/layers/motion/app/composables/useGsap.ts +21 -0
- package/layers/motion/app/composables/useMotion.ts +137 -0
- package/layers/motion/app/composables/useSmoothScroll.ts +154 -0
- package/layers/motion/app/plugins/gsap.client.ts +15 -0
- package/layers/motion/app/plugins/locomotive-scroll.client.ts +49 -0
- package/layers/motion/app/utils/gsapAnimations.ts +122 -0
- package/layers/motion/app.config.ts +30 -0
- package/layers/motion/nuxt.config.ts +19 -0
- package/layers/motion/package.json +17 -0
- package/layers/motion/tsconfig.json +6 -0
- package/layers/shader/AGENTS.MD +195 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/.prettierignore +6 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/.prettierrc +18 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/LICENSE +21 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/README.md +100 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/index.html +13 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/jsconfig.json +30 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/package.json +18 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/pnpm-lock.yaml +633 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/public/vite.svg +1 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/components/sketch/webgpu_sketch.js +128 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/components/sketches_dropdown/index.css +87 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/components/sketches_dropdown/sketches_dropdown.js +169 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/index.css +25 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/main.js +93 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/router.js +43 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/sketches/flare-1.js +68 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/sketches/noise/dawn-1.js +56 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/distortion/bulge_distortion.js +35 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/distortion/swirl_distortion.js +35 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/distortion/wave_distortion.js +43 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/noise/common.js +145 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/noise/curl_noise_3d.js +53 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/noise/curl_noise_4d.js +55 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/noise/fbm.js +163 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/noise/perlin_noise_3d.js +70 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/noise/simplex_noise_3d.js +59 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/noise/simplex_noise_4d.js +72 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/noise/turbulence.js +41 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/patterns/canvas_weave_pattern.js +26 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/patterns/grain_texture_pattern.js +10 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/patterns/led_pattern.js +45 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/patterns/pixellation_pattern.js +15 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/patterns/speckled_noise_pattern.js +34 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/patterns/vignette_pattern.js +21 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/bulge_distortion_effect.js +27 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/chromatic_aberration_effect.js +45 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/crt_scanline_effect.js +45 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/dither_effect.js +126 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/grain_texture_effect.js +21 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/halftone_effect.js +44 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/led_effect.js +31 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/pixellation_effect.js +29 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/swirl_distortion_effect.js +25 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/vignette_effect.js +22 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/wave_distortion_effect.js +27 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/color/cosine_palette.js +15 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/color/tonemapping.js +151 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/function/bloom.js +13 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/function/bloom_edge_pattern.js +20 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/function/domain_index.js +11 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/function/median3.js +22 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/function/repeating_pattern.js +13 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/function/screen_aspect_uv.js +14 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/lighting.js +60 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/math/complex.js +86 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/math/coordinates.js +119 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/sdf/operations.js +24 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/sdf/shapes.js +182 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/utils/math.js +33 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/vite.config.js +23 -0
- package/layers/shader/app/assets/css/main.css +41 -0
- package/layers/shader/app/components/Effect/Bloom.vue +8 -0
- package/layers/shader/app/components/Effect/ChromaticAberration.vue +8 -0
- package/layers/shader/app/components/Effect/PostProcessing.vue +20 -0
- package/layers/shader/app/components/Material/AmbientAurora.vue +172 -0
- package/layers/shader/app/components/Material/AmbientFlow.vue +175 -0
- package/layers/shader/app/components/Material/AmbientGradientMesh.vue +173 -0
- package/layers/shader/app/components/Material/AmbientNebula.vue +181 -0
- package/layers/shader/app/components/Material/AmbientOcean.vue +161 -0
- package/layers/shader/app/components/Material/Fresnel.vue +89 -0
- package/layers/shader/app/components/Material/Gradient.vue +185 -0
- package/layers/shader/app/components/Material/Image.vue +232 -0
- package/layers/shader/app/components/Material/Node.vue +79 -0
- package/layers/shader/app/components/Material/Noise.vue +141 -0
- package/layers/shader/app/components/Mesh/Plane.vue +27 -0
- package/layers/shader/app/components/Shader/Background.vue +159 -0
- package/layers/shader/app/components/Shader/Canvas.vue +97 -0
- package/layers/shader/app/components/Shader/Debug.vue +66 -0
- package/layers/shader/app/components/WebGPUCanvas.client.vue +245 -0
- package/layers/shader/app/composables/useAmbientMaterials.ts +452 -0
- package/layers/shader/app/composables/useMousePosition.ts +94 -0
- package/layers/shader/app/composables/useRendererCapabilities.ts +111 -0
- package/layers/shader/app/composables/useShader.ts +148 -0
- package/layers/shader/app/composables/useShaderTime.ts +146 -0
- package/layers/shader/app/composables/useTSLNodes.ts +112 -0
- package/layers/shader/app/composables/useUniforms.ts +188 -0
- package/layers/shader/app/plugins/shader.client.ts +30 -0
- package/layers/shader/app/shaders/common/blend.ts +255 -0
- package/layers/shader/app/shaders/common/effects.ts +299 -0
- package/layers/shader/app/shaders/common/grain.ts +453 -0
- package/layers/shader/app/shaders/common/index.ts +22 -0
- package/layers/shader/app/shaders/common/lighting.ts +146 -0
- package/layers/shader/app/shaders/common/math.ts +250 -0
- package/layers/shader/app/shaders/common/noise.ts +823 -0
- package/layers/shader/app/shaders/common/noiseHelpers.ts +114 -0
- package/layers/shader/app/shaders/common/palette.ts +319 -0
- package/layers/shader/app/shaders/common/patterns.ts +216 -0
- package/layers/shader/app/shaders/common/sdf.ts +224 -0
- package/layers/shader/app/shaders/common/shapes.ts +366 -0
- package/layers/shader/app/shaders/common/tonemapping.ts +172 -0
- package/layers/shader/app/shaders/common/uv.ts +396 -0
- package/layers/shader/app/shaders/createMaterial.ts +314 -0
- package/layers/shader/app/shaders/index.ts +282 -0
- package/layers/shader/app/shaders/layers/aurora.ts +146 -0
- package/layers/shader/app/shaders/layers/index.ts +19 -0
- package/layers/shader/app/shaders/layers/meshGradient.ts +152 -0
- package/layers/shader/app/shaders/layers/paperShading.ts +148 -0
- package/layers/shader/app/shaders/layers/shaderGradient.ts +152 -0
- package/layers/shader/app/shaders/layers/stripe.ts +137 -0
- package/layers/shader/app/shaders/types.ts +12 -0
- package/layers/shader/app/types/index.ts +4 -0
- package/layers/shader/app/types/materials.ts +45 -0
- package/layers/shader/app/types/renderer.ts +50 -0
- package/layers/shader/app/types/tsl.ts +39 -0
- package/layers/shader/app/types/uniforms.ts +21 -0
- package/layers/shader/app/utils/tsl/animation.ts +251 -0
- package/layers/shader/app/utils/tsl/color.ts +189 -0
- package/layers/shader/app/utils/tsl/index.ts +84 -0
- package/layers/shader/app/utils/tsl/math.ts +111 -0
- package/layers/shader/app/utils/tsl/noise.ts +195 -0
- package/layers/shader/app/utils/tsl/patterns.ts +183 -0
- package/layers/shader/app/utils/tsl/uv.ts +145 -0
- package/layers/shader/app.config.ts +18 -0
- package/layers/shader/modular-tsl-shaders-for-claude/common/blend.tsl +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/common/noise.tsl +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/common/shapes.tsl +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/common/vertexFresnel.tsl +9 -0
- package/layers/shader/modular-tsl-shaders-for-claude/common/vertexPlane.tsl +6 -0
- package/layers/shader/modular-tsl-shaders-for-claude/effects/background.tsl +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/effects/gradient.tsl +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/effects/gradientLegend.tsl +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/effects/simpleGradient.tsl +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/layers/aurora.ts +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/layers/fragmentsTech.ts +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/layers/fresnel.ts +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/layers/linearGradient.ts +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/layers/meshGradient.ts +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/layers/noise.ts +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/layers/paperShading.ts +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/layers/radial.ts +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/layers/shaderGradient.ts +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/layers/stripe.ts +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/materials/createMaterial.ts +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/utils/glslUtils.ts +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/utils/palette.ts +1 -0
- package/layers/shader/nuxt.config.ts +48 -0
- package/layers/shader/package.json +17 -0
- package/layers/shader/tsconfig.json +6 -0
- package/layers/theme/app/assets/css/theme.css +47 -0
- package/layers/theme/app/components/ThemePicker/AccentButton.vue +51 -0
- package/layers/theme/app/components/ThemePicker/Colors.vue +22 -0
- package/layers/theme/app/components/ThemePicker/Menu.vue +108 -0
- package/layers/theme/app/components/ThemePicker/MenuButton.vue +9 -0
- package/layers/theme/app/composables/useThemePreferences.ts +158 -0
- package/layers/theme/app/plugins/theme.client.ts +5 -0
- package/layers/theme/app/types/theme.ts +34 -0
- package/layers/theme/app.config.ts +14 -0
- package/layers/theme/nuxt.config.ts +46 -0
- package/layers/theme/package.json +14 -0
- package/layers/theme/server/plugins/theme-fouc.ts +51 -0
- package/layers/theme/tsconfig.json +7 -0
- package/layers/ui/CLAUDE.MD +325 -0
- package/layers/ui/app/assets/css/main.css +4 -0
- package/layers/ui/app/components/Links/Group.vue +38 -0
- package/layers/ui/app/components/Links/Named.vue +32 -0
- package/layers/ui/app/components/Media/Picture.vue +41 -0
- package/layers/ui/app/components/Site/Title.vue +15 -0
- package/layers/ui/app/components/Typography/CodeBlock.vue +37 -0
- package/layers/ui/app/components/Typography/Headline.vue +73 -0
- package/layers/ui/app/components/Typography/QuoteBlock.vue +13 -0
- package/layers/ui/app/components/Typography/TextStroke.vue +109 -0
- package/layers/ui/app/components/Typography/index.vue +49 -0
- package/layers/ui/app/composables/color.ts +36 -0
- package/layers/ui/app/composables/picture.ts +145 -0
- package/layers/ui/app/composables/typography.ts +77 -0
- package/layers/ui/app/layouts/default.vue +4 -0
- package/layers/ui/app/pages/index.vue +236 -0
- package/layers/ui/app/types/breakpoints.ts +179 -0
- package/layers/ui/app/types/colors.ts +29 -0
- package/layers/ui/app/types/media.ts +185 -0
- package/layers/ui/app/types/typography.ts +108 -0
- package/layers/ui/app/utils/regex.ts +6 -0
- package/layers/ui/app.config.ts +12 -0
- package/layers/ui/nuxt.config.ts +38 -0
- package/layers/ui/package.json +14 -0
- package/layers/ui/tsconfig.json +6 -0
- package/package.json +128 -0
- package/playgroundOLD/app.config.ts +5 -0
- package/playgroundOLD/nuxt.config.ts +12 -0
- package/pnpm-workspace.yaml +6 -0
- package/prettier.config.cjs +19 -0
- package/stylelint.config.mjs +111 -0
- package/turbo.json +16 -0
|
@@ -0,0 +1,848 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/* eslint-disable vue/prefer-true-attribute-shorthand */
|
|
3
|
+
useSeoMeta({
|
|
4
|
+
title: 'Motion Layer Demo',
|
|
5
|
+
description: 'GSAP animations + Locomotive Scroll demos',
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
const { setPageAccent } = useThemePreferences()
|
|
9
|
+
setPageAccent('emerald')
|
|
10
|
+
onUnmounted(() => setPageAccent(null))
|
|
11
|
+
|
|
12
|
+
const { gsap, ScrollTrigger } = useGsap()
|
|
13
|
+
const { scrollTo, scrollToTop, velocity, progress } = useSmoothScroll()
|
|
14
|
+
|
|
15
|
+
// Refs for animations
|
|
16
|
+
const heroTextRef = ref<HTMLElement | null>(null)
|
|
17
|
+
const scrollTriggerBox = ref<HTMLElement | null>(null)
|
|
18
|
+
const parallaxSection = ref<HTMLElement | null>(null)
|
|
19
|
+
const parallaxDeep = ref<HTMLElement | null>(null)
|
|
20
|
+
const parallaxBg = ref<HTMLElement | null>(null)
|
|
21
|
+
const parallaxShapes = ref<HTMLElement | null>(null)
|
|
22
|
+
const parallaxMid = ref<HTMLElement | null>(null)
|
|
23
|
+
const parallaxFg = ref<HTMLElement | null>(null)
|
|
24
|
+
const pinnedSection = ref<HTMLElement | null>(null)
|
|
25
|
+
const pinnedContent = ref<HTMLElement | null>(null)
|
|
26
|
+
const scrubSection = ref<HTMLElement | null>(null)
|
|
27
|
+
const scrubProgress = ref<HTMLElement | null>(null)
|
|
28
|
+
const velocityText = ref<HTMLElement | null>(null)
|
|
29
|
+
const horizontalSection = ref<HTMLElement | null>(null)
|
|
30
|
+
const horizontalTrack = ref<HTMLElement | null>(null)
|
|
31
|
+
const staggeredCards = ref<HTMLElement | null>(null)
|
|
32
|
+
|
|
33
|
+
// Declarative parallax section refs
|
|
34
|
+
const declParallaxSection = ref<HTMLElement | null>(null)
|
|
35
|
+
const declParallaxBg = ref<HTMLElement | null>(null)
|
|
36
|
+
const declParallaxBlur = ref<HTMLElement | null>(null)
|
|
37
|
+
const declParallaxContent = ref<HTMLElement | null>(null)
|
|
38
|
+
|
|
39
|
+
// State
|
|
40
|
+
const reducedMotion = ref(false)
|
|
41
|
+
|
|
42
|
+
onMounted(() => {
|
|
43
|
+
// Check reduced motion preference
|
|
44
|
+
if (import.meta.client) {
|
|
45
|
+
reducedMotion.value = window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Hero text animation
|
|
49
|
+
if (heroTextRef.value) {
|
|
50
|
+
gsap.from(heroTextRef.value.querySelectorAll('.hero-word'), {
|
|
51
|
+
y: 100,
|
|
52
|
+
opacity: 0,
|
|
53
|
+
rotateX: -80,
|
|
54
|
+
stagger: 0.1,
|
|
55
|
+
duration: 1.2,
|
|
56
|
+
ease: 'power3.out',
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Staggered cards
|
|
61
|
+
if (staggeredCards.value) {
|
|
62
|
+
const cards = staggeredCards.value.querySelectorAll('.stagger-card')
|
|
63
|
+
gsap.from(cards, {
|
|
64
|
+
scrollTrigger: {
|
|
65
|
+
trigger: staggeredCards.value,
|
|
66
|
+
start: 'top 80%',
|
|
67
|
+
toggleActions: 'play none none reverse',
|
|
68
|
+
},
|
|
69
|
+
y: 50,
|
|
70
|
+
opacity: 0,
|
|
71
|
+
scale: 0.9,
|
|
72
|
+
duration: 0.6,
|
|
73
|
+
stagger: 0.1,
|
|
74
|
+
ease: 'power3.out',
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Large scroll trigger box
|
|
79
|
+
if (scrollTriggerBox.value) {
|
|
80
|
+
gsap.from(scrollTriggerBox.value, {
|
|
81
|
+
scrollTrigger: {
|
|
82
|
+
trigger: scrollTriggerBox.value,
|
|
83
|
+
start: 'top 85%',
|
|
84
|
+
end: 'top 20%',
|
|
85
|
+
toggleActions: 'play none none reverse',
|
|
86
|
+
},
|
|
87
|
+
y: 100,
|
|
88
|
+
opacity: 0,
|
|
89
|
+
scale: 0.8,
|
|
90
|
+
duration: 1,
|
|
91
|
+
ease: 'power3.out',
|
|
92
|
+
})
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Parallax effect - multiple layers at different speeds
|
|
96
|
+
if (parallaxSection.value) {
|
|
97
|
+
const parallaxTrigger = {
|
|
98
|
+
trigger: parallaxSection.value,
|
|
99
|
+
start: 'top bottom',
|
|
100
|
+
end: 'bottom top',
|
|
101
|
+
scrub: 0.5,
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Deep background (slowest - moves up slightly)
|
|
105
|
+
if (parallaxDeep.value) {
|
|
106
|
+
gsap.to(parallaxDeep.value, {
|
|
107
|
+
scrollTrigger: parallaxTrigger,
|
|
108
|
+
y: -100,
|
|
109
|
+
scale: 1.1,
|
|
110
|
+
ease: 'none',
|
|
111
|
+
})
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Background text (slow)
|
|
115
|
+
if (parallaxBg.value) {
|
|
116
|
+
gsap.to(parallaxBg.value, {
|
|
117
|
+
scrollTrigger: parallaxTrigger,
|
|
118
|
+
y: -300,
|
|
119
|
+
ease: 'none',
|
|
120
|
+
})
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Floating shapes (medium speed + rotation)
|
|
124
|
+
if (parallaxShapes.value) {
|
|
125
|
+
gsap.to(parallaxShapes.value, {
|
|
126
|
+
scrollTrigger: parallaxTrigger,
|
|
127
|
+
y: -150,
|
|
128
|
+
rotation: 15,
|
|
129
|
+
ease: 'none',
|
|
130
|
+
})
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Middle content (subtle movement)
|
|
134
|
+
if (parallaxMid.value) {
|
|
135
|
+
gsap.to(parallaxMid.value, {
|
|
136
|
+
scrollTrigger: parallaxTrigger,
|
|
137
|
+
y: -50,
|
|
138
|
+
ease: 'none',
|
|
139
|
+
})
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Foreground blurs (fastest - moves down)
|
|
143
|
+
if (parallaxFg.value) {
|
|
144
|
+
gsap.to(parallaxFg.value, {
|
|
145
|
+
scrollTrigger: parallaxTrigger,
|
|
146
|
+
y: 200,
|
|
147
|
+
scale: 1.2,
|
|
148
|
+
ease: 'none',
|
|
149
|
+
})
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Pinned section with scroll-linked card reveals
|
|
154
|
+
if (pinnedSection.value && pinnedContent.value) {
|
|
155
|
+
const cards = pinnedContent.value.querySelectorAll('.pinned-card')
|
|
156
|
+
const totalCards = cards.length
|
|
157
|
+
|
|
158
|
+
// Create the pin
|
|
159
|
+
const pinTrigger = ScrollTrigger.create({
|
|
160
|
+
trigger: pinnedSection.value,
|
|
161
|
+
start: 'top top',
|
|
162
|
+
end: `+=${window.innerHeight * 2}`,
|
|
163
|
+
pin: true,
|
|
164
|
+
pinSpacing: true,
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
// Animate each card based on pin progress
|
|
168
|
+
cards.forEach((card, i) => {
|
|
169
|
+
// Set initial state
|
|
170
|
+
gsap.set(card, { opacity: 0, y: 60, scale: 0.9 })
|
|
171
|
+
|
|
172
|
+
// Calculate when this card should animate (spread across the pin duration)
|
|
173
|
+
const startProgress = i / totalCards
|
|
174
|
+
const endProgress = (i + 0.5) / totalCards
|
|
175
|
+
|
|
176
|
+
gsap.to(card, {
|
|
177
|
+
scrollTrigger: {
|
|
178
|
+
trigger: pinnedSection.value,
|
|
179
|
+
start: 'top top',
|
|
180
|
+
end: `+=${window.innerHeight * 2}`,
|
|
181
|
+
scrub: 0.5,
|
|
182
|
+
},
|
|
183
|
+
keyframes: [
|
|
184
|
+
{ opacity: 0, y: 60, scale: 0.9, duration: startProgress },
|
|
185
|
+
{ opacity: 1, y: 0, scale: 1, duration: endProgress - startProgress },
|
|
186
|
+
{ opacity: 1, y: 0, scale: 1, duration: 1 - endProgress },
|
|
187
|
+
],
|
|
188
|
+
ease: 'none',
|
|
189
|
+
})
|
|
190
|
+
})
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Scrub progress animation - progress bar fills as you scroll through section
|
|
194
|
+
if (scrubSection.value && scrubProgress.value) {
|
|
195
|
+
// Set initial state
|
|
196
|
+
gsap.set(scrubProgress.value, { scaleX: 0, transformOrigin: 'left center' })
|
|
197
|
+
|
|
198
|
+
gsap.to(scrubProgress.value, {
|
|
199
|
+
scaleX: 1,
|
|
200
|
+
ease: 'none',
|
|
201
|
+
scrollTrigger: {
|
|
202
|
+
trigger: scrubSection.value,
|
|
203
|
+
start: 'top 80%',
|
|
204
|
+
end: 'bottom 20%',
|
|
205
|
+
scrub: 0.3,
|
|
206
|
+
// markers: true, // Uncomment to debug
|
|
207
|
+
},
|
|
208
|
+
})
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Velocity-based text skew - reacts to scroll speed
|
|
212
|
+
if (velocityText.value) {
|
|
213
|
+
watch(velocity, (vel) => {
|
|
214
|
+
if (!velocityText.value) return
|
|
215
|
+
// Skew based on velocity: faster scroll = more skew
|
|
216
|
+
const skewAmount = Math.max(-20, Math.min(20, vel * 3))
|
|
217
|
+
gsap.to(velocityText.value, {
|
|
218
|
+
skewX: skewAmount,
|
|
219
|
+
duration: 0.2,
|
|
220
|
+
ease: 'power2.out',
|
|
221
|
+
})
|
|
222
|
+
})
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Horizontal scroll section
|
|
226
|
+
if (horizontalSection.value && horizontalTrack.value) {
|
|
227
|
+
const track = horizontalTrack.value
|
|
228
|
+
const trackWidth = track.scrollWidth - window.innerWidth
|
|
229
|
+
|
|
230
|
+
gsap.to(track, {
|
|
231
|
+
scrollTrigger: {
|
|
232
|
+
trigger: horizontalSection.value,
|
|
233
|
+
start: 'top top',
|
|
234
|
+
end: `+=${trackWidth}`,
|
|
235
|
+
pin: true,
|
|
236
|
+
scrub: 1,
|
|
237
|
+
anticipatePin: 1,
|
|
238
|
+
},
|
|
239
|
+
x: -trackWidth,
|
|
240
|
+
ease: 'none',
|
|
241
|
+
})
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Declarative parallax section (GSAP-based since data-scroll needs LS5 config)
|
|
245
|
+
if (declParallaxSection.value) {
|
|
246
|
+
const declTrigger = {
|
|
247
|
+
trigger: declParallaxSection.value,
|
|
248
|
+
start: 'top bottom',
|
|
249
|
+
end: 'bottom top',
|
|
250
|
+
scrub: 0.5,
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (declParallaxBg.value) {
|
|
254
|
+
gsap.to(declParallaxBg.value, {
|
|
255
|
+
scrollTrigger: declTrigger,
|
|
256
|
+
y: -100,
|
|
257
|
+
scale: 1.1,
|
|
258
|
+
ease: 'none',
|
|
259
|
+
})
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (declParallaxBlur.value) {
|
|
263
|
+
gsap.to(declParallaxBlur.value, {
|
|
264
|
+
scrollTrigger: declTrigger,
|
|
265
|
+
y: 80,
|
|
266
|
+
scale: 1.2,
|
|
267
|
+
ease: 'none',
|
|
268
|
+
})
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (declParallaxContent.value) {
|
|
272
|
+
gsap.to(declParallaxContent.value, {
|
|
273
|
+
scrollTrigger: declTrigger,
|
|
274
|
+
y: -40,
|
|
275
|
+
ease: 'none',
|
|
276
|
+
})
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
})
|
|
280
|
+
|
|
281
|
+
function scrollToSection(selector: string) {
|
|
282
|
+
scrollTo(selector, { offset: -20, duration: 1.5 })
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const marqueeItems = ['GSAP', '✦', 'SCROLL', '✦', 'MOTION', '✦', 'ANIMATE', '✦', 'LAYERS', '✦']
|
|
286
|
+
const marqueeItemsAlt = ['PARALLAX', '•', 'PINNING', '•', 'SCRUB', '•', 'VELOCITY', '•']
|
|
287
|
+
</script>
|
|
288
|
+
|
|
289
|
+
<template>
|
|
290
|
+
<div class="motion-page">
|
|
291
|
+
<!-- Hero Section -->
|
|
292
|
+
<section
|
|
293
|
+
class="min-h-screen flex items-center justify-center relative overflow-hidden bg-gray-950"
|
|
294
|
+
>
|
|
295
|
+
<div class="absolute inset-0 bg-linear-to-b from-primary/10 via-transparent to-transparent" />
|
|
296
|
+
|
|
297
|
+
<div class="text-center z-10 px-4">
|
|
298
|
+
<h1
|
|
299
|
+
ref="heroTextRef"
|
|
300
|
+
class="text-5xl sm:text-7xl md:text-8xl lg:text-9xl font-black text-white mb-8 perspective-1000"
|
|
301
|
+
>
|
|
302
|
+
<span class="hero-word inline-block">MOTION</span>
|
|
303
|
+
<br />
|
|
304
|
+
<span class="hero-word inline-block text-primary">LAYER</span>
|
|
305
|
+
</h1>
|
|
306
|
+
<p class="text-xl text-gray-400 mb-12 max-w-2xl mx-auto">
|
|
307
|
+
GSAP + Locomotive Scroll v5. Parallax, pinning, scrub animations, and velocity-based
|
|
308
|
+
effects.
|
|
309
|
+
</p>
|
|
310
|
+
<div class="flex flex-wrap gap-4 justify-center">
|
|
311
|
+
<UButton size="lg" @click="scrollToSection('#demos')"> View Demos </UButton>
|
|
312
|
+
<UButton size="lg" variant="outline" to="/"> Back Home </UButton>
|
|
313
|
+
</div>
|
|
314
|
+
</div>
|
|
315
|
+
|
|
316
|
+
<!-- Scroll indicator -->
|
|
317
|
+
<div class="absolute bottom-8 left-1/2 -translate-x-1/2 text-white/50 animate-bounce">
|
|
318
|
+
<UIcon name="i-lucide-chevron-down" class="text-3xl" />
|
|
319
|
+
</div>
|
|
320
|
+
</section>
|
|
321
|
+
|
|
322
|
+
<!-- Marquee Section - Velocity Reactive -->
|
|
323
|
+
<section class="py-0 bg-primary text-white overflow-hidden">
|
|
324
|
+
<MotionMarquee
|
|
325
|
+
:speed="80"
|
|
326
|
+
direction="left"
|
|
327
|
+
:pause-on-hover="false"
|
|
328
|
+
gap="3rem"
|
|
329
|
+
:velocity-based="true"
|
|
330
|
+
:velocity-sensitivity="0.8"
|
|
331
|
+
:max-speed="4"
|
|
332
|
+
>
|
|
333
|
+
<span
|
|
334
|
+
v-for="(item, i) in marqueeItems"
|
|
335
|
+
:key="i"
|
|
336
|
+
class="text-4xl md:text-6xl font-black whitespace-nowrap"
|
|
337
|
+
>
|
|
338
|
+
{{ item }}
|
|
339
|
+
</span>
|
|
340
|
+
</MotionMarquee>
|
|
341
|
+
</section>
|
|
342
|
+
|
|
343
|
+
<!-- Scroll Velocity Display -->
|
|
344
|
+
<div
|
|
345
|
+
class="fixed top-4 right-4 z-50 bg-black/80 text-white px-4 py-2 rounded-lg font-mono text-sm"
|
|
346
|
+
>
|
|
347
|
+
<div>Velocity: {{ velocity.toFixed(2) }}</div>
|
|
348
|
+
<div>Progress: {{ (progress * 100).toFixed(1) }}%</div>
|
|
349
|
+
</div>
|
|
350
|
+
|
|
351
|
+
<!-- Demos Section -->
|
|
352
|
+
<section id="demos" class="py-24 bg-gray-900">
|
|
353
|
+
<UContainer>
|
|
354
|
+
<div class="text-center mb-16">
|
|
355
|
+
<h2 class="text-4xl md:text-5xl font-bold text-white mb-4">Animation Demos</h2>
|
|
356
|
+
<p class="text-gray-400 text-lg">Scroll down to trigger each animation</p>
|
|
357
|
+
</div>
|
|
358
|
+
|
|
359
|
+
<!-- Large Scroll Trigger Box -->
|
|
360
|
+
<div class="mb-32">
|
|
361
|
+
<h3 class="text-2xl font-bold text-white mb-8 text-center">Scroll Trigger</h3>
|
|
362
|
+
<div
|
|
363
|
+
ref="scrollTriggerBox"
|
|
364
|
+
class="h-[50vh] min-h-[400px] bg-linear-to-br from-blue-600 via-purple-600 to-pink-600 rounded-3xl flex items-center justify-center shadow-2xl shadow-purple-500/25"
|
|
365
|
+
>
|
|
366
|
+
<div class="text-center text-white p-8">
|
|
367
|
+
<UIcon name="i-lucide-sparkles" class="text-6xl mb-4" />
|
|
368
|
+
<h3 class="text-4xl md:text-5xl font-bold mb-4">Scroll Triggered</h3>
|
|
369
|
+
<p class="text-xl text-white/80">This box animates in when you scroll to it</p>
|
|
370
|
+
</div>
|
|
371
|
+
</div>
|
|
372
|
+
</div>
|
|
373
|
+
|
|
374
|
+
<!-- Staggered Cards -->
|
|
375
|
+
<div class="mb-32">
|
|
376
|
+
<h3 class="text-2xl font-bold text-white mb-8 text-center">Staggered Animation</h3>
|
|
377
|
+
<div ref="staggeredCards" class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
378
|
+
<div
|
|
379
|
+
v-for="i in 8"
|
|
380
|
+
:key="i"
|
|
381
|
+
class="stagger-card aspect-square bg-linear-to-br from-gray-800 to-gray-900 rounded-2xl flex items-center justify-center text-4xl font-bold text-white border border-gray-700"
|
|
382
|
+
>
|
|
383
|
+
{{ i }}
|
|
384
|
+
</div>
|
|
385
|
+
</div>
|
|
386
|
+
</div>
|
|
387
|
+
</UContainer>
|
|
388
|
+
</section>
|
|
389
|
+
|
|
390
|
+
<!-- Parallax Section -->
|
|
391
|
+
<section ref="parallaxSection" class="h-[200vh] relative overflow-hidden bg-gray-950">
|
|
392
|
+
<div class="sticky top-0 h-screen flex items-center justify-center overflow-hidden">
|
|
393
|
+
<!-- Deep background layer (slowest) -->
|
|
394
|
+
<div ref="parallaxDeep" class="absolute inset-0 flex items-center justify-center">
|
|
395
|
+
<div class="text-[40vw] font-black text-gray-900/50 select-none">DEEP</div>
|
|
396
|
+
</div>
|
|
397
|
+
|
|
398
|
+
<!-- Background layer -->
|
|
399
|
+
<div ref="parallaxBg" class="absolute inset-0 flex items-center justify-center">
|
|
400
|
+
<div class="text-[25vw] font-black text-gray-800 select-none">PARALLAX</div>
|
|
401
|
+
</div>
|
|
402
|
+
|
|
403
|
+
<!-- Floating shapes layer -->
|
|
404
|
+
<div ref="parallaxShapes" class="absolute inset-0 pointer-events-none">
|
|
405
|
+
<div
|
|
406
|
+
class="absolute top-[10%] left-[10%] w-24 h-24 border-4 border-primary/40 rounded-full"
|
|
407
|
+
/>
|
|
408
|
+
<div class="absolute top-[20%] right-[15%] w-16 h-16 bg-purple-500/30 rotate-45" />
|
|
409
|
+
<div class="absolute bottom-[30%] left-[20%] w-20 h-20 border-4 border-pink-500/40" />
|
|
410
|
+
<div
|
|
411
|
+
class="absolute bottom-[15%] right-[25%] w-32 h-32 border-4 border-blue-500/30 rounded-full"
|
|
412
|
+
/>
|
|
413
|
+
</div>
|
|
414
|
+
|
|
415
|
+
<!-- Middle layer (content) -->
|
|
416
|
+
<div ref="parallaxMid" class="relative z-10 text-center px-4">
|
|
417
|
+
<h2 class="text-5xl md:text-8xl font-bold text-white mb-4">Parallax Layers</h2>
|
|
418
|
+
<p class="text-xl md:text-2xl text-gray-400">
|
|
419
|
+
Multiple layers moving at different speeds
|
|
420
|
+
</p>
|
|
421
|
+
</div>
|
|
422
|
+
|
|
423
|
+
<!-- Foreground blur layer (fastest) -->
|
|
424
|
+
<div ref="parallaxFg" class="absolute inset-0 pointer-events-none">
|
|
425
|
+
<div class="absolute top-1/4 left-[10%] w-40 h-40 bg-primary/40 rounded-full blur-3xl" />
|
|
426
|
+
<div class="absolute top-1/3 right-[5%] w-32 h-32 bg-cyan-500/30 rounded-full blur-2xl" />
|
|
427
|
+
<div
|
|
428
|
+
class="absolute bottom-1/4 right-1/4 w-56 h-56 bg-purple-500/40 rounded-full blur-3xl"
|
|
429
|
+
/>
|
|
430
|
+
<div
|
|
431
|
+
class="absolute bottom-1/3 left-1/4 w-24 h-24 bg-pink-500/30 rounded-full blur-2xl"
|
|
432
|
+
/>
|
|
433
|
+
</div>
|
|
434
|
+
</div>
|
|
435
|
+
</section>
|
|
436
|
+
|
|
437
|
+
<!-- Reverse Marquee - Direction changes with scroll -->
|
|
438
|
+
<section class="py-0 bg-white text-black overflow-hidden">
|
|
439
|
+
<MotionMarquee
|
|
440
|
+
:speed="60"
|
|
441
|
+
direction="right"
|
|
442
|
+
:pause-on-hover="false"
|
|
443
|
+
gap="2rem"
|
|
444
|
+
:velocity-sensitivity="1"
|
|
445
|
+
:min-speed="0.3"
|
|
446
|
+
:max-speed="3"
|
|
447
|
+
:velocity-based="true"
|
|
448
|
+
:velocity-direction="true"
|
|
449
|
+
>
|
|
450
|
+
<span
|
|
451
|
+
v-for="(item, i) in marqueeItemsAlt"
|
|
452
|
+
:key="i"
|
|
453
|
+
class="text-3xl md:text-5xl font-black whitespace-nowrap"
|
|
454
|
+
>
|
|
455
|
+
{{ item }}
|
|
456
|
+
</span>
|
|
457
|
+
</MotionMarquee>
|
|
458
|
+
</section>
|
|
459
|
+
|
|
460
|
+
<!-- Pinned Section -->
|
|
461
|
+
<section ref="pinnedSection" class="h-screen bg-gray-900 relative">
|
|
462
|
+
<div ref="pinnedContent" class="h-full flex items-center justify-center">
|
|
463
|
+
<div class="grid grid-cols-2 md:grid-cols-4 gap-8 px-8 max-w-6xl">
|
|
464
|
+
<div
|
|
465
|
+
v-for="(item, i) in ['Reveal', 'As You', 'Scroll', 'Down']"
|
|
466
|
+
:key="i"
|
|
467
|
+
class="pinned-card aspect-square bg-linear-to-br from-primary to-purple-600 rounded-3xl flex items-center justify-center p-8"
|
|
468
|
+
>
|
|
469
|
+
<span class="text-2xl md:text-4xl font-bold text-white text-center">{{ item }}</span>
|
|
470
|
+
</div>
|
|
471
|
+
</div>
|
|
472
|
+
</div>
|
|
473
|
+
<div class="absolute bottom-8 left-1/2 -translate-x-1/2 text-white/50 text-center">
|
|
474
|
+
<p class="text-sm">Section is pinned - keep scrolling</p>
|
|
475
|
+
</div>
|
|
476
|
+
</section>
|
|
477
|
+
|
|
478
|
+
<!-- Scrub Progress Section -->
|
|
479
|
+
<section ref="scrubSection" class="py-32 bg-gray-950">
|
|
480
|
+
<UContainer>
|
|
481
|
+
<div class="text-center mb-16">
|
|
482
|
+
<h2 class="text-4xl md:text-5xl font-bold text-white mb-4">Scrub Animation</h2>
|
|
483
|
+
<p class="text-gray-400 text-lg">Progress tied directly to scroll position</p>
|
|
484
|
+
</div>
|
|
485
|
+
|
|
486
|
+
<!-- Progress bar -->
|
|
487
|
+
<div class="h-4 bg-gray-800 rounded-full overflow-hidden mb-16">
|
|
488
|
+
<div
|
|
489
|
+
ref="scrubProgress"
|
|
490
|
+
class="h-full bg-linear-to-r from-primary via-purple-500 to-pink-500 origin-left scale-x-0"
|
|
491
|
+
/>
|
|
492
|
+
</div>
|
|
493
|
+
|
|
494
|
+
<!-- Scrub animated elements -->
|
|
495
|
+
<div class="grid md:grid-cols-3 gap-8">
|
|
496
|
+
<div
|
|
497
|
+
v-for="i in 3"
|
|
498
|
+
:key="i"
|
|
499
|
+
class="h-64 bg-gray-800 rounded-2xl flex items-center justify-center"
|
|
500
|
+
>
|
|
501
|
+
<span class="text-6xl font-bold text-gray-600">{{ i }}</span>
|
|
502
|
+
</div>
|
|
503
|
+
</div>
|
|
504
|
+
</UContainer>
|
|
505
|
+
</section>
|
|
506
|
+
|
|
507
|
+
<!-- Velocity-based Text Section -->
|
|
508
|
+
<section class="py-32 bg-black overflow-hidden">
|
|
509
|
+
<div ref="velocityText" class="text-center">
|
|
510
|
+
<h2 class="text-6xl md:text-8xl lg:text-[12rem] font-black text-white leading-none">
|
|
511
|
+
VELOCITY
|
|
512
|
+
</h2>
|
|
513
|
+
<p class="text-gray-500 mt-8 text-lg">Text skews based on scroll velocity</p>
|
|
514
|
+
</div>
|
|
515
|
+
</section>
|
|
516
|
+
|
|
517
|
+
<!-- Large Text Marquee - High velocity response -->
|
|
518
|
+
|
|
519
|
+
<section class="py-8 bg-gray-950 overflow-hidden">
|
|
520
|
+
<MotionMarquee
|
|
521
|
+
:speed="30"
|
|
522
|
+
direction="left"
|
|
523
|
+
:pause-on-hover="true"
|
|
524
|
+
:velocity-based="true"
|
|
525
|
+
gap="4rem"
|
|
526
|
+
:velocity-sensitivity="1.5"
|
|
527
|
+
:max-speed="6"
|
|
528
|
+
>
|
|
529
|
+
<span
|
|
530
|
+
class="text-8xl md:text-[12rem] font-black text-transparent stroke-text whitespace-nowrap"
|
|
531
|
+
>
|
|
532
|
+
SMOOTH SCROLL
|
|
533
|
+
</span>
|
|
534
|
+
</MotionMarquee>
|
|
535
|
+
</section>
|
|
536
|
+
|
|
537
|
+
<!-- Horizontal Scroll Section -->
|
|
538
|
+
<section
|
|
539
|
+
id="horizontal-section"
|
|
540
|
+
ref="horizontalSection"
|
|
541
|
+
class="h-screen bg-gray-900 overflow-hidden"
|
|
542
|
+
>
|
|
543
|
+
<div ref="horizontalTrack" class="h-full flex items-center">
|
|
544
|
+
<div
|
|
545
|
+
v-for="i in 6"
|
|
546
|
+
:key="i"
|
|
547
|
+
class="shrink-0 w-[80vw] md:w-[50vw] h-[70vh] mx-8 first:ml-[10vw] last:mr-[10vw]"
|
|
548
|
+
>
|
|
549
|
+
<div
|
|
550
|
+
class="w-full h-full rounded-3xl flex items-center justify-center text-white"
|
|
551
|
+
:class="[
|
|
552
|
+
i % 3 === 1 ? 'bg-linear-to-br from-blue-600 to-blue-800' : '',
|
|
553
|
+
i % 3 === 2 ? 'bg-linear-to-br from-purple-600 to-purple-800' : '',
|
|
554
|
+
i % 3 === 0 ? 'bg-linear-to-br from-pink-600 to-pink-800' : '',
|
|
555
|
+
]"
|
|
556
|
+
>
|
|
557
|
+
<div class="text-center p-8">
|
|
558
|
+
<h3 class="text-4xl md:text-6xl font-bold mb-4">Panel {{ i }}</h3>
|
|
559
|
+
<p class="text-xl text-white/70">Horizontal scroll with pinning</p>
|
|
560
|
+
</div>
|
|
561
|
+
</div>
|
|
562
|
+
</div>
|
|
563
|
+
</div>
|
|
564
|
+
</section>
|
|
565
|
+
|
|
566
|
+
<!-- Text Reveal Section -->
|
|
567
|
+
<section class="py-32 bg-gray-950">
|
|
568
|
+
<UContainer>
|
|
569
|
+
<div class="max-w-4xl mx-auto text-center">
|
|
570
|
+
<h2 class="text-4xl md:text-6xl font-bold text-white mb-8">
|
|
571
|
+
<MotionTextReveal text="Text Reveal Animation" type="chars" :stagger="0.02" />
|
|
572
|
+
</h2>
|
|
573
|
+
<p class="text-xl text-gray-400">
|
|
574
|
+
<MotionTextReveal
|
|
575
|
+
text="Each character animates in sequence as you scroll into view"
|
|
576
|
+
type="words"
|
|
577
|
+
:stagger="0.05"
|
|
578
|
+
:duration="0.6"
|
|
579
|
+
/>
|
|
580
|
+
</p>
|
|
581
|
+
</div>
|
|
582
|
+
</UContainer>
|
|
583
|
+
</section>
|
|
584
|
+
|
|
585
|
+
<!-- GSAP Parallax Demo Section -->
|
|
586
|
+
<section ref="declParallaxSection" class="py-32 bg-gray-900 overflow-hidden">
|
|
587
|
+
<UContainer>
|
|
588
|
+
<div class="text-center mb-16">
|
|
589
|
+
<h2 class="text-4xl md:text-5xl font-bold text-white mb-4">GSAP Parallax</h2>
|
|
590
|
+
<p class="text-gray-400 text-lg">Multi-layer parallax using GSAP ScrollTrigger</p>
|
|
591
|
+
</div>
|
|
592
|
+
|
|
593
|
+
<div class="relative h-[60vh] flex items-center justify-center">
|
|
594
|
+
<!-- Slow background text -->
|
|
595
|
+
<div
|
|
596
|
+
ref="declParallaxBg"
|
|
597
|
+
class="absolute text-[20vw] font-black text-gray-800/30 select-none"
|
|
598
|
+
>
|
|
599
|
+
SCROLL
|
|
600
|
+
</div>
|
|
601
|
+
|
|
602
|
+
<!-- Foreground blur -->
|
|
603
|
+
<div
|
|
604
|
+
ref="declParallaxBlur"
|
|
605
|
+
class="absolute w-48 h-48 bg-primary/30 rounded-full blur-3xl"
|
|
606
|
+
/>
|
|
607
|
+
|
|
608
|
+
<!-- Center content -->
|
|
609
|
+
<div ref="declParallaxContent" class="relative z-10 text-center">
|
|
610
|
+
<p class="text-2xl md:text-3xl text-white font-bold mb-4">
|
|
611
|
+
Layers move at different speeds
|
|
612
|
+
</p>
|
|
613
|
+
<p class="text-gray-400">Scroll slowly to see the effect</p>
|
|
614
|
+
</div>
|
|
615
|
+
</div>
|
|
616
|
+
</UContainer>
|
|
617
|
+
</section>
|
|
618
|
+
|
|
619
|
+
<!-- Locomotive Scroll Features Showcase -->
|
|
620
|
+
<section class="py-40 bg-gray-950">
|
|
621
|
+
<UContainer>
|
|
622
|
+
<div class="text-center mb-24">
|
|
623
|
+
<div
|
|
624
|
+
class="inline-flex items-center gap-2 bg-primary/10 text-primary px-4 py-2 rounded-full text-sm font-medium mb-8"
|
|
625
|
+
>
|
|
626
|
+
<UIcon name="i-lucide-train" class="text-lg" />
|
|
627
|
+
<span>Locomotive Scroll v5</span>
|
|
628
|
+
</div>
|
|
629
|
+
<h2 class="text-4xl md:text-6xl lg:text-7xl font-bold text-white mb-6">
|
|
630
|
+
Smooth Scrolling Features
|
|
631
|
+
</h2>
|
|
632
|
+
<p class="text-gray-400 text-xl max-w-3xl mx-auto mb-10">
|
|
633
|
+
Native-feeling smooth scroll with declarative parallax, scroll direction detection, and
|
|
634
|
+
buttery performance
|
|
635
|
+
</p>
|
|
636
|
+
<UButton to="/locomotive-scroll" variant="outline" size="xl">
|
|
637
|
+
<UIcon name="i-lucide-book-open" class="mr-2" />
|
|
638
|
+
Deep Dive Guide
|
|
639
|
+
</UButton>
|
|
640
|
+
</div>
|
|
641
|
+
|
|
642
|
+
<!-- Feature Cards Grid -->
|
|
643
|
+
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-8 mb-24">
|
|
644
|
+
<!-- Feature 1: Smooth Scroll -->
|
|
645
|
+
<div
|
|
646
|
+
class="bg-gray-900 rounded-2xl p-8 border border-gray-800 hover:border-primary/50 transition-colors"
|
|
647
|
+
>
|
|
648
|
+
<div class="w-12 h-12 bg-primary/10 rounded-xl flex items-center justify-center mb-6">
|
|
649
|
+
<UIcon name="i-lucide-mouse-pointer-click" class="text-2xl text-primary" />
|
|
650
|
+
</div>
|
|
651
|
+
<h3 class="text-xl font-bold text-white mb-3">Native Smooth Scroll</h3>
|
|
652
|
+
<p class="text-gray-400 mb-4">
|
|
653
|
+
Buttery smooth scrolling using native browser APIs. No hijacking — feels natural on
|
|
654
|
+
all devices.
|
|
655
|
+
</p>
|
|
656
|
+
<code class="text-xs text-gray-500 bg-gray-800 px-2 py-1 rounded">
|
|
657
|
+
useSmoothScroll()
|
|
658
|
+
</code>
|
|
659
|
+
</div>
|
|
660
|
+
|
|
661
|
+
<!-- Feature 2: Data Attributes -->
|
|
662
|
+
<div
|
|
663
|
+
class="bg-gray-900 rounded-2xl p-8 border border-gray-800 hover:border-primary/50 transition-colors"
|
|
664
|
+
>
|
|
665
|
+
<div
|
|
666
|
+
class="w-12 h-12 bg-purple-500/10 rounded-xl flex items-center justify-center mb-6"
|
|
667
|
+
>
|
|
668
|
+
<UIcon name="i-lucide-code" class="text-2xl text-purple-500" />
|
|
669
|
+
</div>
|
|
670
|
+
<h3 class="text-xl font-bold text-white mb-3">Declarative Parallax</h3>
|
|
671
|
+
<p class="text-gray-400 mb-4">
|
|
672
|
+
No JavaScript needed. Just add data-scroll attributes to any element for instant
|
|
673
|
+
parallax effects.
|
|
674
|
+
</p>
|
|
675
|
+
<code class="text-xs text-gray-500 bg-gray-800 px-2 py-1 rounded">
|
|
676
|
+
data-scroll-speed="-0.5"
|
|
677
|
+
</code>
|
|
678
|
+
</div>
|
|
679
|
+
|
|
680
|
+
<!-- Feature 3: Velocity -->
|
|
681
|
+
<div
|
|
682
|
+
class="bg-gray-900 rounded-2xl p-8 border border-gray-800 hover:border-primary/50 transition-colors"
|
|
683
|
+
>
|
|
684
|
+
<div class="w-12 h-12 bg-pink-500/10 rounded-xl flex items-center justify-center mb-6">
|
|
685
|
+
<UIcon name="i-lucide-gauge" class="text-2xl text-pink-500" />
|
|
686
|
+
</div>
|
|
687
|
+
<h3 class="text-xl font-bold text-white mb-3">Scroll Velocity</h3>
|
|
688
|
+
<p class="text-gray-400 mb-4">
|
|
689
|
+
Reactive velocity tracking. Create momentum-based effects that respond to scroll
|
|
690
|
+
speed.
|
|
691
|
+
</p>
|
|
692
|
+
<code class="text-xs text-gray-500 bg-gray-800 px-2 py-1 rounded">
|
|
693
|
+
velocity: {{ velocity.toFixed(2) }}
|
|
694
|
+
</code>
|
|
695
|
+
</div>
|
|
696
|
+
|
|
697
|
+
<!-- Feature 4: Progress -->
|
|
698
|
+
<div
|
|
699
|
+
class="bg-gray-900 rounded-2xl p-8 border border-gray-800 hover:border-primary/50 transition-colors"
|
|
700
|
+
>
|
|
701
|
+
<div class="w-12 h-12 bg-cyan-500/10 rounded-xl flex items-center justify-center mb-6">
|
|
702
|
+
<UIcon name="i-lucide-percent" class="text-2xl text-cyan-500" />
|
|
703
|
+
</div>
|
|
704
|
+
<h3 class="text-xl font-bold text-white mb-3">Scroll Progress</h3>
|
|
705
|
+
<p class="text-gray-400 mb-4">
|
|
706
|
+
Track global scroll progress for page indicators, progress bars, and scroll-linked
|
|
707
|
+
animations.
|
|
708
|
+
</p>
|
|
709
|
+
<code class="text-xs text-gray-500 bg-gray-800 px-2 py-1 rounded">
|
|
710
|
+
progress: {{ (progress * 100).toFixed(0) }}%
|
|
711
|
+
</code>
|
|
712
|
+
</div>
|
|
713
|
+
|
|
714
|
+
<!-- Feature 5: Programmatic Control -->
|
|
715
|
+
<div
|
|
716
|
+
class="bg-gray-900 rounded-2xl p-8 border border-gray-800 hover:border-primary/50 transition-colors"
|
|
717
|
+
>
|
|
718
|
+
<div class="w-12 h-12 bg-amber-500/10 rounded-xl flex items-center justify-center mb-6">
|
|
719
|
+
<UIcon name="i-lucide-navigation" class="text-2xl text-amber-500" />
|
|
720
|
+
</div>
|
|
721
|
+
<h3 class="text-xl font-bold text-white mb-3">Programmatic Scroll</h3>
|
|
722
|
+
<p class="text-gray-400 mb-4">
|
|
723
|
+
Smooth scroll to any element or position with custom duration and easing curves.
|
|
724
|
+
</p>
|
|
725
|
+
<code class="text-xs text-gray-500 bg-gray-800 px-2 py-1 rounded">
|
|
726
|
+
scrollTo('#section')
|
|
727
|
+
</code>
|
|
728
|
+
</div>
|
|
729
|
+
|
|
730
|
+
<!-- Feature 6: GSAP Integration -->
|
|
731
|
+
<div
|
|
732
|
+
class="bg-gray-900 rounded-2xl p-8 border border-gray-800 hover:border-primary/50 transition-colors"
|
|
733
|
+
>
|
|
734
|
+
<div class="w-12 h-12 bg-green-500/10 rounded-xl flex items-center justify-center mb-6">
|
|
735
|
+
<UIcon name="i-lucide-link" class="text-2xl text-green-500" />
|
|
736
|
+
</div>
|
|
737
|
+
<h3 class="text-xl font-bold text-white mb-3">GSAP ScrollTrigger</h3>
|
|
738
|
+
<p class="text-gray-400 mb-4">
|
|
739
|
+
Seamless integration with GSAP ScrollTrigger. Pin, scrub, and animate with precision.
|
|
740
|
+
</p>
|
|
741
|
+
<code class="text-xs text-gray-500 bg-gray-800 px-2 py-1 rounded"> scrollerProxy </code>
|
|
742
|
+
</div>
|
|
743
|
+
</div>
|
|
744
|
+
|
|
745
|
+
<!-- Interactive Demo Area -->
|
|
746
|
+
<div class="relative">
|
|
747
|
+
<div class="text-center mb-12">
|
|
748
|
+
<h3 class="text-2xl font-bold text-white mb-2">Try It</h3>
|
|
749
|
+
<p class="text-gray-400">Click the buttons to see programmatic scrolling</p>
|
|
750
|
+
</div>
|
|
751
|
+
|
|
752
|
+
<div class="flex flex-wrap gap-4 justify-center">
|
|
753
|
+
<UButton variant="outline" @click="scrollTo('#demos', { duration: 1.5 })">
|
|
754
|
+
<UIcon name="i-lucide-arrow-up" class="mr-2" />
|
|
755
|
+
Scroll to Demos
|
|
756
|
+
</UButton>
|
|
757
|
+
<UButton variant="outline" @click="scrollTo('#horizontal-section', { duration: 2 })">
|
|
758
|
+
<UIcon name="i-lucide-move-horizontal" class="mr-2" />
|
|
759
|
+
Horizontal Section
|
|
760
|
+
</UButton>
|
|
761
|
+
<UButton @click="scrollToTop({ duration: 2.5 })">
|
|
762
|
+
<UIcon name="i-lucide-arrow-up-to-line" class="mr-2" />
|
|
763
|
+
Back to Top
|
|
764
|
+
</UButton>
|
|
765
|
+
</div>
|
|
766
|
+
</div>
|
|
767
|
+
</UContainer>
|
|
768
|
+
</section>
|
|
769
|
+
|
|
770
|
+
<!-- Data Attributes Reference -->
|
|
771
|
+
<section class="py-24 bg-gray-900">
|
|
772
|
+
<UContainer>
|
|
773
|
+
<div class="max-w-4xl mx-auto">
|
|
774
|
+
<h3 class="text-3xl font-bold text-white mb-8 text-center">Data Attribute Reference</h3>
|
|
775
|
+
|
|
776
|
+
<div class="grid gap-4">
|
|
777
|
+
<div class="bg-gray-800 rounded-xl p-6 flex flex-col md:flex-row md:items-center gap-4">
|
|
778
|
+
<code class="text-primary font-mono text-sm whitespace-nowrap">data-scroll</code>
|
|
779
|
+
<span class="text-gray-400 flex-1">Enable scroll detection on element</span>
|
|
780
|
+
</div>
|
|
781
|
+
<div class="bg-gray-800 rounded-xl p-6 flex flex-col md:flex-row md:items-center gap-4">
|
|
782
|
+
<code class="text-primary font-mono text-sm whitespace-nowrap">
|
|
783
|
+
data-scroll-speed="-0.5"
|
|
784
|
+
</code>
|
|
785
|
+
<span class="text-gray-400 flex-1">
|
|
786
|
+
Parallax speed (negative = slower, positive = faster)
|
|
787
|
+
</span>
|
|
788
|
+
</div>
|
|
789
|
+
<div class="bg-gray-800 rounded-xl p-6 flex flex-col md:flex-row md:items-center gap-4">
|
|
790
|
+
<code class="text-primary font-mono text-sm whitespace-nowrap">
|
|
791
|
+
data-scroll-direction="horizontal"
|
|
792
|
+
</code>
|
|
793
|
+
<span class="text-gray-400 flex-1">Parallax direction (vertical by default)</span>
|
|
794
|
+
</div>
|
|
795
|
+
<div class="bg-gray-800 rounded-xl p-6 flex flex-col md:flex-row md:items-center gap-4">
|
|
796
|
+
<code class="text-primary font-mono text-sm whitespace-nowrap">
|
|
797
|
+
data-scroll-position="top,bottom"
|
|
798
|
+
</code>
|
|
799
|
+
<span class="text-gray-400 flex-1">When to start/end the parallax effect</span>
|
|
800
|
+
</div>
|
|
801
|
+
</div>
|
|
802
|
+
</div>
|
|
803
|
+
</UContainer>
|
|
804
|
+
</section>
|
|
805
|
+
|
|
806
|
+
<!-- Final Marquee -->
|
|
807
|
+
<section class="py-4 bg-primary overflow-hidden">
|
|
808
|
+
<MotionMarquee :speed="100" direction="left" :pause-on-hover="false" gap="2rem">
|
|
809
|
+
<span v-for="i in 10" :key="i" class="text-2xl font-bold text-white/90 whitespace-nowrap">
|
|
810
|
+
BUILT WITH GSAP + LOCOMOTIVE SCROLL ✦
|
|
811
|
+
</span>
|
|
812
|
+
</MotionMarquee>
|
|
813
|
+
</section>
|
|
814
|
+
|
|
815
|
+
<!-- Footer Navigation -->
|
|
816
|
+
<section class="py-16 bg-gray-950">
|
|
817
|
+
<UContainer>
|
|
818
|
+
<div class="flex flex-col md:flex-row gap-8 items-center justify-between">
|
|
819
|
+
<div>
|
|
820
|
+
<h2 class="text-2xl font-bold text-white mb-2">Motion Layer</h2>
|
|
821
|
+
<p class="text-gray-400">GSAP + Locomotive Scroll for professional animations</p>
|
|
822
|
+
</div>
|
|
823
|
+
<div class="flex gap-4">
|
|
824
|
+
<UButton variant="outline" @click="scrollToTop({ duration: 2 })"> Back to Top </UButton>
|
|
825
|
+
<UButton to="/"> Home </UButton>
|
|
826
|
+
</div>
|
|
827
|
+
</div>
|
|
828
|
+
</UContainer>
|
|
829
|
+
</section>
|
|
830
|
+
</div>
|
|
831
|
+
</template>
|
|
832
|
+
|
|
833
|
+
<style scoped>
|
|
834
|
+
/* stylelint-disable function-disallowed-list */
|
|
835
|
+
.perspective-1000 {
|
|
836
|
+
perspective: 1000px;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
.stroke-text {
|
|
840
|
+
-webkit-text-stroke: 2px rgb(255 255 255 / 0.3);
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
@media (width >= 768px) {
|
|
844
|
+
.stroke-text {
|
|
845
|
+
-webkit-text-stroke: 4px rgb(255 255 255 / 0.3);
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
</style>
|