123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- <template>
- <v-rect
- :config="{
- width: size?.width,
- height: height,
- fill: background ? background : '#000',
- opacity: opacity,
- ...bgConfig,
- }"
- />
- <component
- :is="itemsRenderer"
- :items="items"
- :top="top"
- :activeNdx="active ? items.indexOf(active) : -1"
- :ref="(r: any) => itemShapes = r ? r.shapes : []"
- />
- <template v-for="(itemShape, i) in itemShapes">
- <Operate
- v-if="itemShape"
- :target="itemShape"
- :menus="[
- {
- label: '复制',
- handler: () => copyHandler(i),
- },
- {
- label: '删除',
- handler: () => delHandler(i),
- },
- ]"
- />
- </template>
- </template>
- <script lang="ts" setup>
- import { computed, ref, watch, watchEffect } from "vue";
- import {
- useDrag,
- useGlobalResize,
- useGlobalVar,
- useViewerInvertTransform,
- } from "../drawing/hook";
- import { Transform } from "konva/lib/Util";
- import { DC, EntityShape } from "../drawing/dec";
- import Operate from "../drawing/operate.vue";
- import { checkTLItem, getAddTLItemTime, TLItem } from "./check";
- const { misPixel } = useGlobalVar();
- const { size } = useGlobalResize();
- const props = defineProps<{
- items: TLItem[];
- itemsRenderer: any;
- background?: string;
- height: number;
- opacity: number;
- top: number;
- active?: TLItem;
- }>();
- const emit = defineEmits<{
- (e: "update:active", data: TLItem | undefined): void;
- (e: "update", data: { ndx: number; time: number }): void;
- (e: "add", data: any): void;
- (e: "del", ndx: number): void;
- }>();
- const invMat = useViewerInvertTransform();
- const bgConfig = computed(() => {
- return new Transform()
- .multiply(invMat.value.copy())
- .translate(0, props.top)
- .decompose();
- });
- const itemShapes = ref<DC<EntityShape>[]>([]);
- const { drag } = useDrag(itemShapes);
- let total = { x: 0, y: 0 };
- watch(drag, (drag) => {
- if (!drag) {
- total = { x: 0, y: 0 };
- return;
- }
- const cur = props.items[drag.ndx];
- if (
- checkTLItem(
- props.items,
- { ...cur, time: cur.time + (total.x + drag.x) / misPixel },
- drag.ndx
- )
- ) {
- const curX = cur.time * misPixel + total.x + drag.x;
- emit("update", { ndx: drag.ndx, time: curX / misPixel });
- total = { x: 0, y: 0 };
- } else {
- total.x += drag.x;
- total.y += drag.y;
- }
- });
- watchEffect((onCleanup) => {
- for (let i = 0; i < itemShapes.value.length; i++) {
- const $shape = itemShapes.value[i]?.getNode();
- if (!$shape) continue;
- $shape.on("click.uactive", () => {
- emit("update:active", props.active === props.items[i] ? undefined : props.items[i]);
- });
- onCleanup(() => $shape.off("click.uactive"));
- }
- });
- const copyHandler = (ndx: number) => {
- const newFrame = {
- ...props.items[ndx],
- time: getAddTLItemTime(props.items, ndx, props.items[ndx].duration),
- };
- emit("add", newFrame);
- };
- const delHandler = (ndx: number) => {
- emit("del", ndx);
- };
- </script>
|