|
@@ -1,5 +1,8 @@
|
|
<template>
|
|
<template>
|
|
- <v-circle :config="{ ...style, ...position }" ref="circle" />
|
|
|
|
|
|
+ <v-circle
|
|
|
|
+ :config="{ ...style, ...position, hitStrokeWidth: style.strokeWidth + 10 }"
|
|
|
|
+ ref="circle"
|
|
|
|
+ />
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
<script lang="ts" setup>
|
|
@@ -10,18 +13,21 @@ import { DC } from "@/deconstruction";
|
|
import { Circle } from "konva/lib/shapes/Circle";
|
|
import { Circle } from "konva/lib/shapes/Circle";
|
|
import { useShapeDrag } from "@/core/hook/use-transformer.ts";
|
|
import { useShapeDrag } from "@/core/hook/use-transformer.ts";
|
|
import { getMouseColors } from "@/utils/colors";
|
|
import { getMouseColors } from "@/utils/colors";
|
|
-import { useGlobalSnapInfos, useSnap } from "@/core/hook/use-snap";
|
|
|
|
|
|
+import { useCustomSnapInfos, useGlobalSnapInfos, useSnap } from "@/core/hook/use-snap";
|
|
import { generateSnapInfos } from "../util";
|
|
import { generateSnapInfos } from "../util";
|
|
import { ComponentSnapInfo } from "..";
|
|
import { ComponentSnapInfo } from "..";
|
|
import { useShapeIsHover } from "@/core/hook/use-mouse-status";
|
|
import { useShapeIsHover } from "@/core/hook/use-mouse-status";
|
|
import { useCursor } from "@/core/hook/use-global-vars";
|
|
import { useCursor } from "@/core/hook/use-global-vars";
|
|
|
|
+import { rangMod } from "@/utils/shared";
|
|
|
|
|
|
const props = defineProps<{
|
|
const props = defineProps<{
|
|
- position: Pos;
|
|
|
|
- id?: any;
|
|
|
|
|
|
+ points: Pos[];
|
|
|
|
+ ndx: number;
|
|
|
|
+ id: string;
|
|
color?: string;
|
|
color?: string;
|
|
size?: number;
|
|
size?: number;
|
|
- shapeId?: string;
|
|
|
|
|
|
+ disable?: boolean;
|
|
|
|
+ closed?: boolean;
|
|
getSelfSnapInfos?: (point: Pos) => ComponentSnapInfo[];
|
|
getSelfSnapInfos?: (point: Pos) => ComponentSnapInfo[];
|
|
}>();
|
|
}>();
|
|
const emit = defineEmits<{
|
|
const emit = defineEmits<{
|
|
@@ -30,6 +36,8 @@ const emit = defineEmits<{
|
|
(e: "dragstart"): void;
|
|
(e: "dragstart"): void;
|
|
}>();
|
|
}>();
|
|
|
|
|
|
|
|
+const position = computed(() => props.points[props.ndx]);
|
|
|
|
+
|
|
const style = computed(() => {
|
|
const style = computed(() => {
|
|
const color = getMouseColors(props.color || themeColor);
|
|
const color = getMouseColors(props.color || themeColor);
|
|
const size = props.size || 5;
|
|
const size = props.size || 5;
|
|
@@ -38,21 +46,50 @@ const style = computed(() => {
|
|
fill: color.disable,
|
|
fill: color.disable,
|
|
stroke: color.press,
|
|
stroke: color.press,
|
|
strokeWidth: size / 4,
|
|
strokeWidth: size / 4,
|
|
|
|
+ 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 snapInfos = useGlobalSnapInfos();
|
|
const refSnapInfos = computed(() => {
|
|
const refSnapInfos = computed(() => {
|
|
- if (!props.shapeId) {
|
|
|
|
|
|
+ if (!props.id) {
|
|
return snapInfos.value;
|
|
return snapInfos.value;
|
|
} else {
|
|
} else {
|
|
- return snapInfos.value.filter((p) => !("id" in p) || p.id !== props.shapeId);
|
|
|
|
|
|
+ return snapInfos.value.filter((p) => !("id" in p) || p.id !== props.id);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
const snap = useSnap(refSnapInfos);
|
|
const snap = useSnap(refSnapInfos);
|
|
const circle = ref<DC<Circle>>();
|
|
const circle = ref<DC<Circle>>();
|
|
const offset = useShapeDrag(circle);
|
|
const offset = useShapeDrag(circle);
|
|
-const [isHover] = useShapeIsHover(circle);
|
|
|
|
|
|
+const hResult = useShapeIsHover(circle);
|
|
|
|
+const isHover = hResult[0];
|
|
const cursor = useCursor();
|
|
const cursor = useCursor();
|
|
watch(isHover, (hover, _, onCleanup) => {
|
|
watch(isHover, (hover, _, onCleanup) => {
|
|
if (hover) {
|
|
if (hover) {
|
|
@@ -64,7 +101,8 @@ let init: Pos;
|
|
watch(offset, (offset, oldOffsert) => {
|
|
watch(offset, (offset, oldOffsert) => {
|
|
snap.clear();
|
|
snap.clear();
|
|
if (!oldOffsert) {
|
|
if (!oldOffsert) {
|
|
- init = { ...props.position };
|
|
|
|
|
|
+ init = { ...position.value };
|
|
|
|
+ startHandler();
|
|
emit("dragstart");
|
|
emit("dragstart");
|
|
}
|
|
}
|
|
if (offset) {
|
|
if (offset) {
|
|
@@ -79,6 +117,21 @@ watch(offset, (offset, oldOffsert) => {
|
|
emit("update:position", transform ? transform.point(point) : point);
|
|
emit("update:position", transform ? transform.point(point) : point);
|
|
} else {
|
|
} else {
|
|
emit("dragend");
|
|
emit("dragend");
|
|
|
|
+ clearInfos();
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
+
|
|
|
|
+watch(
|
|
|
|
+ () => props.disable,
|
|
|
|
+ (disable) => {
|
|
|
|
+ if (disable) {
|
|
|
|
+ offset.pause();
|
|
|
|
+ hResult.pause();
|
|
|
|
+ } else {
|
|
|
|
+ offset.resume();
|
|
|
|
+ hResult.resume();
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ { immediate: true }
|
|
|
|
+);
|
|
</script>
|
|
</script>
|