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 (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 { helper, controls , store} = useEditor(); const data = useCompData(props.compId); const canvasRef = ref(); onMounted(()=>{ // draw(); let isDragingIndex = -1; canvasRef.value?.addEventListener("dblclick", function(e:MouseEvent){ const x = helper.pxToDesignSize(e.offsetX ) const y = helper.pxToDesignSize(e.offsetY) const points = data.value.points as number[][]; const w = data.layout.size[0]; const h = data.layout.size[1]; //判断直线相交求解点到直线的距离 const ret = findNearestPoint(data.value.points, w , h, x, y); //判断是否 console.log("dbclick=>xxxxx", ret); if (ret.clicked) {//点击删除 points.splice(ret.index, 1); if (points.length < 4) { return; } } else { points.splice(ret.index+1, 0, [x / w, y / h]); } draw(); }) canvasRef.value?.addEventListener("mousedown", function(e:MouseEvent){ if (store.currCompId != props.compId) return; const el = canvasRef.value as HTMLCanvasElement; const x = helper.pxToDesignSize(e.offsetX ) const y = helper.pxToDesignSize(e.offsetY) console.log(x , y); const points = data.value.points as number[][]; const width = data.layout.size[0]; const height = data.layout.size[1]; let n = points.length; isDragingIndex = -1; let initX = 0; let initY = 0; while(n--) { const p = points[n]; const px = width * p[0]; const py = height * p[1]; if(!(x < (px -10) || x > (px + 10) || y < (py -10) || y > (py+10) ) ) { isDragingIndex = n; initX = p[0] initY = p[1] break; } } const dragingX = x; const dragingY = y; if (isDragingIndex != -1) { e.preventDefault(); e.stopPropagation(); const move = function (e:MouseEvent){ if ( isDragingIndex == -1) return; const offx = (helper.pxToDesignSize(e.offsetX ) - dragingX) / width; const offy = (helper.pxToDesignSize(e.offsetY ) - dragingY) / height; points[isDragingIndex][0] = initX + offx; points[isDragingIndex][1] = initY + offy; draw(); } el.addEventListener("mousemove", move) el.addEventListener("mouseup", function(e:MouseEvent){ el.removeEventListener("mousemove", move); }); el.addEventListener("mouseleave", function(e:MouseEvent){ el.removeEventListener("mousemove", move); }) } }, ) effect(draw); }) 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.strokeStyle = data.value.lineColor; const padding = 0.2; ctx.lineJoin = "round"; ctx.beginPath(); let points = data.value.points as number[][]; if (data.value.points.length == 0) { data.value.points = [[padding, 0.5, 0.4, 0.1], [1 - padding, 0.5, 0.4, 0.1]]; points = data.value.points; } points.forEach((p, index)=>{ const x = width * p[0]; const y = height * p[1]; if (index == 0) { ctx.moveTo(x, y) } else { const preIndex = index -1; const prep = points[preIndex]; if (prep[2] != undefined) { ctx.quadraticCurveTo( width *prep[2], height *prep[3], x, y); } else { ctx.lineTo(x, y); } } }) if (data.value.isClose) { ctx.closePath(); } 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; ctx.fill(); } points.forEach((p, index)=>{ const x = width * p[0]; const y = height * p[1]; if (store.isEditMode && store.currCompId == props.compId) { ctx.fillStyle = "red" ctx.beginPath(); ctx.arc(x, y, 5, 0, Math.PI*2); ctx.fill(); } }) } return () => ( ); }, });