mirror of
https://github.com/DavidHDev/vue-bits.git
synced 2026-04-21 17:44:39 -06:00
feat: added <LineWaves /> background
This commit is contained in:
@@ -0,0 +1,29 @@
|
|||||||
|
import code from '@content/Backgrounds/LineWaves/LineWaves.vue?raw';
|
||||||
|
import { createCodeObject } from '../../../types/code';
|
||||||
|
|
||||||
|
export const lineWaves = createCodeObject(code, 'Backgrounds/LineWaves', {
|
||||||
|
installation: `npm install ogl`,
|
||||||
|
usage: `<template>
|
||||||
|
<div style="width: 100%; height: 600px; position: relative;">
|
||||||
|
<LineWaves
|
||||||
|
:speed="0.3"
|
||||||
|
:innerLineCount="32"
|
||||||
|
:outerLineCount="36"
|
||||||
|
:warpIntensity="1"
|
||||||
|
:rotation="-45"
|
||||||
|
:edgeFadeWidth="0"
|
||||||
|
:colorCycleSpeed="1"
|
||||||
|
:brightness="0.2"
|
||||||
|
:color1="#ffffff"
|
||||||
|
:color2="#ffffff"
|
||||||
|
:color3="#ffffff"
|
||||||
|
:enableMouseInteraction="true"
|
||||||
|
:mouseInfluence="2"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import LineWaves from "./LineWaves.vue";
|
||||||
|
</script>`
|
||||||
|
});
|
||||||
@@ -0,0 +1,289 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { Renderer, Program, Mesh, Triangle } from 'ogl';
|
||||||
|
import { onBeforeUnmount, onMounted, useTemplateRef, watch } from 'vue';
|
||||||
|
|
||||||
|
interface LineWavesProps {
|
||||||
|
speed?: number;
|
||||||
|
innerLineCount?: number;
|
||||||
|
outerLineCount?: number;
|
||||||
|
warpIntensity?: number;
|
||||||
|
rotation?: number;
|
||||||
|
edgeFadeWidth?: number;
|
||||||
|
colorCycleSpeed?: number;
|
||||||
|
brightness?: number;
|
||||||
|
color1?: string;
|
||||||
|
color2?: string;
|
||||||
|
color3?: string;
|
||||||
|
enableMouseInteraction?: boolean;
|
||||||
|
mouseInfluence?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hexToVec3(hex: string): [number, number, number] {
|
||||||
|
const h = hex.replace('#', '');
|
||||||
|
return [parseInt(h.slice(0, 2), 16) / 255, parseInt(h.slice(2, 4), 16) / 255, parseInt(h.slice(4, 6), 16) / 255];
|
||||||
|
}
|
||||||
|
|
||||||
|
const vertexShader = `
|
||||||
|
attribute vec2 uv;
|
||||||
|
attribute vec2 position;
|
||||||
|
varying vec2 vUv;
|
||||||
|
void main() {
|
||||||
|
vUv = uv;
|
||||||
|
gl_Position = vec4(position, 0, 1);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const fragmentShader = `
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
uniform float uTime;
|
||||||
|
uniform vec3 uResolution;
|
||||||
|
uniform float uSpeed;
|
||||||
|
uniform float uInnerLines;
|
||||||
|
uniform float uOuterLines;
|
||||||
|
uniform float uWarpIntensity;
|
||||||
|
uniform float uRotation;
|
||||||
|
uniform float uEdgeFadeWidth;
|
||||||
|
uniform float uColorCycleSpeed;
|
||||||
|
uniform float uBrightness;
|
||||||
|
uniform vec3 uColor1;
|
||||||
|
uniform vec3 uColor2;
|
||||||
|
uniform vec3 uColor3;
|
||||||
|
uniform vec2 uMouse;
|
||||||
|
uniform float uMouseInfluence;
|
||||||
|
uniform bool uEnableMouse;
|
||||||
|
|
||||||
|
#define HALF_PI 1.5707963
|
||||||
|
|
||||||
|
float hashF(float n) {
|
||||||
|
return fract(sin(n * 127.1) * 43758.5453123);
|
||||||
|
}
|
||||||
|
|
||||||
|
float smoothNoise(float x) {
|
||||||
|
float i = floor(x);
|
||||||
|
float f = fract(x);
|
||||||
|
float u = f * f * (3.0 - 2.0 * f);
|
||||||
|
return mix(hashF(i), hashF(i + 1.0), u);
|
||||||
|
}
|
||||||
|
|
||||||
|
float displaceA(float coord, float t) {
|
||||||
|
float result = sin(coord * 2.123) * 0.2;
|
||||||
|
result += sin(coord * 3.234 + t * 4.345) * 0.1;
|
||||||
|
result += sin(coord * 0.589 + t * 0.934) * 0.5;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
float displaceB(float coord, float t) {
|
||||||
|
float result = sin(coord * 1.345) * 0.3;
|
||||||
|
result += sin(coord * 2.734 + t * 3.345) * 0.2;
|
||||||
|
result += sin(coord * 0.189 + t * 0.934) * 0.3;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 rotate2D(vec2 p, float angle) {
|
||||||
|
float c = cos(angle);
|
||||||
|
float s = sin(angle);
|
||||||
|
return vec2(p.x * c - p.y * s, p.x * s + p.y * c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 coords = gl_FragCoord.xy / uResolution.xy;
|
||||||
|
coords = coords * 2.0 - 1.0;
|
||||||
|
coords = rotate2D(coords, uRotation);
|
||||||
|
|
||||||
|
float halfT = uTime * uSpeed * 0.5;
|
||||||
|
float fullT = uTime * uSpeed;
|
||||||
|
|
||||||
|
float mouseWarp = 0.0;
|
||||||
|
if (uEnableMouse) {
|
||||||
|
vec2 mPos = rotate2D(uMouse * 2.0 - 1.0, uRotation);
|
||||||
|
float mDist = length(coords - mPos);
|
||||||
|
mouseWarp = uMouseInfluence * exp(-mDist * mDist * 4.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
float warpAx = coords.x + displaceA(coords.y, halfT) * uWarpIntensity + mouseWarp;
|
||||||
|
float warpAy = coords.y - displaceA(coords.x * cos(fullT) * 1.235, halfT) * uWarpIntensity;
|
||||||
|
float warpBx = coords.x + displaceB(coords.y, halfT) * uWarpIntensity + mouseWarp;
|
||||||
|
float warpBy = coords.y - displaceB(coords.x * sin(fullT) * 1.235, halfT) * uWarpIntensity;
|
||||||
|
|
||||||
|
vec2 fieldA = vec2(warpAx, warpAy);
|
||||||
|
vec2 fieldB = vec2(warpBx, warpBy);
|
||||||
|
vec2 blended = mix(fieldA, fieldB, mix(fieldA, fieldB, 0.5));
|
||||||
|
|
||||||
|
float fadeTop = smoothstep(uEdgeFadeWidth, uEdgeFadeWidth + 0.4, blended.y);
|
||||||
|
float fadeBottom = smoothstep(-uEdgeFadeWidth, -(uEdgeFadeWidth + 0.4), blended.y);
|
||||||
|
float vMask = 1.0 - max(fadeTop, fadeBottom);
|
||||||
|
|
||||||
|
float tileCount = mix(uOuterLines, uInnerLines, vMask);
|
||||||
|
float scaledY = blended.y * tileCount;
|
||||||
|
float nY = smoothNoise(abs(scaledY));
|
||||||
|
|
||||||
|
float ridge = pow(
|
||||||
|
step(abs(nY - blended.x) * 2.0, HALF_PI) * cos(2.0 * (nY - blended.x)),
|
||||||
|
5.0
|
||||||
|
);
|
||||||
|
|
||||||
|
float lines = 0.0;
|
||||||
|
for (float i = 1.0; i < 3.0; i += 1.0) {
|
||||||
|
lines += pow(max(fract(scaledY), fract(-scaledY)), i * 2.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
float pattern = vMask * lines;
|
||||||
|
|
||||||
|
float cycleT = fullT * uColorCycleSpeed;
|
||||||
|
float rChannel = (pattern + lines * ridge) * (cos(blended.y + cycleT * 0.234) * 0.5 + 1.0);
|
||||||
|
float gChannel = (pattern + vMask * ridge) * (sin(blended.x + cycleT * 1.745) * 0.5 + 1.0);
|
||||||
|
float bChannel = (pattern + lines * ridge) * (cos(blended.x + cycleT * 0.534) * 0.5 + 1.0);
|
||||||
|
|
||||||
|
vec3 col = (rChannel * uColor1 + gChannel * uColor2 + bChannel * uColor3) * uBrightness;
|
||||||
|
float alpha = clamp(length(col), 0.0, 1.0);
|
||||||
|
|
||||||
|
gl_FragColor = vec4(col, alpha);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<LineWavesProps>(), {
|
||||||
|
speed: 0.3,
|
||||||
|
innerLineCount: 32.0,
|
||||||
|
outerLineCount: 36.0,
|
||||||
|
warpIntensity: 1.0,
|
||||||
|
rotation: -45,
|
||||||
|
edgeFadeWidth: 0.0,
|
||||||
|
colorCycleSpeed: 1.0,
|
||||||
|
brightness: 0.2,
|
||||||
|
color1: '#ffffff',
|
||||||
|
color2: '#ffffff',
|
||||||
|
color3: '#ffffff',
|
||||||
|
enableMouseInteraction: true,
|
||||||
|
mouseInfluence: 2.0
|
||||||
|
});
|
||||||
|
|
||||||
|
const containerRef = useTemplateRef<HTMLDivElement>('containerRef');
|
||||||
|
|
||||||
|
let cleanup: (() => void) | null = null;
|
||||||
|
const setup = () => {
|
||||||
|
if (!containerRef.value) return;
|
||||||
|
const container = containerRef.value;
|
||||||
|
const renderer = new Renderer({ alpha: true, premultipliedAlpha: false });
|
||||||
|
const gl = renderer.gl;
|
||||||
|
gl.clearColor(0, 0, 0, 0);
|
||||||
|
|
||||||
|
const currentMouse = [0.5, 0.5];
|
||||||
|
let targetMouse = [0.5, 0.5];
|
||||||
|
|
||||||
|
function handleMouseMove(e: MouseEvent) {
|
||||||
|
const rect = gl.canvas.getBoundingClientRect();
|
||||||
|
targetMouse = [(e.clientX - rect.left) / rect.width, 1.0 - (e.clientY - rect.top) / rect.height];
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleMouseLeave() {
|
||||||
|
targetMouse = [0.5, 0.5];
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer.setSize(container.offsetWidth, container.offsetHeight);
|
||||||
|
|
||||||
|
const geometry = new Triangle(gl);
|
||||||
|
const rotationRad = (props.rotation * Math.PI) / 180;
|
||||||
|
const program = new Program(gl, {
|
||||||
|
vertex: vertexShader,
|
||||||
|
fragment: fragmentShader,
|
||||||
|
uniforms: {
|
||||||
|
uTime: { value: 0 },
|
||||||
|
uResolution: { value: [gl.canvas.width, gl.canvas.height, gl.canvas.width / gl.canvas.height] },
|
||||||
|
uSpeed: { value: props.speed },
|
||||||
|
uInnerLines: { value: props.innerLineCount },
|
||||||
|
uOuterLines: { value: props.outerLineCount },
|
||||||
|
uWarpIntensity: { value: props.warpIntensity },
|
||||||
|
uRotation: { value: rotationRad },
|
||||||
|
uEdgeFadeWidth: { value: props.edgeFadeWidth },
|
||||||
|
uColorCycleSpeed: { value: props.colorCycleSpeed },
|
||||||
|
uBrightness: { value: props.brightness },
|
||||||
|
uColor1: { value: hexToVec3(props.color1) },
|
||||||
|
uColor2: { value: hexToVec3(props.color2) },
|
||||||
|
uColor3: { value: hexToVec3(props.color3) },
|
||||||
|
uMouse: { value: new Float32Array([0.5, 0.5]) },
|
||||||
|
uMouseInfluence: { value: props.mouseInfluence },
|
||||||
|
uEnableMouse: { value: props.enableMouseInteraction }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function resize() {
|
||||||
|
renderer.setSize(container.offsetWidth, container.offsetHeight);
|
||||||
|
program.uniforms.uResolution.value = [gl.canvas.width, gl.canvas.height, gl.canvas.width / gl.canvas.height];
|
||||||
|
}
|
||||||
|
window.addEventListener('resize', resize);
|
||||||
|
|
||||||
|
const mesh = new Mesh(gl, { geometry, program });
|
||||||
|
container.appendChild(gl.canvas);
|
||||||
|
|
||||||
|
if (props.enableMouseInteraction) {
|
||||||
|
gl.canvas.addEventListener('mousemove', handleMouseMove);
|
||||||
|
gl.canvas.addEventListener('mouseleave', handleMouseLeave);
|
||||||
|
}
|
||||||
|
|
||||||
|
let animationFrameId: number;
|
||||||
|
|
||||||
|
function update(time: number) {
|
||||||
|
animationFrameId = requestAnimationFrame(update);
|
||||||
|
program.uniforms.uTime.value = time * 0.001;
|
||||||
|
|
||||||
|
if (props.enableMouseInteraction) {
|
||||||
|
currentMouse[0] += 0.05 * (targetMouse[0] - currentMouse[0]);
|
||||||
|
currentMouse[1] += 0.05 * (targetMouse[1] - currentMouse[1]);
|
||||||
|
program.uniforms.uMouse.value[0] = currentMouse[0];
|
||||||
|
program.uniforms.uMouse.value[1] = currentMouse[1];
|
||||||
|
} else {
|
||||||
|
program.uniforms.uMouse.value[0] = 0.5;
|
||||||
|
program.uniforms.uMouse.value[1] = 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer.render({ scene: mesh });
|
||||||
|
}
|
||||||
|
animationFrameId = requestAnimationFrame(update);
|
||||||
|
|
||||||
|
cleanup = () => {
|
||||||
|
cancelAnimationFrame(animationFrameId);
|
||||||
|
window.removeEventListener('resize', resize);
|
||||||
|
if (props.enableMouseInteraction) {
|
||||||
|
gl.canvas.removeEventListener('mousemove', handleMouseMove);
|
||||||
|
gl.canvas.removeEventListener('mouseleave', handleMouseLeave);
|
||||||
|
}
|
||||||
|
container.removeChild(gl.canvas);
|
||||||
|
gl.getExtension('WEBGL_lose_context')?.loseContext();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
setup();
|
||||||
|
});
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
cleanup?.();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => [
|
||||||
|
props.speed,
|
||||||
|
props.innerLineCount,
|
||||||
|
props.outerLineCount,
|
||||||
|
props.warpIntensity,
|
||||||
|
props.rotation,
|
||||||
|
props.edgeFadeWidth,
|
||||||
|
props.colorCycleSpeed,
|
||||||
|
props.brightness,
|
||||||
|
props.color1,
|
||||||
|
props.color2,
|
||||||
|
props.color3,
|
||||||
|
props.enableMouseInteraction,
|
||||||
|
props.mouseInfluence
|
||||||
|
],
|
||||||
|
() => {
|
||||||
|
cleanup?.();
|
||||||
|
setup();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div ref="containerRef" class="w-full h-full" />
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,173 @@
|
|||||||
|
<template>
|
||||||
|
<TabbedLayout>
|
||||||
|
<template #preview>
|
||||||
|
<div class="relative p-0 h-[600px] overflow-hidden demo-container">
|
||||||
|
<LineWaves
|
||||||
|
:speed="speed"
|
||||||
|
:inner-line-count="innerLineCount"
|
||||||
|
:outer-line-count="outerLineCount"
|
||||||
|
:warp-intensity="warpIntensity"
|
||||||
|
:rotation="rotation"
|
||||||
|
:edge-fade-width="edgeFadeWidth"
|
||||||
|
:color-cycle-speed="colorCycleSpeed"
|
||||||
|
:brightness="brightness"
|
||||||
|
:color1="color1"
|
||||||
|
:color2="color2"
|
||||||
|
:color3="color3"
|
||||||
|
:enable-mouse-interaction="enableMouseInteraction"
|
||||||
|
:mouse-influence="mouseInfluence"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<BackgroundContent pill-text="New Background" headline="Ride the waves of your creativity!" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Customize>
|
||||||
|
<div class="flex items-center gap-4 mt-4">
|
||||||
|
<PreviewColor title="Color 1" v-model="color1" />
|
||||||
|
<PreviewColor title="Color 2" v-model="color2" />
|
||||||
|
<PreviewColor title="Color 3" v-model="color3" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<PreviewSlider title="Speed" :min="0.1" :max="3" :step="0.1" v-model="speed" />
|
||||||
|
<PreviewSlider title="Inner Line Count" :min="2" :max="40" :step="1" v-model="innerLineCount" />
|
||||||
|
<PreviewSlider title="Outer Line Count" :min="2" :max="40" :step="1" v-model="outerLineCount" />
|
||||||
|
<PreviewSlider title="Warp Intensity" :min="0.1" :max="3" :step="0.1" v-model="warpIntensity" />
|
||||||
|
<PreviewSlider title="Rotation" :min="-180" :max="180" :step="1" v-model="rotation" />
|
||||||
|
<PreviewSlider title="Edge Fade Width" :min="0.0" :max="1.0" :step="0.05" v-model="edgeFadeWidth" />
|
||||||
|
<PreviewSlider title="Color Cycle Speed" :min="0.1" :max="5" :step="0.1" v-model="colorCycleSpeed" />
|
||||||
|
<PreviewSlider title="Brightness" :min="0.1" :max="3" :step="0.1" v-model="brightness" />
|
||||||
|
<PreviewSwitch title="Mouse Interaction" v-model="enableMouseInteraction" />
|
||||||
|
<PreviewSlider
|
||||||
|
v-if="enableMouseInteraction"
|
||||||
|
title="Mouse Influence"
|
||||||
|
:min="0.1"
|
||||||
|
:max="2"
|
||||||
|
:step="0.1"
|
||||||
|
v-model="mouseInfluence"
|
||||||
|
/>
|
||||||
|
</Customize>
|
||||||
|
|
||||||
|
<PropTable :data="propData" />
|
||||||
|
<Dependencies :dependency-list="['ogl']" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #code>
|
||||||
|
<CodeExample :code-object="lineWaves" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #cli>
|
||||||
|
<CliInstallation :command="lineWaves.cli" />
|
||||||
|
</template>
|
||||||
|
</TabbedLayout>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
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 { lineWaves } from '@/constants/code/Backgrounds/lineWavesCode';
|
||||||
|
import LineWaves from '@/content/Backgrounds/LineWaves/LineWaves.vue';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
const speed = ref(0.3);
|
||||||
|
const innerLineCount = ref(32.0);
|
||||||
|
const outerLineCount = ref(36.0);
|
||||||
|
const warpIntensity = ref(1.0);
|
||||||
|
const rotation = ref(-45);
|
||||||
|
const edgeFadeWidth = ref(0.0);
|
||||||
|
const colorCycleSpeed = ref(1.0);
|
||||||
|
const brightness = ref(0.2);
|
||||||
|
const color1 = ref('#ffffff');
|
||||||
|
const color2 = ref('#ffffff');
|
||||||
|
const color3 = ref('#ffffff');
|
||||||
|
const enableMouseInteraction = ref(true);
|
||||||
|
const mouseInfluence = ref(2.0);
|
||||||
|
|
||||||
|
const propData = [
|
||||||
|
{
|
||||||
|
name: 'speed',
|
||||||
|
type: 'number',
|
||||||
|
default: '0.3',
|
||||||
|
description: 'Overall animation speed multiplier.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'innerLineCount',
|
||||||
|
type: 'number',
|
||||||
|
default: '32.0',
|
||||||
|
description: 'Number of lines in the inner (center) wave region.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'outerLineCount',
|
||||||
|
type: 'number',
|
||||||
|
default: '36.0',
|
||||||
|
description: 'Number of lines in the outer (edge) wave region.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'warpIntensity',
|
||||||
|
type: 'number',
|
||||||
|
default: '1.0',
|
||||||
|
description: 'Intensity of the wave distortion effect.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'rotation',
|
||||||
|
type: 'number',
|
||||||
|
default: '-45',
|
||||||
|
description: 'Rotation of the wave pattern in degrees.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'edgeFadeWidth',
|
||||||
|
type: 'number',
|
||||||
|
default: '0.0',
|
||||||
|
description: 'Width of the edge fade between inner and outer regions.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'colorCycleSpeed',
|
||||||
|
type: 'number',
|
||||||
|
default: '1.0',
|
||||||
|
description: 'Speed of color cycling animation.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'brightness',
|
||||||
|
type: 'number',
|
||||||
|
default: '0.2',
|
||||||
|
description: 'Overall brightness multiplier.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'color1',
|
||||||
|
type: 'string',
|
||||||
|
default: '"#ffffff"',
|
||||||
|
description: 'First color channel in HEX format.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'color2',
|
||||||
|
type: 'string',
|
||||||
|
default: '"#ffffff"',
|
||||||
|
description: 'Second color channel in HEX format.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'color3',
|
||||||
|
type: 'string',
|
||||||
|
default: '"#ffffff"',
|
||||||
|
description: 'Third color channel in HEX format.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'enableMouseInteraction',
|
||||||
|
type: 'boolean',
|
||||||
|
default: 'true',
|
||||||
|
description: 'Enable cursor-reactive wave distortion.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'mouseInfluence',
|
||||||
|
type: 'number',
|
||||||
|
default: '2.0',
|
||||||
|
description: 'Strength of mouse influence on the wave pattern.'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
</script>
|
||||||
Reference in New Issue
Block a user