basic setup
This commit is contained in:
32
components/Btn.vue
Normal file
32
components/Btn.vue
Normal file
@@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<component :is="tag" class="btn">
|
||||
<svg-btn-outline />
|
||||
|
||||
<slot />
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import SvgBtnOutline from '@/components/svg/BtnOutline.vue'
|
||||
|
||||
const props = defineProps({
|
||||
tag: {
|
||||
type: String,
|
||||
default: 'button',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.btn {
|
||||
text-transform: uppercase;
|
||||
padding: desktop-vw(5px) desktop-vw(16px) desktop-vw(6px);
|
||||
color: var(--grey-100);
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: var(--theme-accent);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
69
components/Lenis.vue
Normal file
69
components/Lenis.vue
Normal file
@@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<div v-if="!root" class="lenis" ref="wrapper">
|
||||
<div ref="content">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<slot v-else />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Lenis from 'lenis'
|
||||
import Tempus from 'tempus'
|
||||
import { onBeforeUnmount, onMounted, provide, ref, shallowRef } from 'vue'
|
||||
|
||||
const { root, instance, options } = defineProps({
|
||||
root: {
|
||||
type: Boolean,
|
||||
default: () => false,
|
||||
},
|
||||
instance: { type: String },
|
||||
options: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
duration: 1.2,
|
||||
}),
|
||||
},
|
||||
})
|
||||
|
||||
const lenis = shallowRef()
|
||||
const wrapper = ref()
|
||||
const content = ref()
|
||||
const removeRaf = ref()
|
||||
|
||||
// Provide instance for useLenis composable
|
||||
const instanceKey = `lenis${instance ? `-${instance}` : ''}`
|
||||
provide(instanceKey, lenis)
|
||||
|
||||
// Initialize with Tempus
|
||||
const initLenis = () => {
|
||||
if (lenis.value) return
|
||||
|
||||
lenis.value = new Lenis({
|
||||
...options,
|
||||
...(!root
|
||||
? {
|
||||
wrapper: wrapper.value,
|
||||
content: content.value,
|
||||
eventsTarget: wrapper.value,
|
||||
}
|
||||
: {}),
|
||||
})
|
||||
|
||||
removeRaf.value = Tempus.add((time) => {
|
||||
lenis.value.raf(time)
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (!lenis.value) {
|
||||
initLenis()
|
||||
}
|
||||
})
|
||||
// Kill lenis before unmount
|
||||
onBeforeUnmount(() => {
|
||||
lenis.value?.destroy()
|
||||
removeRaf.value?.()
|
||||
})
|
||||
</script>
|
||||
67
components/svg/BtnOutline.vue
Normal file
67
components/svg/BtnOutline.vue
Normal file
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<div class="svg-btn-outline">
|
||||
<svg
|
||||
class="side left"
|
||||
width="16"
|
||||
height="28"
|
||||
viewBox="0 0 16 28"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M15.7207 0.5H14.7207L0.720634 14.8612L14.7207 27.5H15.7207"
|
||||
stroke="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
<div class="fill">
|
||||
<div class="borders" />
|
||||
</div>
|
||||
|
||||
<svg
|
||||
class="side right"
|
||||
width="16"
|
||||
height="28"
|
||||
viewBox="0 0 16 28"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M15.7207 0.5H14.7207L0.720634 14.8612L14.7207 27.5H15.7207"
|
||||
stroke="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.svg-btn-outline {
|
||||
grid-template-columns: auto 1fr auto;
|
||||
display: grid;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
|
||||
.side {
|
||||
height: 100%;
|
||||
|
||||
&.right {
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
}
|
||||
.fill {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
|
||||
.borders {
|
||||
position: absolute;
|
||||
inset: 0 -1px;
|
||||
border: solid currentColor;
|
||||
border-width: 1px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user