New useContent composable to store global navigation state. Fixes for Markdown and Canvas

This commit is contained in:
2024-12-30 20:46:24 +01:00
parent 031a51c2fe
commit 9515132659
31 changed files with 320 additions and 220 deletions

View File

@@ -4,7 +4,6 @@ import type { CanvasNode } from '~/types/canvas';
interface Props {
node: CanvasNode;
zoom: number;
}
const props = defineProps<Props>();
@@ -35,16 +34,9 @@ const colors = computed(() => {
<div class="absolute" :style="{transform: `translate(${node.x}px, ${node.y}px)`, width: `${node.width}px`, height: `${node.height}px`, '--canvas-color': node.color?.hex}" :class="{'-z-10': node.type === 'group', 'z-10': node.type !== 'group'}">
<div :class="[colors.border]" class="border-2 bg-light-20 dark:bg-dark-20 overflow-hidden contain-strict w-full h-full flex">
<div class="w-full h-full py-2 px-4 flex !bg-opacity-[0.07]" :class="colors.bg">
<template v-if="node.type === 'group' || zoom > Math.min(0.4, 1000 / size)">
<div v-if="node.text?.length > 0" class="flex items-center">
<MarkdownRenderer :content="node.text" />
</div>
</template>
<template v-else>
<div class="flex flex-1 justify-center items-center bg-light-30 dark:bg-dark-30">
<Icon icon="radix-icons:text-align-left" class="w-8 h-8"/>
</div>
</template>
<div v-if="node.text?.length > 0" class="flex items-center">
<MarkdownRenderer :content="node.text" />
</div>
</div>
</div>
<div v-if="node.type === 'group' && node.label !== undefined" :class="[colors.border]" style="max-width: 100%; font-size: calc(18px * var(--zoom-multiplier))" class="origin-bottom-left tracking-wider border-4 truncate inline-block text-light-100 dark:text-dark-100 absolute bottom-[100%] mb-2 px-2 py-1 font-thin">{{ node.label }}</div>

View File

@@ -1,7 +1,7 @@
<template>
<div class="absolute top-0 left-0 w-full h-full origin-center pointer-events-none *:pointer-events-auto *:select-none">
<div class="absolute top-0 left-0 w-full h-full origin-center pointer-events-none *:pointer-events-auto *:select-none" v-if="canvas">
<div>
<CanvasNode v-for="node of canvas.nodes" :key="node.id" :node="node" :zoom="zoom" />
<CanvasNode v-for="node of canvas.nodes" :key="node.id" :node="node" />
</div>
<template v-for="edge of canvas.edges">
<div :key="edge.id" v-if="edge.label" class="absolute z-10"
@@ -11,17 +11,29 @@
</template>
<svg class="absolute top-0 left-0 overflow-visible w-full h-full origin-top pointer-events-none">
<CanvasEdge v-for="edge of canvas.edges" :key="edge.id"
:path="path(getNode(canvas.nodes, edge.fromNode)!, edge.fromSide, getNode(canvas.nodes, edge.toNode)!, edge.toSide)"
:path="getPath(getNode(canvas.nodes, edge.fromNode)!, edge.fromSide, getNode(canvas.nodes, edge.toNode)!, edge.toSide)"
:color="edge.color" :label="edge.label" />
</svg>
</div>
</template>
<script setup lang="ts">
const { canvas, zoom } = defineProps<{
canvas: CanvasContent
zoom: number
const { path } = defineProps<{
path: string
}>();
const { content, get } = useContent();
const overview = computed(() => content.value.find(e => e.path === path));
const loading = ref(false);
if(overview.value && !overview.value.content)
{
loading.value = true;
await get(path);
loading.value = false;
}
const canvas = computed(() => overview.value && overview.value.content ? JSON.parse(overview.value.content) as CanvasContent : undefined);
</script>
<script lang="ts">
@@ -71,7 +83,7 @@ function posFromDir(e: { minX: number, minY: number, maxX: number, maxY: number
function getBbox(node: CanvasNode): { minX: number, minY: number, maxX: number, maxY: number } {
return { minX: node.x, minY: node.y, maxX: node.x + node.width, maxY: node.y + node.height };
}
function path(from: CanvasNode, fromSide: 'bottom' | 'top' | 'left' | 'right', to: CanvasNode, toSide: 'bottom' | 'top' | 'left' | 'right'): any {
function getPath(from: CanvasNode, fromSide: 'bottom' | 'top' | 'left' | 'right', to: CanvasNode, toSide: 'bottom' | 'top' | 'left' | 'right'): any {
if(from === undefined || to === undefined)
{
return {