From baec3d542977ae042be724812132b23e3d6df625 Mon Sep 17 00:00:00 2001 From: unanmed <1319491857@qq.com> Date: Wed, 26 Feb 2025 22:01:57 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20Arrow=20=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/module/render/components/misc.tsx | 58 ++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/src/module/render/components/misc.tsx b/src/module/render/components/misc.tsx index d59f9f8..af0b49a 100644 --- a/src/module/render/components/misc.tsx +++ b/src/module/render/components/misc.tsx @@ -1,5 +1,5 @@ -import { DefaultProps, ElementLocator, Sprite } from '@/core/render'; -import { defineComponent, ref, watch } from 'vue'; +import { DefaultProps, ElementLocator, PathProps, Sprite } from '@/core/render'; +import { computed, defineComponent, ref, watch } from 'vue'; import { SetupComponentOptions } from './types'; import { MotaOffscreenCanvas2D } from '@/core/fx/canvas2d'; @@ -53,3 +53,57 @@ export const Progress = defineComponent(props => { return ; }; }, progressProps); + +export interface ArrowProps extends PathProps { + /** 箭头的四个坐标 */ + arrow: [number, number, number, number]; + /** 箭头的头部大小 */ + head?: number; + /** 箭头的颜色 */ + color?: CanvasStyle; +} + +const arrowProps = { + props: ['arrow', 'head', 'color'] +} satisfies SetupComponentOptions; + +export const Arrow = defineComponent(props => { + const loc = computed(() => { + const [x1, y1, x2, y2] = props.arrow; + const left = Math.min(x1, x2); + const right = Math.max(x1, x2); + const top = Math.min(y1, y2); + const bottom = Math.max(y1, y2); + return [left, top, right - left, bottom - top]; + }); + const path = computed(() => { + const path = new Path2D(); + const head = props.head ?? 8; + const [x = 0, y = 0] = loc.value; + const [x1, y1, x2, y2] = props.arrow; + path.moveTo(x1 - x, y1 - y); + path.lineTo(x2 - x, y2 - y); + const angle = Math.atan2(y2 - y1, x2 - x1); + path.moveTo( + x2 - head * Math.cos(angle - Math.PI / 6), + y2 - head * Math.sin(angle - Math.PI / 6) + ); + path.lineTo(x2 - x, y2 - y); + path.lineTo( + x2 - head * Math.cos(angle + Math.PI / 6), + y2 - head * Math.sin(angle + Math.PI / 6) + ); + return path; + }); + + return () => ( + + ); +}, arrowProps);