123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- <template>
- <TempText
- :data="tData"
- editer
- @update-content="submitHandler"
- :ref="(v: any) => shape = v?.shape"
- />
- <PropertyUpdate
- :describes="describes"
- :data="data"
- :target="shape"
- @change="emit('updateShape', { ...data })"
- />
- <Operate :target="shape" :menus="operateMenus" />
- </template>
- <script lang="ts" setup>
- import { TextData, getMouseStyle, defaultStyle } from "./index.ts";
- import { PropertyUpdate, Operate } from "../../propertys";
- import TempText from "./temp-text.vue";
- import { useComponentStatus } from "@/core/hook/use-component.ts";
- import { cloneRepShape, useCustomTransformer } from "@/core/hook/use-transformer.ts";
- import { Transform } from "konva/lib/Util";
- import { Text } from "konva/lib/shapes/Text";
- import { computed, ref, watch } from "vue";
- import { setShapeTransform } from "@/utils/shape.ts";
- import { zeroEq } from "@/utils/math.ts";
- import { MathUtils } from "three";
- const props = defineProps<{ data: TextData }>();
- const emit = defineEmits<{
- (e: "updateShape", value: TextData): void;
- (e: "addShape", value: TextData): void;
- (e: "delShape"): void;
- }>();
- const { shape, tData, data, operateMenus, describes } = useComponentStatus<
- Text,
- TextData
- >({
- emit,
- props,
- getMouseStyle,
- defaultStyle,
- transformType: "custom",
- customTransform(callback, shape, data) {
- useCustomTransformer(shape, data, {
- openSnap: true,
- getRepShape($shape) {
- const repShape = cloneRepShape($shape).shape;
- return {
- shape: repShape,
- update(data) {
- data.width && repShape.width(data.width);
- data.fontSize && repShape.fontSize(data.fontSize);
- setShapeTransform(repShape, new Transform(data.mat));
- },
- };
- },
- transformerConfig: {
- rotateEnabled: true,
- enabledAnchors: ["middle-left", "middle-right"],
- boundBoxFunc: (oldBox, newBox) => {
- if (newBox.width - minWidth.value < -0.01) {
- return oldBox;
- }
- return newBox;
- },
- },
- beforeHandler(data, mat) {
- return { ...data, ...update(mat, data) };
- },
- handler(data, mat) {
- const setAttrib = update(mat, data);
- Object.assign(data, setAttrib);
- if (setAttrib.width) {
- return true;
- }
- },
- callback,
- });
- },
- copyHandler(tf, data) {
- return {
- ...data,
- mat: tf.multiply(new Transform(data.mat)).m,
- };
- },
- propertys: [
- "fill",
- "stroke",
- "strokeWidth",
- "dash",
- "opacity",
- "fontSize",
- "align",
- "fontStyle",
- // "ref",
- // "zIndex",
- ],
- });
- const minWidth = computed(() => (data.value.fontSize || 12) * 2);
- const getWidth = (data: TextData, scaleX: number) => {
- let width: number;
- if ("width" in data) {
- width = Math.max(data.width! * scaleX, minWidth.value);
- } else {
- width = Math.max(shape.value!.getNode()!.width() * scaleX, minWidth.value);
- }
- return width;
- };
- const update = (mat: Transform, data: TextData) => {
- const { scaleX, x, y, rotation } = mat.decompose();
- if (!zeroEq(scaleX - 1)) {
- return {
- width: getWidth(data, scaleX),
- mat: new Transform()
- .translate(x, y)
- .rotate(MathUtils.degToRad(rotation))
- .scale(1, 1).m,
- };
- } else {
- return {
- mat: mat.m,
- };
- }
- };
- // 字体大小变化时,更新width
- watch(
- () => data.value.fontSize,
- () => {
- data.value.width = getWidth(data.value, 1);
- const $shape = shape.value?.getNode();
- $shape && $shape.fire("bound-change");
- }
- );
- const submitHandler = (val: string) => {
- if (val !== data.value.content) {
- data.value.content = val;
- emit("updateShape", { ...data.value });
- }
- };
- </script>
|