mirror of
https://github.com/DavidHDev/vue-bits.git
synced 2026-04-22 09:54:39 -06:00
Add prettier config, format codebase
This commit is contained in:
@@ -3,22 +3,22 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted, watch } from 'vue'
|
||||
import { Renderer, Camera, Geometry, Program, Mesh } from 'ogl'
|
||||
import { ref, onMounted, onUnmounted, watch } from 'vue';
|
||||
import { Renderer, Camera, Geometry, Program, Mesh } from 'ogl';
|
||||
|
||||
interface ParticlesProps {
|
||||
particleCount?: number
|
||||
particleSpread?: number
|
||||
speed?: number
|
||||
particleColors?: string[]
|
||||
moveParticlesOnHover?: boolean
|
||||
particleHoverFactor?: number
|
||||
alphaParticles?: boolean
|
||||
particleBaseSize?: number
|
||||
sizeRandomness?: number
|
||||
cameraDistance?: number
|
||||
disableRotation?: boolean
|
||||
className?: string
|
||||
particleCount?: number;
|
||||
particleSpread?: number;
|
||||
speed?: number;
|
||||
particleColors?: string[];
|
||||
moveParticlesOnHover?: boolean;
|
||||
particleHoverFactor?: number;
|
||||
alphaParticles?: boolean;
|
||||
particleBaseSize?: number;
|
||||
sizeRandomness?: number;
|
||||
cameraDistance?: number;
|
||||
disableRotation?: boolean;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<ParticlesProps>(), {
|
||||
@@ -34,32 +34,35 @@ const props = withDefaults(defineProps<ParticlesProps>(), {
|
||||
cameraDistance: 20,
|
||||
disableRotation: false,
|
||||
className: ''
|
||||
})
|
||||
});
|
||||
|
||||
const containerRef = ref<HTMLDivElement>()
|
||||
const mouseRef = ref({ x: 0, y: 0 })
|
||||
const containerRef = ref<HTMLDivElement>();
|
||||
const mouseRef = ref({ x: 0, y: 0 });
|
||||
|
||||
let renderer: Renderer | null = null
|
||||
let camera: Camera | null = null
|
||||
let particles: Mesh | null = null
|
||||
let program: Program | null = null
|
||||
let animationFrameId: number | null = null
|
||||
let lastTime = 0
|
||||
let elapsed = 0
|
||||
let renderer: Renderer | null = null;
|
||||
let camera: Camera | null = null;
|
||||
let particles: Mesh | null = null;
|
||||
let program: Program | null = null;
|
||||
let animationFrameId: number | null = null;
|
||||
let lastTime = 0;
|
||||
let elapsed = 0;
|
||||
|
||||
const defaultColors = ['#ffffff', '#ffffff', '#ffffff']
|
||||
const defaultColors = ['#ffffff', '#ffffff', '#ffffff'];
|
||||
|
||||
const hexToRgb = (hex: string): [number, number, number] => {
|
||||
hex = hex.replace(/^#/, '')
|
||||
hex = hex.replace(/^#/, '');
|
||||
if (hex.length === 3) {
|
||||
hex = hex.split('').map((c) => c + c).join('')
|
||||
hex = hex
|
||||
.split('')
|
||||
.map(c => c + c)
|
||||
.join('');
|
||||
}
|
||||
const int = parseInt(hex, 16)
|
||||
const r = ((int >> 16) & 255) / 255
|
||||
const g = ((int >> 8) & 255) / 255
|
||||
const b = (int & 255) / 255
|
||||
return [r, g, b]
|
||||
}
|
||||
const int = parseInt(hex, 16);
|
||||
const r = ((int >> 16) & 255) / 255;
|
||||
const g = ((int >> 8) & 255) / 255;
|
||||
const b = (int & 255) / 255;
|
||||
return [r, g, b];
|
||||
};
|
||||
|
||||
const vertex = /* glsl */ `
|
||||
attribute vec3 position;
|
||||
@@ -94,7 +97,7 @@ const vertex = /* glsl */ `
|
||||
gl_PointSize = (uBaseSize * (1.0 + uSizeRandomness * (random.x - 0.5))) / length(mvPos.xyz);
|
||||
gl_Position = projectionMatrix * mvPos;
|
||||
}
|
||||
`
|
||||
`;
|
||||
|
||||
const fragment = /* glsl */ `
|
||||
precision highp float;
|
||||
@@ -118,89 +121,89 @@ const fragment = /* glsl */ `
|
||||
gl_FragColor = vec4(vColor + 0.2 * sin(uv.yxx + uTime + vRandom.y * 6.28), circle);
|
||||
}
|
||||
}
|
||||
`
|
||||
`;
|
||||
|
||||
const handleMouseMove = (e: MouseEvent) => {
|
||||
const container = containerRef.value
|
||||
if (!container) return
|
||||
const container = containerRef.value;
|
||||
if (!container) return;
|
||||
|
||||
const rect = container.getBoundingClientRect()
|
||||
const x = ((e.clientX - rect.left) / rect.width) * 2 - 1
|
||||
const y = -(((e.clientY - rect.top) / rect.height) * 2 - 1)
|
||||
mouseRef.value = { x, y }
|
||||
}
|
||||
const rect = container.getBoundingClientRect();
|
||||
const x = ((e.clientX - rect.left) / rect.width) * 2 - 1;
|
||||
const y = -(((e.clientY - rect.top) / rect.height) * 2 - 1);
|
||||
mouseRef.value = { x, y };
|
||||
};
|
||||
|
||||
const initParticles = () => {
|
||||
const container = containerRef.value
|
||||
if (!container) return
|
||||
const container = containerRef.value;
|
||||
if (!container) return;
|
||||
|
||||
renderer = new Renderer({ depth: false, alpha: true })
|
||||
const gl = renderer.gl
|
||||
container.appendChild(gl.canvas)
|
||||
gl.clearColor(0, 0, 0, 0)
|
||||
renderer = new Renderer({ depth: false, alpha: true });
|
||||
const gl = renderer.gl;
|
||||
container.appendChild(gl.canvas);
|
||||
gl.clearColor(0, 0, 0, 0);
|
||||
|
||||
gl.canvas.style.width = '100%'
|
||||
gl.canvas.style.height = '100%'
|
||||
gl.canvas.style.display = 'block'
|
||||
gl.canvas.style.position = 'absolute'
|
||||
gl.canvas.style.top = '0'
|
||||
gl.canvas.style.left = '0'
|
||||
gl.canvas.style.width = '100%';
|
||||
gl.canvas.style.height = '100%';
|
||||
gl.canvas.style.display = 'block';
|
||||
gl.canvas.style.position = 'absolute';
|
||||
gl.canvas.style.top = '0';
|
||||
gl.canvas.style.left = '0';
|
||||
|
||||
camera = new Camera(gl, { fov: 15 })
|
||||
camera.position.set(0, 0, props.cameraDistance)
|
||||
camera = new Camera(gl, { fov: 15 });
|
||||
camera.position.set(0, 0, props.cameraDistance);
|
||||
|
||||
const resize = () => {
|
||||
if (!container) return
|
||||
|
||||
const parentWidth = container.parentElement?.offsetWidth || container.offsetWidth || window.innerWidth
|
||||
const parentHeight = container.parentElement?.offsetHeight || container.offsetHeight || window.innerHeight
|
||||
|
||||
const width = Math.max(parentWidth, 300)
|
||||
const height = Math.max(parentHeight, 300)
|
||||
|
||||
renderer!.setSize(width, height)
|
||||
camera!.perspective({ aspect: width / height })
|
||||
if (!container) return;
|
||||
|
||||
gl.canvas.style.width = '100%'
|
||||
gl.canvas.style.height = '100%'
|
||||
gl.canvas.style.display = 'block'
|
||||
gl.canvas.style.position = 'absolute'
|
||||
gl.canvas.style.top = '0'
|
||||
gl.canvas.style.left = '0'
|
||||
}
|
||||
window.addEventListener('resize', resize, false)
|
||||
resize()
|
||||
const parentWidth = container.parentElement?.offsetWidth || container.offsetWidth || window.innerWidth;
|
||||
const parentHeight = container.parentElement?.offsetHeight || container.offsetHeight || window.innerHeight;
|
||||
|
||||
const width = Math.max(parentWidth, 300);
|
||||
const height = Math.max(parentHeight, 300);
|
||||
|
||||
renderer!.setSize(width, height);
|
||||
camera!.perspective({ aspect: width / height });
|
||||
|
||||
gl.canvas.style.width = '100%';
|
||||
gl.canvas.style.height = '100%';
|
||||
gl.canvas.style.display = 'block';
|
||||
gl.canvas.style.position = 'absolute';
|
||||
gl.canvas.style.top = '0';
|
||||
gl.canvas.style.left = '0';
|
||||
};
|
||||
window.addEventListener('resize', resize, false);
|
||||
resize();
|
||||
|
||||
if (props.moveParticlesOnHover) {
|
||||
container.addEventListener('mousemove', handleMouseMove)
|
||||
container.addEventListener('mousemove', handleMouseMove);
|
||||
}
|
||||
|
||||
const count = props.particleCount
|
||||
const positions = new Float32Array(count * 3)
|
||||
const randoms = new Float32Array(count * 4)
|
||||
const colors = new Float32Array(count * 3)
|
||||
const palette = props.particleColors && props.particleColors.length > 0 ? props.particleColors : defaultColors
|
||||
const count = props.particleCount;
|
||||
const positions = new Float32Array(count * 3);
|
||||
const randoms = new Float32Array(count * 4);
|
||||
const colors = new Float32Array(count * 3);
|
||||
const palette = props.particleColors && props.particleColors.length > 0 ? props.particleColors : defaultColors;
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
let x: number, y: number, z: number, len: number
|
||||
let x: number, y: number, z: number, len: number;
|
||||
do {
|
||||
x = Math.random() * 2 - 1
|
||||
y = Math.random() * 2 - 1
|
||||
z = Math.random() * 2 - 1
|
||||
len = x * x + y * y + z * z
|
||||
} while (len > 1 || len === 0)
|
||||
const r = Math.cbrt(Math.random())
|
||||
positions.set([x * r, y * r, z * r], i * 3)
|
||||
randoms.set([Math.random(), Math.random(), Math.random(), Math.random()], i * 4)
|
||||
const col = hexToRgb(palette[Math.floor(Math.random() * palette.length)])
|
||||
colors.set(col, i * 3)
|
||||
x = Math.random() * 2 - 1;
|
||||
y = Math.random() * 2 - 1;
|
||||
z = Math.random() * 2 - 1;
|
||||
len = x * x + y * y + z * z;
|
||||
} while (len > 1 || len === 0);
|
||||
const r = Math.cbrt(Math.random());
|
||||
positions.set([x * r, y * r, z * r], i * 3);
|
||||
randoms.set([Math.random(), Math.random(), Math.random(), Math.random()], i * 4);
|
||||
const col = hexToRgb(palette[Math.floor(Math.random() * palette.length)]);
|
||||
colors.set(col, i * 3);
|
||||
}
|
||||
|
||||
const geometry = new Geometry(gl, {
|
||||
position: { size: 3, data: positions },
|
||||
random: { size: 4, data: randoms },
|
||||
color: { size: 3, data: colors },
|
||||
})
|
||||
color: { size: 3, data: colors }
|
||||
});
|
||||
|
||||
program = new Program(gl, {
|
||||
vertex,
|
||||
@@ -210,105 +213,105 @@ const initParticles = () => {
|
||||
uSpread: { value: props.particleSpread },
|
||||
uBaseSize: { value: props.particleBaseSize },
|
||||
uSizeRandomness: { value: props.sizeRandomness },
|
||||
uAlphaParticles: { value: props.alphaParticles ? 1 : 0 },
|
||||
uAlphaParticles: { value: props.alphaParticles ? 1 : 0 }
|
||||
},
|
||||
transparent: true,
|
||||
depthTest: false,
|
||||
})
|
||||
depthTest: false
|
||||
});
|
||||
|
||||
particles = new Mesh(gl, { mode: gl.POINTS, geometry, program })
|
||||
particles = new Mesh(gl, { mode: gl.POINTS, geometry, program });
|
||||
|
||||
lastTime = performance.now()
|
||||
elapsed = 0
|
||||
lastTime = performance.now();
|
||||
elapsed = 0;
|
||||
|
||||
const update = (t: number) => {
|
||||
if (!animationFrameId) return
|
||||
animationFrameId = requestAnimationFrame(update)
|
||||
const delta = t - lastTime
|
||||
lastTime = t
|
||||
elapsed += delta * props.speed
|
||||
if (!animationFrameId) return;
|
||||
animationFrameId = requestAnimationFrame(update);
|
||||
const delta = t - lastTime;
|
||||
lastTime = t;
|
||||
elapsed += delta * props.speed;
|
||||
|
||||
if (program) {
|
||||
program.uniforms.uTime.value = elapsed * 0.001
|
||||
program.uniforms.uSpread.value = props.particleSpread
|
||||
program.uniforms.uBaseSize.value = props.particleBaseSize
|
||||
program.uniforms.uSizeRandomness.value = props.sizeRandomness
|
||||
program.uniforms.uAlphaParticles.value = props.alphaParticles ? 1 : 0
|
||||
program.uniforms.uTime.value = elapsed * 0.001;
|
||||
program.uniforms.uSpread.value = props.particleSpread;
|
||||
program.uniforms.uBaseSize.value = props.particleBaseSize;
|
||||
program.uniforms.uSizeRandomness.value = props.sizeRandomness;
|
||||
program.uniforms.uAlphaParticles.value = props.alphaParticles ? 1 : 0;
|
||||
}
|
||||
|
||||
if (particles) {
|
||||
if (props.moveParticlesOnHover) {
|
||||
particles.position.x = -mouseRef.value.x * props.particleHoverFactor
|
||||
particles.position.y = -mouseRef.value.y * props.particleHoverFactor
|
||||
particles.position.x = -mouseRef.value.x * props.particleHoverFactor;
|
||||
particles.position.y = -mouseRef.value.y * props.particleHoverFactor;
|
||||
} else {
|
||||
particles.position.x = 0
|
||||
particles.position.y = 0
|
||||
particles.position.x = 0;
|
||||
particles.position.y = 0;
|
||||
}
|
||||
|
||||
if (!props.disableRotation) {
|
||||
particles.rotation.x = Math.sin(elapsed * 0.0002) * 0.1
|
||||
particles.rotation.y = Math.cos(elapsed * 0.0005) * 0.15
|
||||
particles.rotation.z += 0.01 * props.speed
|
||||
particles.rotation.x = Math.sin(elapsed * 0.0002) * 0.1;
|
||||
particles.rotation.y = Math.cos(elapsed * 0.0005) * 0.15;
|
||||
particles.rotation.z += 0.01 * props.speed;
|
||||
}
|
||||
}
|
||||
|
||||
if (renderer && camera && particles) {
|
||||
renderer.render({ scene: particles, camera })
|
||||
renderer.render({ scene: particles, camera });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
animationFrameId = requestAnimationFrame(update)
|
||||
animationFrameId = requestAnimationFrame(update);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('resize', resize)
|
||||
window.removeEventListener('resize', resize);
|
||||
if (props.moveParticlesOnHover) {
|
||||
container.removeEventListener('mousemove', handleMouseMove)
|
||||
container.removeEventListener('mousemove', handleMouseMove);
|
||||
}
|
||||
if (animationFrameId) {
|
||||
cancelAnimationFrame(animationFrameId)
|
||||
animationFrameId = null
|
||||
cancelAnimationFrame(animationFrameId);
|
||||
animationFrameId = null;
|
||||
}
|
||||
if (container.contains(gl.canvas)) {
|
||||
container.removeChild(gl.canvas)
|
||||
container.removeChild(gl.canvas);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const cleanup = () => {
|
||||
if (animationFrameId) {
|
||||
cancelAnimationFrame(animationFrameId)
|
||||
animationFrameId = null
|
||||
cancelAnimationFrame(animationFrameId);
|
||||
animationFrameId = null;
|
||||
}
|
||||
if (renderer) {
|
||||
const container = containerRef.value
|
||||
const gl = renderer.gl
|
||||
const container = containerRef.value;
|
||||
const gl = renderer.gl;
|
||||
if (container && gl.canvas.parentNode === container) {
|
||||
container.removeChild(gl.canvas)
|
||||
container.removeChild(gl.canvas);
|
||||
}
|
||||
gl.getExtension('WEBGL_lose_context')?.loseContext()
|
||||
gl.getExtension('WEBGL_lose_context')?.loseContext();
|
||||
}
|
||||
renderer = null
|
||||
camera = null
|
||||
particles = null
|
||||
program = null
|
||||
}
|
||||
renderer = null;
|
||||
camera = null;
|
||||
particles = null;
|
||||
program = null;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
initParticles()
|
||||
})
|
||||
initParticles();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
cleanup()
|
||||
})
|
||||
cleanup();
|
||||
});
|
||||
|
||||
watch(
|
||||
() => [props.particleCount, props.particleColors],
|
||||
() => {
|
||||
cleanup()
|
||||
initParticles()
|
||||
cleanup();
|
||||
initParticles();
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
);
|
||||
|
||||
watch(
|
||||
() => [
|
||||
@@ -322,7 +325,7 @@ watch(
|
||||
props.disableRotation
|
||||
],
|
||||
() => {}
|
||||
)
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
Reference in New Issue
Block a user