Files
nuxt-portfolio/app/components/GraphView.vue
2025-12-02 12:18:41 +01:00

121 lines
3.7 KiB
Vue

<script setup lang="ts">
const nodes = [
{
name: "Hi, I'm Alex",
img: "/face.jpg",
textTop: true,
moveFactor: 6,
initialWidth: 'w-50',
initialHeight: 'h-50',
scaleFactor: 2,
hOffset: 'left-1/3',
vOffset: 'top-1/3',
topTextOffset: '-top-50',
},
{
name: "DevOps engineer",
color: "bg-blue-100",
hOffset: 'left-30',
vOffset: 'top-30',
initialWidth: 'w-2',
initialHeight: 'h-2',
scaleFactor: 10,
bottomTextOffset: '-bottom-10'
},
{
name: "Game developer",
color: "bg-blue-200",
hOffset: 'right-30',
vOffset: 'top-30',
},
{
name: "Fullstack developer",
color: "bg-blue-300",
hOffset: 'left-30',
vOffset: 'bottom-30',
textTop: true
},
{
name: "Tools programmer",
color: "bg-blue-400",
hOffset: 'right-30',
vOffset: 'bottom-30',
textTop: true
},
]
const divsLocations = ref(nodes.map(() => {
return {x: 0, y: 0}
}))
const linesLocations = ref(new Array<{x1: number, y1: number, x2: number, y2: number}>())
for (let i = 0; i < divsLocations.value.length - 1; i++) {
const startLocation = divsLocations.value[i]!
const endLocation = divsLocations.value[i+1]!
linesLocations.value.push({x1: startLocation.x, y1: startLocation.y, x2: endLocation.x, y2: endLocation.y})
}
linesLocations.value.push({x1: 0, y1: 0, x2: 0, y2: 0})
const nodeMoved = (nodeIndex: number, x: number, y: number) => {
divsLocations.value[nodeIndex] = {x: x, y: y}
}
useRafFn(() => {
for (let i = 0; i < divsLocations.value.length - 1; i++) {
const startLocation = divsLocations.value[i]!
const endLocation = divsLocations.value[i+1]!
linesLocations.value[i] = {x1: startLocation.x, y1: startLocation.y, x2: endLocation.x, y2: endLocation.y}
}
linesLocations.value[linesLocations.value.length - 1] = {
x1: divsLocations.value[divsLocations.value.length - 1]!.x,
y1: divsLocations.value[divsLocations.value.length - 1]!.y,
x2: divsLocations.value[0]!.x,
y2: divsLocations.value[0]!.y
}
})
</script>
<template>
<div class="hero bg-base-200 min-h-screen">
<div class="overflow-hidden">
<ul v-for="(line, index) in linesLocations" :key="index">
<li>
<svg height="100%" width="100%" class="absolute top-0 left-0">
<line
:x1="line.x1"
:y1="line.y1"
:x2="line.x2"
:y2="line.y2" stroke="white"/>
</svg>
</li>
</ul>
<ul v-for="(node, index) in nodes" :key="index">
<li>
<GraphNode
:name="node.name"
:img="node.img"
:color="node.color"
:class="`${node.hOffset ? node.hOffset : ''} ${node.vOffset ? node.vOffset : ''}`"
:text-top="node.textTop"
:move-factor="node.moveFactor"
:scale-factor="node.scaleFactor"
:initial-width="node.initialWidth"
:initial-height="node.initialHeight"
:top-text-offset="node.topTextOffset"
:bottom-text-offset="node.bottomTextOffset"
@position-changed="(x, y) => { nodeMoved(index, x, y) }"/>
</li>
</ul>
</div>
</div>
</template>
<style>
* {
overflow: hidden;
}
</style>