mirror of
https://github.com/DavidHDev/vue-bits.git
synced 2026-03-07 06:29:30 -07:00
add smooth scroll to demo
This commit is contained in:
27
package-lock.json
generated
27
package-lock.json
generated
@@ -15,6 +15,7 @@
|
|||||||
"@vueuse/motion": "^3.0.3",
|
"@vueuse/motion": "^3.0.3",
|
||||||
"@wdns/vue-code-block": "^2.3.5",
|
"@wdns/vue-code-block": "^2.3.5",
|
||||||
"gsap": "^3.13.0",
|
"gsap": "^3.13.0",
|
||||||
|
"lenis": "^1.3.8",
|
||||||
"matter-js": "^0.20.0",
|
"matter-js": "^0.20.0",
|
||||||
"motion-v": "^1.5.0",
|
"motion-v": "^1.5.0",
|
||||||
"ogl": "^1.0.11",
|
"ogl": "^1.0.11",
|
||||||
@@ -6433,6 +6434,32 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/lenis": {
|
||||||
|
"version": "1.3.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/lenis/-/lenis-1.3.8.tgz",
|
||||||
|
"integrity": "sha512-LVeoMs6jZE1eu3gPsexndm+vk01pLFeq7P00vjIpI17saD52IYu8nPA4gX43elz8tp/TTCXcX6Em1MEjDl9NTw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/darkroomengineering"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@nuxt/kit": ">=3.0.0",
|
||||||
|
"react": ">=17.0.0",
|
||||||
|
"vue": ">=3.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@nuxt/kit": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"vue": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/levn": {
|
"node_modules/levn": {
|
||||||
"version": "0.4.1",
|
"version": "0.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
"@vueuse/motion": "^3.0.3",
|
"@vueuse/motion": "^3.0.3",
|
||||||
"@wdns/vue-code-block": "^2.3.5",
|
"@wdns/vue-code-block": "^2.3.5",
|
||||||
"gsap": "^3.13.0",
|
"gsap": "^3.13.0",
|
||||||
|
"lenis": "^1.3.8",
|
||||||
"matter-js": "^0.20.0",
|
"matter-js": "^0.20.0",
|
||||||
"motion-v": "^1.5.0",
|
"motion-v": "^1.5.0",
|
||||||
"ogl": "^1.0.11",
|
"ogl": "^1.0.11",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<TabbedLayout>
|
<TabbedLayout>
|
||||||
<template #preview>
|
<template #preview>
|
||||||
<div class="relative overflow-y-auto no-scrollbar demo-container">
|
<div class="relative overflow-y-auto no-scrollbar demo-container" ref="scrollContainerRef">
|
||||||
<GlassSurface
|
<GlassSurface
|
||||||
:key="key"
|
:key="key"
|
||||||
:width="360"
|
:width="360"
|
||||||
@@ -22,26 +22,21 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="absolute flex flex-col items-center gap-6 top-0 left-0 right-0">
|
<div class="absolute flex flex-col items-center gap-6 top-0 left-0 right-0">
|
||||||
<div
|
<div class="absolute translate-y-1/2 top-12 text-4xl font-bold text-[#333] z-0 whitespace-nowrap text-center">
|
||||||
class="absolute translate-y-1/2 top-12 text-4xl font-bold text-[#27FF64] z-0 whitespace-nowrap text-center"
|
|
||||||
>
|
|
||||||
Try scrolling.
|
Try scrolling.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Top Spacer -->
|
|
||||||
<div class="h-60 w-full" />
|
<div class="h-60 w-full" />
|
||||||
|
|
||||||
<!-- Image Blocks -->
|
<div v-for="(item, index) in imageBlocks" :key="index" class="relative py-4">
|
||||||
<div v-for="(item, index) in imageBlocks" :key="index" class="relative">
|
|
||||||
<img :src="item.src" class="w-128 rounded-2xl object-cover grayscale-100" />
|
<img :src="item.src" class="w-128 rounded-2xl object-cover grayscale-100" />
|
||||||
<div
|
<div
|
||||||
class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 font-extrabold text-center leading-[100%] text-[3rem] min-w-72"
|
class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 font-extrabold text-center leading-[100%] text-[3rem] min-w-72 mix-blend-overlay text-white"
|
||||||
>
|
>
|
||||||
{{ item.text }}
|
{{ item.text }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Bottom Spacer -->
|
|
||||||
<div class="h-60 w-full" />
|
<div class="h-60 w-full" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -75,7 +70,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch } from 'vue';
|
import { ref, watch, onMounted, onUnmounted, useTemplateRef } from 'vue';
|
||||||
|
import Lenis from 'lenis';
|
||||||
import TabbedLayout from '../../components/common/TabbedLayout.vue';
|
import TabbedLayout from '../../components/common/TabbedLayout.vue';
|
||||||
import PropTable from '../../components/common/PropTable.vue';
|
import PropTable from '../../components/common/PropTable.vue';
|
||||||
import CliInstallation from '../../components/code/CliInstallation.vue';
|
import CliInstallation from '../../components/code/CliInstallation.vue';
|
||||||
@@ -88,6 +84,10 @@ import { useForceRerender } from '@/composables/useForceRerender';
|
|||||||
|
|
||||||
const { rerenderKey: key, forceRerender } = useForceRerender();
|
const { rerenderKey: key, forceRerender } = useForceRerender();
|
||||||
|
|
||||||
|
const scrollContainerRef = useTemplateRef<HTMLElement>('scrollContainerRef');
|
||||||
|
let lenis: Lenis | null = null;
|
||||||
|
let rafId: number | null = null;
|
||||||
|
|
||||||
const borderRadius = ref(50);
|
const borderRadius = ref(50);
|
||||||
const backgroundOpacity = ref(0.1);
|
const backgroundOpacity = ref(0.1);
|
||||||
const saturation = ref(1);
|
const saturation = ref(1);
|
||||||
@@ -118,6 +118,49 @@ watch(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const initLenis = () => {
|
||||||
|
if (!scrollContainerRef.value) return;
|
||||||
|
|
||||||
|
lenis = new Lenis({
|
||||||
|
wrapper: scrollContainerRef.value,
|
||||||
|
content: scrollContainerRef.value.firstElementChild as HTMLElement,
|
||||||
|
duration: 1.2,
|
||||||
|
easing: (t: number) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
|
||||||
|
orientation: 'vertical',
|
||||||
|
gestureOrientation: 'vertical',
|
||||||
|
smoothWheel: true,
|
||||||
|
wheelMultiplier: 1,
|
||||||
|
touchMultiplier: 2,
|
||||||
|
infinite: false
|
||||||
|
});
|
||||||
|
|
||||||
|
const raf = (time: number) => {
|
||||||
|
lenis?.raf(time);
|
||||||
|
rafId = requestAnimationFrame(raf);
|
||||||
|
};
|
||||||
|
|
||||||
|
rafId = requestAnimationFrame(raf);
|
||||||
|
};
|
||||||
|
|
||||||
|
const destroyLenis = () => {
|
||||||
|
if (rafId) {
|
||||||
|
cancelAnimationFrame(rafId);
|
||||||
|
rafId = null;
|
||||||
|
}
|
||||||
|
if (lenis) {
|
||||||
|
lenis.destroy();
|
||||||
|
lenis = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
initLenis();
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
destroyLenis();
|
||||||
|
});
|
||||||
|
|
||||||
const imageBlocks = [
|
const imageBlocks = [
|
||||||
{
|
{
|
||||||
src: 'https://images.unsplash.com/photo-1500673587002-1d2548cfba1b?q=80&w=1740&auto=format&fit=crop',
|
src: 'https://images.unsplash.com/photo-1500673587002-1d2548cfba1b?q=80&w=1740&auto=format&fit=crop',
|
||||||
|
|||||||
Reference in New Issue
Block a user