|
@@ -0,0 +1,128 @@
|
|
|
+import { defineComponent, onMounted , ref, effect} from "vue";
|
|
|
+import { string } from "vue-types";
|
|
|
+import { useCompData } from ".";
|
|
|
+import { useEditor } from "../../../..";
|
|
|
+import { View } from "../View";
|
|
|
+import { CompUI } from "../..";
|
|
|
+import { values } from "lodash";
|
|
|
+import { Angle } from "@/modules/editor/controllers/SelectCtrl/objects/mathUtils";
|
|
|
+
|
|
|
+function findNearestPoint(points: number[][], w:number, h:number, sx:number, sy:number) {
|
|
|
+ const n = points.length;
|
|
|
+ let minv = 100000;
|
|
|
+ let minIndex = -1;
|
|
|
+ const positions = []
|
|
|
+
|
|
|
+ for(let i=0; i<n; i++) {
|
|
|
+ const p = points[i];
|
|
|
+ const x = w *p[0];
|
|
|
+ const y = h *p[1];
|
|
|
+ positions.push([x, y]);
|
|
|
+
|
|
|
+ const ln = (sx-x)*(sx-x) + (sy-y)*(sy-y);
|
|
|
+ if ( ln < minv ) {
|
|
|
+ minIndex = i;
|
|
|
+ minv = ln;
|
|
|
+ if(!(sx < (x -10) || sx > (x + 10) || sy < (y -10) || sy > (y+10) ) ) {
|
|
|
+ return {clicked: true, index: i};
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ let preIndex = minIndex -1;
|
|
|
+ if (preIndex < 0 ) preIndex = n-1;
|
|
|
+ let afterIndex = minIndex + 1;
|
|
|
+ if ( afterIndex >= n) afterIndex = 0;
|
|
|
+
|
|
|
+ const currV = {x:sx-positions[minIndex][0], y:sy-positions[minIndex][1]};
|
|
|
+ const preV = {x:positions[preIndex][0]-positions[minIndex][0], y:positions[preIndex][1]-positions[minIndex][1]}
|
|
|
+ const afterV = {x:positions[afterIndex][0]-positions[minIndex][0], y:positions[afterIndex][1]-positions[minIndex][1]}
|
|
|
+
|
|
|
+ const a1 = Angle(currV, preV)
|
|
|
+ const a2 = Angle(currV, afterV);
|
|
|
+
|
|
|
+ if (a1 < a2) {
|
|
|
+ return {index: preIndex};
|
|
|
+ }
|
|
|
+
|
|
|
+ return {index: minIndex};
|
|
|
+}
|
|
|
+
|
|
|
+export const Component = defineComponent({
|
|
|
+ props: {
|
|
|
+ compId: string().isRequired,
|
|
|
+ },
|
|
|
+ setup(props) {
|
|
|
+ const data = useCompData(props.compId);
|
|
|
+ const canvasRef = ref<HTMLCanvasElement>();
|
|
|
+
|
|
|
+ onMounted(()=>{
|
|
|
+ effect(draw);
|
|
|
+ })
|
|
|
+
|
|
|
+ function drawPoly(ctx:CanvasRenderingContext2D, n:number, cx:number, cy:number, size:number) {
|
|
|
+ ctx.beginPath();
|
|
|
+ let degree = (2 *Math.PI) / n
|
|
|
+ for (let i = 0; i<n; i++) {
|
|
|
+ const a = i*degree - Math.PI / 2.0;
|
|
|
+ const x = Math.cos(a), y = Math.sin(a);
|
|
|
+ ctx.lineTo(x*size + cx, y*size + cy)
|
|
|
+ }
|
|
|
+ ctx.closePath();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ function draw() {
|
|
|
+ const canvas = canvasRef.value as HTMLCanvasElement;
|
|
|
+ if (!canvas) return;
|
|
|
+
|
|
|
+ const ctx = canvasRef.value?.getContext("2d") as CanvasRenderingContext2D;
|
|
|
+
|
|
|
+ const width = data.layout.size[0];
|
|
|
+ const height = data.layout.size[1];
|
|
|
+ canvas.width = Math.ceil(Math.max(1, width));
|
|
|
+ canvas.height = Math.ceil(Math.max(1, height));
|
|
|
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
|
+ ctx.lineWidth = data.value.lineWidth;
|
|
|
+ ctx.save();
|
|
|
+
|
|
|
+ if (data.value.reverseFill) {
|
|
|
+ ctx.fillStyle = data.value.fillColor;
|
|
|
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
|
+ }
|
|
|
+
|
|
|
+ ctx.strokeStyle = data.value.lineColor;
|
|
|
+
|
|
|
+ const padding = data.value.lineWidth;
|
|
|
+
|
|
|
+ ctx.lineJoin = "round";
|
|
|
+
|
|
|
+ drawPoly(ctx, data.value.edges, width/2.0, height / 2.0, (Math.min(width, height) - padding) / 2.0)
|
|
|
+
|
|
|
+ if (data.value.lineWidth !== 0) {
|
|
|
+ ctx.stroke();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (data.value.isFill) {
|
|
|
+ let bColor = data.value.fillColor;
|
|
|
+ if (!bColor) bColor = data.value.lineColor;
|
|
|
+ ctx.fillStyle = bColor;
|
|
|
+ if (data.value.reverseFill) {
|
|
|
+ ctx.fillStyle = "red";
|
|
|
+ // 设置剪切区域
|
|
|
+ ctx.clip();
|
|
|
+ // 将当前路径指定的区域颜色扣除
|
|
|
+ ctx.globalCompositeOperation = "destination-out";
|
|
|
+ }
|
|
|
+ ctx.fill();
|
|
|
+ }
|
|
|
+ ctx.restore();
|
|
|
+ }
|
|
|
+
|
|
|
+ return () => (
|
|
|
+ <View compId={props.compId}>
|
|
|
+ <canvas ref={canvasRef} style={{width:"100%", height: "100%"}}> </canvas>
|
|
|
+ </View>
|
|
|
+ );
|
|
|
+ },
|
|
|
+});
|