123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- <template>
- <v-circle
- :config="{ ...style, ...position, hitStrokeWidth: style.strokeWidth }"
- ref="circle"
- />
- <Operate :target="circle" :menus="[{ label: '删除', handler: () => emit('delete') }]" />
- </template>
- <script lang="ts" setup>
- import { Pos } from "@/utils/math.ts";
- import { themeColor } from "@/constant";
- import { computed, ref, watch } from "vue";
- import { DC } from "@/deconstruction";
- import { Circle } from "konva/lib/shapes/Circle";
- import { useShapeDrag } from "@/core/hook/use-transformer.ts";
- import { getMouseColors } from "@/utils/colors";
- import { useCustomSnapInfos, useGlobalSnapInfos, useSnap } from "@/core/hook/use-snap";
- import { generateSnapInfos } from "../util";
- import { ComponentSnapInfo } from "..";
- import { useShapeIsHover } from "@/core/hook/use-mouse-status";
- import { useCursor } from "@/core/hook/use-global-vars";
- import { rangMod } from "@/utils/shared";
- import { Operate } from "../../html-mount/propertys/index.ts";
- const props = defineProps<{
- points: Pos[];
- ndx: number;
- id: string;
- color?: string;
- size?: number;
- disable?: boolean;
- opacity?: number;
- closed?: boolean;
- notDelete?: boolean;
- getSelfSnapInfos?: (point: Pos) => ComponentSnapInfo[];
- }>();
- const emit = defineEmits<{
- (e: "update:position", position: Pos): void;
- (e: "dragend"): void;
- (e: "dragstart"): void;
- (e: "delete"): void;
- }>();
- const position = computed(() => props.points[props.ndx]);
- const style = computed(() => {
- const color = getMouseColors(props.color || themeColor);
- const size = props.size || 5;
- return {
- radius: size / 2,
- fill: isHover.value || dragIng.value ? "#fff" : color.pub,
- stroke: color.pub,
- strokeWidth: size / 4,
- opacity: props.opacity !== undefined ? props.opacity : props.disable ? 0.5 : 1,
- };
- });
- const infos = useCustomSnapInfos();
- const addedInfos = [] as ComponentSnapInfo[];
- const clearInfos = () => {
- addedInfos.forEach(infos.remove);
- };
- const startHandler = () => {
- clearInfos();
- const ndx = props.ndx;
- const geos = [
- props.points.slice(0, ndx),
- props.points.slice(ndx + 1, props.points.length),
- ];
- if (props.closed || (ndx > 0 && ndx < props.points.length - 1)) {
- const prev = rangMod(ndx - 1, props.points.length);
- const next = rangMod(ndx + 1, props.points.length);
- geos.push([props.points[prev], props.points[next]]);
- }
- geos.forEach((geo) => {
- const snapInfos = generateSnapInfos(geo, true, true, true);
- snapInfos.forEach((item) => {
- infos.add(item);
- addedInfos.push(item);
- });
- });
- };
- const snapInfos = useGlobalSnapInfos();
- const refSnapInfos = computed(() => {
- if (!props.id) {
- return snapInfos.value;
- } else {
- return snapInfos.value.filter((p) => !("id" in p) || p.id !== props.id);
- }
- });
- const snap = useSnap(refSnapInfos);
- const circle = ref<DC<Circle>>();
- const offset = useShapeDrag(circle);
- const hResult = useShapeIsHover(circle);
- const isHover = hResult[0];
- const cursor = useCursor();
- if (!props.notDelete) {
- watch(
- isHover,
- (hover, _, onCleanup) => {
- if (hover) {
- onCleanup(cursor.push("/icons/m_move.png"));
- }
- },
- { immediate: true }
- );
- }
- const dragIng = ref(false);
- let init: Pos;
- watch(offset, (offset, oldOffsert) => {
- snap.clear();
- if (!oldOffsert) {
- init = { ...position.value };
- startHandler();
- emit("dragstart");
- cursor.push("/icons/m_move.png");
- dragIng.value = true;
- }
- if (offset) {
- const point = {
- x: init.x + offset.x,
- y: init.y + offset.y,
- };
- const refSnapInfos = props.getSelfSnapInfos
- ? props.getSelfSnapInfos(point)
- : generateSnapInfos([point], true, true);
- // console.log(refSnapInfos);
- const transform = snap.move(refSnapInfos);
- emit("update:position", transform ? transform.point(point) : point);
- } else {
- emit("dragend");
- cursor.pop();
- clearInfos();
- dragIng.value = false;
- }
- });
- watch(
- () => props.disable,
- (disable) => {
- if (disable) {
- offset.pause();
- hResult.pause();
- } else {
- offset.resume();
- hResult.resume();
- }
- },
- { immediate: true }
- );
- defineExpose({
- get shape() {
- return circle.value;
- },
- });
- </script>
|