mirror of
https://github.com/DavidHDev/vue-bits.git
synced 2026-04-22 01:54:38 -06:00
Merge branch 'main' into feat/stepper
This commit is contained in:
@@ -0,0 +1,202 @@
|
||||
<template>
|
||||
<TabbedLayout>
|
||||
<template #preview>
|
||||
<div class="relative p-0 h-[600px] overflow-hidden demo-container">
|
||||
<FaultyTerminal
|
||||
:key="key"
|
||||
:scale="scale"
|
||||
:digit-size="digitSize"
|
||||
:time-scale="timeScale"
|
||||
:scanline-intensity="scanlineIntensity"
|
||||
:curvature="curvature"
|
||||
:tint="tint"
|
||||
:mouse-react="mouseReact"
|
||||
:mouse-strength="mouseStrength"
|
||||
:page-load-animation="pageLoadAnimation"
|
||||
:noise-amp="noiseAmp"
|
||||
:brightness="brightness"
|
||||
/>
|
||||
<BackgroundContent pill-text="New Background" headline="It works on my machine, please check again" />
|
||||
</div>
|
||||
|
||||
<Customize>
|
||||
<PreviewColor title="Tint Color" v-model="tint" />
|
||||
<PreviewSlider :min="1" :max="3" :step="0.1" v-model="scale" title="Scale" />
|
||||
<PreviewSlider :min="0.5" :max="3" :step="0.1" v-model="digitSize" title="Digit Size" />
|
||||
<PreviewSlider :min="0" :max="3" :step="0.1" v-model="timeScale" title="Speed" />
|
||||
<PreviewSlider :min="0.5" :max="1" :step="0.1" v-model="noiseAmp" title="Noise Amplitude" />
|
||||
<PreviewSlider :min="0.1" :max="1" :step="0.1" v-model="brightness" title="Brightness" />
|
||||
<PreviewSlider :min="0" :max="2" :step="0.1" v-model="scanlineIntensity" title="Scanline Intensity" />
|
||||
<PreviewSlider :min="0" :max="0.5" :step="0.01" v-model="curvature" title="Curvature" />
|
||||
<PreviewSlider :min="0" :max="2" :step="0.1" v-model="mouseStrength" title="Mouse Strength" />
|
||||
<PreviewSwitch title="Mouse React" v-model="mouseReact" />
|
||||
<PreviewSwitch title="Page Load Animation" v-model="pageLoadAnimation" />
|
||||
</Customize>
|
||||
|
||||
<PropTable :data="propData" />
|
||||
<Dependencies :dependency-list="['ogl']" />
|
||||
</template>
|
||||
|
||||
<template #code>
|
||||
<CodeExample :code-object="faultyTerminal" />
|
||||
</template>
|
||||
|
||||
<template #cli>
|
||||
<CliInstallation :command="faultyTerminal.cli" />
|
||||
</template>
|
||||
</TabbedLayout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useForceRerender } from '@/composables/useForceRerender';
|
||||
import { ref } from 'vue';
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue';
|
||||
import CodeExample from '../../components/code/CodeExample.vue';
|
||||
import Dependencies from '../../components/code/Dependencies.vue';
|
||||
import BackgroundContent from '../../components/common/BackgroundContent.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 PropTable from '../../components/common/PropTable.vue';
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue';
|
||||
import { faultyTerminal } from '../../constants/code/Backgrounds/faultyTerminalCode';
|
||||
import FaultyTerminal from '../../content/Backgrounds/FaultyTerminal/FaultyTerminal.vue';
|
||||
|
||||
const { rerenderKey: key } = useForceRerender();
|
||||
|
||||
const scale = ref(1.5);
|
||||
const digitSize = ref(1.2);
|
||||
const timeScale = ref(0.5);
|
||||
const scanlineIntensity = ref(0.5);
|
||||
const curvature = ref(0.1);
|
||||
const tint = ref('#A7EF9E');
|
||||
const mouseReact = ref(true);
|
||||
const mouseStrength = ref(0.5);
|
||||
const pageLoadAnimation = ref(true);
|
||||
const noiseAmp = ref(1);
|
||||
const brightness = ref(0.6);
|
||||
|
||||
const propData = [
|
||||
{
|
||||
name: 'scale',
|
||||
type: 'number',
|
||||
default: '1.5',
|
||||
description: 'Controls the zoom/scale of the pattern.'
|
||||
},
|
||||
{
|
||||
name: 'gridMul',
|
||||
type: 'Vec2',
|
||||
default: '[2, 1]',
|
||||
description: 'Grid multiplier for glyph density [x, y].'
|
||||
},
|
||||
{
|
||||
name: 'digitSize',
|
||||
type: 'number',
|
||||
default: '1.2',
|
||||
description: 'Size of individual glyphs.'
|
||||
},
|
||||
{
|
||||
name: 'timeScale',
|
||||
type: 'number',
|
||||
default: '1',
|
||||
description: 'Animation speed multiplier.'
|
||||
},
|
||||
{
|
||||
name: 'pause',
|
||||
type: 'boolean',
|
||||
default: 'false',
|
||||
description: 'Pause/resume animation.'
|
||||
},
|
||||
{
|
||||
name: 'scanlineIntensity',
|
||||
type: 'number',
|
||||
default: '1',
|
||||
description: 'Strength of scanline effects.'
|
||||
},
|
||||
{
|
||||
name: 'glitchAmount',
|
||||
type: 'number',
|
||||
default: '1',
|
||||
description: 'Glitch displacement intensity.'
|
||||
},
|
||||
{
|
||||
name: 'flickerAmount',
|
||||
type: 'number',
|
||||
default: '1',
|
||||
description: 'Flicker effect strength.'
|
||||
},
|
||||
{
|
||||
name: 'noiseAmp',
|
||||
type: 'number',
|
||||
default: '1',
|
||||
description: 'Noise pattern amplitude.'
|
||||
},
|
||||
{
|
||||
name: 'chromaticAberration',
|
||||
type: 'number',
|
||||
default: '0',
|
||||
description: 'RGB channel separation in pixels.'
|
||||
},
|
||||
{
|
||||
name: 'dither',
|
||||
type: 'number | boolean',
|
||||
default: '0',
|
||||
description: 'Dithering effect intensity.'
|
||||
},
|
||||
{
|
||||
name: 'curvature',
|
||||
type: 'number',
|
||||
default: '0',
|
||||
description: 'Barrel distortion amount.'
|
||||
},
|
||||
{
|
||||
name: 'tint',
|
||||
type: 'string',
|
||||
default: "'#ffffff'",
|
||||
description: 'Color tint (hex).'
|
||||
},
|
||||
{
|
||||
name: 'mouseReact',
|
||||
type: 'boolean',
|
||||
default: 'true',
|
||||
description: 'Enable/disable mouse interaction.'
|
||||
},
|
||||
{
|
||||
name: 'mouseStrength',
|
||||
type: 'number',
|
||||
default: '0.5',
|
||||
description: 'Mouse interaction intensity.'
|
||||
},
|
||||
{
|
||||
name: 'pageLoadAnimation',
|
||||
type: 'boolean',
|
||||
default: 'false',
|
||||
description: 'Enable fade-in animation on load.'
|
||||
},
|
||||
{
|
||||
name: 'brightness',
|
||||
type: 'number',
|
||||
default: '1',
|
||||
description: 'Overall opacity/brightness control.'
|
||||
},
|
||||
{
|
||||
name: 'className',
|
||||
type: 'string',
|
||||
default: "''",
|
||||
description: 'Additional CSS classes.'
|
||||
},
|
||||
{
|
||||
name: 'style',
|
||||
type: 'React.CSSProperties',
|
||||
default: '{}',
|
||||
description: 'Inline styles.'
|
||||
}
|
||||
];
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.demo-container {
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,243 @@
|
||||
<template>
|
||||
<TabbedLayout>
|
||||
<template #preview>
|
||||
<div class="h-[600px] overflow-hidden demo-container relative">
|
||||
<LightRays
|
||||
:rays-origin="raysOrigin"
|
||||
:rays-color="raysColor"
|
||||
:rays-speed="raysSpeed"
|
||||
:light-spread="lightSpread"
|
||||
:ray-length="rayLength"
|
||||
:pulsating="pulsating"
|
||||
:fade-distance="fadeDistance"
|
||||
:saturation="saturation"
|
||||
:follow-mouse="true"
|
||||
:mouse-influence="mouseInfluence"
|
||||
:noise-amount="noiseAmount"
|
||||
:distortion="distortion"
|
||||
class="w-full h-full"
|
||||
/>
|
||||
|
||||
<BackgroundContent pill-text="New Background" headline="May these lights guide you on your path" />
|
||||
</div>
|
||||
|
||||
<Customize>
|
||||
<PreviewColor
|
||||
title="Rays Color"
|
||||
v-model="raysColor"
|
||||
/>
|
||||
|
||||
<PreviewSelect
|
||||
title="Rays Origin"
|
||||
v-model="raysOrigin"
|
||||
:options="raysOriginOptions"
|
||||
/>
|
||||
|
||||
<PreviewSlider
|
||||
title="Rays Speed"
|
||||
v-model="raysSpeed"
|
||||
:min="0.1"
|
||||
:max="3"
|
||||
:step="0.1"
|
||||
/>
|
||||
|
||||
<PreviewSlider
|
||||
title="Light Spread"
|
||||
v-model="lightSpread"
|
||||
:min="0.1"
|
||||
:max="2"
|
||||
:step="0.1"
|
||||
/>
|
||||
|
||||
<PreviewSlider
|
||||
title="Ray Length"
|
||||
v-model="rayLength"
|
||||
:min="0.5"
|
||||
:max="3"
|
||||
:step="0.1"
|
||||
/>
|
||||
|
||||
<PreviewSlider
|
||||
title="Fade Distance"
|
||||
v-model="fadeDistance"
|
||||
:min="0.5"
|
||||
:max="2"
|
||||
:step="0.1"
|
||||
/>
|
||||
|
||||
<PreviewSlider
|
||||
title="Saturation"
|
||||
v-model="saturation"
|
||||
:min="0"
|
||||
:max="2"
|
||||
:step="0.1"
|
||||
/>
|
||||
|
||||
<PreviewSlider
|
||||
title="Mouse Influence"
|
||||
v-model="mouseInfluence"
|
||||
:min="0"
|
||||
:max="1"
|
||||
:step="0.1"
|
||||
/>
|
||||
|
||||
<PreviewSlider
|
||||
title="Noise Amount"
|
||||
v-model="noiseAmount"
|
||||
:min="0"
|
||||
:max="0.5"
|
||||
:step="0.01"
|
||||
/>
|
||||
|
||||
<PreviewSlider
|
||||
title="Distortion"
|
||||
v-model="distortion"
|
||||
:min="0"
|
||||
:max="1"
|
||||
:step="0.1"
|
||||
/>
|
||||
|
||||
<PreviewSwitch title="Pulsating" v-model="pulsating" />
|
||||
</Customize>
|
||||
|
||||
<PropTable :data="propData" />
|
||||
<Dependencies :dependency-list="['ogl']" />
|
||||
</template>
|
||||
|
||||
<template #code>
|
||||
<CodeExample :code-object="lightRays" />
|
||||
</template>
|
||||
|
||||
<template #cli>
|
||||
<CliInstallation :command="lightRays.cli" />
|
||||
</template>
|
||||
</TabbedLayout>
|
||||
</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 PreviewSlider from '@/components/common/PreviewSlider.vue';
|
||||
import PreviewSelect from '@/components/common/PreviewSelect.vue';
|
||||
import PreviewColor from '@/components/common/PreviewColor.vue';
|
||||
import BackgroundContent from '@/components/common/BackgroundContent.vue';
|
||||
import LightRays, { type RaysOrigin } from '../../content/Backgrounds/LightRays/LightRays.vue';
|
||||
import { lightRays } from '@/constants/code/Backgrounds/lightRaysCode';
|
||||
|
||||
const raysOrigin = ref<RaysOrigin>('top-center');
|
||||
const raysColor = ref('#ffffff');
|
||||
const raysSpeed = ref(1);
|
||||
const lightSpread = ref(0.5);
|
||||
const rayLength = ref(1.0);
|
||||
const pulsating = ref(false);
|
||||
const fadeDistance = ref(1.0);
|
||||
const saturation = ref(1.0);
|
||||
const mouseInfluence = ref(0.5);
|
||||
const noiseAmount = ref(0.0);
|
||||
const distortion = ref(0.0);
|
||||
|
||||
const raysOriginOptions = [
|
||||
{ value: 'top-center', label: 'Top' },
|
||||
{ value: 'right', label: 'Right' },
|
||||
{ value: 'left', label: 'Left' },
|
||||
{ value: 'bottom-center', label: 'Bottom' },
|
||||
{ value: 'top-left', label: 'Top Left' },
|
||||
{ value: 'top-right', label: 'Top Right' },
|
||||
{ value: 'bottom-left', label: 'Bottom Left' },
|
||||
{ value: 'bottom-right', label: 'Bottom Right' }
|
||||
];
|
||||
|
||||
const propData = [
|
||||
{
|
||||
name: 'raysOrigin',
|
||||
type: 'RaysOrigin',
|
||||
default: '"top-center"',
|
||||
description:
|
||||
"Origin position of the light rays. Options: 'top-center', 'top-left', 'top-right', 'right', 'left', 'bottom-center', 'bottom-right', 'bottom-left'"
|
||||
},
|
||||
{
|
||||
name: 'raysColor',
|
||||
type: 'string',
|
||||
default: '"#ffffff"',
|
||||
description: 'Color of the light rays in hex format'
|
||||
},
|
||||
{
|
||||
name: 'raysSpeed',
|
||||
type: 'number',
|
||||
default: '1',
|
||||
description: 'Animation speed of the rays'
|
||||
},
|
||||
{
|
||||
name: 'lightSpread',
|
||||
type: 'number',
|
||||
default: '0.5',
|
||||
description: 'How wide the light rays spread. Lower values = tighter rays, higher values = wider spread'
|
||||
},
|
||||
{
|
||||
name: 'rayLength',
|
||||
type: 'number',
|
||||
default: '1.0',
|
||||
description: 'Maximum length/reach of the rays'
|
||||
},
|
||||
{
|
||||
name: 'pulsating',
|
||||
type: 'boolean',
|
||||
default: 'false',
|
||||
description: 'Enable pulsing animation effect'
|
||||
},
|
||||
{
|
||||
name: 'fadeDistance',
|
||||
type: 'number',
|
||||
default: '1.0',
|
||||
description: 'How far rays fade out from origin'
|
||||
},
|
||||
{
|
||||
name: 'saturation',
|
||||
type: 'number',
|
||||
default: '1.0',
|
||||
description: 'Color saturation level (0-1)'
|
||||
},
|
||||
{
|
||||
name: 'followMouse',
|
||||
type: 'boolean',
|
||||
default: 'false',
|
||||
description: 'Make rays rotate towards the mouse cursor'
|
||||
},
|
||||
{
|
||||
name: 'mouseInfluence',
|
||||
type: 'number',
|
||||
default: '0.5',
|
||||
description: 'How much mouse affects rays (0-1)'
|
||||
},
|
||||
{
|
||||
name: 'noiseAmount',
|
||||
type: 'number',
|
||||
default: '0.0',
|
||||
description: 'Add noise/grain to rays (0-1)'
|
||||
},
|
||||
{
|
||||
name: 'distortion',
|
||||
type: 'number',
|
||||
default: '0.0',
|
||||
description: 'Apply wave distortion to rays'
|
||||
},
|
||||
{
|
||||
name: 'className',
|
||||
type: 'string',
|
||||
default: '""',
|
||||
description: 'Additional CSS classes to apply to the container'
|
||||
}
|
||||
];
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.demo-container {
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,146 @@
|
||||
<template>
|
||||
<TabbedLayout>
|
||||
<template #preview>
|
||||
<div class="demo-container bounce-cards-demo">
|
||||
<RefreshButton @refresh="forceRerender" />
|
||||
|
||||
<BounceCards
|
||||
:key="rerenderKey"
|
||||
class="custom-bounceCards"
|
||||
:images="images"
|
||||
:animation-delay="animationDelay"
|
||||
:animation-stagger="animationStagger"
|
||||
ease-type="elastic.out(1, 0.5)"
|
||||
:transform-styles="transformStyles"
|
||||
:enable-hover="enableHover"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Customize>
|
||||
<PreviewSwitch title="Enable Hover Effect" v-model="enableHover" />
|
||||
|
||||
<PreviewSlider title="Animation Delay" v-model="animationDelay" :min="0.1" :max="2" :step="0.1" />
|
||||
|
||||
<PreviewSlider title="Animation Stagger" v-model="animationStagger" :min="0" :max="0.3" :step="0.01" />
|
||||
</Customize>
|
||||
|
||||
<PropTable :data="propData" />
|
||||
|
||||
<Dependencies :dependency-list="['gsap']" />
|
||||
</template>
|
||||
|
||||
<template #code>
|
||||
<CodeExample :code-object="bounceCards" />
|
||||
</template>
|
||||
|
||||
<template #cli>
|
||||
<CliInstallation :command="bounceCards.cli" />
|
||||
</template>
|
||||
</TabbedLayout>
|
||||
</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 BounceCards from '@/content/Components/BounceCards/BounceCards.vue';
|
||||
import { bounceCards } from '@/constants/code/Components/bounceCardsCode';
|
||||
import { useForceRerender } from '@/composables/useForceRerender';
|
||||
|
||||
const enableHover = ref(false);
|
||||
const animationDelay = ref(1);
|
||||
const animationStagger = ref(0.08);
|
||||
const { rerenderKey, forceRerender } = useForceRerender();
|
||||
|
||||
const images = ref([
|
||||
'https://picsum.photos/id/287/300/300?grayscale',
|
||||
'https://picsum.photos/id/1001/300/300?grayscale',
|
||||
'https://picsum.photos/id/1027/300/300?grayscale',
|
||||
'https://picsum.photos/id/1025/300/300?grayscale',
|
||||
'https://picsum.photos/id/1026/300/300?grayscale'
|
||||
]);
|
||||
|
||||
const transformStyles = ref([
|
||||
'rotate(5deg) translate(-150px)',
|
||||
'rotate(0deg) translate(-70px)',
|
||||
'rotate(-5deg)',
|
||||
'rotate(5deg) translate(70px)',
|
||||
'rotate(-5deg) translate(150px)'
|
||||
]);
|
||||
|
||||
const propData = [
|
||||
{
|
||||
name: 'className',
|
||||
type: 'string',
|
||||
default: '-',
|
||||
description: 'Additional CSS classes for the container.'
|
||||
},
|
||||
{
|
||||
name: 'images',
|
||||
type: 'string[]',
|
||||
default: '[]',
|
||||
description: 'Array of image URLs to display.'
|
||||
},
|
||||
{
|
||||
name: 'containerWidth',
|
||||
type: 'number',
|
||||
default: '400',
|
||||
description: 'Width of the container (px).'
|
||||
},
|
||||
{
|
||||
name: 'containerHeight',
|
||||
type: 'number',
|
||||
default: '400',
|
||||
description: 'Height of the container (px).'
|
||||
},
|
||||
{
|
||||
name: 'animationDelay',
|
||||
type: 'number',
|
||||
default: '-',
|
||||
description: 'Delay (in seconds) before the animation starts.'
|
||||
},
|
||||
{
|
||||
name: 'animationStagger',
|
||||
type: 'number',
|
||||
default: '-',
|
||||
description: "Time (in seconds) between each card's animation."
|
||||
},
|
||||
{
|
||||
name: 'easeType',
|
||||
type: 'string',
|
||||
default: 'elastic.out(1, 0.8)',
|
||||
description: 'Easing function for the bounce.'
|
||||
},
|
||||
{
|
||||
name: 'transformStyles',
|
||||
type: 'string[]',
|
||||
default: 'various rotations/translations',
|
||||
description: 'Custom transforms for each card position.'
|
||||
},
|
||||
{
|
||||
name: 'enableHover',
|
||||
type: 'boolean',
|
||||
default: 'false',
|
||||
description: "If true, hovering pushes siblings aside and flattens the hovered card's rotation."
|
||||
}
|
||||
];
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.bounce-cards-demo {
|
||||
min-height: 400px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,177 @@
|
||||
<template>
|
||||
<TabbedLayout>
|
||||
<template #preview>
|
||||
<div class="demo-container h-[400px] overflow-hidden relative">
|
||||
<Counter
|
||||
:value="value"
|
||||
:places="[100, 10, 1]"
|
||||
gradientFrom="#0b0b0b"
|
||||
:fontSize="fontSize"
|
||||
:padding="5"
|
||||
:gap="gap"
|
||||
:borderRadius="10"
|
||||
:horizontalPadding="15"
|
||||
textColor="white"
|
||||
:fontWeight="900"
|
||||
/>
|
||||
|
||||
<div class="flex gap-4 bottom-4 justify-center mt-4 absolute left-1/2 transform -translate-x-1/2">
|
||||
<button
|
||||
class="cursor-pointer bg-[#0b0b0b] rounded-[10px] border border-[#333] hover:bg-[#222] text-white h-10 w-10 transition-colors"
|
||||
@click="value > 0 && value--"
|
||||
>
|
||||
-
|
||||
</button>
|
||||
<button
|
||||
class="cursor-pointer bg-[#0b0b0b] rounded-[10px] border border-[#333] hover:bg-[#222] text-white h-10 w-10 transition-colors"
|
||||
@click="value < 999 && value++"
|
||||
>
|
||||
+
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Customize>
|
||||
<PreviewSlider title="Value" v-model="value" :min="0" :max="999" :step="1" />
|
||||
|
||||
<PreviewSlider title="Gap" v-model="gap" :min="0" :max="50" :step="5" />
|
||||
|
||||
<PreviewSlider title="Font Size" v-model="fontSize" :min="40" :max="200" :step="10" />
|
||||
</Customize>
|
||||
|
||||
<PropTable :data="propData" />
|
||||
<Dependencies :dependency-list="['motion-v']" />
|
||||
</template>
|
||||
|
||||
<template #code>
|
||||
<CodeExample :code-object="counter" />
|
||||
</template>
|
||||
|
||||
<template #cli>
|
||||
<CliInstallation :command="counter.cli" />
|
||||
</template>
|
||||
</TabbedLayout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue';
|
||||
import Customize from '../../components/common/Customize.vue';
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue';
|
||||
import PropTable from '../../components/common/PropTable.vue';
|
||||
import CodeExample from '../../components/code/CodeExample.vue';
|
||||
import CliInstallation from '../../components/code/CliInstallation.vue';
|
||||
import Dependencies from '../../components/code/Dependencies.vue';
|
||||
|
||||
import Counter from '../../content/Components/Counter/Counter.vue';
|
||||
import { counter } from '../../constants/code/Components/counterCode';
|
||||
|
||||
const value = ref(123);
|
||||
const fontSize = ref(80);
|
||||
const gap = ref(10);
|
||||
|
||||
const propData = [
|
||||
{
|
||||
name: 'value',
|
||||
type: 'number',
|
||||
default: 'N/A (required)',
|
||||
description: 'The numeric value to display in the counter.'
|
||||
},
|
||||
{
|
||||
name: 'fontSize',
|
||||
type: 'number',
|
||||
default: '100',
|
||||
description: 'The base font size used for the counter digits.'
|
||||
},
|
||||
{
|
||||
name: 'padding',
|
||||
type: 'number',
|
||||
default: '0',
|
||||
description: 'Additional padding added to the digit height.'
|
||||
},
|
||||
{
|
||||
name: 'places',
|
||||
type: 'number[]',
|
||||
default: '[100, 10, 1]',
|
||||
description: 'An array of place values to determine which digits to display.'
|
||||
},
|
||||
{
|
||||
name: 'gap',
|
||||
type: 'number',
|
||||
default: '8',
|
||||
description: 'The gap (in pixels) between each digit.'
|
||||
},
|
||||
{
|
||||
name: 'borderRadius',
|
||||
type: 'number',
|
||||
default: '4',
|
||||
description: 'The border radius (in pixels) for the counter container.'
|
||||
},
|
||||
{
|
||||
name: 'horizontalPadding',
|
||||
type: 'number',
|
||||
default: '8',
|
||||
description: 'The horizontal padding (in pixels) for the counter container.'
|
||||
},
|
||||
{
|
||||
name: 'textColor',
|
||||
type: 'string',
|
||||
default: "'white'",
|
||||
description: 'The text color for the counter digits.'
|
||||
},
|
||||
{
|
||||
name: 'fontWeight',
|
||||
type: 'string | number',
|
||||
default: "'bold'",
|
||||
description: 'The font weight of the counter digits.'
|
||||
},
|
||||
{
|
||||
name: 'containerStyle',
|
||||
type: 'CSSProperties',
|
||||
default: '{}',
|
||||
description: 'Custom inline styles for the outer container.'
|
||||
},
|
||||
{
|
||||
name: 'counterStyle',
|
||||
type: 'CSSProperties',
|
||||
default: '{}',
|
||||
description: 'Custom inline styles for the counter element.'
|
||||
},
|
||||
{
|
||||
name: 'digitStyle',
|
||||
type: 'CSSProperties',
|
||||
default: '{}',
|
||||
description: 'Custom inline styles for each digit container.'
|
||||
},
|
||||
{
|
||||
name: 'gradientHeight',
|
||||
type: 'number',
|
||||
default: '16',
|
||||
description: 'The height (in pixels) of the gradient overlays.'
|
||||
},
|
||||
{
|
||||
name: 'gradientFrom',
|
||||
type: 'string',
|
||||
default: "'black'",
|
||||
description: 'The starting color for the gradient overlays.'
|
||||
},
|
||||
{
|
||||
name: 'gradientTo',
|
||||
type: 'string',
|
||||
default: "'transparent'",
|
||||
description: 'The ending color for the gradient overlays.'
|
||||
},
|
||||
{
|
||||
name: 'topGradientStyle',
|
||||
type: 'CSSProperties',
|
||||
default: 'undefined',
|
||||
description: 'Custom inline styles for the top gradient overlay.'
|
||||
},
|
||||
{
|
||||
name: 'bottomGradientStyle',
|
||||
type: 'CSSProperties',
|
||||
default: 'undefined',
|
||||
description: 'Custom inline styles for the bottom gradient overlay.'
|
||||
}
|
||||
];
|
||||
</script>
|
||||
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<TabbedLayout>
|
||||
<template #preview>
|
||||
<div class="demo-container relative min-h-[500px] overflow-hidden">
|
||||
<div class="flex h-full max-w-[600px] flex-col items-center justify-center">
|
||||
<h2
|
||||
class="absolute top-4 mt-6 whitespace-nowrap text-center font-black text-2xl text-white md:top-4 md:text-5xl"
|
||||
>
|
||||
Your trip to Thailand.
|
||||
</h2>
|
||||
<RollingGallery
|
||||
:autoplay="autoplay"
|
||||
:pause-on-hover="pauseOnHover"
|
||||
:images="customImages.length > 0 ? customImages : undefined"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Customize>
|
||||
<PreviewSwitch title="Autoplay" v-model="autoplay" />
|
||||
|
||||
<PreviewSwitch title="Pause on Hover" v-model="pauseOnHover" />
|
||||
</Customize>
|
||||
|
||||
<PropTable :data="propData" />
|
||||
<Dependencies :dependency-list="['motion-v']" />
|
||||
</template>
|
||||
|
||||
<template #code>
|
||||
<CodeExample :code-object="rollingGallery" />
|
||||
</template>
|
||||
|
||||
<template #cli>
|
||||
<CliInstallation :command="rollingGallery.cli" />
|
||||
</template>
|
||||
</TabbedLayout>
|
||||
</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 RollingGallery from '@/content/Components/RollingGallery/RollingGallery.vue';
|
||||
import { rollingGallery } from '@/constants/code/Components/rollingGalleryCode';
|
||||
|
||||
const autoplay = ref(true);
|
||||
const pauseOnHover = ref(true);
|
||||
const customImages = ref<string[]>([]);
|
||||
|
||||
const propData = [
|
||||
{
|
||||
name: 'autoplay',
|
||||
type: 'boolean',
|
||||
default: 'false',
|
||||
description: 'Controls the autoplay toggle of the carousel. When turned on, it rotates and loops infinitely.'
|
||||
},
|
||||
{
|
||||
name: 'pauseOnHover',
|
||||
type: 'boolean',
|
||||
default: 'false',
|
||||
description: 'Allows the carousel to be paused on hover when autoplay is turned on.'
|
||||
},
|
||||
{
|
||||
name: 'images',
|
||||
type: 'string[]',
|
||||
default: '[]',
|
||||
description: 'Array of image URLs to display in the gallery.'
|
||||
}
|
||||
];
|
||||
</script>
|
||||
@@ -0,0 +1,216 @@
|
||||
<template>
|
||||
<TabbedLayout>
|
||||
<template #preview>
|
||||
<div class="relative h-[500px] overflow-hidden demo-container">
|
||||
<RefreshButton
|
||||
@refresh="
|
||||
() => {
|
||||
isCompleted = false;
|
||||
forceRerender();
|
||||
}
|
||||
"
|
||||
/>
|
||||
<p
|
||||
class="top-[25%] left-[50%] absolute font-black text-[#333] text-[clamp(2rem,4vw,3rem)] text-center transition-all -translate-x-1/2 -translate-y-1/2 duration-300 ease-in-out pointer-events-none transform"
|
||||
>
|
||||
{{ isCompleted ? 'Stack Completed!' : 'Scroll Down' }}
|
||||
</p>
|
||||
|
||||
<ScrollStack
|
||||
:key="rerenderKey"
|
||||
:item-distance="itemDistance"
|
||||
className="scroll-stack-demo-container"
|
||||
:item-stack-distance="itemStackDistance"
|
||||
:stack-position="stackPosition"
|
||||
:base-scale="baseScale"
|
||||
:rotation-amount="rotationAmount"
|
||||
:blur-amount="blurAmount"
|
||||
@stackComplete="handleStackComplete"
|
||||
>
|
||||
<ScrollStackItem itemClassName="scroll-stack-card-demo ssc-demo-1">
|
||||
<h3>Text Animations</h3>
|
||||
|
||||
<div className="stack-img-container">
|
||||
<i class="pi-align-left pi" style="font-size: 120px"></i>
|
||||
</div>
|
||||
</ScrollStackItem>
|
||||
|
||||
<ScrollStackItem itemClassName="scroll-stack-card-demo ssc-demo-2">
|
||||
<h3>Animations</h3>
|
||||
|
||||
<div className="stack-img-container">
|
||||
<i class="pi pi-play" style="font-size: 120px"></i>
|
||||
</div>
|
||||
</ScrollStackItem>
|
||||
|
||||
<ScrollStackItem itemClassName="scroll-stack-card-demo ssc-demo-3">
|
||||
<h3>Components</h3>
|
||||
|
||||
<div className="stack-img-container">
|
||||
<i class="pi pi-sliders-h" style="font-size: 120px"></i>
|
||||
</div>
|
||||
</ScrollStackItem>
|
||||
|
||||
<ScrollStackItem itemClassName="scroll-stack-card-demo ssc-demo-4">
|
||||
<h3>Backgrounds</h3>
|
||||
|
||||
<div className="stack-img-container">
|
||||
<i class="pi pi-image" style="font-size: 120px"></i>
|
||||
</div>
|
||||
</ScrollStackItem>
|
||||
|
||||
<ScrollStackItem itemClassName="scroll-stack-card-demo ssc-demo-5">
|
||||
<h3>All on Vue Bits!</h3>
|
||||
</ScrollStackItem>
|
||||
</ScrollStack>
|
||||
</div>
|
||||
|
||||
<Customize>
|
||||
<PreviewSlider title="Item Distance" v-model="itemDistance" :min="0" :max="1000" :step="10" value-unit="px" />
|
||||
<PreviewSlider
|
||||
title="Stack Distance"
|
||||
v-model="itemStackDistance"
|
||||
:min="0"
|
||||
:max="40"
|
||||
:step="5"
|
||||
value-unit="px"
|
||||
/>
|
||||
<PreviewSelect title="Stack Position" v-model="stackPosition" :options="stackPositionOptions" />
|
||||
<PreviewSlider title="Base Scale" v-model="baseScale" :min="0.5" :max="1.0" :step="0.05" />
|
||||
<PreviewSlider title="Rotation Amount" v-model="rotationAmount" :min="0" :max="1" :step="0.1" value-unit="°" />
|
||||
<PreviewSlider title="Blur Amount" v-model="blurAmount" :min="0" :max="10" :step="0.5" value-unit="px" />
|
||||
</Customize>
|
||||
|
||||
<PropTable :data="propData" />
|
||||
<Dependencies :dependency-list="['lenis']" />
|
||||
</template>
|
||||
|
||||
<template #code>
|
||||
<CodeExample :code-object="scrollStack" />
|
||||
</template>
|
||||
|
||||
<template #cli>
|
||||
<CliInstallation :command="scrollStack.cli" />
|
||||
</template>
|
||||
</TabbedLayout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import PreviewSelect from '@/components/common/PreviewSelect.vue';
|
||||
import { useForceRerender } from '@/composables/useForceRerender';
|
||||
import { ref } from '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 PreviewSlider from '../../components/common/PreviewSlider.vue';
|
||||
import PropTable from '../../components/common/PropTable.vue';
|
||||
import RefreshButton from '../../components/common/RefreshButton.vue';
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue';
|
||||
import { scrollStack } from '../../constants/code/Components/scrollStackCode';
|
||||
import ScrollStack, { ScrollStackItem } from '../../content/Components/ScrollStack/ScrollStack.vue';
|
||||
|
||||
const { rerenderKey, forceRerender } = useForceRerender();
|
||||
|
||||
const isCompleted = ref(false);
|
||||
const itemDistance = ref(200);
|
||||
const itemStackDistance = ref(30);
|
||||
const baseScale = ref(0.85);
|
||||
const rotationAmount = ref(0);
|
||||
const blurAmount = ref(0);
|
||||
const stackPosition = ref('20%');
|
||||
|
||||
const handleStackComplete = () => {
|
||||
isCompleted.value = true;
|
||||
};
|
||||
|
||||
const stackPositionOptions = [
|
||||
{ value: '10%', label: '10%' },
|
||||
{ value: '15%', label: '15%' },
|
||||
{ value: '20%', label: '20%' },
|
||||
{ value: '25%', label: '25%' },
|
||||
{ value: '30%', label: '30%' },
|
||||
{ value: '35%', label: '35%' }
|
||||
];
|
||||
|
||||
const propData = [
|
||||
{
|
||||
name: 'children',
|
||||
type: 'ReactNode',
|
||||
default: 'required',
|
||||
description: 'The content to be displayed in the scroll stack. Should contain ScrollStackItem components.'
|
||||
},
|
||||
{
|
||||
name: 'className',
|
||||
type: 'string',
|
||||
default: '""',
|
||||
description: 'Additional CSS classes to apply to the scroll stack container.'
|
||||
},
|
||||
{
|
||||
name: 'itemDistance',
|
||||
type: 'number',
|
||||
default: '100',
|
||||
description: 'Distance between stacked items in pixels.'
|
||||
},
|
||||
{
|
||||
name: 'itemScale',
|
||||
type: 'number',
|
||||
default: '0.03',
|
||||
description: 'Scale increment for each stacked item.'
|
||||
},
|
||||
{
|
||||
name: 'itemStackDistance',
|
||||
type: 'number',
|
||||
default: '30',
|
||||
description: 'Distance between items when they start stacking.'
|
||||
},
|
||||
{
|
||||
name: 'stackPosition',
|
||||
type: 'string',
|
||||
default: '"20%"',
|
||||
description: 'Position where the stacking effect begins as a percentage of viewport height.'
|
||||
},
|
||||
{
|
||||
name: 'scaleEndPosition',
|
||||
type: 'string',
|
||||
default: '"10%"',
|
||||
description: 'Position where the scaling effect ends as a percentage of viewport height.'
|
||||
},
|
||||
{
|
||||
name: 'baseScale',
|
||||
type: 'number',
|
||||
default: '0.85',
|
||||
description: 'Base scale value for the first item in the stack.'
|
||||
},
|
||||
{
|
||||
name: 'scaleDuration',
|
||||
type: 'number',
|
||||
default: '0.5',
|
||||
description: 'Duration of the scaling animation in seconds.'
|
||||
},
|
||||
{
|
||||
name: 'rotationAmount',
|
||||
type: 'number',
|
||||
default: '0',
|
||||
description: 'Rotation amount for each item in degrees.'
|
||||
},
|
||||
{
|
||||
name: 'blurAmount',
|
||||
type: 'number',
|
||||
default: '0',
|
||||
description: 'Blur amount for items that are further back in the stack.'
|
||||
},
|
||||
{
|
||||
name: 'onStackComplete',
|
||||
type: 'function',
|
||||
default: 'undefined',
|
||||
description: 'Callback function called when the stack animation is complete.'
|
||||
}
|
||||
];
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.demo-container {
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<TabbedLayout>
|
||||
<template #preview>
|
||||
<div
|
||||
ref="containerRef"
|
||||
class="demo-container relative min-h-[400px] overflow-hidden p-4 font-['Roboto_Flex',sans-serif]"
|
||||
>
|
||||
<VariableProximity
|
||||
label="Hover me! And then star Vue Bits on GitHub, or else..."
|
||||
class-name="variable-proximity-demo"
|
||||
from-font-variation-settings="'wght' 400, 'opsz' 9"
|
||||
to-font-variation-settings="'wght' 1000, 'opsz' 40"
|
||||
:container-ref="containerRef"
|
||||
:radius="radius"
|
||||
:falloff="falloff"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Customize>
|
||||
<PreviewSlider title="Radius" v-model="radius" :min="50" :max="300" :step="10" />
|
||||
|
||||
<div class="flex gap-2 flex-wrap">
|
||||
<button
|
||||
v-for="type in falloffTypes"
|
||||
:key="type"
|
||||
class="text-xs cursor-pointer bg-[#0b0b0b] rounded-[10px] border border-[#333] hover:bg-[#222] text-white h-8 px-3 transition-colors"
|
||||
:class="{ 'bg-[#333]': falloff === type }"
|
||||
@click="falloff = type"
|
||||
>
|
||||
{{ type }}
|
||||
</button>
|
||||
</div>
|
||||
</Customize>
|
||||
|
||||
<PropTable :data="propData" />
|
||||
<Dependencies :dependency-list="['motion-v']" />
|
||||
</template>
|
||||
|
||||
<template #code>
|
||||
<CodeExample :code-object="variableProximity" />
|
||||
</template>
|
||||
|
||||
<template #cli>
|
||||
<CliInstallation :command="variableProximity.cli" />
|
||||
</template>
|
||||
</TabbedLayout>
|
||||
</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 VariableProximity, { type FalloffType } from '@/content/TextAnimations/VariableProximity/VariableProximity.vue';
|
||||
import { variableProximity } from '@/constants/code/TextAnimations/variableProximityCode';
|
||||
|
||||
const containerRef = ref<HTMLElement | null>(null);
|
||||
const radius = ref(100);
|
||||
const falloff = ref<FalloffType>('linear');
|
||||
|
||||
const falloffTypes: FalloffType[] = ['linear', 'exponential', 'gaussian'];
|
||||
|
||||
const propData = [
|
||||
{
|
||||
name: 'label',
|
||||
type: 'string',
|
||||
default: '""',
|
||||
description: 'The text content to display.'
|
||||
},
|
||||
{
|
||||
name: 'fromFontVariationSettings',
|
||||
type: 'string',
|
||||
default: "\"'wght' 400, 'opsz' 9\"",
|
||||
description: 'The starting variation settings.'
|
||||
},
|
||||
{
|
||||
name: 'toFontVariationSettings',
|
||||
type: 'string',
|
||||
default: "\"'wght' 800, 'opsz' 40\"",
|
||||
description: 'The variation settings to reach at cursor proximity.'
|
||||
},
|
||||
{
|
||||
name: 'containerRef',
|
||||
type: 'HTMLElement',
|
||||
default: 'undefined',
|
||||
description: 'Reference to container for relative calculations.'
|
||||
},
|
||||
{
|
||||
name: 'radius',
|
||||
type: 'number',
|
||||
default: '50',
|
||||
description: 'Proximity radius to influence the effect.'
|
||||
},
|
||||
{
|
||||
name: 'falloff',
|
||||
type: '"linear" | "exponential" | "gaussian"',
|
||||
default: '"linear"',
|
||||
description: 'Type of falloff for the effect.'
|
||||
},
|
||||
{
|
||||
name: 'className',
|
||||
type: 'string',
|
||||
default: '""',
|
||||
description: 'Additional CSS classes to apply.'
|
||||
},
|
||||
{
|
||||
name: 'style',
|
||||
type: 'CSSProperties',
|
||||
default: '{}',
|
||||
description: 'Inline styles to apply.'
|
||||
},
|
||||
{
|
||||
name: 'onClick',
|
||||
type: '() => void',
|
||||
default: 'undefined',
|
||||
description: 'Click event handler.'
|
||||
}
|
||||
];
|
||||
</script>
|
||||
<style scoped>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Roboto+Flex:opsz,wght@8..144,100..1000&display=swap');
|
||||
</style>
|
||||
Reference in New Issue
Block a user