egirlskey/packages/frontend/src/components/MkTagCloud.vue

92 lines
2.3 KiB
Vue
Raw Normal View History

<!--
SPDX-FileCopyrightText: syuilo and other misskey contributors
SPDX-License-Identifier: AGPL-3.0-only
-->
2022-06-29 12:22:15 +00:00
<template>
2023-05-24 08:50:15 +00:00
<div ref="rootEl" :class="$style.root">
<canvas :id="idForCanvas" ref="canvasEl" style="display: block;" :width="width" height="300" @contextmenu.prevent="() => {}"></canvas>
<div :id="idForTags" ref="tagsEl" :class="$style.tags">
2022-06-29 12:22:15 +00:00
<ul>
<slot></slot>
</ul>
</div>
</div>
</template>
<script lang="ts" setup>
import { onMounted, watch, onBeforeUnmount, ref, shallowRef } from 'vue';
2022-06-29 12:22:15 +00:00
import tinycolor from 'tinycolor2';
const loaded = !!window.TagCanvas;
const SAFE_FOR_HTML_ID = 'abcdefghijklmnopqrstuvwxyz';
const computedStyle = getComputedStyle(document.documentElement);
const idForCanvas = Array.from({ length: 16 }, () => SAFE_FOR_HTML_ID[Math.floor(Math.random() * SAFE_FOR_HTML_ID.length)]).join('');
const idForTags = Array.from({ length: 16 }, () => SAFE_FOR_HTML_ID[Math.floor(Math.random() * SAFE_FOR_HTML_ID.length)]).join('');
const available = ref(false);
const rootEl = shallowRef<HTMLElement | null>(null);
const canvasEl = shallowRef<HTMLCanvasElement | null>(null);
const tagsEl = shallowRef<HTMLElement | null>(null);
const width = ref(300);
2022-06-29 12:22:15 +00:00
watch(available, () => {
try {
window.TagCanvas.Start(idForCanvas, idForTags, {
textColour: '#ffffff',
outlineColour: tinycolor(computedStyle.getPropertyValue('--accent')).toHexString(),
outlineRadius: 10,
initial: [-0.030, -0.010],
frontSelect: true,
imageRadius: 8,
//dragControl: true,
dragThreshold: 3,
wheelZoom: false,
reverse: true,
depth: 0.5,
maxSpeed: 0.2,
minSpeed: 0.003,
stretchX: 0.8,
stretchY: 0.8,
});
2022-07-23 05:31:54 +00:00
} catch (err) {}
2022-06-29 12:22:15 +00:00
});
onMounted(() => {
width.value = rootEl.value.offsetWidth;
2022-06-30 01:13:27 +00:00
2022-06-29 12:22:15 +00:00
if (loaded) {
available.value = true;
2022-06-29 12:22:15 +00:00
} else {
document.head.appendChild(Object.assign(document.createElement('script'), {
async: true,
src: '/client-assets/tagcanvas.min.js',
})).addEventListener('load', () => available.value = true);
2022-06-29 12:22:15 +00:00
}
});
onBeforeUnmount(() => {
if (window.TagCanvas) window.TagCanvas.Delete(idForCanvas);
2022-06-29 12:22:15 +00:00
});
2022-06-30 01:13:27 +00:00
defineExpose({
update: () => {
window.TagCanvas.Update(idForCanvas);
},
});
2022-06-29 12:22:15 +00:00
</script>
2023-05-24 08:50:15 +00:00
<style lang="scss" module>
.root {
2022-06-29 12:22:15 +00:00
position: relative;
2022-07-13 12:41:06 +00:00
overflow: clip;
2022-06-29 12:22:15 +00:00
display: grid;
place-items: center;
2023-05-24 08:50:15 +00:00
}
2022-06-29 12:22:15 +00:00
2023-05-24 08:50:15 +00:00
.tags {
position: absolute;
top: 999px;
left: 999px;
2022-06-29 12:22:15 +00:00
}
</style>