Add prettier config, format codebase

This commit is contained in:
David Haz
2025-07-12 11:59:33 +03:00
parent ac8b2c04d8
commit f4d97ee94e
211 changed files with 10586 additions and 8810 deletions

View File

@@ -1,79 +1,140 @@
<template>
<div class="relative overflow-hidden">
<canvas ref="canvasRef" class="absolute top-0 left-0 w-full h-full" />
<div v-if="outerVignette"
class="absolute top-0 left-0 w-full h-full pointer-events-none bg-[radial-gradient(circle,_rgba(0,0,0,0)_60%,_rgba(0,0,0,1)_100%)]" />
<div v-if="centerVignette"
class="absolute top-0 left-0 w-full h-full pointer-events-none bg-[radial-gradient(circle,_rgba(0,0,0,0.8)_0%,_rgba(0,0,0,0)_60%)]" />
<div
v-if="outerVignette"
class="absolute top-0 left-0 w-full h-full pointer-events-none bg-[radial-gradient(circle,_rgba(0,0,0,0)_60%,_rgba(0,0,0,1)_100%)]"
/>
<div
v-if="centerVignette"
class="absolute top-0 left-0 w-full h-full pointer-events-none bg-[radial-gradient(circle,_rgba(0,0,0,0.8)_0%,_rgba(0,0,0,0)_60%)]"
/>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch } from 'vue'
import { ref, onMounted, onUnmounted, watch } from 'vue';
interface Props {
glitchColors?: string[]
glitchSpeed?: number
centerVignette?: boolean
outerVignette?: boolean
smooth?: boolean
glitchColors?: string[];
glitchSpeed?: number;
centerVignette?: boolean;
outerVignette?: boolean;
smooth?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
glitchColors: () => ["#2b4539", "#61dca3", "#61b3dc"],
glitchColors: () => ['#2b4539', '#61dca3', '#61b3dc'],
glitchSpeed: 50,
centerVignette: false,
outerVignette: false,
smooth: true
})
});
const canvasRef = ref<HTMLCanvasElement | null>(null)
const animationRef = ref<number | null>(null)
const letters = ref<{
char: string
color: string
targetColor: string
colorProgress: number
}[]>([])
const grid = ref({ columns: 0, rows: 0 })
const context = ref<CanvasRenderingContext2D | null>(null)
const lastGlitchTime = ref(Date.now())
const canvasRef = ref<HTMLCanvasElement | null>(null);
const animationRef = ref<number | null>(null);
const letters = ref<
{
char: string;
color: string;
targetColor: string;
colorProgress: number;
}[]
>([]);
const grid = ref({ columns: 0, rows: 0 });
const context = ref<CanvasRenderingContext2D | null>(null);
const lastGlitchTime = ref(Date.now());
const fontSize = 16
const charWidth = 10
const charHeight = 20
const fontSize = 16;
const charWidth = 10;
const charHeight = 20;
const lettersAndSymbols = [
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
"!", "@", "#", "$", "&", "*", "(", ")", "-", "_", "+", "=", "/",
"[", "]", "{", "}", ";", ":", "<", ">", ",", "0", "1", "2", "3",
"4", "5", "6", "7", "8", "9"
]
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
'!',
'@',
'#',
'$',
'&',
'*',
'(',
')',
'-',
'_',
'+',
'=',
'/',
'[',
']',
'{',
'}',
';',
':',
'<',
'>',
',',
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9'
];
const getRandomChar = () => {
return lettersAndSymbols[Math.floor(Math.random() * lettersAndSymbols.length)]
}
return lettersAndSymbols[Math.floor(Math.random() * lettersAndSymbols.length)];
};
const getRandomColor = () => {
return props.glitchColors[Math.floor(Math.random() * props.glitchColors.length)]
}
return props.glitchColors[Math.floor(Math.random() * props.glitchColors.length)];
};
const hexToRgb = (hex: string) => {
const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i
const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
hex = hex.replace(shorthandRegex, (m, r, g, b) => {
return r + r + g + g + b + b
})
return r + r + g + g + b + b;
});
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result
? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16),
}
: null
}
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
}
: null;
};
const interpolateColor = (
start: { r: number; g: number; b: number },
@@ -83,171 +144,167 @@ const interpolateColor = (
const result = {
r: Math.round(start.r + (end.r - start.r) * factor),
g: Math.round(start.g + (end.g - start.g) * factor),
b: Math.round(start.b + (end.b - start.b) * factor),
}
return `rgb(${result.r}, ${result.g}, ${result.b})`
}
b: Math.round(start.b + (end.b - start.b) * factor)
};
return `rgb(${result.r}, ${result.g}, ${result.b})`;
};
const calculateGrid = (width: number, height: number) => {
const columns = Math.ceil(width / charWidth)
const rows = Math.ceil(height / charHeight)
return { columns, rows }
}
const columns = Math.ceil(width / charWidth);
const rows = Math.ceil(height / charHeight);
return { columns, rows };
};
const initializeLetters = (columns: number, rows: number) => {
grid.value = { columns, rows }
const totalLetters = columns * rows
grid.value = { columns, rows };
const totalLetters = columns * rows;
letters.value = Array.from({ length: totalLetters }, () => ({
char: getRandomChar(),
color: getRandomColor(),
targetColor: getRandomColor(),
colorProgress: 1,
}))
}
colorProgress: 1
}));
};
const resizeCanvas = () => {
const canvas = canvasRef.value
if (!canvas) return
const parent = canvas.parentElement
if (!parent) return
const canvas = canvasRef.value;
if (!canvas) return;
const parent = canvas.parentElement;
if (!parent) return;
const dpr = window.devicePixelRatio || 1
const parentWidth = parent.parentElement?.offsetWidth || parent.offsetWidth || window.innerWidth
const parentHeight = parent.parentElement?.offsetHeight || parent.offsetHeight || window.innerHeight
const width = Math.max(parentWidth, 300)
const height = Math.max(parentHeight, 300)
const dpr = window.devicePixelRatio || 1;
canvas.width = width * dpr
canvas.height = height * dpr
const parentWidth = parent.parentElement?.offsetWidth || parent.offsetWidth || window.innerWidth;
const parentHeight = parent.parentElement?.offsetHeight || parent.offsetHeight || window.innerHeight;
canvas.style.width = `${width}px`
canvas.style.height = `${height}px`
const width = Math.max(parentWidth, 300);
const height = Math.max(parentHeight, 300);
canvas.width = width * dpr;
canvas.height = height * dpr;
canvas.style.width = `${width}px`;
canvas.style.height = `${height}px`;
if (context.value) {
context.value.setTransform(dpr, 0, 0, dpr, 0, 0)
context.value.setTransform(dpr, 0, 0, dpr, 0, 0);
}
const { columns, rows } = calculateGrid(width, height)
initializeLetters(columns, rows)
drawLetters()
}
const { columns, rows } = calculateGrid(width, height);
initializeLetters(columns, rows);
drawLetters();
};
const drawLetters = () => {
if (!context.value || letters.value.length === 0) return
const ctx = context.value
const { width, height } = canvasRef.value!.getBoundingClientRect()
ctx.clearRect(0, 0, width, height)
ctx.font = `${fontSize}px monospace`
ctx.textBaseline = "top"
if (!context.value || letters.value.length === 0) return;
const ctx = context.value;
const { width, height } = canvasRef.value!.getBoundingClientRect();
ctx.clearRect(0, 0, width, height);
ctx.font = `${fontSize}px monospace`;
ctx.textBaseline = 'top';
letters.value.forEach((letter, index) => {
const x = (index % grid.value.columns) * charWidth
const y = Math.floor(index / grid.value.columns) * charHeight
ctx.fillStyle = letter.color
ctx.fillText(letter.char, x, y)
})
}
const x = (index % grid.value.columns) * charWidth;
const y = Math.floor(index / grid.value.columns) * charHeight;
ctx.fillStyle = letter.color;
ctx.fillText(letter.char, x, y);
});
};
const updateLetters = () => {
if (!letters.value || letters.value.length === 0) return
if (!letters.value || letters.value.length === 0) return;
const updateCount = Math.max(1, Math.floor(letters.value.length * 0.05))
const updateCount = Math.max(1, Math.floor(letters.value.length * 0.05));
for (let i = 0; i < updateCount; i++) {
const index = Math.floor(Math.random() * letters.value.length)
if (!letters.value[index]) continue
const index = Math.floor(Math.random() * letters.value.length);
if (!letters.value[index]) continue;
letters.value[index].char = getRandomChar()
letters.value[index].targetColor = getRandomColor()
letters.value[index].char = getRandomChar();
letters.value[index].targetColor = getRandomColor();
if (!props.smooth) {
letters.value[index].color = letters.value[index].targetColor
letters.value[index].colorProgress = 1
letters.value[index].color = letters.value[index].targetColor;
letters.value[index].colorProgress = 1;
} else {
letters.value[index].colorProgress = 0
letters.value[index].colorProgress = 0;
}
}
}
};
const handleSmoothTransitions = () => {
let needsRedraw = false
letters.value.forEach((letter) => {
let needsRedraw = false;
letters.value.forEach(letter => {
if (letter.colorProgress < 1) {
letter.colorProgress += 0.05
if (letter.colorProgress > 1) letter.colorProgress = 1
letter.colorProgress += 0.05;
if (letter.colorProgress > 1) letter.colorProgress = 1;
const startRgb = hexToRgb(letter.color)
const endRgb = hexToRgb(letter.targetColor)
const startRgb = hexToRgb(letter.color);
const endRgb = hexToRgb(letter.targetColor);
if (startRgb && endRgb) {
letter.color = interpolateColor(
startRgb,
endRgb,
letter.colorProgress
)
needsRedraw = true
letter.color = interpolateColor(startRgb, endRgb, letter.colorProgress);
needsRedraw = true;
}
}
})
});
if (needsRedraw) {
drawLetters()
drawLetters();
}
}
};
const animate = () => {
const now = Date.now()
const now = Date.now();
if (now - lastGlitchTime.value >= props.glitchSpeed) {
updateLetters()
drawLetters()
lastGlitchTime.value = now
updateLetters();
drawLetters();
lastGlitchTime.value = now;
}
if (props.smooth) {
handleSmoothTransitions()
handleSmoothTransitions();
}
animationRef.value = requestAnimationFrame(animate)
}
animationRef.value = requestAnimationFrame(animate);
};
let resizeTimeout: number
let resizeTimeout: number;
const handleResize = () => {
clearTimeout(resizeTimeout)
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(() => {
if (animationRef.value) {
cancelAnimationFrame(animationRef.value)
cancelAnimationFrame(animationRef.value);
}
resizeCanvas()
animate()
}, 100)
}
resizeCanvas();
animate();
}, 100);
};
onMounted(() => {
const canvas = canvasRef.value
if (!canvas) return
const canvas = canvasRef.value;
if (!canvas) return;
context.value = canvas.getContext("2d")
resizeCanvas()
animate()
context.value = canvas.getContext('2d');
resizeCanvas();
animate();
window.addEventListener("resize", handleResize)
})
window.addEventListener('resize', handleResize);
});
onUnmounted(() => {
if (animationRef.value) {
cancelAnimationFrame(animationRef.value)
cancelAnimationFrame(animationRef.value);
}
window.removeEventListener("resize", handleResize)
})
window.removeEventListener('resize', handleResize);
});
watch([() => props.glitchSpeed, () => props.smooth], () => {
if (animationRef.value) {
cancelAnimationFrame(animationRef.value)
cancelAnimationFrame(animationRef.value);
}
animate()
})
animate();
});
</script>
<style scoped>
@@ -266,4 +323,4 @@ div {
width: 100% !important;
height: 100% !important;
}
</style>
</style>