first commit
This commit is contained in:
106
src/composables/useLuopan.ts
Normal file
106
src/composables/useLuopan.ts
Normal 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>;
|
||||
Reference in New Issue
Block a user