text.vue 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. <template>
  2. <TempText :data="{ ...atData, ...animation.data }" :ref="(e: any) => shape = e.shape" />
  3. </template>
  4. <script lang="ts" setup>
  5. import TempText from "./temp-text.vue";
  6. import { TextData, style } from "./index.ts";
  7. import { computed, ref, watch, watchEffect } from "vue";
  8. import { DC } from "@/helper/deconstruction";
  9. import { useShapeTransformer } from "../../hook/use-transformer.ts";
  10. import { useAutomaticData } from "../../hook/use-automatic-data.ts";
  11. import { useMouseStyle } from "../../hook/use-mouse-status.ts";
  12. import { useAniamtion } from "../../hook/use-animation.ts";
  13. import { Text } from "konva/lib/shapes/Text";
  14. const props = defineProps<{ data: TextData; addMode?: boolean }>();
  15. const emit = defineEmits<{ (e: "update", value: TextData): void }>();
  16. const shape = ref<DC<Text>>();
  17. const minWidth = computed(() => (props.data.fontSize || 12) * 2);
  18. const transform = useShapeTransformer(shape, {
  19. enabledAnchors: ["middle-left", "middle-right"],
  20. flipEnabled: false,
  21. boundBoxFunc: (oldBox, newBox) => {
  22. if (Math.abs(newBox.width) < minWidth.value) {
  23. return oldBox;
  24. }
  25. return newBox;
  26. },
  27. });
  28. const atData = useAutomaticData(() => props.data);
  29. watchEffect(() => {
  30. const $text = shape.value?.getNode();
  31. if (!$text) return;
  32. $text.on("transform", () => {
  33. const newWidth = Math.max($text.width() * $text.scaleX(), minWidth.value);
  34. $text.setAttrs({
  35. width: newWidth,
  36. scaleX: 1,
  37. scaleY: 1,
  38. });
  39. });
  40. });
  41. watch(transform, (transform, oldTransform) => {
  42. if (!transform && oldTransform) {
  43. const $text = shape.value!.getNode();
  44. emit("update", {
  45. ...atData.value,
  46. width: $text.width(),
  47. mat: $text.getTransform().m,
  48. });
  49. }
  50. });
  51. const { currentStyle } = useMouseStyle({ style, shape });
  52. const animation = useAniamtion(currentStyle);
  53. </script>