mirror of
https://github.com/DavidHDev/vue-bits.git
synced 2026-03-07 06:29:30 -07:00
Added <FaultyTerminal /> background
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// Highlighted sidebar items
|
||||
export const NEW = ['Target Cursor', 'Ripple Grid', 'Magic Bento', 'Galaxy', 'Text Type', 'Glass Surface', 'Sticker Peel', 'Scroll Stack'];
|
||||
export const NEW = ['Target Cursor', 'Ripple Grid', 'Magic Bento', 'Galaxy', 'Text Type', 'Glass Surface', 'Sticker Peel', 'Scroll Stack', 'Faulty Terminal'];
|
||||
export const UPDATED = [];
|
||||
|
||||
// Used for main sidebar navigation
|
||||
@@ -93,6 +93,7 @@ export const CATEGORIES = [
|
||||
'Dither',
|
||||
'Dot Grid',
|
||||
'Hyperspeed',
|
||||
'Faulty Terminal',
|
||||
'Ripple Grid',
|
||||
'Silk',
|
||||
'Lightning',
|
||||
|
||||
@@ -95,6 +95,7 @@ const backgrounds = {
|
||||
'grid-distortion': () => import('../demo/Backgrounds/GridDistortionDemo.vue'),
|
||||
'ripple-grid': () => import('../demo/Backgrounds/RippleGridDemo.vue'),
|
||||
'galaxy': () => import('../demo/Backgrounds/GalaxyDemo.vue'),
|
||||
'faulty-terminal': () => import('../demo/Backgrounds/FaultyTerminalDemo.vue'),
|
||||
};
|
||||
|
||||
export const componentMap = {
|
||||
|
||||
33
src/constants/code/Backgrounds/faultyTerminalCode.ts
Normal file
33
src/constants/code/Backgrounds/faultyTerminalCode.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import code from '@content/Backgrounds/FaultyTerminal/FaultyTerminal.vue?raw';
|
||||
import { createCodeObject } from '../../../types/code';
|
||||
|
||||
export const faultyTerminal = createCodeObject(code, 'Backgrounds/FaultyTerminal', {
|
||||
installation: `npm install ogl`,
|
||||
usage: `<template>
|
||||
<div class="relative w-full h-[600px]">
|
||||
<FaultyTerminal
|
||||
:scale="1.5"
|
||||
:grid-mul="[2, 1]"
|
||||
:digit-size="1.2"
|
||||
:time-scale="1"
|
||||
:pause="false"
|
||||
:scanline-intensity="1"
|
||||
:glitch-amount="1"
|
||||
:flicker-amount="1"
|
||||
:noise-amp="1"
|
||||
:chromatic-aberration="0"
|
||||
:dither="0"
|
||||
:curvature="0"
|
||||
tint="#ffffff"
|
||||
:mouse-react="true"
|
||||
:mouse-strength="0.5"
|
||||
:page-load-animation="false"
|
||||
:brightness="1"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import FaultyTerminal from "./FaultyTerminal.vue";
|
||||
</script>`
|
||||
});
|
||||
439
src/content/Backgrounds/FaultyTerminal/FaultyTerminal.vue
Normal file
439
src/content/Backgrounds/FaultyTerminal/FaultyTerminal.vue
Normal file
@@ -0,0 +1,439 @@
|
||||
<script setup lang="ts">
|
||||
import { Color, Mesh, Program, Renderer, Triangle } from 'ogl';
|
||||
import { computed, onBeforeUnmount, onMounted, ref, useTemplateRef, watch } from 'vue';
|
||||
|
||||
type Vec2 = [number, number];
|
||||
|
||||
interface FaultyTerminalProps {
|
||||
scale?: number;
|
||||
gridMul?: Vec2;
|
||||
digitSize?: number;
|
||||
timeScale?: number;
|
||||
pause?: boolean;
|
||||
scanlineIntensity?: number;
|
||||
glitchAmount?: number;
|
||||
flickerAmount?: number;
|
||||
noiseAmp?: number;
|
||||
chromaticAberration?: number;
|
||||
dither?: number | boolean;
|
||||
curvature?: number;
|
||||
tint?: string;
|
||||
mouseReact?: boolean;
|
||||
mouseStrength?: number;
|
||||
dpr?: number;
|
||||
pageLoadAnimation?: boolean;
|
||||
brightness?: number;
|
||||
className?: string;
|
||||
style?: Record<string, string | number>;
|
||||
}
|
||||
|
||||
const vertexShader = `
|
||||
attribute vec2 position;
|
||||
attribute vec2 uv;
|
||||
varying vec2 vUv;
|
||||
void main() {
|
||||
vUv = uv;
|
||||
gl_Position = vec4(position, 0.0, 1.0);
|
||||
}
|
||||
`;
|
||||
|
||||
const fragmentShader = `
|
||||
precision mediump float;
|
||||
|
||||
varying vec2 vUv;
|
||||
|
||||
uniform float iTime;
|
||||
uniform vec3 iResolution;
|
||||
uniform float uScale;
|
||||
|
||||
uniform vec2 uGridMul;
|
||||
uniform float uDigitSize;
|
||||
uniform float uScanlineIntensity;
|
||||
uniform float uGlitchAmount;
|
||||
uniform float uFlickerAmount;
|
||||
uniform float uNoiseAmp;
|
||||
uniform float uChromaticAberration;
|
||||
uniform float uDither;
|
||||
uniform float uCurvature;
|
||||
uniform vec3 uTint;
|
||||
uniform vec2 uMouse;
|
||||
uniform float uMouseStrength;
|
||||
uniform float uUseMouse;
|
||||
uniform float uPageLoadProgress;
|
||||
uniform float uUsePageLoadAnimation;
|
||||
uniform float uBrightness;
|
||||
|
||||
float time;
|
||||
|
||||
float hash21(vec2 p){
|
||||
p = fract(p * 234.56);
|
||||
p += dot(p, p + 34.56);
|
||||
return fract(p.x * p.y);
|
||||
}
|
||||
|
||||
float noise(vec2 p)
|
||||
{
|
||||
return sin(p.x * 10.0) * sin(p.y * (3.0 + sin(time * 0.090909))) + 0.2;
|
||||
}
|
||||
|
||||
mat2 rotate(float angle)
|
||||
{
|
||||
float c = cos(angle);
|
||||
float s = sin(angle);
|
||||
return mat2(c, -s, s, c);
|
||||
}
|
||||
|
||||
float fbm(vec2 p)
|
||||
{
|
||||
p *= 1.1;
|
||||
float f = 0.0;
|
||||
float amp = 0.5 * uNoiseAmp;
|
||||
|
||||
mat2 modify0 = rotate(time * 0.02);
|
||||
f += amp * noise(p);
|
||||
p = modify0 * p * 2.0;
|
||||
amp *= 0.454545; // 1/2.2
|
||||
|
||||
mat2 modify1 = rotate(time * 0.02);
|
||||
f += amp * noise(p);
|
||||
p = modify1 * p * 2.0;
|
||||
amp *= 0.454545;
|
||||
|
||||
mat2 modify2 = rotate(time * 0.08);
|
||||
f += amp * noise(p);
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
float pattern(vec2 p, out vec2 q, out vec2 r) {
|
||||
vec2 offset1 = vec2(1.0);
|
||||
vec2 offset0 = vec2(0.0);
|
||||
mat2 rot01 = rotate(0.1 * time);
|
||||
mat2 rot1 = rotate(0.1);
|
||||
|
||||
q = vec2(fbm(p + offset1), fbm(rot01 * p + offset1));
|
||||
r = vec2(fbm(rot1 * q + offset0), fbm(q + offset0));
|
||||
return fbm(p + r);
|
||||
}
|
||||
|
||||
float digit(vec2 p){
|
||||
vec2 grid = uGridMul * 15.0;
|
||||
vec2 s = floor(p * grid) / grid;
|
||||
p = p * grid;
|
||||
vec2 q, r;
|
||||
float intensity = pattern(s * 0.1, q, r) * 1.3 - 0.03;
|
||||
|
||||
if(uUseMouse > 0.5){
|
||||
vec2 mouseWorld = uMouse * uScale;
|
||||
float distToMouse = distance(s, mouseWorld);
|
||||
float mouseInfluence = exp(-distToMouse * 8.0) * uMouseStrength * 10.0;
|
||||
intensity += mouseInfluence;
|
||||
|
||||
float ripple = sin(distToMouse * 20.0 - iTime * 5.0) * 0.1 * mouseInfluence;
|
||||
intensity += ripple;
|
||||
}
|
||||
|
||||
if(uUsePageLoadAnimation > 0.5){
|
||||
float cellRandom = fract(sin(dot(s, vec2(12.9898, 78.233))) * 43758.5453);
|
||||
float cellDelay = cellRandom * 0.8;
|
||||
float cellProgress = clamp((uPageLoadProgress - cellDelay) / 0.2, 0.0, 1.0);
|
||||
|
||||
float fadeAlpha = smoothstep(0.0, 1.0, cellProgress);
|
||||
intensity *= fadeAlpha;
|
||||
}
|
||||
|
||||
p = fract(p);
|
||||
p *= uDigitSize;
|
||||
|
||||
float px5 = p.x * 5.0;
|
||||
float py5 = (1.0 - p.y) * 5.0;
|
||||
float x = fract(px5);
|
||||
float y = fract(py5);
|
||||
|
||||
float i = floor(py5) - 2.0;
|
||||
float j = floor(px5) - 2.0;
|
||||
float n = i * i + j * j;
|
||||
float f = n * 0.0625;
|
||||
|
||||
float isOn = step(0.1, intensity - f);
|
||||
float brightness = isOn * (0.2 + y * 0.8) * (0.75 + x * 0.25);
|
||||
|
||||
return step(0.0, p.x) * step(p.x, 1.0) * step(0.0, p.y) * step(p.y, 1.0) * brightness;
|
||||
}
|
||||
|
||||
float onOff(float a, float b, float c)
|
||||
{
|
||||
return step(c, sin(iTime + a * cos(iTime * b))) * uFlickerAmount;
|
||||
}
|
||||
|
||||
float displace(vec2 look)
|
||||
{
|
||||
float y = look.y - mod(iTime * 0.25, 1.0);
|
||||
float window = 1.0 / (1.0 + 50.0 * y * y);
|
||||
return sin(look.y * 20.0 + iTime) * 0.0125 * onOff(4.0, 2.0, 0.8) * (1.0 + cos(iTime * 60.0)) * window;
|
||||
}
|
||||
|
||||
vec3 getColor(vec2 p){
|
||||
|
||||
float bar = step(mod(p.y + time * 20.0, 1.0), 0.2) * 0.4 + 1.0; // more efficient than ternary
|
||||
bar *= uScanlineIntensity;
|
||||
|
||||
float displacement = displace(p);
|
||||
p.x += displacement;
|
||||
|
||||
if (uGlitchAmount != 1.0) {
|
||||
float extra = displacement * (uGlitchAmount - 1.0);
|
||||
p.x += extra;
|
||||
}
|
||||
|
||||
float middle = digit(p);
|
||||
|
||||
const float off = 0.002;
|
||||
float sum = digit(p + vec2(-off, -off)) + digit(p + vec2(0.0, -off)) + digit(p + vec2(off, -off)) +
|
||||
digit(p + vec2(-off, 0.0)) + digit(p + vec2(0.0, 0.0)) + digit(p + vec2(off, 0.0)) +
|
||||
digit(p + vec2(-off, off)) + digit(p + vec2(0.0, off)) + digit(p + vec2(off, off));
|
||||
|
||||
vec3 baseColor = vec3(0.9) * middle + sum * 0.1 * vec3(1.0) * bar;
|
||||
return baseColor;
|
||||
}
|
||||
|
||||
vec2 barrel(vec2 uv){
|
||||
vec2 c = uv * 2.0 - 1.0;
|
||||
float r2 = dot(c, c);
|
||||
c *= 1.0 + uCurvature * r2;
|
||||
return c * 0.5 + 0.5;
|
||||
}
|
||||
|
||||
void main() {
|
||||
time = iTime * 0.333333;
|
||||
vec2 uv = vUv;
|
||||
|
||||
if(uCurvature != 0.0){
|
||||
uv = barrel(uv);
|
||||
}
|
||||
|
||||
vec2 p = uv * uScale;
|
||||
vec3 col = getColor(p);
|
||||
|
||||
if(uChromaticAberration != 0.0){
|
||||
vec2 ca = vec2(uChromaticAberration) / iResolution.xy;
|
||||
col.r = getColor(p + ca).r;
|
||||
col.b = getColor(p - ca).b;
|
||||
}
|
||||
|
||||
col *= uTint;
|
||||
col *= uBrightness;
|
||||
|
||||
if(uDither > 0.0){
|
||||
float rnd = hash21(gl_FragCoord.xy);
|
||||
col += (rnd - 0.5) * (uDither * 0.003922);
|
||||
}
|
||||
|
||||
gl_FragColor = vec4(col, 1.0);
|
||||
}
|
||||
`;
|
||||
|
||||
function hexToRgb(hex: string): [number, number, number] {
|
||||
let h = hex.replace('#', '').trim();
|
||||
if (h.length === 3)
|
||||
h = h
|
||||
.split('')
|
||||
.map(c => c + c)
|
||||
.join('');
|
||||
const num = parseInt(h, 16);
|
||||
return [((num >> 16) & 255) / 255, ((num >> 8) & 255) / 255, (num & 255) / 255];
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<FaultyTerminalProps>(), {
|
||||
scale: 1,
|
||||
gridMul: () => [2, 1],
|
||||
digitSize: 1.5,
|
||||
timeScale: 0.3,
|
||||
pause: false,
|
||||
scanlineIntensity: 0.3,
|
||||
glitchAmount: 1,
|
||||
flickerAmount: 1,
|
||||
noiseAmp: 1,
|
||||
chromaticAberration: 0,
|
||||
dither: 0,
|
||||
curvature: 0.2,
|
||||
tint: '#ffffff',
|
||||
mouseReact: true,
|
||||
mouseStrength: 0.2,
|
||||
dpr: Math.min(window.devicePixelRatio || 1, 2),
|
||||
pageLoadAnimation: true,
|
||||
brightness: 1,
|
||||
className: '',
|
||||
style: () => ({})
|
||||
});
|
||||
|
||||
const containerRef = useTemplateRef('containerRef');
|
||||
const programRef = ref<Program | null>(null);
|
||||
const rendererRef = ref<Renderer | null>(null);
|
||||
const mouseRef = ref({ x: 0.5, y: 0.5 });
|
||||
const smoothMouseRef = ref({ x: 0.5, y: 0.5 });
|
||||
const frozenTimeRef = ref(0);
|
||||
const rafRef = ref<number>(0);
|
||||
const loadAnimationStartRef = ref<number>(0);
|
||||
const timeOffsetRef = ref<number>(Math.random() * 100);
|
||||
|
||||
const tintVec = computed(() => hexToRgb(props.tint));
|
||||
|
||||
const ditherValue = computed(() => (typeof props.dither === 'boolean' ? (props.dither ? 1 : 0) : props.dither));
|
||||
|
||||
const handleMouseMove = (e: MouseEvent) => {
|
||||
const ctn = containerRef.value;
|
||||
if (!ctn) return;
|
||||
const rect = ctn.getBoundingClientRect();
|
||||
const x = (e.clientX - rect.left) / rect.width;
|
||||
const y = 1 - (e.clientY - rect.top) / rect.height;
|
||||
mouseRef.value = { x, y };
|
||||
};
|
||||
|
||||
let cleanup: (() => void) | null = null;
|
||||
const setup = () => {
|
||||
const ctn = containerRef.value;
|
||||
if (!ctn) return;
|
||||
|
||||
const renderer = new Renderer({ dpr: props.dpr });
|
||||
rendererRef.value = renderer;
|
||||
const gl = renderer.gl;
|
||||
gl.clearColor(0, 0, 0, 1);
|
||||
|
||||
const geometry = new Triangle(gl);
|
||||
|
||||
const program = new Program(gl, {
|
||||
vertex: vertexShader,
|
||||
fragment: fragmentShader,
|
||||
uniforms: {
|
||||
iTime: { value: 0 },
|
||||
iResolution: {
|
||||
value: new Color(gl.canvas.width, gl.canvas.height, gl.canvas.width / gl.canvas.height)
|
||||
},
|
||||
uScale: { value: props.scale },
|
||||
|
||||
uGridMul: { value: new Float32Array(props.gridMul) },
|
||||
uDigitSize: { value: props.digitSize },
|
||||
uScanlineIntensity: { value: props.scanlineIntensity },
|
||||
uGlitchAmount: { value: props.glitchAmount },
|
||||
uFlickerAmount: { value: props.flickerAmount },
|
||||
uNoiseAmp: { value: props.noiseAmp },
|
||||
uChromaticAberration: { value: props.chromaticAberration },
|
||||
uDither: { value: ditherValue },
|
||||
uCurvature: { value: props.curvature },
|
||||
uTint: { value: new Color(tintVec.value[0], tintVec.value[1], tintVec.value[2]) },
|
||||
uMouse: {
|
||||
value: new Float32Array([smoothMouseRef.value.x, smoothMouseRef.value.y])
|
||||
},
|
||||
uMouseStrength: { value: props.mouseStrength },
|
||||
uUseMouse: { value: props.mouseReact ? 1 : 0 },
|
||||
uPageLoadProgress: { value: props.pageLoadAnimation ? 0 : 1 },
|
||||
uUsePageLoadAnimation: { value: props.pageLoadAnimation ? 1 : 0 },
|
||||
uBrightness: { value: props.brightness }
|
||||
}
|
||||
});
|
||||
programRef.value = program;
|
||||
|
||||
const mesh = new Mesh(gl, { geometry, program });
|
||||
|
||||
function resize() {
|
||||
if (!ctn || !renderer) return;
|
||||
renderer.setSize(ctn.offsetWidth, ctn.offsetHeight);
|
||||
program.uniforms.iResolution.value = new Color(
|
||||
gl.canvas.width,
|
||||
gl.canvas.height,
|
||||
gl.canvas.width / gl.canvas.height
|
||||
);
|
||||
}
|
||||
|
||||
const resizeObserver = new ResizeObserver(() => resize());
|
||||
resizeObserver.observe(ctn);
|
||||
resize();
|
||||
|
||||
const update = (t: number) => {
|
||||
rafRef.value = requestAnimationFrame(update);
|
||||
|
||||
if (props.pageLoadAnimation && loadAnimationStartRef.value === 0) {
|
||||
loadAnimationStartRef.value = t;
|
||||
}
|
||||
|
||||
if (!props.pause) {
|
||||
const elapsed = (t * 0.001 + timeOffsetRef.value) * props.timeScale;
|
||||
program.uniforms.iTime.value = elapsed;
|
||||
frozenTimeRef.value = elapsed;
|
||||
} else {
|
||||
program.uniforms.iTime.value = frozenTimeRef.value;
|
||||
}
|
||||
|
||||
if (props.pageLoadAnimation && loadAnimationStartRef.value > 0) {
|
||||
const animationDuration = 2000;
|
||||
const animationElapsed = t - loadAnimationStartRef.value;
|
||||
const progress = Math.min(animationElapsed / animationDuration, 1);
|
||||
program.uniforms.uPageLoadProgress.value = progress;
|
||||
}
|
||||
|
||||
if (props.mouseReact) {
|
||||
const dampingFactor = 0.08;
|
||||
const smoothMouse = smoothMouseRef.value;
|
||||
const mouse = mouseRef.value;
|
||||
smoothMouse.x += (mouse.x - smoothMouse.x) * dampingFactor;
|
||||
smoothMouse.y += (mouse.y - smoothMouse.y) * dampingFactor;
|
||||
|
||||
const mouseUniform = program.uniforms.uMouse.value as Float32Array;
|
||||
mouseUniform[0] = smoothMouse.x;
|
||||
mouseUniform[1] = smoothMouse.y;
|
||||
}
|
||||
|
||||
renderer.render({ scene: mesh });
|
||||
};
|
||||
rafRef.value = requestAnimationFrame(update);
|
||||
ctn.appendChild(gl.canvas);
|
||||
|
||||
if (props.mouseReact) ctn.addEventListener('mousemove', handleMouseMove);
|
||||
|
||||
cleanup = () => {
|
||||
cancelAnimationFrame(rafRef.value);
|
||||
resizeObserver.disconnect();
|
||||
if (props.mouseReact) ctn.removeEventListener('mousemove', handleMouseMove);
|
||||
if (gl.canvas.parentElement === ctn) ctn.removeChild(gl.canvas);
|
||||
gl.getExtension('WEBGL_lose_context')?.loseContext();
|
||||
loadAnimationStartRef.value = 0;
|
||||
timeOffsetRef.value = Math.random() * 100;
|
||||
};
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
const ctn = containerRef.value;
|
||||
if (ctn) {
|
||||
setup();
|
||||
}
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (cleanup) {
|
||||
cleanup();
|
||||
cleanup = null;
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props,
|
||||
() => {
|
||||
if (cleanup) {
|
||||
cleanup();
|
||||
cleanup = null;
|
||||
}
|
||||
setup();
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
ref="containerRef"
|
||||
:class="['w-full h-full relative overflow-hidden', className]"
|
||||
:style="style"
|
||||
v-bind="$attrs"
|
||||
/>
|
||||
</template>
|
||||
202
src/demo/Backgrounds/FaultyTerminalDemo.vue
Normal file
202
src/demo/Backgrounds/FaultyTerminalDemo.vue
Normal file
@@ -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>
|
||||
Reference in New Issue
Block a user