mirror of
https://github.com/DavidHDev/vue-bits.git
synced 2026-03-07 06:29:30 -07:00
Merge pull request #91 from Utkarsh-Singhal-26/feat/liquid-ether
FEAT: 🎉 New <LiquidEther /> component
This commit is contained in:
@@ -19,10 +19,10 @@
|
||||
/>
|
||||
|
||||
<div class="hero-main-content">
|
||||
<router-link to="/backgrounds/staggered-menu" class="hero-new-badge-container">
|
||||
<router-link to="/backgrounds/liquid-ether" class="hero-new-badge-container">
|
||||
<span class="hero-new-badge">New 🎉</span>
|
||||
<div class="hero-new-badge-text">
|
||||
<span>Staggered Menu</span>
|
||||
<span>Liquid Ether</span>
|
||||
<i class="pi-arrow-right pi" style="font-size: 0.8rem"></i>
|
||||
</div>
|
||||
</router-link>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Highlighted sidebar items
|
||||
export const NEW = ['Staggered Menu', 'Pixel Blast', 'Gradual Blur', 'Gradient Blinds', 'Bubble Menu', 'Prism', 'Plasma', 'Electric Border', 'Target Cursor', 'Pill Nav', 'Card Nav', 'Logo Loop', 'Prismatic Burst'];
|
||||
export const NEW = ['Liquid Ether', 'Staggered Menu', 'Pixel Blast', 'Gradual Blur', 'Gradient Blinds', 'Bubble Menu', 'Prism', 'Plasma', 'Electric Border', 'Target Cursor', 'Pill Nav', 'Card Nav', 'Logo Loop', 'Prismatic Burst'];
|
||||
export const UPDATED = [];
|
||||
|
||||
// Used for main sidebar navigation
|
||||
@@ -111,6 +111,7 @@ export const CATEGORIES = [
|
||||
'Hyperspeed',
|
||||
'Faulty Terminal',
|
||||
'Plasma',
|
||||
'Liquid Ether',
|
||||
'Ripple Grid',
|
||||
'Silk',
|
||||
'Lightning',
|
||||
|
||||
@@ -114,6 +114,7 @@ const backgrounds = {
|
||||
'gradient-blinds': () => import('../demo/Backgrounds/GradientBlindsDemo.vue'),
|
||||
'prismatic-burst': () => import('../demo/Backgrounds/PrismaticBurstDemo.vue'),
|
||||
'pixel-blast': () => import('../demo/Backgrounds/PixelBlastDemo.vue'),
|
||||
'liquid-ether': () => import('../demo/Backgrounds/LiquidEtherDemo.vue'),
|
||||
};
|
||||
|
||||
export const componentMap = {
|
||||
|
||||
31
src/constants/code/Backgrounds/liquidEtherCode.ts
Normal file
31
src/constants/code/Backgrounds/liquidEtherCode.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import code from '@content/Backgrounds/LiquidEther/LiquidEther.vue?raw';
|
||||
import { createCodeObject } from '../../../types/code';
|
||||
|
||||
export const liquidEther = createCodeObject(code, 'Backgrounds/LiquidEther', {
|
||||
installation: `npm install three`,
|
||||
usage: `<template>
|
||||
<div style="width: 100%; height: 600px; position: relative">
|
||||
<LiquidEther
|
||||
:colors="['#48FF28', '#A2FFC6', '#9EF19E']"
|
||||
:mouseForce="20"
|
||||
:cursorSize="100"
|
||||
:isViscous="false"
|
||||
:viscous="30"
|
||||
:iterationsViscous="32"
|
||||
:iterationsPoisson="32"
|
||||
:resolution="0.5"
|
||||
:isBounce="false"
|
||||
:autoDemo="true"
|
||||
:autoSpeed="0.5"
|
||||
:autoIntensity="2.2"
|
||||
:takeoverDuration="0.25"
|
||||
:autoResumeDelay="3000"
|
||||
:autoRampDuration="0.6"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import LiquidEther from './LiquidEther.vue'
|
||||
</script>`
|
||||
});
|
||||
1265
src/content/Backgrounds/LiquidEther/LiquidEther.vue
Normal file
1265
src/content/Backgrounds/LiquidEther/LiquidEther.vue
Normal file
File diff suppressed because it is too large
Load Diff
217
src/demo/Backgrounds/LiquidEtherDemo.vue
Normal file
217
src/demo/Backgrounds/LiquidEtherDemo.vue
Normal file
@@ -0,0 +1,217 @@
|
||||
<template>
|
||||
<TabbedLayout>
|
||||
<template #preview>
|
||||
<div class="relative p-0 h-[600px] overflow-hidden demo-container">
|
||||
<LiquidEther
|
||||
:colors="userColors"
|
||||
:mouse-force="mouseForce"
|
||||
:cursor-size="cursorSize"
|
||||
:resolution="resolution"
|
||||
:is-viscous="isViscous"
|
||||
:viscous="viscous"
|
||||
:iterations-viscous="iterationsViscous"
|
||||
:iterations-poisson="iterationsPoisson"
|
||||
:is-bounce="isBounce"
|
||||
:auto-demo="autoDemo"
|
||||
:auto-speed="autoSpeed"
|
||||
:auto-intensity="autoIntensity"
|
||||
:auto-resume-delay="500"
|
||||
/>
|
||||
|
||||
<BackgroundContent pill-text="New Background" headline="The web, made fluid at your fingertips." />
|
||||
</div>
|
||||
|
||||
<Customize>
|
||||
<div class="flex gap-4">
|
||||
<p class="mt-2 mb-1 text-sm">Color</p>
|
||||
<PreviewColor v-model="color0" />
|
||||
<PreviewColor v-model="color1" />
|
||||
<PreviewColor v-model="color2" />
|
||||
</div>
|
||||
|
||||
<PreviewSlider :min="0" :max="60" :step="1" v-model="mouseForce" title="Mouse Force" />
|
||||
<PreviewSlider :min="10" :max="200" :step="5" v-model="cursorSize" title="Cursor Size" />
|
||||
<PreviewSlider :min="0.2" :max="0.5" :step="0.05" v-model="resolution" title="Resolution" />
|
||||
<PreviewSlider :min="0" :max="1" :step="0.05" v-model="autoSpeed" title="Auto Speed" />
|
||||
<PreviewSlider :min="0" :max="4" :step="0.1" v-model="autoIntensity" title="Auto Intensity" />
|
||||
<PreviewSlider :min="1" :max="64" :step="1" v-model="iterationsPoisson" title="Pressure" />
|
||||
|
||||
<PreviewSwitch title="Bounce Edges" v-model="isBounce" />
|
||||
<PreviewSwitch title="Auto Animate" v-model="autoDemo" />
|
||||
<PreviewSwitch title="Viscous" v-model="isViscous" />
|
||||
|
||||
<PreviewSlider v-if="isViscous" :min="1" :max="100" :step="1" v-model="viscous" title="Viscous Coef" />
|
||||
<PreviewSlider
|
||||
v-if="isViscous"
|
||||
:min="1"
|
||||
:max="64"
|
||||
:step="1"
|
||||
v-model="iterationsViscous"
|
||||
title="Viscous Iterations"
|
||||
/>
|
||||
</Customize>
|
||||
|
||||
<PropTable :data="propData" />
|
||||
<Dependencies :dependency-list="['three']" />
|
||||
</template>
|
||||
|
||||
<template #code>
|
||||
<CodeExample :code-object="liquidEther" />
|
||||
</template>
|
||||
|
||||
<template #cli>
|
||||
<CliInstallation :command="liquidEther.cli" />
|
||||
</template>
|
||||
</TabbedLayout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { liquidEther } from '@/constants/code/Backgrounds/liquidEtherCode';
|
||||
import { computed, 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 PreviewSwitch from '../../components/common/PreviewSwitch.vue';
|
||||
import PreviewSlider from '../../components/common/PreviewSlider.vue';
|
||||
import PropTable from '../../components/common/PropTable.vue';
|
||||
import TabbedLayout from '../../components/common/TabbedLayout.vue';
|
||||
import LiquidEther from '../../content/Backgrounds/LiquidEther/LiquidEther.vue';
|
||||
|
||||
const mouseForce = ref(20);
|
||||
const cursorSize = ref(100);
|
||||
const resolution = ref(0.5);
|
||||
const isViscous = ref(true);
|
||||
const viscous = ref(30);
|
||||
const iterationsViscous = ref(32);
|
||||
const iterationsPoisson = ref(32);
|
||||
const isBounce = ref(false);
|
||||
const autoDemo = ref(true);
|
||||
const autoSpeed = ref(0.5);
|
||||
const autoIntensity = ref(2.2);
|
||||
|
||||
const color0 = ref('#48FF28');
|
||||
const color1 = ref('#A2FFC6');
|
||||
const color2 = ref('#9EF19E');
|
||||
|
||||
const userColors = computed(() => [color0.value, color1.value, color2.value].filter(Boolean) as string[]);
|
||||
|
||||
const propData = [
|
||||
{
|
||||
name: 'colors',
|
||||
type: 'string[]',
|
||||
default: `["#48FF28", "#A2FFC6", "#9EF19E"]`,
|
||||
description: 'Array of hex color stops used to build the velocity-to-color palette.'
|
||||
},
|
||||
{
|
||||
name: 'mouseForce',
|
||||
type: 'number',
|
||||
default: '20',
|
||||
description: 'Strength multiplier applied to mouse / touch movement when injecting velocity.'
|
||||
},
|
||||
{
|
||||
name: 'cursorSize',
|
||||
type: 'number',
|
||||
default: '100',
|
||||
description: 'Radius (in pixels at base resolution) of the force brush.'
|
||||
},
|
||||
{
|
||||
name: 'resolution',
|
||||
type: 'number',
|
||||
default: '0.5',
|
||||
description: 'Simulation texture scale relative to canvas size (lower = better performance, more blur).'
|
||||
},
|
||||
{
|
||||
name: 'dt',
|
||||
type: 'number',
|
||||
default: '0.014',
|
||||
description: 'Fixed simulation timestep used inside the advection / diffusion passes.'
|
||||
},
|
||||
{
|
||||
name: 'BFECC',
|
||||
type: 'boolean',
|
||||
default: 'true',
|
||||
description: 'Enable BFECC advection (error-compensated) for crisper flow; disable for slight performance gain.'
|
||||
},
|
||||
{
|
||||
name: 'isViscous',
|
||||
type: 'boolean',
|
||||
default: 'false',
|
||||
description: 'Toggle iterative viscosity solve (smoother, thicker motion when enabled).'
|
||||
},
|
||||
{
|
||||
name: 'viscous',
|
||||
type: 'number',
|
||||
default: '30',
|
||||
description: 'Viscosity coefficient used when isViscous is true.'
|
||||
},
|
||||
{
|
||||
name: 'iterationsViscous',
|
||||
type: 'number',
|
||||
default: '32',
|
||||
description: 'Number of Gauss-Seidel iterations for viscosity (higher = smoother, slower).'
|
||||
},
|
||||
{
|
||||
name: 'iterationsPoisson',
|
||||
type: 'number',
|
||||
default: '32',
|
||||
description: 'Number of pressure Poisson iterations to enforce incompressibility.'
|
||||
},
|
||||
{
|
||||
name: 'isBounce',
|
||||
type: 'boolean',
|
||||
default: 'false',
|
||||
description: 'If true, shows bounce boundaries (velocity clamped at edges).'
|
||||
},
|
||||
{
|
||||
name: 'autoDemo',
|
||||
type: 'boolean',
|
||||
default: 'true',
|
||||
description: 'Enable idle auto-driving of the pointer when no user interaction.'
|
||||
},
|
||||
{
|
||||
name: 'autoSpeed',
|
||||
type: 'number',
|
||||
default: '0.5',
|
||||
description: 'Speed (normalized units/sec) for auto pointer motion.'
|
||||
},
|
||||
{
|
||||
name: 'autoIntensity',
|
||||
type: 'number',
|
||||
default: '2.2',
|
||||
description: 'Multiplier applied to velocity delta while in auto mode.'
|
||||
},
|
||||
{
|
||||
name: 'takeoverDuration',
|
||||
type: 'number',
|
||||
default: '0.25',
|
||||
description: 'Seconds to interpolate from auto pointer to real cursor when user moves mouse.'
|
||||
},
|
||||
{
|
||||
name: 'autoResumeDelay',
|
||||
type: 'number',
|
||||
default: '1000',
|
||||
description: 'Milliseconds of inactivity before auto mode resumes.'
|
||||
},
|
||||
{
|
||||
name: 'autoRampDuration',
|
||||
type: 'number',
|
||||
default: '0.6',
|
||||
description: 'Seconds to ramp auto movement speed from 0 to full after activation.'
|
||||
},
|
||||
{
|
||||
name: 'className',
|
||||
type: 'string',
|
||||
default: "''",
|
||||
description: 'Optional class for the root container.'
|
||||
},
|
||||
{
|
||||
name: 'style',
|
||||
type: 'CSSProperties',
|
||||
default: '{}',
|
||||
description: 'Inline styles applied to the root container.'
|
||||
}
|
||||
];
|
||||
</script>
|
||||
Reference in New Issue
Block a user