@ahmiao666/lucky-wheel-vue
Version:
421 lines (415 loc) • 15.2 kB
TypeScript
import { DefineComponent } from 'vue';
interface SectorImageConfig {
url: string;
width?: number;
height?: number;
}
interface SectorTextConfig {
fontSize?: number;
color?: string;
lineHeight?: number;
maxLines?: number;
direction?: 'horizontal' | 'vertical';
offsetX?: number;
offsetY?: number;
textAlign?: 'left' | 'center' | 'right';
fontFamily?: string;
fontWeight?: string;
textRadius?: number;
}
interface SectorContentImageConfig {
url: string | HTMLImageElement;
width?: number;
height?: number;
offsetX?: number;
offsetY?: number;
imageRadius?: number;
rotation?: number;
opacity?: number;
visible?: boolean;
}
interface SectorConfig {
id: string;
text: string;
color: string;
image?: SectorImageConfig;
textConfig?: SectorTextConfig;
contentImage?: SectorContentImageConfig;
}
interface ArrowConfig {
visible?: boolean;
size?: number;
color?: string;
distance?: number;
image?: string | HTMLImageElement;
imageWidth?: number;
imageHeight?: number;
}
interface CenterButtonArrowConfig {
size?: number;
color?: string;
offsetY?: number;
image?: string | HTMLImageElement;
imageWidth?: number;
imageHeight?: number;
}
interface CenterButtonAnimationConfig {
enabled?: boolean;
speed?: number;
scale?: number;
}
interface CenterButtonConfig {
visible?: boolean;
width?: number;
height?: number;
backgroundColor?: string;
backgroundImage?: string | HTMLImageElement;
border?: BorderConfig;
arrow?: CenterButtonArrowConfig;
animation?: boolean | CenterButtonAnimationConfig;
}
interface BorderConfig {
width?: number;
color?: string;
style?: "solid" | "dashed" | "dotted";
}
interface WheelConfig {
sectors: SectorConfig[];
size?: number;
stopOffsetRange?: number;
targetDirection?: number;
arrow?: ArrowConfig;
centerButton?: CenterButtonConfig;
border?: BorderConfig;
backgroundImage?: string | HTMLImageElement;
innerPadding?: number;
canvasPadding?: number;
sectorStroke?: {
width?: number;
color?: string;
};
}
/**幸运大转盘引擎 */
declare class LuckyWheelEngine {
private static readonly DEFAULTS;
private canvas;
private ctx;
private config;
private rotateDeg;
private speed;
private accelerationTime;
private decelerationTime;
private stopOffsetRange;
private targetDirection;
private startTime;
private endTime;
private stopDeg;
private endDeg;
private prizeDeg;
private FPS;
private animationId?;
private continuousAnimationId?;
private onStopCallback?;
private images;
private imageLoadStates;
private step;
private prizeFlag;
private devicePixelRatio;
private onCenterButtonClickCallback?;
private centerButtonAnimationTime;
constructor(canvas: HTMLCanvasElement, config: WheelConfig);
/**
* 获取默认尺寸,撑满父元素
*/
private getDefaultSize;
/**
* 设置高DPI Canvas,解决模糊问题
*/
private setupHighDPICanvas;
/**
* 设置中心按钮鼠标事件
*/
private setupCenterButtonMouseEvents;
/**
* 检查鼠标位置是否在中心按钮内
*/
private isPointInCenterButton;
private imageLoaders;
private loadAllImages;
private loadSingleImage;
private loadImage;
private loadMapImages;
private loadSectorImages;
private loadSectorContentImages;
private reloadImageByName;
private loadArrowImage;
private loadCenterButtonBackgroundImage;
private loadCenterButtonArrowImage;
/**
* 获取动画配置
*/
private getAnimationConfig;
/**
* 启动持续动画循环(用于中心按钮呼吸灯效果)
*/
private startContinuousAnimation;
/**
* 停止持续动画循环
*/
private stopContinuousAnimation;
start(): void;
stop(targetId?: string, onStop?: (result: SectorConfig) => void): void;
/**
* 设置中心按钮点击回调函数
*/
setCenterButtonClickCallback(callback?: () => void): void;
private updateConfig;
private createConfigSetter;
setStopOffsetRange: (range: number) => void;
setTargetDirection: (direction: number) => void;
setArrowConfig: (updates: Partial<ArrowConfig>) => void;
setArrowDistance: (distance: number) => void;
setArrowVisible: (visible: boolean) => void;
setBorderConfig: (updates: Partial<BorderConfig>) => void;
setBorderWidth: (width: number) => void;
setBorderColor: (color: string) => void;
setBorderStyle: (style: "solid" | "dashed" | "dotted") => void;
setInnerPadding: (padding: number) => void;
setSectorStrokeConfig: (updates: Partial<{
width?: number | undefined;
color?: string | undefined;
}>) => void;
setSectorStrokeWidth: (width: number) => void;
setSectorStrokeColor: (color: string) => void;
setCenterButtonConfig: (updates: Partial<CenterButtonConfig>) => void;
setCenterButtonAnimation: (enabled: boolean) => void;
setCenterButtonAnimationConfig: (animationConfig: CenterButtonAnimationConfig) => void;
setCenterButtonAnimationSpeed: (speed: number) => void;
setCenterButtonAnimationScale: (scale: number) => void;
private findSector;
private createSectorConfigSetter;
setSectorTextConfig: (sectorId: string, updates: Partial<SectorTextConfig>) => void;
setBatchSectorTextConfig: (configs: Array<{
sectorId: string;
config: SectorTextConfig;
}>) => void;
getSectorTextConfigById: (sectorId: string) => SectorTextConfig | undefined;
resetSectorTextConfig: (sectorId: string) => void;
setSectorTextFontSize: (sectorId: string, fontSize: number) => void;
setSectorTextColor: (sectorId: string, color: string) => void;
setSectorTextLineHeight: (sectorId: string, lineHeight: number) => void;
setSectorTextMaxLines: (sectorId: string, maxLines: number) => void;
setSectorTextDirection: (sectorId: string, direction: "horizontal" | "vertical") => void;
setSectorTextOffset: (sectorId: string, offsetX: number, offsetY: number) => void;
setSectorTextAlign: (sectorId: string, textAlign: "left" | "center" | "right") => void;
setSectorTextFont: (sectorId: string, fontFamily: string, fontWeight?: string) => void;
setSectorTextRadius: (sectorId: string, textRadius: number) => void;
setSectorContentImageConfig: (sectorId: string, imageConfig: Partial<SectorContentImageConfig>) => void;
setSectorContentImage: (sectorId: string, imageUrl: string | HTMLImageElement, options?: {
width?: number;
height?: number;
offsetX?: number;
offsetY?: number;
imageRadius?: number;
rotation?: number;
opacity?: number;
}) => void;
removeSectorContentImage: (sectorId: string) => void;
setSectorContentImageSize: (sectorId: string, width: number, height: number) => void;
setSectorContentImageOffset: (sectorId: string, offsetX: number, offsetY: number) => void;
setSectorContentImageRadius: (sectorId: string, imageRadius: number) => void;
setSectorContentImageRotation: (sectorId: string, rotation: number) => void;
setSectorContentImageOpacity: (sectorId: string, opacity: number) => void;
setSectorContentImageVisible: (sectorId: string, visible: boolean) => void;
private run;
private carveOnGunwaleOfAMovingBoat;
/**
* 二次缓动 - 加速
*/
private quadEaseIn;
/**
* 二次缓动 - 减速
*/
private quadEaseOut;
private draw;
private drawBackgroundImage;
private drawSector;
/**
* 获取扇形文本的默认配置
*/
private getDefaultTextConfig;
/**
* 获取扇形的完整文本配置(合并默认配置和自定义配置)
*/
private getSectorTextConfig;
/**
* 绘制扇形文字(支持横向/纵向、换行、溢出隐藏、自定义位置)
*/
private drawSectorText;
/**
* 计算文本区域尺寸
*/
private calculateTextArea;
/**
* 创建文本裁剪路径
*/
private createTextClipPath;
/**
* 智能文本换行(支持中英文混合)
*/
private wrapTextWithConfig;
/**
* 渲染文本行
*/
private renderTextLines;
/**
* 统一绘制扇形分割线,使用全局描边配置
*/
private drawSectorDividers;
private drawSectorImage;
private drawSectorContentImage;
/**
* 获取内容图片的默认配置
*/
private getDefaultContentImageConfig;
private drawArrow;
private drawCenterButton;
private drawCenterButtonArrow;
private drawWheelBorder;
private getRandomSectorId;
setBackgroundImage: (image: string | HTMLImageElement | undefined) => void;
setSectorImage(sectorId: string, imageUrl: string | undefined, options?: {
width?: number;
height?: number;
}): void;
destroy(): void;
}
interface VueLuckyWheelProps {
/** 转盘配置 */
config: WheelConfig;
/** 画布样式类名 */
className?: string;
/** 画布样式 */
style?: Record<string, any>;
}
interface VueLuckyWheelEmits {
stop: [result: SectorConfig];
centerButtonClick: [];
start: [];
ready: [engine: LuckyWheelEngine];
}
interface VueLuckyWheelRef {
/** 获取引擎实例 */
getEngine: () => LuckyWheelEngine | null;
/** 开始转动 */
start: () => void;
/** 停止转动 */
stop: (targetId?: string, onStop?: (result: SectorConfig) => void) => void;
/** 设置停止偏移范围 */
setStopOffsetRange: (range: number) => void;
/** 设置目标方向 */
setTargetDirection: (direction: number) => void;
/** 设置箭头配置 */
setArrowConfig: (arrowConfig: ArrowConfig) => void;
/** 设置箭头距离 */
setArrowDistance: (distance: number) => void;
/** 设置箭头是否可见 */
setArrowVisible: (visible: boolean) => void;
/** 设置边框配置 */
setBorderConfig: (borderConfig: BorderConfig) => void;
/** 设置边框宽度 */
setBorderWidth: (width: number) => void;
/** 设置边框颜色 */
setBorderColor: (color: string) => void;
/** 设置边框样式 */
setBorderStyle: (style: "solid" | "dashed" | "dotted") => void;
/** 设置内边距 */
setInnerPadding: (padding: number) => void;
/** 设置中心按钮点击回调 */
setCenterButtonClickCallback: (callback?: () => void) => void;
/** 设置扇形描边配置 */
setSectorStrokeConfig: (strokeConfig: {
width?: number;
color?: string;
}) => void;
/** 设置扇形描边宽度 */
setSectorStrokeWidth: (width: number) => void;
/** 设置扇形描边颜色 */
setSectorStrokeColor: (color: string) => void;
/** 设置中心按钮配置 */
setCenterButtonConfig: (centerButtonConfig: CenterButtonConfig) => void;
/** 设置中心按钮动画 */
setCenterButtonAnimation: (enabled: boolean) => void;
/** 设置中心按钮动画配置 */
setCenterButtonAnimationConfig: (animationConfig: CenterButtonAnimationConfig) => void;
/** 设置中心按钮动画速度 */
setCenterButtonAnimationSpeed: (speed: number) => void;
/** 设置中心按钮动画缩放 */
setCenterButtonAnimationScale: (scale: number) => void;
/** 设置背景图片 */
setBackgroundImage: (image: string | HTMLImageElement | undefined) => void;
/** 设置扇形图片 */
setSectorImage: (sectorId: string, imageUrl: string | undefined, options?: {
width?: number;
height?: number;
}) => void;
/** 设置扇形文本配置 */
setSectorTextConfig: (sectorId: string, textConfig: SectorTextConfig) => void;
/** 批量设置扇形文本配置 */
setBatchSectorTextConfig: (configs: Array<{
sectorId: string;
config: SectorTextConfig;
}>) => void;
/** 获取扇形文本配置 */
getSectorTextConfigById: (sectorId: string) => SectorTextConfig | undefined;
/** 重置扇形文本配置 */
resetSectorTextConfig: (sectorId: string) => void;
/** 设置文本字体大小 */
setSectorTextFontSize: (sectorId: string, fontSize: number) => void;
/** 设置文本颜色 */
setSectorTextColor: (sectorId: string, color: string) => void;
/** 设置文本行高 */
setSectorTextLineHeight: (sectorId: string, lineHeight: number) => void;
/** 设置文本最大行数 */
setSectorTextMaxLines: (sectorId: string, maxLines: number) => void;
/** 设置文本方向 */
setSectorTextDirection: (sectorId: string, direction: "horizontal" | "vertical") => void;
/** 设置文本位置偏移 */
setSectorTextOffset: (sectorId: string, offsetX: number, offsetY: number) => void;
/** 设置文本对齐方式 */
setSectorTextAlign: (sectorId: string, textAlign: "left" | "center" | "right") => void;
/** 设置文本字体 */
setSectorTextFont: (sectorId: string, fontFamily: string, fontWeight?: string) => void;
/** 设置文本半径比例 */
setSectorTextRadius: (sectorId: string, textRadius: number) => void;
/** 设置扇形内容图片配置 */
setSectorContentImageConfig: (sectorId: string, imageConfig: Partial<SectorContentImageConfig>) => void;
/** 设置扇形内容图片 */
setSectorContentImage: (sectorId: string, imageUrl: string | HTMLImageElement, options?: {
width?: number;
height?: number;
offsetX?: number;
offsetY?: number;
imageRadius?: number;
rotation?: number;
opacity?: number;
}) => void;
/** 移除扇形内容图片 */
removeSectorContentImage: (sectorId: string) => void;
/** 设置内容图片尺寸 */
setSectorContentImageSize: (sectorId: string, width: number, height: number) => void;
/** 设置内容图片位置偏移 */
setSectorContentImageOffset: (sectorId: string, offsetX: number, offsetY: number) => void;
/** 设置内容图片半径位置 */
setSectorContentImageRadius: (sectorId: string, imageRadius: number) => void;
/** 设置内容图片旋转角度 */
setSectorContentImageRotation: (sectorId: string, rotation: number) => void;
/** 设置内容图片透明度 */
setSectorContentImageOpacity: (sectorId: string, opacity: number) => void;
/** 设置内容图片可见性 */
setSectorContentImageVisible: (sectorId: string, visible: boolean) => void;
/** 销毁转盘实例 */
destroy: () => void;
}
declare const VueLuckyWheelComponent: DefineComponent<VueLuckyWheelProps>;
export { ArrowConfig, BorderConfig, CenterButtonAnimationConfig, CenterButtonArrowConfig, CenterButtonConfig, LuckyWheelEngine, SectorConfig, SectorContentImageConfig, SectorImageConfig, SectorTextConfig, VueLuckyWheelComponent as VueLuckyWheel, VueLuckyWheelEmits, VueLuckyWheelProps, VueLuckyWheelRef, WheelConfig, VueLuckyWheelComponent as default };