first commit

This commit is contained in:
douboer
2026-01-21 13:22:26 +08:00
commit 24452838a1
28 changed files with 7901 additions and 0 deletions

View File

@@ -0,0 +1,106 @@
/**
* 罗盘业务逻辑组合函数
*/
import { computed, type Ref, type ComputedRef } from 'vue';
import type { Example, Sector, TextRadialPosition } from '../types';
import {
polarToXY,
calculateLabelRotation,
generateSectorData,
} from '../utils';
/**
* 罗盘逻辑 Hook
* @param exampleRef 当前示例的响应式引用
* @param textRadialPositionRef 文字径向位置的响应式引用
* @returns 罗盘相关的计算属性和方法
*/
export function useLuopan(
exampleRef: Ref<Example>,
textRadialPositionRef: Ref<TextRadialPosition>
) {
/**
* 角度分割点列表
*/
const anglesDeg = computed(() => exampleRef.value.angles);
/**
* 圆环半径列表
*/
const rings = computed(() => exampleRef.value.radii);
/**
* 最外层半径
*/
const outerMost = computed(() => {
const radii = exampleRef.value.radii;
return radii[radii.length - 1];
});
/**
* 生成所有扇区数据
*/
const sectors = computed<Sector[]>(() => {
const res: Sector[] = [];
const A = exampleRef.value.angles;
const R = exampleRef.value.radii;
const layerCount = R.length;
const pieCount = A.length - 1;
for (let j = 0; j < layerCount; j++) {
const rInner = j === 0 ? 0 : R[j - 1];
const rOuter = R[j];
for (let i = 0; i < pieCount; i++) {
const aStart = A[i];
const aEnd = A[i + 1];
const sector = generateSectorData({
layerIndex: j,
pieIndex: i,
rInner,
rOuter,
aStart,
aEnd,
layerCount,
pieCount,
textRadialPosition: textRadialPositionRef.value,
});
res.push(sector);
}
}
return res;
});
/**
* 计算标签的变换属性
* @param s 扇区数据
* @returns SVG transform 字符串
*/
const getLabelTransform = (s: Sector): string => {
const rotDeg = calculateLabelRotation(s.aMidDeg);
return `translate(${s.cx} ${s.cy}) rotate(${rotDeg})`;
};
/**
* 极坐标转 XY暴露给模板使用
*/
const toXY = polarToXY;
return {
anglesDeg,
rings,
outerMost,
sectors,
getLabelTransform,
toXY,
};
}
/**
* 返回类型定义
*/
export type UseLuopanReturn = ReturnType<typeof useLuopan>;