konva-demo/src/views/select/text-resizing/index.vue

86 lines
1.9 KiB
Vue

<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import Konva from 'konva/lib';
import { useWindowSize } from '@vueuse/core';
import { Stage } from 'konva/lib/Stage';
const { width, height } = useWindowSize();
const MIN_WIDTH = 100;
const stage = ref<Stage>();
const SCALE_BY = 1.1;
const zoomed = () => {
stage.value?.on('wheel', ev => {
if (!stage.value) return;
const scaleX = stage.value?.scaleX();
const scaleY = stage.value?.scaleY();
const pointerPosition = stage.value?.getPointerPosition();
const mousePointTo = {
x: (pointerPosition!.x - stage.value?.x()) / scaleX,
y: (pointerPosition!.y - stage.value?.y()) / scaleY,
};
const direction = ev.evt.deltaY > 0 ? -1 : 1;
const x = direction > 0 ? scaleX * SCALE_BY : scaleX / SCALE_BY;
const y = direction > 0 ? scaleY * SCALE_BY : scaleY / SCALE_BY;
stage.value?.scale({ x, y });
const position = {
x: pointerPosition!.x - mousePointTo.x * x,
y: pointerPosition!.y - mousePointTo.y * y,
};
stage.value?.position(position);
});
};
const initial = () => {
stage.value = new Konva.Stage({ container: 'container', width: width.value, height: height.value });
const layer = new Konva.Layer();
stage.value.add(layer);
zoomed();
const text = new Konva.Text({
x: 50,
y: 60,
fontSize: 20,
text: 'Hello from the Konva framework. Try to resize me.',
draggable: true,
});
layer.add(text);
const tr = new Konva.Transformer({
nodes: [text],
padding: 5,
flipEnabled: false,
enabledAnchors: ['middle-left', 'middle-right'],
boundBoxFunc(oldBox, newBox) {
if (Math.abs(newBox.width) < MIN_WIDTH) {
return oldBox;
}
return newBox;
},
});
layer.add(tr);
text.on('transform', () => {
text.setAttrs({
width: Math.max(text.width() * text.scaleX(), MIN_WIDTH),
scaleX: 1,
scaleY: 1,
});
});
};
onMounted(() => {
initial();
});
</script>
<template>
<div id="container"></div>
</template>