mirror of
https://github.com/DavidHDev/vue-bits.git
synced 2026-03-07 22:49:31 -07:00
Add prettier config, format codebase
This commit is contained in:
@@ -5,10 +5,22 @@
|
||||
<div class="demo-container relative min-h-[400px] overflow-hidden">
|
||||
<RefreshButton @refresh="forceRerender" />
|
||||
|
||||
<BlurText :key="rerenderKey" text="Isn't this so cool?!" :delay="delay"
|
||||
class-name="text-3xl md:text-6xl font-bold text-center" :animate-by="animateBy" :direction="direction"
|
||||
:threshold="threshold" :root-margin="rootMargin" :step-duration="stepDuration"
|
||||
@animation-complete="() => { showCallback && showToast() }" />
|
||||
<BlurText
|
||||
:key="rerenderKey"
|
||||
text="Isn't this so cool?!"
|
||||
:delay="delay"
|
||||
class-name="text-3xl md:text-6xl font-bold text-center"
|
||||
:animate-by="animateBy"
|
||||
:direction="direction"
|
||||
:threshold="threshold"
|
||||
:root-margin="rootMargin"
|
||||
:step-duration="stepDuration"
|
||||
@animation-complete="
|
||||
() => {
|
||||
showCallback && showToast();
|
||||
}
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Customize>
|
||||
@@ -17,27 +29,51 @@
|
||||
<div class="flex gap-4 flex-wrap">
|
||||
<button
|
||||
class="text-xs bg-[#0b0b0b] rounded-[10px] border border-[#1e3721] hover:bg-[#1e3721] text-white h-8 px-3 transition-colors"
|
||||
@click="toggleAnimateBy">
|
||||
Animate By: <span class="text-[#a1a1aa]"> {{ animateBy }}</span>
|
||||
@click="toggleAnimateBy"
|
||||
>
|
||||
Animate By:
|
||||
<span class="text-[#a1a1aa]"> {{ animateBy }}</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="text-xs bg-[#0b0b0b] rounded-[10px] border border-[#1e3721] hover:bg-[#1e3721] text-white h-8 px-3 transition-colors"
|
||||
@click="toggleDirection">
|
||||
Direction: <span class="text-[#a1a1aa]"> {{ direction }}</span>
|
||||
@click="toggleDirection"
|
||||
>
|
||||
Direction:
|
||||
<span class="text-[#a1a1aa]"> {{ direction }}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<PreviewSlider title="Delay (ms)" v-model="delay" :min="50" :max="500" :step="10"
|
||||
@update:model-value="forceRerender" />
|
||||
<PreviewSlider
|
||||
title="Delay (ms)"
|
||||
v-model="delay"
|
||||
:min="50"
|
||||
:max="500"
|
||||
:step="10"
|
||||
@update:model-value="forceRerender"
|
||||
/>
|
||||
|
||||
<PreviewSlider title="Step Duration (s)" v-model="stepDuration" :min="0.1" :max="1" :step="0.05"
|
||||
@update:model-value="forceRerender" />
|
||||
<PreviewSlider
|
||||
title="Step Duration (s)"
|
||||
v-model="stepDuration"
|
||||
:min="0.1"
|
||||
:max="1"
|
||||
:step="0.05"
|
||||
@update:model-value="forceRerender"
|
||||
/>
|
||||
|
||||
<PreviewSlider title="Threshold" v-model="threshold" :min="0.1" :max="1" :step="0.1"
|
||||
@update:model-value="forceRerender" />
|
||||
<PreviewSlider
|
||||
title="Threshold"
|
||||
v-model="threshold"
|
||||
:min="0.1"
|
||||
:max="1"
|
||||
:step="0.1"
|
||||
@update:model-value="forceRerender"
|
||||
/>
|
||||
</Customize>
|
||||
|
||||
<PropTable :data="propData" />
|
||||
|
||||
<Dependencies :dependency-list="['motion-v']" />
|
||||
</template>
|
||||
|
||||
@@ -53,61 +89,96 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue'
|
||||
import RefreshButton from '../../components/common/RefreshButton.vue'
|
||||
import PropTable from '../../components/common/PropTable.vue'
|
||||
import Dependencies from '../../components/code/Dependencies.vue'
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue'
|
||||
import CodeExample from '../../components/code/CodeExample.vue'
|
||||
import Customize from '../../components/common/Customize.vue'
|
||||
import PreviewSwitch from '../../components/common/PreviewSwitch.vue'
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue'
|
||||
import BlurText from '../../content/TextAnimations/BlurText/BlurText.vue'
|
||||
import { blurText } from '@/constants/code/TextAnimations/blurTextCode'
|
||||
import { useToast } from 'primevue/usetoast'
|
||||
import { useForceRerender } from '@/composables/useForceRerender'
|
||||
import { ref } from 'vue';
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue';
|
||||
import RefreshButton from '../../components/common/RefreshButton.vue';
|
||||
import PropTable from '../../components/common/PropTable.vue';
|
||||
import Dependencies from '../../components/code/Dependencies.vue';
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue';
|
||||
import CodeExample from '../../components/code/CodeExample.vue';
|
||||
import Customize from '../../components/common/Customize.vue';
|
||||
import PreviewSwitch from '../../components/common/PreviewSwitch.vue';
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue';
|
||||
import BlurText from '../../content/TextAnimations/BlurText/BlurText.vue';
|
||||
import { blurText } from '@/constants/code/TextAnimations/blurTextCode';
|
||||
import { useToast } from 'primevue/usetoast';
|
||||
import { useForceRerender } from '@/composables/useForceRerender';
|
||||
|
||||
const animateBy = ref<'words' | 'letters'>('words')
|
||||
const direction = ref<'top' | 'bottom'>('top')
|
||||
const delay = ref(200)
|
||||
const stepDuration = ref(0.35)
|
||||
const threshold = ref(0.1)
|
||||
const rootMargin = ref('0px')
|
||||
const showCallback = ref(true)
|
||||
const toast = useToast()
|
||||
const { rerenderKey, forceRerender } = useForceRerender()
|
||||
const animateBy = ref<'words' | 'letters'>('words');
|
||||
const direction = ref<'top' | 'bottom'>('top');
|
||||
const delay = ref(200);
|
||||
const stepDuration = ref(0.35);
|
||||
const threshold = ref(0.1);
|
||||
const rootMargin = ref('0px');
|
||||
const showCallback = ref(true);
|
||||
const toast = useToast();
|
||||
const { rerenderKey, forceRerender } = useForceRerender();
|
||||
|
||||
const toggleAnimateBy = () => {
|
||||
animateBy.value = animateBy.value === 'words' ? 'letters' : 'words'
|
||||
forceRerender()
|
||||
}
|
||||
animateBy.value = animateBy.value === 'words' ? 'letters' : 'words';
|
||||
forceRerender();
|
||||
};
|
||||
|
||||
const toggleDirection = () => {
|
||||
direction.value = direction.value === 'top' ? 'bottom' : 'top'
|
||||
forceRerender()
|
||||
}
|
||||
direction.value = direction.value === 'top' ? 'bottom' : 'top';
|
||||
forceRerender();
|
||||
};
|
||||
|
||||
const showToast = () => {
|
||||
toast.add({
|
||||
severity: 'secondary',
|
||||
summary: 'Animation Finished!',
|
||||
life: 3000
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const propData = [
|
||||
{ name: 'text', type: 'string', default: '""', description: 'The text content to animate.' },
|
||||
{ name: 'animateBy', type: 'string', default: '"words"', description: 'Determines whether to animate by "words" or "letters".' },
|
||||
{ name: 'direction', type: 'string', default: '"top"', description: 'Direction from which the words/letters appear ("top" or "bottom").' },
|
||||
{ name: 'delay', type: 'number', default: '200', description: 'Delay between animations for each word/letter (in ms).' },
|
||||
{ name: 'stepDuration', type: 'number', default: '0.35', description: 'The time taken for each letter/word to animate (in seconds).' },
|
||||
{ name: 'threshold', type: 'number', default: '0.1', description: 'Intersection threshold for triggering the animation.' },
|
||||
{
|
||||
name: 'animateBy',
|
||||
type: 'string',
|
||||
default: '"words"',
|
||||
description: 'Determines whether to animate by "words" or "letters".'
|
||||
},
|
||||
{
|
||||
name: 'direction',
|
||||
type: 'string',
|
||||
default: '"top"',
|
||||
description: 'Direction from which the words/letters appear ("top" or "bottom").'
|
||||
},
|
||||
{
|
||||
name: 'delay',
|
||||
type: 'number',
|
||||
default: '200',
|
||||
description: 'Delay between animations for each word/letter (in ms).'
|
||||
},
|
||||
{
|
||||
name: 'stepDuration',
|
||||
type: 'number',
|
||||
default: '0.35',
|
||||
description: 'The time taken for each letter/word to animate (in seconds).'
|
||||
},
|
||||
{
|
||||
name: 'threshold',
|
||||
type: 'number',
|
||||
default: '0.1',
|
||||
description: 'Intersection threshold for triggering the animation.'
|
||||
},
|
||||
{ name: 'rootMargin', type: 'string', default: '"0px"', description: 'Root margin for the intersection observer.' },
|
||||
{ name: 'className', type: 'string', default: '""', description: 'Additional class names to style the component.' },
|
||||
{ name: 'animationFrom', type: 'object', default: 'undefined', description: 'Custom initial animation properties.' },
|
||||
{ name: 'animationTo', type: 'array', default: 'undefined', description: 'Custom target animation properties array.' },
|
||||
{
|
||||
name: 'animationTo',
|
||||
type: 'array',
|
||||
default: 'undefined',
|
||||
description: 'Custom target animation properties array.'
|
||||
},
|
||||
{ name: 'easing', type: 'function', default: '(t) => t', description: 'Custom easing function for the animation.' },
|
||||
{ name: 'onAnimationComplete', type: 'function', default: 'undefined', description: 'Callback function triggered when all animations complete.' }
|
||||
]
|
||||
{
|
||||
name: 'onAnimationComplete',
|
||||
type: 'function',
|
||||
default: 'undefined',
|
||||
description: 'Callback function triggered when all animations complete.'
|
||||
}
|
||||
];
|
||||
</script>
|
||||
|
||||
@@ -3,24 +3,38 @@
|
||||
<TabbedLayout>
|
||||
<template #preview>
|
||||
<div class="demo-container relative min-h-[400px] overflow-hidden flex items-center justify-center">
|
||||
<CircularText :key="rerenderKey" text="VUE * BITS * IS * AWESOME * " :spin-duration="spinDuration"
|
||||
:on-hover="onHover" class-name="text-blue-500" />
|
||||
<CircularText
|
||||
:key="rerenderKey"
|
||||
text="VUE * BITS * IS * AWESOME * "
|
||||
:spin-duration="spinDuration"
|
||||
:on-hover="onHover"
|
||||
class-name="text-blue-500"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Customize>
|
||||
<div class="flex gap-4 flex-wrap">
|
||||
<button
|
||||
class="text-xs bg-[#0b0b0b] rounded-[10px] border border-[#1e3721] hover:bg-[#1e3721] text-white h-8 px-3 transition-colors"
|
||||
@click="toggleOnHover">
|
||||
On Hover: <span class="text-[#a1a1aa]"> {{ onHover }}</span>
|
||||
@click="toggleOnHover"
|
||||
>
|
||||
On Hover:
|
||||
<span class="text-[#a1a1aa]"> {{ onHover }}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<PreviewSlider title="Spin Duration (s)" v-model="spinDuration" :min="1" :max="50" :step="1"
|
||||
@update:model-value="forceRerender" />
|
||||
<PreviewSlider
|
||||
title="Spin Duration (s)"
|
||||
v-model="spinDuration"
|
||||
:min="1"
|
||||
:max="50"
|
||||
:step="1"
|
||||
@update:model-value="forceRerender"
|
||||
/>
|
||||
</Customize>
|
||||
|
||||
<PropTable :data="propData" />
|
||||
|
||||
<Dependencies :dependency-list="['motion-v']" />
|
||||
</template>
|
||||
|
||||
@@ -36,40 +50,45 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue'
|
||||
import PropTable from '../../components/common/PropTable.vue'
|
||||
import Dependencies from '../../components/code/Dependencies.vue'
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue'
|
||||
import CodeExample from '../../components/code/CodeExample.vue'
|
||||
import Customize from '../../components/common/Customize.vue'
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue'
|
||||
import CircularText from '../../content/TextAnimations/CircularText/CircularText.vue'
|
||||
import { circularText } from '@/constants/code/TextAnimations/circularTextCode'
|
||||
import { useForceRerender } from '@/composables/useForceRerender'
|
||||
import { ref } from 'vue';
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue';
|
||||
import PropTable from '../../components/common/PropTable.vue';
|
||||
import Dependencies from '../../components/code/Dependencies.vue';
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue';
|
||||
import CodeExample from '../../components/code/CodeExample.vue';
|
||||
import Customize from '../../components/common/Customize.vue';
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue';
|
||||
import CircularText from '../../content/TextAnimations/CircularText/CircularText.vue';
|
||||
import { circularText } from '@/constants/code/TextAnimations/circularTextCode';
|
||||
import { useForceRerender } from '@/composables/useForceRerender';
|
||||
|
||||
const onHover = ref<'slowDown' | 'speedUp' | 'pause' | 'goBonkers'>('speedUp')
|
||||
const spinDuration = ref(20)
|
||||
const { rerenderKey, forceRerender } = useForceRerender()
|
||||
const onHover = ref<'slowDown' | 'speedUp' | 'pause' | 'goBonkers'>('speedUp');
|
||||
const spinDuration = ref(20);
|
||||
const { rerenderKey, forceRerender } = useForceRerender();
|
||||
|
||||
const hoverOptions: Array<'slowDown' | 'speedUp' | 'pause' | 'goBonkers'> = [
|
||||
'slowDown',
|
||||
'speedUp',
|
||||
'pause',
|
||||
'goBonkers'
|
||||
]
|
||||
];
|
||||
|
||||
const toggleOnHover = () => {
|
||||
const currentIndex = hoverOptions.indexOf(onHover.value)
|
||||
const nextIndex = (currentIndex + 1) % hoverOptions.length
|
||||
onHover.value = hoverOptions[nextIndex]
|
||||
forceRerender()
|
||||
}
|
||||
const currentIndex = hoverOptions.indexOf(onHover.value);
|
||||
const nextIndex = (currentIndex + 1) % hoverOptions.length;
|
||||
onHover.value = hoverOptions[nextIndex];
|
||||
forceRerender();
|
||||
};
|
||||
|
||||
const propData = [
|
||||
{ name: 'text', type: 'string', default: '""', description: 'The text content to display in a circular pattern.' },
|
||||
{ name: 'spinDuration', type: 'number', default: '20', description: 'Duration of one full rotation in seconds.' },
|
||||
{ name: 'onHover', type: 'string', default: '"speedUp"', description: 'Hover behavior: "slowDown", "speedUp", "pause", or "goBonkers".' },
|
||||
{
|
||||
name: 'onHover',
|
||||
type: 'string',
|
||||
default: '"speedUp"',
|
||||
description: 'Hover behavior: "slowDown", "speedUp", "pause", or "goBonkers".'
|
||||
},
|
||||
{ name: 'className', type: 'string', default: '""', description: 'Additional class names to style the component.' }
|
||||
]
|
||||
];
|
||||
</script>
|
||||
|
||||
@@ -3,26 +3,57 @@
|
||||
<TabbedLayout>
|
||||
<template #preview>
|
||||
<div class="demo-container relative h-[500px] overflow-hidden p-0">
|
||||
<CurvedLoop :key="rerenderKey" :marquee-text="marqueeText" :speed="speed" :curve-amount="curveAmount"
|
||||
:interactive="interactive" />
|
||||
<CurvedLoop
|
||||
:key="rerenderKey"
|
||||
:marquee-text="marqueeText"
|
||||
:speed="speed"
|
||||
:curve-amount="curveAmount"
|
||||
:interactive="interactive"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Customize>
|
||||
<div class="mb-4">
|
||||
<label class="block text-sm font-medium mb-2">Marquee Text</label>
|
||||
<input v-model="marqueeText" type="text" placeholder="Enter text..."
|
||||
|
||||
<input
|
||||
v-model="marqueeText"
|
||||
type="text"
|
||||
placeholder="Enter text..."
|
||||
class="w-[300px] px-3 py-2 bg-[#0b0b0b] border border-[#333] rounded-md text-white focus:outline-none focus:border-[#666]"
|
||||
@input="forceRerender" />
|
||||
@input="forceRerender"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<PreviewSlider title="Speed" v-model="speed" :min="0" :max="10" :step="0.1"
|
||||
@update:model-value="forceRerender" />
|
||||
<PreviewSlider
|
||||
title="Speed"
|
||||
v-model="speed"
|
||||
:min="0"
|
||||
:max="10"
|
||||
:step="0.1"
|
||||
@update:model-value="forceRerender"
|
||||
/>
|
||||
|
||||
<PreviewSlider title="Curve Amount" v-model="curveAmount" :min="-400" :max="400" :step="10" value-unit="px"
|
||||
@update:model-value="forceRerender" />
|
||||
<PreviewSlider
|
||||
title="Curve Amount"
|
||||
v-model="curveAmount"
|
||||
:min="-400"
|
||||
:max="400"
|
||||
:step="10"
|
||||
value-unit="px"
|
||||
@update:model-value="forceRerender"
|
||||
/>
|
||||
|
||||
<PreviewSwitch title="Draggable" :model-value="interactive"
|
||||
@update:model-value="(val: boolean) => { interactive = val; forceRerender() }" />
|
||||
<PreviewSwitch
|
||||
title="Draggable"
|
||||
:model-value="interactive"
|
||||
@update:model-value="
|
||||
(val: boolean) => {
|
||||
interactive = val;
|
||||
forceRerender();
|
||||
}
|
||||
"
|
||||
/>
|
||||
</Customize>
|
||||
|
||||
<PropTable :data="propData" />
|
||||
@@ -40,24 +71,24 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue'
|
||||
import PropTable from '../../components/common/PropTable.vue'
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue'
|
||||
import CodeExample from '../../components/code/CodeExample.vue'
|
||||
import Customize from '../../components/common/Customize.vue'
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue'
|
||||
import PreviewSwitch from '../../components/common/PreviewSwitch.vue'
|
||||
import CurvedLoop from '../../content/TextAnimations/CurvedLoop/CurvedLoop.vue'
|
||||
import { curvedLoop } from '@/constants/code/TextAnimations/curvedLoopCode'
|
||||
import { useForceRerender } from '@/composables/useForceRerender'
|
||||
import { ref } from 'vue';
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue';
|
||||
import PropTable from '../../components/common/PropTable.vue';
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue';
|
||||
import CodeExample from '../../components/code/CodeExample.vue';
|
||||
import Customize from '../../components/common/Customize.vue';
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue';
|
||||
import PreviewSwitch from '../../components/common/PreviewSwitch.vue';
|
||||
import CurvedLoop from '../../content/TextAnimations/CurvedLoop/CurvedLoop.vue';
|
||||
import { curvedLoop } from '@/constants/code/TextAnimations/curvedLoopCode';
|
||||
import { useForceRerender } from '@/composables/useForceRerender';
|
||||
|
||||
const marqueeText = ref('Be ✦ Creative ✦ With ✦ Vue ✦ Bits ✦')
|
||||
const speed = ref(2)
|
||||
const curveAmount = ref(400)
|
||||
const interactive = ref(true)
|
||||
const marqueeText = ref('Be ✦ Creative ✦ With ✦ Vue ✦ Bits ✦');
|
||||
const speed = ref(2);
|
||||
const curveAmount = ref(400);
|
||||
const interactive = ref(true);
|
||||
|
||||
const { rerenderKey, forceRerender } = useForceRerender()
|
||||
const { rerenderKey, forceRerender } = useForceRerender();
|
||||
|
||||
const propData = [
|
||||
{
|
||||
@@ -96,5 +127,5 @@ const propData = [
|
||||
default: 'true',
|
||||
description: 'Whether the marquee can be dragged by the user'
|
||||
}
|
||||
]
|
||||
];
|
||||
</script>
|
||||
|
||||
@@ -4,20 +4,52 @@
|
||||
<template #preview>
|
||||
<div class="demo-container relative py-6 overflow-hidden">
|
||||
<RefreshButton @click="forceRerender" />
|
||||
|
||||
<div :key="key" class="pl-6 m-8 w-full flex flex-col justify-start items-start">
|
||||
<DecryptedText :speed="speed" text="Ahoy, matey!" :max-iterations="maxIterations" :sequential="sequential"
|
||||
:reveal-direction="revealDirection" parent-class-name="decrypted-text"
|
||||
:use-original-chars-only="useOriginalCharsOnly" :animate-on="animateOn" />
|
||||
<DecryptedText :speed="speed" text="Set yer eyes on this" :max-iterations="maxIterations"
|
||||
:sequential="sequential" :reveal-direction="revealDirection" parent-class-name="decrypted-text"
|
||||
:use-original-chars-only="useOriginalCharsOnly" :animate-on="animateOn" />
|
||||
<DecryptedText :speed="speed" text="And try tinkerin' round'" :max-iterations="maxIterations"
|
||||
:sequential="sequential" :reveal-direction="revealDirection" parent-class-name="decrypted-text"
|
||||
:use-original-chars-only="useOriginalCharsOnly" :animate-on="animateOn" />
|
||||
<DecryptedText :speed="speed" text="with these here props, arr!" :max-iterations="maxIterations"
|
||||
:sequential="sequential" :reveal-direction="revealDirection" parent-class-name="decrypted-text"
|
||||
:use-original-chars-only="useOriginalCharsOnly" :animate-on="animateOn"
|
||||
@animation-complete="() => console.log('✅ Animation Finished!')" />
|
||||
<DecryptedText
|
||||
:speed="speed"
|
||||
text="Ahoy, matey!"
|
||||
:max-iterations="maxIterations"
|
||||
:sequential="sequential"
|
||||
:reveal-direction="revealDirection"
|
||||
parent-class-name="decrypted-text"
|
||||
:use-original-chars-only="useOriginalCharsOnly"
|
||||
:animate-on="animateOn"
|
||||
/>
|
||||
|
||||
<DecryptedText
|
||||
:speed="speed"
|
||||
text="Set yer eyes on this"
|
||||
:max-iterations="maxIterations"
|
||||
:sequential="sequential"
|
||||
:reveal-direction="revealDirection"
|
||||
parent-class-name="decrypted-text"
|
||||
:use-original-chars-only="useOriginalCharsOnly"
|
||||
:animate-on="animateOn"
|
||||
/>
|
||||
|
||||
<DecryptedText
|
||||
:speed="speed"
|
||||
text="And try tinkerin' round'"
|
||||
:max-iterations="maxIterations"
|
||||
:sequential="sequential"
|
||||
:reveal-direction="revealDirection"
|
||||
parent-class-name="decrypted-text"
|
||||
:use-original-chars-only="useOriginalCharsOnly"
|
||||
:animate-on="animateOn"
|
||||
/>
|
||||
|
||||
<DecryptedText
|
||||
:speed="speed"
|
||||
text="with these here props, arr!"
|
||||
:max-iterations="maxIterations"
|
||||
:sequential="sequential"
|
||||
:reveal-direction="revealDirection"
|
||||
parent-class-name="decrypted-text"
|
||||
:use-original-chars-only="useOriginalCharsOnly"
|
||||
:animate-on="animateOn"
|
||||
@animation-complete="() => console.log('✅ Animation Finished!')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -26,17 +58,48 @@
|
||||
|
||||
<PreviewSwitch title="Original Chars" v-model="useOriginalCharsOnly" @update:model-value="forceRerender" />
|
||||
|
||||
<PreviewSlider title="Speed" v-model="speed" :min="10" :max="200" :step="10" value-unit="ms"
|
||||
@update:model-value="forceRerender" />
|
||||
<PreviewSlider
|
||||
title="Speed"
|
||||
v-model="speed"
|
||||
:min="10"
|
||||
:max="200"
|
||||
:step="10"
|
||||
value-unit="ms"
|
||||
@update:model-value="forceRerender"
|
||||
/>
|
||||
|
||||
<PreviewSlider title="Iterations" v-model="maxIterations" :min="1" :max="50" :step="1"
|
||||
@update:model-value="forceRerender" />
|
||||
<PreviewSlider
|
||||
title="Iterations"
|
||||
v-model="maxIterations"
|
||||
:min="1"
|
||||
:max="50"
|
||||
:step="1"
|
||||
@update:model-value="forceRerender"
|
||||
/>
|
||||
|
||||
<PreviewSelect title="Animation Trigger" v-model="animateOn" :options="animateOptions"
|
||||
@update:model-value="(val) => { animateOn = val as 'view' | 'hover'; forceRerender(); }" />
|
||||
<PreviewSelect
|
||||
title="Animation Trigger"
|
||||
v-model="animateOn"
|
||||
:options="animateOptions"
|
||||
@update:model-value="
|
||||
val => {
|
||||
animateOn = val as 'view' | 'hover';
|
||||
forceRerender();
|
||||
}
|
||||
"
|
||||
/>
|
||||
|
||||
<PreviewSelect title="Animation Direction" v-model="revealDirection" :options="directionOptions"
|
||||
@update:model-value="(val) => { revealDirection = val as 'start' | 'end' | 'center'; forceRerender(); }" />
|
||||
<PreviewSelect
|
||||
title="Animation Direction"
|
||||
v-model="revealDirection"
|
||||
:options="directionOptions"
|
||||
@update:model-value="
|
||||
val => {
|
||||
revealDirection = val as 'start' | 'end' | 'center';
|
||||
forceRerender();
|
||||
}
|
||||
"
|
||||
/>
|
||||
</Customize>
|
||||
|
||||
<PropTable :data="propData" />
|
||||
@@ -54,39 +117,39 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue'
|
||||
import PropTable from '../../components/common/PropTable.vue'
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue'
|
||||
import CodeExample from '../../components/code/CodeExample.vue'
|
||||
import Customize from '../../components/common/Customize.vue'
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue'
|
||||
import PreviewSwitch from '../../components/common/PreviewSwitch.vue'
|
||||
import PreviewSelect from '../../components/common/PreviewSelect.vue'
|
||||
import RefreshButton from '../../components/common/RefreshButton.vue'
|
||||
import DecryptedText from '../../content/TextAnimations/DecryptedText/DecryptedText.vue'
|
||||
import { decryptedText } from '@/constants/code/TextAnimations/decryptedTextCode'
|
||||
import { useForceRerender } from '@/composables/useForceRerender'
|
||||
import { ref } from 'vue';
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue';
|
||||
import PropTable from '../../components/common/PropTable.vue';
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue';
|
||||
import CodeExample from '../../components/code/CodeExample.vue';
|
||||
import Customize from '../../components/common/Customize.vue';
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue';
|
||||
import PreviewSwitch from '../../components/common/PreviewSwitch.vue';
|
||||
import PreviewSelect from '../../components/common/PreviewSelect.vue';
|
||||
import RefreshButton from '../../components/common/RefreshButton.vue';
|
||||
import DecryptedText from '../../content/TextAnimations/DecryptedText/DecryptedText.vue';
|
||||
import { decryptedText } from '@/constants/code/TextAnimations/decryptedTextCode';
|
||||
import { useForceRerender } from '@/composables/useForceRerender';
|
||||
|
||||
const { rerenderKey: key, forceRerender } = useForceRerender()
|
||||
const { rerenderKey: key, forceRerender } = useForceRerender();
|
||||
|
||||
const speed = ref(60)
|
||||
const maxIterations = ref(10)
|
||||
const sequential = ref(true)
|
||||
const useOriginalCharsOnly = ref(false)
|
||||
const revealDirection = ref<'start' | 'end' | 'center'>('start')
|
||||
const animateOn = ref<'view' | 'hover'>('view')
|
||||
const speed = ref(60);
|
||||
const maxIterations = ref(10);
|
||||
const sequential = ref(true);
|
||||
const useOriginalCharsOnly = ref(false);
|
||||
const revealDirection = ref<'start' | 'end' | 'center'>('start');
|
||||
const animateOn = ref<'view' | 'hover'>('view');
|
||||
|
||||
const animateOptions = [
|
||||
{ label: 'View', value: 'view' },
|
||||
{ label: 'Hover', value: 'hover' }
|
||||
]
|
||||
];
|
||||
|
||||
const directionOptions = [
|
||||
{ label: 'Start', value: 'start' },
|
||||
{ label: 'End', value: 'end' },
|
||||
{ label: 'Center', value: 'center' }
|
||||
]
|
||||
];
|
||||
|
||||
const propData = [
|
||||
{
|
||||
@@ -149,7 +212,7 @@ const propData = [
|
||||
default: '"hover"',
|
||||
description: 'Trigger scrambling on hover or scroll-into-view.'
|
||||
}
|
||||
]
|
||||
];
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -3,10 +3,15 @@
|
||||
<TabbedLayout>
|
||||
<template #preview>
|
||||
<div class="demo-container relative h-[400px] overflow-hidden p-0 flex justify-center items-center">
|
||||
<FallingText :key="key"
|
||||
<FallingText
|
||||
:key="key"
|
||||
text="Vue Bits is a library of animated and interactive Vue components designed to streamline UI development and simplify your workflow."
|
||||
:highlight-words="['Vue', 'Bits', 'animated', 'components', 'simplify']" :trigger="trigger"
|
||||
:gravity="gravity" font-size="2rem" :mouse-constraint-stiffness="mouseConstraintStiffness" />
|
||||
:highlight-words="['Vue', 'Bits', 'animated', 'components', 'simplify']"
|
||||
:trigger="trigger"
|
||||
:gravity="gravity"
|
||||
font-size="2rem"
|
||||
:mouse-constraint-stiffness="mouseConstraintStiffness"
|
||||
/>
|
||||
|
||||
<div class="absolute z-0 text-[4rem] font-[900] text-[#222] select-none" v-if="!effectStarted">
|
||||
{{ trigger === 'hover' ? 'Hover Me' : trigger === 'click' ? 'Click Me' : 'Auto Start' }}
|
||||
@@ -14,17 +19,34 @@
|
||||
</div>
|
||||
|
||||
<Customize>
|
||||
<PreviewSelect title="Animation Trigger" v-model="trigger" :options="triggerOptions"
|
||||
@update:model-value="forceRerender" />
|
||||
<PreviewSelect
|
||||
title="Animation Trigger"
|
||||
v-model="trigger"
|
||||
:options="triggerOptions"
|
||||
@update:model-value="forceRerender"
|
||||
/>
|
||||
|
||||
<PreviewSlider title="Gravity" v-model="gravity" :min="0.1" :max="2" :step="0.01"
|
||||
@update:model-value="forceRerender" />
|
||||
<PreviewSlider
|
||||
title="Gravity"
|
||||
v-model="gravity"
|
||||
:min="0.1"
|
||||
:max="2"
|
||||
:step="0.01"
|
||||
@update:model-value="forceRerender"
|
||||
/>
|
||||
|
||||
<PreviewSlider title="Mouse Constraint Stiffness" v-model="mouseConstraintStiffness" :min="0.1" :max="2"
|
||||
:step="0.1" @update:model-value="forceRerender" />
|
||||
<PreviewSlider
|
||||
title="Mouse Constraint Stiffness"
|
||||
v-model="mouseConstraintStiffness"
|
||||
:min="0.1"
|
||||
:max="2"
|
||||
:step="0.1"
|
||||
@update:model-value="forceRerender"
|
||||
/>
|
||||
</Customize>
|
||||
|
||||
<PropTable :data="propData" />
|
||||
|
||||
<Dependencies :dependency-list="['matter-js']" />
|
||||
</template>
|
||||
|
||||
@@ -40,33 +62,33 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue'
|
||||
import PropTable from '../../components/common/PropTable.vue'
|
||||
import Dependencies from '../../components/code/Dependencies.vue'
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue'
|
||||
import CodeExample from '../../components/code/CodeExample.vue'
|
||||
import Customize from '../../components/common/Customize.vue'
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue'
|
||||
import PreviewSelect from '../../components/common/PreviewSelect.vue'
|
||||
import FallingText from '../../content/TextAnimations/FallingText/FallingText.vue'
|
||||
import { fallingText } from '@/constants/code/TextAnimations/fallingTextCode'
|
||||
import { useForceRerender } from '@/composables/useForceRerender'
|
||||
import { ref, computed } from 'vue';
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue';
|
||||
import PropTable from '../../components/common/PropTable.vue';
|
||||
import Dependencies from '../../components/code/Dependencies.vue';
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue';
|
||||
import CodeExample from '../../components/code/CodeExample.vue';
|
||||
import Customize from '../../components/common/Customize.vue';
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue';
|
||||
import PreviewSelect from '../../components/common/PreviewSelect.vue';
|
||||
import FallingText from '../../content/TextAnimations/FallingText/FallingText.vue';
|
||||
import { fallingText } from '@/constants/code/TextAnimations/fallingTextCode';
|
||||
import { useForceRerender } from '@/composables/useForceRerender';
|
||||
|
||||
const { rerenderKey: key, forceRerender } = useForceRerender()
|
||||
const { rerenderKey: key, forceRerender } = useForceRerender();
|
||||
|
||||
const gravity = ref(0.56)
|
||||
const mouseConstraintStiffness = ref(0.9)
|
||||
const trigger = ref<'hover' | 'click' | 'auto' | 'scroll'>('hover')
|
||||
const gravity = ref(0.56);
|
||||
const mouseConstraintStiffness = ref(0.9);
|
||||
const trigger = ref<'hover' | 'click' | 'auto' | 'scroll'>('hover');
|
||||
|
||||
const effectStarted = computed(() => trigger.value === 'auto')
|
||||
const effectStarted = computed(() => trigger.value === 'auto');
|
||||
|
||||
const triggerOptions = [
|
||||
{ value: 'hover', label: 'Hover' },
|
||||
{ value: 'click', label: 'Click' },
|
||||
{ value: 'auto', label: 'Auto' },
|
||||
{ value: 'scroll', label: 'Scroll' }
|
||||
]
|
||||
];
|
||||
|
||||
const propData = [
|
||||
{
|
||||
@@ -117,7 +139,7 @@ const propData = [
|
||||
default: '"1rem"',
|
||||
description: 'Font size applied to the text before it falls.'
|
||||
}
|
||||
]
|
||||
];
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
|
||||
@@ -4,23 +4,58 @@
|
||||
<template #preview>
|
||||
<div class="demo-container relative h-[500px] overflow-hidden">
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<FuzzyText :key="`main-${rerenderKey}`" text="404" :base-intensity="baseIntensity"
|
||||
:hover-intensity="hoverIntensity" :enable-hover="enableHover" :font-size="140" />
|
||||
<FuzzyText
|
||||
:key="`main-${rerenderKey}`"
|
||||
text="404"
|
||||
:base-intensity="baseIntensity"
|
||||
:hover-intensity="hoverIntensity"
|
||||
:enable-hover="enableHover"
|
||||
:font-size="140"
|
||||
/>
|
||||
|
||||
<div class="my-1" />
|
||||
<FuzzyText :key="`sub-${rerenderKey}`" text="not found" :base-intensity="baseIntensity"
|
||||
:hover-intensity="hoverIntensity" :enable-hover="enableHover" :font-size="70" font-family="Gochi Hand" />
|
||||
|
||||
<FuzzyText
|
||||
:key="`sub-${rerenderKey}`"
|
||||
text="not found"
|
||||
:base-intensity="baseIntensity"
|
||||
:hover-intensity="hoverIntensity"
|
||||
:enable-hover="enableHover"
|
||||
:font-size="70"
|
||||
font-family="Gochi Hand"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Customize>
|
||||
<PreviewSlider title="Base Intensity" v-model="baseIntensity" :min="0" :max="1" :step="0.01"
|
||||
@update:model-value="forceRerender" />
|
||||
<PreviewSlider
|
||||
title="Base Intensity"
|
||||
v-model="baseIntensity"
|
||||
:min="0"
|
||||
:max="1"
|
||||
:step="0.01"
|
||||
@update:model-value="forceRerender"
|
||||
/>
|
||||
|
||||
<PreviewSlider title="Hover Intensity" v-model="hoverIntensity" :min="0" :max="2" :step="0.01"
|
||||
@update:model-value="forceRerender" />
|
||||
<PreviewSlider
|
||||
title="Hover Intensity"
|
||||
v-model="hoverIntensity"
|
||||
:min="0"
|
||||
:max="2"
|
||||
:step="0.01"
|
||||
@update:model-value="forceRerender"
|
||||
/>
|
||||
|
||||
<PreviewSwitch title="Enable Hover" :model-value="enableHover"
|
||||
@update:model-value="(val: boolean) => { enableHover = val; forceRerender() }" />
|
||||
<PreviewSwitch
|
||||
title="Enable Hover"
|
||||
:model-value="enableHover"
|
||||
@update:model-value="
|
||||
(val: boolean) => {
|
||||
enableHover = val;
|
||||
forceRerender();
|
||||
}
|
||||
"
|
||||
/>
|
||||
</Customize>
|
||||
|
||||
<PropTable :data="propData" />
|
||||
@@ -38,23 +73,23 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue'
|
||||
import PropTable from '../../components/common/PropTable.vue'
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue'
|
||||
import CodeExample from '../../components/code/CodeExample.vue'
|
||||
import Customize from '../../components/common/Customize.vue'
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue'
|
||||
import PreviewSwitch from '../../components/common/PreviewSwitch.vue'
|
||||
import FuzzyText from '../../content/TextAnimations/FuzzyText/FuzzyText.vue'
|
||||
import { fuzzyText } from '@/constants/code/TextAnimations/fuzzyTextCode'
|
||||
import { useForceRerender } from '@/composables/useForceRerender'
|
||||
import { ref } from 'vue';
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue';
|
||||
import PropTable from '../../components/common/PropTable.vue';
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue';
|
||||
import CodeExample from '../../components/code/CodeExample.vue';
|
||||
import Customize from '../../components/common/Customize.vue';
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue';
|
||||
import PreviewSwitch from '../../components/common/PreviewSwitch.vue';
|
||||
import FuzzyText from '../../content/TextAnimations/FuzzyText/FuzzyText.vue';
|
||||
import { fuzzyText } from '@/constants/code/TextAnimations/fuzzyTextCode';
|
||||
import { useForceRerender } from '@/composables/useForceRerender';
|
||||
|
||||
const baseIntensity = ref(0.2)
|
||||
const hoverIntensity = ref(0.5)
|
||||
const enableHover = ref(true)
|
||||
const baseIntensity = ref(0.2);
|
||||
const hoverIntensity = ref(0.5);
|
||||
const enableHover = ref(true);
|
||||
|
||||
const { rerenderKey, forceRerender } = useForceRerender()
|
||||
const { rerenderKey, forceRerender } = useForceRerender();
|
||||
|
||||
const propData = [
|
||||
{
|
||||
@@ -67,7 +102,8 @@ const propData = [
|
||||
name: 'fontSize',
|
||||
type: 'number | string',
|
||||
default: '"clamp(2rem, 8vw, 8rem)"',
|
||||
description: 'Specifies the font size of the text. Accepts any valid CSS font-size value or a number (interpreted as pixels).'
|
||||
description:
|
||||
'Specifies the font size of the text. Accepts any valid CSS font-size value or a number (interpreted as pixels).'
|
||||
},
|
||||
{
|
||||
name: 'fontWeight',
|
||||
@@ -105,5 +141,5 @@ const propData = [
|
||||
default: '0.5',
|
||||
description: 'The fuzz intensity when the text is hovered.'
|
||||
}
|
||||
]
|
||||
];
|
||||
</script>
|
||||
|
||||
@@ -3,18 +3,29 @@
|
||||
<TabbedLayout>
|
||||
<template #preview>
|
||||
<h2 class="demo-title-extra">Default</h2>
|
||||
|
||||
<div class="demo-container relative min-h-[150px] flex items-center justify-center">
|
||||
<div class="text-[2rem]">
|
||||
<GradientText text="Add a splash of color!" :colors="gradientPreview" :animation-speed="speed"
|
||||
:show-border="false" />
|
||||
<GradientText
|
||||
text="Add a splash of color!"
|
||||
:colors="gradientPreview"
|
||||
:animation-speed="speed"
|
||||
:show-border="false"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 class="demo-title-extra">Border Animation</h2>
|
||||
|
||||
<div class="demo-container relative min-h-[150px] flex items-center justify-center">
|
||||
<div class="text-[2rem]">
|
||||
<GradientText text="Now with a cool border!" :colors="gradientPreview" :animation-speed="speed"
|
||||
:show-border="true" class-name="custom-gradient-class" />
|
||||
<GradientText
|
||||
text="Now with a cool border!"
|
||||
:colors="gradientPreview"
|
||||
:animation-speed="speed"
|
||||
:show-border="true"
|
||||
class-name="custom-gradient-class"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -24,20 +35,32 @@
|
||||
<div class="flex flex-col gap-0">
|
||||
<div class="mb-4">
|
||||
<label class="block text-sm font-medium mb-2">Colors</label>
|
||||
<input v-model="colors" type="text" placeholder="Enter colors separated by commas" maxlength="100"
|
||||
class="w-[300px] px-3 py-2 bg-[#0b0b0b] border border-[#333] rounded-md text-white focus:outline-none focus:border-[#666]" />
|
||||
|
||||
<input
|
||||
v-model="colors"
|
||||
type="text"
|
||||
placeholder="Enter colors separated by commas"
|
||||
maxlength="100"
|
||||
class="w-[300px] px-3 py-2 bg-[#0b0b0b] border border-[#333] rounded-md text-white focus:outline-none focus:border-[#666]"
|
||||
/>
|
||||
</div>
|
||||
<div class="w-[300px] h-3 rounded-md border border-[#271E37]" :style="{
|
||||
background: `linear-gradient(to right, ${gradientPreview.join(', ')})`
|
||||
}" />
|
||||
|
||||
<div
|
||||
class="w-[300px] h-3 rounded-md border border-[#271E37]"
|
||||
:style="{
|
||||
background: `linear-gradient(to right, ${gradientPreview.join(', ')})`
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
</Customize>
|
||||
|
||||
<p class="demo-extra-info mt-4 flex items-center gap-2">
|
||||
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd"
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
|
||||
clip-rule="evenodd" />
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
For a smoother animation, the gradient should start and end with the same color.
|
||||
</p>
|
||||
@@ -57,20 +80,20 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue'
|
||||
import PropTable from '../../components/common/PropTable.vue'
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue'
|
||||
import CodeExample from '../../components/code/CodeExample.vue'
|
||||
import Customize from '../../components/common/Customize.vue'
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue'
|
||||
import GradientText from '../../content/TextAnimations/GradientText/GradientText.vue'
|
||||
import { gradientText } from '@/constants/code/TextAnimations/gradientTextCode'
|
||||
import { ref, computed } from 'vue';
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue';
|
||||
import PropTable from '../../components/common/PropTable.vue';
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue';
|
||||
import CodeExample from '../../components/code/CodeExample.vue';
|
||||
import Customize from '../../components/common/Customize.vue';
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue';
|
||||
import GradientText from '../../content/TextAnimations/GradientText/GradientText.vue';
|
||||
import { gradientText } from '@/constants/code/TextAnimations/gradientTextCode';
|
||||
|
||||
const colors = ref('#40ffaa, #4079ff, #40ffaa, #4079ff, #40ffaa')
|
||||
const speed = ref(3)
|
||||
const colors = ref('#40ffaa, #4079ff, #40ffaa, #4079ff, #40ffaa');
|
||||
const speed = ref(3);
|
||||
|
||||
const gradientPreview = computed(() => colors.value.split(',').map(color => color.trim()))
|
||||
const gradientPreview = computed(() => colors.value.split(',').map(color => color.trim()));
|
||||
|
||||
const propData = [
|
||||
{
|
||||
@@ -103,7 +126,7 @@ const propData = [
|
||||
default: 'false',
|
||||
description: 'Determines whether a border with the gradient effect is displayed.'
|
||||
}
|
||||
]
|
||||
];
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -2,30 +2,35 @@
|
||||
<TabbedLayout>
|
||||
<template #preview>
|
||||
<div ref="containerRef" class="demo-container" @wheel="smoothScroll">
|
||||
|
||||
<div class="scroll-instruction">
|
||||
Scroll Down
|
||||
</div>
|
||||
<div class="scroll-instruction">Scroll Down</div>
|
||||
|
||||
<div class="scroll-content">
|
||||
<ScrollFloat
|
||||
:children="scrollText"
|
||||
:animation-duration="animationDuration"
|
||||
<ScrollFloat
|
||||
:children="scrollText"
|
||||
:animation-duration="animationDuration"
|
||||
:ease="ease"
|
||||
:scroll-start="scrollStart"
|
||||
:scroll-end="scrollEnd"
|
||||
:scroll-start="scrollStart"
|
||||
:scroll-end="scrollEnd"
|
||||
:stagger="stagger"
|
||||
:container-class-name="containerClassName"
|
||||
:container-class-name="containerClassName"
|
||||
:text-class-name="textClassName"
|
||||
:scroll-container-ref="{ current: containerRef }"
|
||||
:key="rerenderKey"
|
||||
:scroll-container-ref="{ current: containerRef }"
|
||||
:key="rerenderKey"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Customize>
|
||||
<PreviewSlider title="Stagger:" v-model="stagger" :min="0.01" :max="0.1" :step="0.01" value-unit="s" />
|
||||
<PreviewSlider title="Animation Duration:" v-model="animationDuration" :min="1" :max="10" :step="0.1" value-unit="s" />
|
||||
|
||||
<PreviewSlider
|
||||
title="Animation Duration:"
|
||||
v-model="animationDuration"
|
||||
:min="1"
|
||||
:max="10"
|
||||
:step="0.1"
|
||||
value-unit="s"
|
||||
/>
|
||||
</Customize>
|
||||
|
||||
<PropTable :data="propData" />
|
||||
@@ -42,60 +47,57 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted } from 'vue'
|
||||
import { gsap } from 'gsap'
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue'
|
||||
import PropTable from '../../components/common/PropTable.vue'
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue'
|
||||
import CodeExample from '../../components/code/CodeExample.vue'
|
||||
import Customize from '../../components/common/Customize.vue'
|
||||
import ScrollFloat from '../../content/TextAnimations/ScrollFloat/ScrollFloat.vue'
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue'
|
||||
import { scrollFloatCode } from '@/constants/code/TextAnimations/scrollFloatCode'
|
||||
|
||||
|
||||
const containerRef = ref<HTMLElement | null>(null)
|
||||
const scrollText = ref("vuebits")
|
||||
const animationDuration = ref(1)
|
||||
const ease = ref('back.inOut(2)')
|
||||
const scrollStart = ref('center bottom+=50%')
|
||||
const scrollEnd = ref('bottom bottom-=40%')
|
||||
const stagger = ref(0.03)
|
||||
const containerClassName = ref("")
|
||||
const textClassName = ref("")
|
||||
const rerenderKey = ref(0)
|
||||
import { ref, onMounted, onUnmounted } from 'vue';
|
||||
import { gsap } from 'gsap';
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue';
|
||||
import PropTable from '../../components/common/PropTable.vue';
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue';
|
||||
import CodeExample from '../../components/code/CodeExample.vue';
|
||||
import Customize from '../../components/common/Customize.vue';
|
||||
import ScrollFloat from '../../content/TextAnimations/ScrollFloat/ScrollFloat.vue';
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue';
|
||||
import { scrollFloatCode } from '@/constants/code/TextAnimations/scrollFloatCode';
|
||||
|
||||
const containerRef = ref<HTMLElement | null>(null);
|
||||
const scrollText = ref('vuebits');
|
||||
const animationDuration = ref(1);
|
||||
const ease = ref('back.inOut(2)');
|
||||
const scrollStart = ref('center bottom+=50%');
|
||||
const scrollEnd = ref('bottom bottom-=40%');
|
||||
const stagger = ref(0.03);
|
||||
const containerClassName = ref('');
|
||||
const textClassName = ref('');
|
||||
const rerenderKey = ref(0);
|
||||
|
||||
const smoothScroll = (e: WheelEvent) => {
|
||||
e.preventDefault()
|
||||
const container = containerRef.value
|
||||
if (!container) return
|
||||
e.preventDefault();
|
||||
const container = containerRef.value;
|
||||
if (!container) return;
|
||||
|
||||
const delta = e.deltaY || e.detail
|
||||
const scrollAmount = delta * 2
|
||||
const delta = e.deltaY || e.detail;
|
||||
const scrollAmount = delta * 2;
|
||||
|
||||
gsap.to(container, {
|
||||
scrollTop: container.scrollTop + scrollAmount,
|
||||
duration: 1,
|
||||
ease: "power3.out",
|
||||
overwrite: "auto"
|
||||
})
|
||||
}
|
||||
|
||||
ease: 'power3.out',
|
||||
overwrite: 'auto'
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
const container = containerRef.value
|
||||
const container = containerRef.value;
|
||||
if (container) {
|
||||
container.addEventListener('wheel', smoothScroll, { passive: false })
|
||||
container.addEventListener('wheel', smoothScroll, { passive: false });
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
const container = containerRef.value
|
||||
const container = containerRef.value;
|
||||
if (container) {
|
||||
container.removeEventListener('wheel', smoothScroll)
|
||||
container.removeEventListener('wheel', smoothScroll);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
const propData = [
|
||||
{
|
||||
@@ -152,8 +154,9 @@ const propData = [
|
||||
default: '0.03',
|
||||
description: 'Delay between each character animation'
|
||||
}
|
||||
]
|
||||
];
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.demo-container {
|
||||
height: 60vh;
|
||||
@@ -180,4 +183,4 @@ const propData = [
|
||||
.scroll-content {
|
||||
color: aliceblue;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
<TabbedLayout>
|
||||
<template #preview>
|
||||
<h2 class="demo-title-extra">Basic</h2>
|
||||
|
||||
<div class="demo-container relative min-h-[150px] text-2xl flex items-center justify-center">
|
||||
<ShinyText text="Just some shiny text!" :disabled="false" :speed="3" class-name="shiny-text-demo" />
|
||||
</div>
|
||||
|
||||
<h2 class="demo-title-extra">Button Text</h2>
|
||||
|
||||
<div class="demo-container relative min-h-[150px] text-2xl flex items-center justify-center">
|
||||
<div class="shiny-button">
|
||||
<ShinyText text="Shiny Button" :disabled="false" :speed="3" class-name="shiny-text-demo" />
|
||||
@@ -15,9 +17,14 @@
|
||||
</div>
|
||||
|
||||
<h2 class="demo-title-extra">Configurable Speed</h2>
|
||||
|
||||
<div class="demo-container relative min-h-[150px] text-2xl flex items-center justify-center">
|
||||
<ShinyText :text="speed < 2.5 ? '🐎 This is fast!' : '🐌 This is slow!'" :disabled="false" :speed="speed"
|
||||
class-name="shiny-text-demo" />
|
||||
<ShinyText
|
||||
:text="speed < 2.5 ? '🐎 This is fast!' : '🐌 This is slow!'"
|
||||
:disabled="false"
|
||||
:speed="speed"
|
||||
class-name="shiny-text-demo"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Customize>
|
||||
@@ -39,17 +46,17 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue'
|
||||
import PropTable from '../../components/common/PropTable.vue'
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue'
|
||||
import CodeExample from '../../components/code/CodeExample.vue'
|
||||
import Customize from '../../components/common/Customize.vue'
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue'
|
||||
import ShinyText from '../../content/TextAnimations/ShinyText/ShinyText.vue'
|
||||
import { shinyText } from '@/constants/code/TextAnimations/shinyTextCode'
|
||||
import { ref } from 'vue';
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue';
|
||||
import PropTable from '../../components/common/PropTable.vue';
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue';
|
||||
import CodeExample from '../../components/code/CodeExample.vue';
|
||||
import Customize from '../../components/common/Customize.vue';
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue';
|
||||
import ShinyText from '../../content/TextAnimations/ShinyText/ShinyText.vue';
|
||||
import { shinyText } from '@/constants/code/TextAnimations/shinyTextCode';
|
||||
|
||||
const speed = ref(3)
|
||||
const speed = ref(3);
|
||||
|
||||
const propData = [
|
||||
{
|
||||
@@ -76,7 +83,7 @@ const propData = [
|
||||
default: "''",
|
||||
description: 'Adds custom classes to the root element.'
|
||||
}
|
||||
]
|
||||
];
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -5,25 +5,56 @@
|
||||
<div class="demo-container">
|
||||
<RefreshButton @refresh="forceRerender" />
|
||||
|
||||
<SplitText :key="rerenderKey" text="Hello, Vue!" :delay="delay" :duration="duration" :ease="ease"
|
||||
:split-type="splitType" :threshold="threshold" class="split-text-demo-text"
|
||||
@animation-complete="() => { showCallback && showToast() }" />
|
||||
<SplitText
|
||||
:key="rerenderKey"
|
||||
text="Hello, Vue!"
|
||||
:delay="delay"
|
||||
:duration="duration"
|
||||
:ease="ease"
|
||||
:split-type="splitType"
|
||||
:threshold="threshold"
|
||||
class="split-text-demo-text"
|
||||
@animation-complete="
|
||||
() => {
|
||||
showCallback && showToast();
|
||||
}
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Customize>
|
||||
<PreviewSwitch title="Show Completion Toast" v-model="showCallback" @update:model-value="forceRerender" />
|
||||
|
||||
<PreviewSlider title="Stagger Delay (ms)" v-model="delay" :min="10" :max="500" :step="10"
|
||||
@update:model-value="forceRerender" />
|
||||
<PreviewSlider
|
||||
title="Stagger Delay (ms)"
|
||||
v-model="delay"
|
||||
:min="10"
|
||||
:max="500"
|
||||
:step="10"
|
||||
@update:model-value="forceRerender"
|
||||
/>
|
||||
|
||||
<PreviewSlider title="Duration (s)" v-model="duration" :min="0.1" :max="2" :step="0.1"
|
||||
@update:model-value="forceRerender" />
|
||||
<PreviewSlider
|
||||
title="Duration (s)"
|
||||
v-model="duration"
|
||||
:min="0.1"
|
||||
:max="2"
|
||||
:step="0.1"
|
||||
@update:model-value="forceRerender"
|
||||
/>
|
||||
|
||||
<PreviewSlider title="Threshold" v-model="threshold" :min="0.1" :max="1" :step="0.1"
|
||||
@update:model-value="forceRerender" />
|
||||
<PreviewSlider
|
||||
title="Threshold"
|
||||
v-model="threshold"
|
||||
:min="0.1"
|
||||
:max="1"
|
||||
:step="0.1"
|
||||
@update:model-value="forceRerender"
|
||||
/>
|
||||
</Customize>
|
||||
|
||||
<PropTable :data="propData" />
|
||||
|
||||
<Dependencies :dependency-list="['gsap']" />
|
||||
</template>
|
||||
|
||||
@@ -39,37 +70,37 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue'
|
||||
import RefreshButton from '../../components/common/RefreshButton.vue'
|
||||
import PropTable from '../../components/common/PropTable.vue'
|
||||
import Dependencies from '../../components/code/Dependencies.vue'
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue'
|
||||
import CodeExample from '../../components/code/CodeExample.vue'
|
||||
import Customize from '../../components/common/Customize.vue'
|
||||
import PreviewSwitch from '../../components/common/PreviewSwitch.vue'
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue'
|
||||
import SplitText from '../../content/TextAnimations/SplitText/SplitText.vue'
|
||||
import { splitText } from '@/constants/code/TextAnimations/splitTextCode'
|
||||
import { useToast } from 'primevue/usetoast'
|
||||
import { useForceRerender } from '@/composables/useForceRerender'
|
||||
import { ref } from 'vue';
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue';
|
||||
import RefreshButton from '../../components/common/RefreshButton.vue';
|
||||
import PropTable from '../../components/common/PropTable.vue';
|
||||
import Dependencies from '../../components/code/Dependencies.vue';
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue';
|
||||
import CodeExample from '../../components/code/CodeExample.vue';
|
||||
import Customize from '../../components/common/Customize.vue';
|
||||
import PreviewSwitch from '../../components/common/PreviewSwitch.vue';
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue';
|
||||
import SplitText from '../../content/TextAnimations/SplitText/SplitText.vue';
|
||||
import { splitText } from '@/constants/code/TextAnimations/splitTextCode';
|
||||
import { useToast } from 'primevue/usetoast';
|
||||
import { useForceRerender } from '@/composables/useForceRerender';
|
||||
|
||||
const delay = ref(10)
|
||||
const duration = ref(2)
|
||||
const ease = ref('elastic.out(1, 0.3)')
|
||||
const splitType = ref<'chars' | 'words' | 'lines' | 'words, chars'>('chars')
|
||||
const threshold = ref(0.1)
|
||||
const showCallback = ref(true)
|
||||
const toast = useToast()
|
||||
const { rerenderKey, forceRerender } = useForceRerender()
|
||||
const delay = ref(10);
|
||||
const duration = ref(2);
|
||||
const ease = ref('elastic.out(1, 0.3)');
|
||||
const splitType = ref<'chars' | 'words' | 'lines' | 'words, chars'>('chars');
|
||||
const threshold = ref(0.1);
|
||||
const showCallback = ref(true);
|
||||
const toast = useToast();
|
||||
const { rerenderKey, forceRerender } = useForceRerender();
|
||||
|
||||
const showToast = () => {
|
||||
toast.add({
|
||||
severity: 'secondary',
|
||||
summary: 'Animation Finished!',
|
||||
life: 3000
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const propData = [
|
||||
{ name: 'text', type: 'string', default: '""', description: 'The text content to animate.' },
|
||||
@@ -77,12 +108,42 @@ const propData = [
|
||||
{ name: 'delay', type: 'number', default: '100', description: 'Delay between animations for each letter (in ms).' },
|
||||
{ name: 'duration', type: 'number', default: '0.6', description: 'Duration of each letter animation (in seconds).' },
|
||||
{ name: 'ease', type: 'string', default: '"power3.out"', description: 'GSAP easing function for the animation.' },
|
||||
{ name: 'splitType', type: 'string', default: '"chars"', description: 'Split type: "chars", "words", "lines", or "words, chars".' },
|
||||
{ name: 'from', type: 'object', default: '{ opacity: 0, y: 40 }', description: 'Initial GSAP properties for each letter/word.' },
|
||||
{ name: 'to', type: 'object', default: '{ opacity: 1, y: 0 }', description: 'Target GSAP properties for each letter/word.' },
|
||||
{ name: 'threshold', type: 'number', default: '0.1', description: 'Intersection threshold to trigger the animation (0-1).' },
|
||||
{
|
||||
name: 'splitType',
|
||||
type: 'string',
|
||||
default: '"chars"',
|
||||
description: 'Split type: "chars", "words", "lines", or "words, chars".'
|
||||
},
|
||||
{
|
||||
name: 'from',
|
||||
type: 'object',
|
||||
default: '{ opacity: 0, y: 40 }',
|
||||
description: 'Initial GSAP properties for each letter/word.'
|
||||
},
|
||||
{
|
||||
name: 'to',
|
||||
type: 'object',
|
||||
default: '{ opacity: 1, y: 0 }',
|
||||
description: 'Target GSAP properties for each letter/word.'
|
||||
},
|
||||
{
|
||||
name: 'threshold',
|
||||
type: 'number',
|
||||
default: '0.1',
|
||||
description: 'Intersection threshold to trigger the animation (0-1).'
|
||||
},
|
||||
{ name: 'rootMargin', type: 'string', default: '"-100px"', description: 'Root margin for the ScrollTrigger.' },
|
||||
{ name: 'textAlign', type: 'string', default: '"center"', description: 'Text alignment: "left", "center", "right", etc.' },
|
||||
{ name: 'onLetterAnimationComplete', type: 'function', default: 'undefined', description: 'Callback function when all animations complete.' }
|
||||
]
|
||||
</script>
|
||||
{
|
||||
name: 'textAlign',
|
||||
type: 'string',
|
||||
default: '"center"',
|
||||
description: 'Text alignment: "left", "center", "right", etc.'
|
||||
},
|
||||
{
|
||||
name: 'onLetterAnimationComplete',
|
||||
type: 'function',
|
||||
default: 'undefined',
|
||||
description: 'Callback function when all animations complete.'
|
||||
}
|
||||
];
|
||||
</script>
|
||||
|
||||
@@ -3,10 +3,16 @@
|
||||
<TabbedLayout>
|
||||
<template #preview>
|
||||
<div class="demo-container relative h-[500px] overflow-hidden">
|
||||
<TextCursor :key="key" :text="text" :follow-mouse-direction="followMouseDirection"
|
||||
:random-float="randomFloat" />
|
||||
<TextCursor
|
||||
:key="key"
|
||||
:text="text"
|
||||
:follow-mouse-direction="followMouseDirection"
|
||||
:random-float="randomFloat"
|
||||
/>
|
||||
|
||||
<div
|
||||
class="absolute inset-0 flex items-center justify-center pointer-events-none text-[4rem] font-[900] text-[#222] select-none">
|
||||
class="absolute inset-0 flex items-center justify-center pointer-events-none text-[4rem] font-[900] text-[#222] select-none"
|
||||
>
|
||||
Hover Around!
|
||||
</div>
|
||||
</div>
|
||||
@@ -14,17 +20,27 @@
|
||||
<Customize>
|
||||
<div class="mb-4">
|
||||
<label class="block text-sm font-medium mb-2">Text</label>
|
||||
<input v-model="text" type="text" placeholder="Enter text..." maxlength="10"
|
||||
class="w-[160px] px-3 py-2 bg-[#0b0b0b] border border-[#333] rounded-md text-white focus:outline-none focus:border-[#666]" />
|
||||
|
||||
<input
|
||||
v-model="text"
|
||||
type="text"
|
||||
placeholder="Enter text..."
|
||||
maxlength="10"
|
||||
class="w-[160px] px-3 py-2 bg-[#0b0b0b] border border-[#333] rounded-md text-white focus:outline-none focus:border-[#666]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<PreviewSwitch title="Follow Mouse Direction" v-model="followMouseDirection"
|
||||
@update:model-value="forceRerender" />
|
||||
<PreviewSwitch
|
||||
title="Follow Mouse Direction"
|
||||
v-model="followMouseDirection"
|
||||
@update:model-value="forceRerender"
|
||||
/>
|
||||
|
||||
<PreviewSwitch title="Enable Random Floating" v-model="randomFloat" @update:model-value="forceRerender" />
|
||||
</Customize>
|
||||
|
||||
<PropTable :data="propData" />
|
||||
|
||||
<Dependencies :dependency-list="['motion-v']" />
|
||||
</template>
|
||||
|
||||
@@ -40,23 +56,23 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue'
|
||||
import PropTable from '../../components/common/PropTable.vue'
|
||||
import Dependencies from '../../components/code/Dependencies.vue'
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue'
|
||||
import CodeExample from '../../components/code/CodeExample.vue'
|
||||
import Customize from '../../components/common/Customize.vue'
|
||||
import PreviewSwitch from '../../components/common/PreviewSwitch.vue'
|
||||
import TextCursor from '../../content/TextAnimations/TextCursor/TextCursor.vue'
|
||||
import { textCursor } from '@/constants/code/TextAnimations/textCursorCode'
|
||||
import { useForceRerender } from '@/composables/useForceRerender'
|
||||
import { ref } from 'vue';
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue';
|
||||
import PropTable from '../../components/common/PropTable.vue';
|
||||
import Dependencies from '../../components/code/Dependencies.vue';
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue';
|
||||
import CodeExample from '../../components/code/CodeExample.vue';
|
||||
import Customize from '../../components/common/Customize.vue';
|
||||
import PreviewSwitch from '../../components/common/PreviewSwitch.vue';
|
||||
import TextCursor from '../../content/TextAnimations/TextCursor/TextCursor.vue';
|
||||
import { textCursor } from '@/constants/code/TextAnimations/textCursorCode';
|
||||
import { useForceRerender } from '@/composables/useForceRerender';
|
||||
|
||||
const { rerenderKey: key, forceRerender } = useForceRerender()
|
||||
const { rerenderKey: key, forceRerender } = useForceRerender();
|
||||
|
||||
const text = ref('💚')
|
||||
const followMouseDirection = ref(true)
|
||||
const randomFloat = ref(true)
|
||||
const text = ref('💚');
|
||||
const followMouseDirection = ref(true);
|
||||
const randomFloat = ref(true);
|
||||
|
||||
const propData = [
|
||||
{
|
||||
@@ -107,5 +123,5 @@ const propData = [
|
||||
default: '5',
|
||||
description: 'The maximum number of trail points to display.'
|
||||
}
|
||||
]
|
||||
</script>
|
||||
];
|
||||
</script>
|
||||
|
||||
@@ -4,17 +4,33 @@
|
||||
<template #preview>
|
||||
<div class="demo-container relative bg-[#060010] min-h-[400px] max-h-[450px] overflow-hidden mb-6">
|
||||
<div class="w-full h-full">
|
||||
<TextPressure :key="rerenderKey" :text="text" :flex="flex" :alpha="alpha" :stroke="stroke" :width="width"
|
||||
:weight="weight" :italic="italic" :text-color="textColor" :stroke-color="strokeColor"
|
||||
:min-font-size="36" />
|
||||
<TextPressure
|
||||
:key="rerenderKey"
|
||||
:text="text"
|
||||
:flex="flex"
|
||||
:alpha="alpha"
|
||||
:stroke="stroke"
|
||||
:width="width"
|
||||
:weight="weight"
|
||||
:italic="italic"
|
||||
:text-color="textColor"
|
||||
:stroke-color="strokeColor"
|
||||
:min-font-size="36"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Customize>
|
||||
<div class="mb-4">
|
||||
<label class="block text-sm font-medium mb-2">Text</label>
|
||||
<input v-model="text" type="text" placeholder="Your text here..." maxlength="10"
|
||||
class="w-[200px] px-3 py-2 bg-[#0b0b0b] border border-[#333] rounded-md text-white focus:outline-none focus:border-[#666]" />
|
||||
|
||||
<input
|
||||
v-model="text"
|
||||
type="text"
|
||||
placeholder="Your text here..."
|
||||
maxlength="10"
|
||||
class="w-[200px] px-3 py-2 bg-[#0b0b0b] border border-[#333] rounded-md text-white focus:outline-none focus:border-[#666]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="color-controls">
|
||||
@@ -24,19 +40,73 @@
|
||||
</div>
|
||||
|
||||
<p class="mt-6 text-[#999] text-sm">Animation Settings</p>
|
||||
|
||||
<div class="flex gap-4 flex-wrap">
|
||||
<PreviewSwitch title="Flex" :model-value="flex"
|
||||
@update:model-value="(val: boolean) => { flex = val; forceRerender() }" />
|
||||
<PreviewSwitch title="Alpha" :model-value="alpha"
|
||||
@update:model-value="(val: boolean) => { alpha = val; forceRerender() }" />
|
||||
<PreviewSwitch title="Stroke" :model-value="stroke"
|
||||
@update:model-value="(val: boolean) => { stroke = val; forceRerender() }" />
|
||||
<PreviewSwitch title="Width" :model-value="width"
|
||||
@update:model-value="(val: boolean) => { width = val; forceRerender() }" />
|
||||
<PreviewSwitch title="Weight" :model-value="weight"
|
||||
@update:model-value="(val: boolean) => { weight = val; forceRerender() }" />
|
||||
<PreviewSwitch title="Italic" :model-value="italic"
|
||||
@update:model-value="(val: boolean) => { italic = val; forceRerender() }" />
|
||||
<PreviewSwitch
|
||||
title="Flex"
|
||||
:model-value="flex"
|
||||
@update:model-value="
|
||||
(val: boolean) => {
|
||||
flex = val;
|
||||
forceRerender();
|
||||
}
|
||||
"
|
||||
/>
|
||||
|
||||
<PreviewSwitch
|
||||
title="Alpha"
|
||||
:model-value="alpha"
|
||||
@update:model-value="
|
||||
(val: boolean) => {
|
||||
alpha = val;
|
||||
forceRerender();
|
||||
}
|
||||
"
|
||||
/>
|
||||
|
||||
<PreviewSwitch
|
||||
title="Stroke"
|
||||
:model-value="stroke"
|
||||
@update:model-value="
|
||||
(val: boolean) => {
|
||||
stroke = val;
|
||||
forceRerender();
|
||||
}
|
||||
"
|
||||
/>
|
||||
|
||||
<PreviewSwitch
|
||||
title="Width"
|
||||
:model-value="width"
|
||||
@update:model-value="
|
||||
(val: boolean) => {
|
||||
width = val;
|
||||
forceRerender();
|
||||
}
|
||||
"
|
||||
/>
|
||||
|
||||
<PreviewSwitch
|
||||
title="Weight"
|
||||
:model-value="weight"
|
||||
@update:model-value="
|
||||
(val: boolean) => {
|
||||
weight = val;
|
||||
forceRerender();
|
||||
}
|
||||
"
|
||||
/>
|
||||
|
||||
<PreviewSwitch
|
||||
title="Italic"
|
||||
:model-value="italic"
|
||||
@update:model-value="
|
||||
(val: boolean) => {
|
||||
italic = val;
|
||||
forceRerender();
|
||||
}
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</Customize>
|
||||
|
||||
@@ -55,29 +125,29 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue'
|
||||
import PropTable from '../../components/common/PropTable.vue'
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue'
|
||||
import CodeExample from '../../components/code/CodeExample.vue'
|
||||
import Customize from '../../components/common/Customize.vue'
|
||||
import PreviewSwitch from '../../components/common/PreviewSwitch.vue'
|
||||
import PreviewColor from '../../components/common/PreviewColor.vue'
|
||||
import TextPressure from '../../content/TextAnimations/TextPressure/TextPressure.vue'
|
||||
import { textPressure } from '@/constants/code/TextAnimations/textPressureCode'
|
||||
import { useForceRerender } from '@/composables/useForceRerender'
|
||||
import { ref } from 'vue';
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue';
|
||||
import PropTable from '../../components/common/PropTable.vue';
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue';
|
||||
import CodeExample from '../../components/code/CodeExample.vue';
|
||||
import Customize from '../../components/common/Customize.vue';
|
||||
import PreviewSwitch from '../../components/common/PreviewSwitch.vue';
|
||||
import PreviewColor from '../../components/common/PreviewColor.vue';
|
||||
import TextPressure from '../../content/TextAnimations/TextPressure/TextPressure.vue';
|
||||
import { textPressure } from '@/constants/code/TextAnimations/textPressureCode';
|
||||
import { useForceRerender } from '@/composables/useForceRerender';
|
||||
|
||||
const text = ref('Hello!')
|
||||
const flex = ref(true)
|
||||
const alpha = ref(false)
|
||||
const stroke = ref(false)
|
||||
const width = ref(true)
|
||||
const weight = ref(true)
|
||||
const italic = ref(true)
|
||||
const textColor = ref('#ffffff')
|
||||
const strokeColor = ref('#27FF64')
|
||||
const text = ref('Hello!');
|
||||
const flex = ref(true);
|
||||
const alpha = ref(false);
|
||||
const stroke = ref(false);
|
||||
const width = ref(true);
|
||||
const weight = ref(true);
|
||||
const italic = ref(true);
|
||||
const textColor = ref('#ffffff');
|
||||
const strokeColor = ref('#27FF64');
|
||||
|
||||
const { rerenderKey, forceRerender } = useForceRerender()
|
||||
const { rerenderKey, forceRerender } = useForceRerender();
|
||||
|
||||
const propData = [
|
||||
{
|
||||
@@ -164,7 +234,7 @@ const propData = [
|
||||
default: '24',
|
||||
description: 'Sets a minimum font-size to avoid overly tiny text on smaller screens.'
|
||||
}
|
||||
]
|
||||
];
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -3,28 +3,59 @@
|
||||
<TabbedLayout>
|
||||
<template #preview>
|
||||
<div class="demo-container relative h-[500px] overflow-hidden p-0">
|
||||
<TextTrail :key="`${key}-${animateColor}`" :noise-factor="noiseFactor" :noise-scale="noiseScale / 10000"
|
||||
:font-weight="fontWeight" :alpha-persist-factor="alphaPersistFactor" :animate-color="animateColor"
|
||||
:text-color="animateColor ? undefined : '#ffffff'" />
|
||||
<TextTrail
|
||||
:key="`${key}-${animateColor}`"
|
||||
:noise-factor="noiseFactor"
|
||||
:noise-scale="noiseScale / 10000"
|
||||
:font-weight="fontWeight"
|
||||
:alpha-persist-factor="alphaPersistFactor"
|
||||
:animate-color="animateColor"
|
||||
:text-color="animateColor ? undefined : '#ffffff'"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Customize>
|
||||
<PreviewSlider title="Noise Factor" v-model="noiseFactor" :min="1" :max="25" :step="1"
|
||||
@update:model-value="forceRerender" />
|
||||
<PreviewSlider
|
||||
title="Noise Factor"
|
||||
v-model="noiseFactor"
|
||||
:min="1"
|
||||
:max="25"
|
||||
:step="1"
|
||||
@update:model-value="forceRerender"
|
||||
/>
|
||||
|
||||
<PreviewSlider title="Noise Scale" v-model="noiseScale" :min="0" :max="100" :step="1"
|
||||
@update:model-value="forceRerender" />
|
||||
<PreviewSlider
|
||||
title="Noise Scale"
|
||||
v-model="noiseScale"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:step="1"
|
||||
@update:model-value="forceRerender"
|
||||
/>
|
||||
|
||||
<PreviewSlider title="Font Weight" v-model="fontWeight" :min="100" :max="900" :step="100"
|
||||
@update:model-value="forceRerender" />
|
||||
<PreviewSlider
|
||||
title="Font Weight"
|
||||
v-model="fontWeight"
|
||||
:min="100"
|
||||
:max="900"
|
||||
:step="100"
|
||||
@update:model-value="forceRerender"
|
||||
/>
|
||||
|
||||
<PreviewSlider title="Alpha Persist Factor" v-model="alphaPersistFactor" :min="0.5" :max="0.95" :step="0.01"
|
||||
@update:model-value="forceRerender" />
|
||||
<PreviewSlider
|
||||
title="Alpha Persist Factor"
|
||||
v-model="alphaPersistFactor"
|
||||
:min="0.5"
|
||||
:max="0.95"
|
||||
:step="0.01"
|
||||
@update:model-value="forceRerender"
|
||||
/>
|
||||
|
||||
<PreviewSwitch title="Animate Color" v-model="animateColor" @update:model-value="forceRerender" />
|
||||
</Customize>
|
||||
|
||||
<PropTable :data="propData" />
|
||||
|
||||
<Dependencies :dependency-list="['three']" />
|
||||
</template>
|
||||
|
||||
@@ -40,26 +71,26 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue'
|
||||
import PropTable from '../../components/common/PropTable.vue'
|
||||
import Dependencies from '../../components/code/Dependencies.vue'
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue'
|
||||
import CodeExample from '../../components/code/CodeExample.vue'
|
||||
import Customize from '../../components/common/Customize.vue'
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue'
|
||||
import PreviewSwitch from '../../components/common/PreviewSwitch.vue'
|
||||
import TextTrail from '../../content/TextAnimations/TextTrail/TextTrail.vue'
|
||||
import { textTrail } from '@/constants/code/TextAnimations/textTrailCode'
|
||||
import { useForceRerender } from '@/composables/useForceRerender'
|
||||
import { ref } from 'vue';
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue';
|
||||
import PropTable from '../../components/common/PropTable.vue';
|
||||
import Dependencies from '../../components/code/Dependencies.vue';
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue';
|
||||
import CodeExample from '../../components/code/CodeExample.vue';
|
||||
import Customize from '../../components/common/Customize.vue';
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue';
|
||||
import PreviewSwitch from '../../components/common/PreviewSwitch.vue';
|
||||
import TextTrail from '../../content/TextAnimations/TextTrail/TextTrail.vue';
|
||||
import { textTrail } from '@/constants/code/TextAnimations/textTrailCode';
|
||||
import { useForceRerender } from '@/composables/useForceRerender';
|
||||
|
||||
const { rerenderKey: key, forceRerender } = useForceRerender()
|
||||
const { rerenderKey: key, forceRerender } = useForceRerender();
|
||||
|
||||
const noiseFactor = ref(1)
|
||||
const noiseScale = ref(5)
|
||||
const fontWeight = ref(900)
|
||||
const alphaPersistFactor = ref(0.95)
|
||||
const animateColor = ref(false)
|
||||
const noiseFactor = ref(1);
|
||||
const noiseScale = ref(5);
|
||||
const fontWeight = ref(900);
|
||||
const alphaPersistFactor = ref(0.95);
|
||||
const animateColor = ref(false);
|
||||
|
||||
const propData = [
|
||||
{
|
||||
@@ -140,7 +171,7 @@ const propData = [
|
||||
default: '2',
|
||||
description: 'Supersampling factor for text quality (higher = better quality)'
|
||||
}
|
||||
]
|
||||
];
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -13,17 +13,41 @@
|
||||
|
||||
<PreviewSwitch title="Hover Mode" v-model="manualMode" @update:model-value="forceRerender" />
|
||||
|
||||
<PreviewSlider title="Blur Amount" v-model="blurAmount" :min="0" :max="15" :step="0.5" value-unit="px"
|
||||
@update:model-value="forceRerender" />
|
||||
<PreviewSlider
|
||||
title="Blur Amount"
|
||||
v-model="blurAmount"
|
||||
:min="0"
|
||||
:max="15"
|
||||
:step="0.5"
|
||||
value-unit="px"
|
||||
@update:model-value="forceRerender"
|
||||
/>
|
||||
|
||||
<PreviewSlider title="Animation Duration" v-model="animationDuration" :min="0.1" :max="3" :step="0.1"
|
||||
value-unit="s" :disabled="!manualMode" @update:model-value="forceRerender" />
|
||||
<PreviewSlider
|
||||
title="Animation Duration"
|
||||
v-model="animationDuration"
|
||||
:min="0.1"
|
||||
:max="3"
|
||||
:step="0.1"
|
||||
value-unit="s"
|
||||
:disabled="!manualMode"
|
||||
@update:model-value="forceRerender"
|
||||
/>
|
||||
|
||||
<PreviewSlider title="Pause Between Animations" v-model="pauseBetweenAnimations" :min="0" :max="5" :step="0.5"
|
||||
value-unit="s" :disabled="manualMode" @update:model-value="forceRerender" />
|
||||
<PreviewSlider
|
||||
title="Pause Between Animations"
|
||||
v-model="pauseBetweenAnimations"
|
||||
:min="0"
|
||||
:max="5"
|
||||
:step="0.5"
|
||||
value-unit="s"
|
||||
:disabled="manualMode"
|
||||
@update:model-value="forceRerender"
|
||||
/>
|
||||
</Customize>
|
||||
|
||||
<PropTable :data="propData" />
|
||||
|
||||
<Dependencies :dependency-list="['framer-motion']" />
|
||||
</template>
|
||||
|
||||
@@ -39,19 +63,19 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from "vue";
|
||||
import TabbedLayout from "../../components/common/TabbedLayout.vue";
|
||||
import PropTable from "../../components/common/PropTable.vue";
|
||||
import CliInstallation from "../../components/code/CliInstallation.vue";
|
||||
import CodeExample from "../../components/code/CodeExample.vue";
|
||||
import Dependencies from "../../components/code/Dependencies.vue";
|
||||
import Customize from "../../components/common/Customize.vue";
|
||||
import PreviewColor from "../../components/common/PreviewColor.vue";
|
||||
import PreviewSlider from "../../components/common/PreviewSlider.vue";
|
||||
import PreviewSwitch from "../../components/common/PreviewSwitch.vue";
|
||||
import TrueFocus from "../../content/TextAnimations/TrueFocus/TrueFocus.vue";
|
||||
import { trueFocus } from "../../constants/code/TextAnimations/trueFocusCode";
|
||||
import { useForceRerender } from "@/composables/useForceRerender";
|
||||
import { ref, computed } from 'vue';
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue';
|
||||
import PropTable from '../../components/common/PropTable.vue';
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue';
|
||||
import CodeExample from '../../components/code/CodeExample.vue';
|
||||
import Dependencies from '../../components/code/Dependencies.vue';
|
||||
import Customize from '../../components/common/Customize.vue';
|
||||
import PreviewColor from '../../components/common/PreviewColor.vue';
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue';
|
||||
import PreviewSwitch from '../../components/common/PreviewSwitch.vue';
|
||||
import TrueFocus from '../../content/TextAnimations/TrueFocus/TrueFocus.vue';
|
||||
import { trueFocus } from '../../constants/code/TextAnimations/trueFocusCode';
|
||||
import { useForceRerender } from '@/composables/useForceRerender';
|
||||
|
||||
const { rerenderKey: key, forceRerender } = useForceRerender();
|
||||
|
||||
@@ -59,59 +83,59 @@ const manualMode = ref(false);
|
||||
const blurAmount = ref(5);
|
||||
const animationDuration = ref(0.5);
|
||||
const pauseBetweenAnimations = ref(1);
|
||||
const borderColor = ref("#27FF64");
|
||||
const borderColor = ref('#27FF64');
|
||||
|
||||
const config = computed(() => ({
|
||||
sentence: "True Focus",
|
||||
sentence: 'True Focus',
|
||||
manualMode: manualMode.value,
|
||||
blurAmount: blurAmount.value,
|
||||
borderColor: borderColor.value,
|
||||
animationDuration: animationDuration.value,
|
||||
pauseBetweenAnimations: pauseBetweenAnimations.value,
|
||||
pauseBetweenAnimations: pauseBetweenAnimations.value
|
||||
}));
|
||||
|
||||
const propData = [
|
||||
{
|
||||
name: "sentence",
|
||||
type: "string",
|
||||
name: 'sentence',
|
||||
type: 'string',
|
||||
default: "'True Focus'",
|
||||
description: "The text to display with the focus animation.",
|
||||
description: 'The text to display with the focus animation.'
|
||||
},
|
||||
{
|
||||
name: "manualMode",
|
||||
type: "boolean",
|
||||
default: "false",
|
||||
description: "Disables automatic animation when set to true.",
|
||||
name: 'manualMode',
|
||||
type: 'boolean',
|
||||
default: 'false',
|
||||
description: 'Disables automatic animation when set to true.'
|
||||
},
|
||||
{
|
||||
name: "blurAmount",
|
||||
type: "number",
|
||||
default: "5",
|
||||
description: "The amount of blur applied to non-active words.",
|
||||
name: 'blurAmount',
|
||||
type: 'number',
|
||||
default: '5',
|
||||
description: 'The amount of blur applied to non-active words.'
|
||||
},
|
||||
{
|
||||
name: "borderColor",
|
||||
type: "string",
|
||||
name: 'borderColor',
|
||||
type: 'string',
|
||||
default: "'green'",
|
||||
description: "The color of the focus borders.",
|
||||
description: 'The color of the focus borders.'
|
||||
},
|
||||
{
|
||||
name: "glowColor",
|
||||
type: "string",
|
||||
name: 'glowColor',
|
||||
type: 'string',
|
||||
default: "'rgba(0, 255, 0, 0.6)'",
|
||||
description: "The color of the glowing effect on the borders.",
|
||||
description: 'The color of the glowing effect on the borders.'
|
||||
},
|
||||
{
|
||||
name: "animationDuration",
|
||||
type: "number",
|
||||
default: "0.5",
|
||||
description: "The duration of the animation for each word.",
|
||||
name: 'animationDuration',
|
||||
type: 'number',
|
||||
default: '0.5',
|
||||
description: 'The duration of the animation for each word.'
|
||||
},
|
||||
{
|
||||
name: "pauseBetweenAnimations",
|
||||
type: "number",
|
||||
default: "1",
|
||||
description: "Time to pause between focusing on each word (in auto mode).",
|
||||
},
|
||||
name: 'pauseBetweenAnimations',
|
||||
type: 'number',
|
||||
default: '1',
|
||||
description: 'Time to pause between focusing on each word (in auto mode).'
|
||||
}
|
||||
];
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user