lucky-canvas
Advanced tools
Comparing version 1.0.1 to 1.0.2
@@ -9,5 +9,7 @@ 'use strict'; | ||
this.dpr = 1; | ||
// 初始化一些公共设置 | ||
this.subs = {}; | ||
// 初始化 | ||
this.setDpr(); | ||
this.setHTMLFontSize(); | ||
this.resetArrayPropo(); | ||
} | ||
@@ -67,14 +69,18 @@ /** | ||
/** | ||
* vue2.x 响应式 - 数据劫持 | ||
* 更新数据并重新绘制 canvas 画布 | ||
*/ | ||
draw() { } | ||
/** | ||
* 数据劫持 | ||
* @param obj 将要处理的数据 | ||
*/ | ||
observer(obj) { | ||
if (typeof obj !== 'object' || obj === null) | ||
return obj; | ||
Object.keys(obj).forEach(key => { | ||
this.defineReactive(obj, key, obj[key]); | ||
observer(data) { | ||
if (!data || typeof data !== 'object') | ||
return; | ||
Object.keys(data).forEach(key => { | ||
this.defineReactive(data, key, data[key]); | ||
}); | ||
} | ||
/** | ||
* vue2.x 响应式 - 重写setter和getter | ||
* 重写 setter 和 getter | ||
* @param obj 数据 | ||
@@ -84,18 +90,67 @@ * @param key 属性 | ||
*/ | ||
defineReactive(obj, key, val) { | ||
this.observer(val); | ||
Object.defineProperty(obj, key, { | ||
get() { | ||
console.log('get', key); | ||
return val; | ||
defineReactive(data, key, value) { | ||
this.observer(value); | ||
Object.defineProperty(data, key, { | ||
get: () => { | ||
return value; | ||
}, | ||
set(newVal) { | ||
console.log('set', key, val); | ||
if (newVal !== val) { | ||
val = newVal; | ||
this.observer(val); | ||
} | ||
set: (newVal) => { | ||
let oldVal = value; | ||
if (newVal === value) | ||
return; | ||
value = newVal; | ||
this.observer(value); | ||
if (this.subs[key]) | ||
this.subs[key].call(this, value, oldVal); | ||
this.draw(); | ||
} | ||
}); | ||
} | ||
/** | ||
* 添加一个新的响应式数据 | ||
* @param data 数据 | ||
* @param key 属性 | ||
* @param value 新值 | ||
*/ | ||
$set(data, key, value) { | ||
if (!data || typeof data !== 'object') | ||
return; | ||
this.defineReactive(data, key, value); | ||
} | ||
/** | ||
* 添加一个属性计算 | ||
* @param data 源数据 | ||
* @param key 属性名 | ||
* @param callback 回调函数 | ||
*/ | ||
$computed(data, key, callback) { | ||
Object.defineProperty(data, key, { | ||
get: () => { | ||
return callback.call(this); | ||
} | ||
}); | ||
} | ||
/** | ||
* 添加一个观察者 | ||
* @param key 属性名 | ||
* @param callback 回调函数 | ||
*/ | ||
$watch(key, callback) { | ||
this.subs[key] = callback; | ||
} | ||
/** | ||
* 重写数组的原型方法 | ||
*/ | ||
resetArrayPropo() { | ||
const _this = this; | ||
const oldArrayProto = Array.prototype; | ||
const newArrayProto = Object.create(oldArrayProto); | ||
const methods = ['push', 'pop', 'shift', 'unshift', 'sort', 'splice', 'reverse']; | ||
methods.forEach(name => { | ||
newArrayProto[name] = function () { | ||
_this.draw(); | ||
oldArrayProto[name].call(this, ...arguments); | ||
}; | ||
}); | ||
} | ||
} | ||
@@ -370,3 +425,4 @@ | ||
this.buttons = []; | ||
this.defaultConfig = { | ||
this.defaultConfig = {}; | ||
this._defaultConfig = { | ||
gutter: '0px', | ||
@@ -378,3 +434,4 @@ offsetDegree: 0, | ||
}; | ||
this.defaultStyle = { | ||
this.defaultStyle = {}; | ||
this._defaultStyle = { | ||
fontSize: '18px', | ||
@@ -384,2 +441,3 @@ fontColor: '#000', | ||
fontWeight: '400', | ||
lineHeight: '', | ||
background: '#fff', | ||
@@ -407,3 +465,5 @@ wordWrap: true, | ||
this.ctx = this.canvas.getContext('2d'); | ||
this.setData(data); | ||
this.initData(data); | ||
this.initComputed(); | ||
this.initWatch(); | ||
// 收集首次渲染的图片 | ||
@@ -419,16 +479,118 @@ let willUpdate = [[]]; | ||
*/ | ||
setData(data) { | ||
this.blocks = data.blocks || []; | ||
this.prizes = data.prizes || []; | ||
this.buttons = data.buttons || []; | ||
this.startCallback = data.start; | ||
this.endCallback = data.end; | ||
for (let key in data.defaultConfig) { | ||
this.defaultConfig[key] = data.defaultConfig[key]; | ||
} | ||
for (let key in data.defaultStyle) { | ||
this.defaultStyle[key] = data.defaultStyle[key]; | ||
} | ||
initData(data) { | ||
this.$set(this, 'blocks', data.blocks || []); | ||
this.$set(this, 'prizes', data.prizes || []); | ||
this.$set(this, 'buttons', data.buttons || []); | ||
this.$set(this, 'defaultConfig', data.defaultConfig || {}); | ||
this.$set(this, 'defaultStyle', data.defaultStyle || {}); | ||
this.$set(this, 'startCallback', data.start); | ||
this.$set(this, 'endCallback', data.end); | ||
} | ||
/** | ||
* 初始化属性计算 | ||
*/ | ||
initComputed() { | ||
// 默认配置 | ||
this.$computed(this, '_defaultConfig', () => { | ||
const config = { | ||
gutter: '0px', | ||
offsetDegree: 0, | ||
speed: 20, | ||
accelerationTime: 2500, | ||
decelerationTime: 2500, | ||
...this.defaultConfig | ||
}; | ||
return config; | ||
}); | ||
// 默认样式 | ||
this.$computed(this, '_defaultStyle', () => { | ||
const style = { | ||
fontSize: '18px', | ||
fontColor: '#000', | ||
fontStyle: 'microsoft yahei ui,microsoft yahei,simsun,sans-serif', | ||
fontWeight: '400', | ||
background: '#fff', | ||
wordWrap: true, | ||
lengthLimit: '90%', | ||
...this.defaultStyle | ||
}; | ||
return style; | ||
}); | ||
} | ||
/** | ||
* 初始化观察者 | ||
*/ | ||
initWatch() { | ||
// 观察奖品数据的变化 | ||
this.$watch('prizes', (newData, oldData) => { | ||
let willUpdate = []; | ||
// 首次渲染时oldData为undefined | ||
if (!oldData) | ||
willUpdate = newData.map(prize => prize.imgs); | ||
// 此时新值一定存在 | ||
else if (newData) | ||
newData.forEach((newPrize, prizeIndex) => { | ||
let prizeImgs = []; | ||
const oldPrize = oldData[prizeIndex]; | ||
// 如果旧奖品不存在 | ||
if (!oldPrize) | ||
prizeImgs = newPrize.imgs || []; | ||
// 新奖品有图片才能进行对比 | ||
else if (newPrize.imgs) | ||
newPrize.imgs.forEach((newImg, imgIndex) => { | ||
if (!oldPrize.imgs) | ||
return prizeImgs[imgIndex] = newImg; | ||
const oldImg = oldPrize.imgs[imgIndex]; | ||
// 如果旧值不存在 | ||
if (!oldImg) | ||
prizeImgs[imgIndex] = newImg; | ||
// 如果缓存中没有奖品或图片 | ||
else if (!this.prizeImgs[prizeIndex] || !this.prizeImgs[prizeIndex][imgIndex]) { | ||
prizeImgs[imgIndex] = newImg; | ||
} | ||
// 如果新值和旧值的src不相等 | ||
else if (newImg.src !== oldImg.src) | ||
prizeImgs[imgIndex] = newImg; | ||
}); | ||
willUpdate[prizeIndex] = prizeImgs; | ||
}); | ||
return this.init(willUpdate); | ||
}); | ||
// 观察按钮数据的变化 | ||
this.$watch('buttons', (newData, oldData) => { | ||
let willUpdate = []; | ||
// 首次渲染时oldData为undefined | ||
if (!oldData) | ||
willUpdate = newData.map(btn => btn.imgs); | ||
// 此时新值一定存在 | ||
else if (newData) | ||
newData.forEach((newBtn, btnIndex) => { | ||
let btnImgs = []; | ||
const oldBtn = oldData[btnIndex]; | ||
// 如果旧奖品不存在或旧奖品的图片不存在 | ||
if (!oldBtn || !oldBtn.imgs) | ||
btnImgs = newBtn.imgs || []; | ||
// 新奖品有图片才能进行对比 | ||
else if (newBtn.imgs) | ||
newBtn.imgs.forEach((newImg, imgIndex) => { | ||
if (!oldBtn.imgs) | ||
return btnImgs[imgIndex] = newImg; | ||
const oldImg = oldBtn.imgs[imgIndex]; | ||
// 如果旧值不存在 | ||
if (!oldImg) | ||
btnImgs[imgIndex] = newImg; | ||
// 如果缓存中没有按钮或图片 | ||
else if (!this.btnImgs[btnIndex] || !this.btnImgs[btnIndex][imgIndex]) { | ||
btnImgs[imgIndex] = newImg; | ||
} | ||
// 如果新值和旧值的src不相等 | ||
else if (newImg.src !== oldImg.src) | ||
btnImgs[imgIndex] = newImg; | ||
}); | ||
willUpdate[btnIndex] = btnImgs; | ||
}); | ||
return this.init([...new Array(this.prizes.length).fill(undefined), ...willUpdate]); | ||
}); | ||
} | ||
/** | ||
* 初始化 canvas 抽奖 | ||
@@ -545,3 +707,3 @@ * @param { Array<ImgType[]> } willUpdateImgs 需要更新的图片 | ||
draw() { | ||
const { ctx, dpr, defaultConfig, defaultStyle } = this; | ||
const { ctx, dpr, _defaultConfig, _defaultStyle } = this; | ||
ctx.clearRect(-this.Radius, -this.Radius, this.Radius * 2, this.Radius * 2); | ||
@@ -559,3 +721,3 @@ // 绘制blocks边框 | ||
this.prizeRadian = getAngle(this.prizeDeg); | ||
let start = getAngle(-90 + this.rotateDeg + defaultConfig.offsetDegree); | ||
let start = getAngle(-90 + this.rotateDeg + _defaultConfig.offsetDegree); | ||
// 计算文字横坐标 | ||
@@ -568,3 +730,3 @@ const getFontX = (line) => { | ||
// 优先使用字体行高, 要么使用默认行高, 其次使用字体大小, 否则使用默认字体大小 | ||
const lineHeight = font.lineHeight || defaultStyle.lineHeight || font.fontSize || defaultStyle.fontSize; | ||
const lineHeight = font.lineHeight || _defaultStyle.lineHeight || font.fontSize || _defaultStyle.fontSize; | ||
return this.getHeight(font.top, height) + (lineIndex + 1) * this.getLength(lineHeight) * dpr; | ||
@@ -580,3 +742,3 @@ }; | ||
// 绘制背景 | ||
drawSector(ctx, this.maxBtnRadius, this.prizeRadius, currMiddleDeg - this.prizeRadian / 2, currMiddleDeg + this.prizeRadian / 2, this.getLength(defaultConfig.gutter) * dpr, prize.background || defaultStyle.background || 'rgba(0, 0, 0, 0)'); | ||
drawSector(ctx, this.maxBtnRadius, this.prizeRadius, currMiddleDeg - this.prizeRadian / 2, currMiddleDeg + this.prizeRadian / 2, this.getLength(_defaultConfig.gutter) * dpr, prize.background || _defaultStyle.background || 'rgba(0, 0, 0, 0)'); | ||
// 计算临时坐标并旋转文字 | ||
@@ -599,10 +761,10 @@ let x = Math.cos(currMiddleDeg) * this.prizeRadius; | ||
prize.fonts && prize.fonts.forEach(font => { | ||
let fontColor = font.fontColor || defaultStyle.fontColor; | ||
let fontWeight = font.fontWeight || defaultStyle.fontWeight; | ||
let fontSize = this.getLength(font.fontSize || defaultStyle.fontSize); | ||
let fontStyle = font.fontStyle || defaultStyle.fontStyle; | ||
let fontColor = font.fontColor || _defaultStyle.fontColor; | ||
let fontWeight = font.fontWeight || _defaultStyle.fontWeight; | ||
let fontSize = this.getLength(font.fontSize || _defaultStyle.fontSize); | ||
let fontStyle = font.fontStyle || _defaultStyle.fontStyle; | ||
ctx.fillStyle = fontColor; | ||
ctx.font = `${fontWeight} ${fontSize * dpr}px ${fontStyle}`; | ||
let lines = [], text = String(font.text); | ||
if (font.hasOwnProperty('wordWrap') ? font.wordWrap : defaultStyle.wordWrap) { | ||
if (font.hasOwnProperty('wordWrap') ? font.wordWrap : _defaultStyle.wordWrap) { | ||
text = removeEnter(text); | ||
@@ -614,4 +776,4 @@ let str = ''; | ||
let maxWidth = (this.prizeRadius - getFontY(font, prizeHeight, lines.length)) | ||
* Math.tan(this.prizeRadian / 2) * 2 - this.getLength(defaultConfig.gutter) * dpr; | ||
if (currWidth > this.getWidth(font.lengthLimit || defaultStyle.lengthLimit, maxWidth)) { | ||
* Math.tan(this.prizeRadian / 2) * 2 - this.getLength(_defaultConfig.gutter) * dpr; | ||
if (currWidth > this.getWidth(font.lengthLimit || _defaultStyle.lengthLimit, maxWidth)) { | ||
lines.push(str.slice(0, -1)); | ||
@@ -671,6 +833,6 @@ str = text[i]; | ||
btn.fonts && btn.fonts.forEach(font => { | ||
let fontColor = font.fontColor || defaultStyle.fontColor; | ||
let fontWeight = font.fontWeight || defaultStyle.fontWeight; | ||
let fontSize = this.getLength(font.fontSize || defaultStyle.fontSize); | ||
let fontStyle = font.fontStyle || defaultStyle.fontStyle; | ||
let fontColor = font.fontColor || _defaultStyle.fontColor; | ||
let fontWeight = font.fontWeight || _defaultStyle.fontWeight; | ||
let fontSize = this.getLength(font.fontSize || _defaultStyle.fontSize); | ||
let fontStyle = font.fontStyle || _defaultStyle.fontStyle; | ||
ctx.fillStyle = fontColor; | ||
@@ -708,6 +870,6 @@ ctx.font = `${fontWeight} ${fontSize * dpr}px ${fontStyle}`; | ||
run(num = 0) { | ||
const { prizeFlag, prizeDeg, rotateDeg, defaultConfig } = this; | ||
const { prizeFlag, prizeDeg, rotateDeg, _defaultConfig } = this; | ||
let interval = Date.now() - this.startTime; | ||
// 先完全旋转, 再停止 | ||
if (interval >= defaultConfig.accelerationTime && prizeFlag !== undefined) { | ||
if (interval >= _defaultConfig.accelerationTime && prizeFlag !== undefined) { | ||
// 记录帧率 | ||
@@ -720,7 +882,7 @@ this.FPS = interval / num; | ||
// 最终停止的角度 | ||
this.endDeg = 360 * 5 - prizeFlag * prizeDeg - rotateDeg - defaultConfig.offsetDegree; | ||
this.endDeg = 360 * 5 - prizeFlag * prizeDeg - rotateDeg - _defaultConfig.offsetDegree; | ||
cancelAnimationFrame(this.animationId); | ||
return this.slowDown(); | ||
} | ||
this.rotateDeg = (rotateDeg + quad.easeIn(interval, 0, defaultConfig.speed, defaultConfig.accelerationTime)) % 360; | ||
this.rotateDeg = (rotateDeg + quad.easeIn(interval, 0, _defaultConfig.speed, _defaultConfig.accelerationTime)) % 360; | ||
this.draw(); | ||
@@ -733,5 +895,5 @@ this.animationId = window.requestAnimationFrame(this.run.bind(this, num + 1)); | ||
slowDown() { | ||
const { prizes, prizeFlag, stopDeg, endDeg, defaultConfig } = this; | ||
const { prizes, prizeFlag, stopDeg, endDeg, _defaultConfig } = this; | ||
let interval = Date.now() - this.endTime; | ||
if (interval >= defaultConfig.decelerationTime) { | ||
if (interval >= _defaultConfig.decelerationTime) { | ||
this.startTime = 0; | ||
@@ -741,3 +903,3 @@ this.endCallback?.({ ...prizes.find((prize, index) => index === prizeFlag) }); | ||
} | ||
this.rotateDeg = quad.easeOut(interval, stopDeg, endDeg, defaultConfig.decelerationTime) % 360; | ||
this.rotateDeg = quad.easeOut(interval, stopDeg, endDeg, _defaultConfig.decelerationTime) % 360; | ||
this.draw(); | ||
@@ -806,3 +968,4 @@ this.animationId = window.requestAnimationFrame(this.slowDown.bind(this)); | ||
this.prizes = []; | ||
this.defaultConfig = { | ||
this.defaultConfig = {}; | ||
this._defaultConfig = { | ||
gutter: 5, | ||
@@ -813,3 +976,4 @@ speed: 20, | ||
}; | ||
this.defaultStyle = { | ||
this.defaultStyle = {}; | ||
this._defaultStyle = { | ||
borderRadius: 20, | ||
@@ -820,2 +984,3 @@ fontColor: '#000', | ||
fontWeight: '400', | ||
lineHeight: '', | ||
background: '#fff', | ||
@@ -826,5 +991,11 @@ shadow: '', | ||
}; | ||
this.activeStyle = { | ||
this.activeStyle = {}; | ||
this._activeStyle = { | ||
background: '#ffce98', | ||
shadow: '', | ||
fontStyle: '', | ||
fontWeight: '', | ||
fontSize: '', | ||
lineHeight: '', | ||
fontColor: '', | ||
}; | ||
@@ -848,4 +1019,2 @@ this.boxWidth = 0; // 九宫格宽度 | ||
this.cellImgs = []; | ||
// 边框绘制信息 | ||
this.blockData = []; | ||
this.box = document.querySelector(el); | ||
@@ -855,3 +1024,5 @@ this.canvas = document.createElement('canvas'); | ||
this.ctx = this.canvas.getContext('2d'); | ||
this.setData(data); | ||
this.initData(data); | ||
this.initComputed(); | ||
this.initWatch(); | ||
// 收集首次渲染的图片 | ||
@@ -867,27 +1038,122 @@ let willUpdate = [[]]; | ||
*/ | ||
setData(data) { | ||
this.rows = Number(data.rows) || 3; | ||
this.cols = Number(data.cols) || 3; | ||
this.blocks = data.blocks || []; | ||
this.prizes = data.prizes || []; | ||
this.button = data.button; | ||
this.startCallback = data.start; | ||
this.endCallback = data.end; | ||
const config = this.defaultConfig; | ||
const style = this.defaultStyle; | ||
const active = this.activeStyle; | ||
for (let key in data.defaultConfig) { | ||
config[key] = data.defaultConfig[key]; | ||
} | ||
config.gutter = this.getLength(config.gutter) * this.dpr; | ||
config.speed /= 40; | ||
for (let key in data.defaultStyle) { | ||
style[key] = data.defaultStyle[key]; | ||
} | ||
style.borderRadius = this.getLength(style.borderRadius) * this.dpr; | ||
for (let key in data.activeStyle) { | ||
active[key] = data.activeStyle[key]; | ||
} | ||
initData(data) { | ||
this.$set(this, 'rows', Number(data.rows) || 3); | ||
this.$set(this, 'cols', Number(data.cols) || 3); | ||
this.$set(this, 'blocks', data.blocks || []); | ||
this.$set(this, 'prizes', data.prizes || []); | ||
this.$set(this, 'button', data.button); | ||
this.$set(this, 'defaultConfig', data.defaultConfig || {}); | ||
this.$set(this, 'defaultStyle', data.defaultStyle || {}); | ||
this.$set(this, 'activeStyle', data.activeStyle || {}); | ||
this.$set(this, 'startCallback', data.start); | ||
this.$set(this, 'endCallback', data.end); | ||
} | ||
/** | ||
* 初始化属性计算 | ||
*/ | ||
initComputed() { | ||
// 默认配置 | ||
this.$computed(this, '_defaultConfig', () => { | ||
const config = { | ||
gutter: 5, | ||
speed: 20, | ||
accelerationTime: 2500, | ||
decelerationTime: 2500, | ||
...this.defaultConfig | ||
}; | ||
config.gutter = this.getLength(config.gutter) * this.dpr; | ||
config.speed = config.speed / 40; | ||
return config; | ||
}); | ||
// 默认样式 | ||
this.$computed(this, '_defaultStyle', () => { | ||
return { | ||
borderRadius: 20, | ||
fontColor: '#000', | ||
fontSize: '18px', | ||
fontStyle: 'microsoft yahei ui,microsoft yahei,simsun,sans-serif', | ||
fontWeight: '400', | ||
background: '#fff', | ||
shadow: '', | ||
wordWrap: true, | ||
lengthLimit: '90%', | ||
...this.defaultStyle | ||
}; | ||
}); | ||
// 中奖样式 | ||
this.$computed(this, '_activeStyle', () => { | ||
return { | ||
background: '#ffce98', | ||
shadow: '', | ||
...this.activeStyle | ||
}; | ||
}); | ||
} | ||
/** | ||
* 初始化观察者 | ||
*/ | ||
initWatch() { | ||
// 监听奖品数据的变化 | ||
this.$watch('prizes', (newData, oldData) => { | ||
let willUpdate = []; | ||
// 首次渲染时oldData为undefined | ||
if (!oldData) | ||
willUpdate = newData.map(prize => prize.imgs); | ||
// 此时新值一定存在 | ||
else if (newData) | ||
newData.forEach((newPrize, prizeIndex) => { | ||
let prizeImgs = []; | ||
const oldPrize = oldData[prizeIndex]; | ||
// 如果旧奖品不存在 | ||
if (!oldPrize) | ||
prizeImgs = newPrize.imgs || []; | ||
// 新奖品有图片才能进行对比 | ||
else if (newPrize.imgs) | ||
newPrize.imgs.forEach((newImg, imgIndex) => { | ||
if (!oldPrize.imgs) | ||
return prizeImgs[imgIndex] = newImg; | ||
const oldImg = oldPrize.imgs[imgIndex]; | ||
// 如果旧值不存在 | ||
if (!oldImg) | ||
prizeImgs[imgIndex] = newImg; | ||
// 如果缓存中没有图片 | ||
else if (!this.cellImgs[prizeIndex][imgIndex]) | ||
prizeImgs[imgIndex] = newImg; | ||
// 如果新值和旧值的src不相等 | ||
else if (newImg.src !== oldImg.src) | ||
prizeImgs[imgIndex] = newImg; | ||
}); | ||
willUpdate[prizeIndex] = prizeImgs; | ||
}); | ||
return this.init(willUpdate); | ||
}); | ||
// 监听按钮数据的变化 | ||
this.$watch('button', (newData, oldData) => { | ||
let willUpdate = [], btnIndex = this.cols * this.rows - 1; | ||
// 首次渲染时, oldData不存在 | ||
if (!oldData || !oldData.imgs) | ||
willUpdate[btnIndex] = newData.imgs; | ||
// 如果新值存在img, 才能进行对比 | ||
else if (newData.imgs) { | ||
const btnImg = []; | ||
newData.imgs.forEach((newImg, imgIndex) => { | ||
if (!oldData.imgs) | ||
return btnImg[imgIndex] = newImg; | ||
const oldImg = oldData.imgs[imgIndex]; | ||
// 如果旧值不存在 | ||
if (!oldImg) | ||
btnImg[imgIndex] = newImg; | ||
// 如果缓存中没有图片 | ||
else if (!this.cellImgs[btnIndex][imgIndex]) | ||
btnImg[imgIndex] = newImg; | ||
// 如果新值和旧值的src不相等 | ||
else if (newImg.src !== oldImg.src) | ||
btnImg[imgIndex] = newImg; | ||
}); | ||
willUpdate[btnIndex] = btnImg; | ||
} | ||
return this.init(willUpdate); | ||
}); | ||
} | ||
/** | ||
* 初始化 canvas 抽奖 | ||
@@ -899,3 +1165,3 @@ * @param willUpdateImgs 需要更新的图片 | ||
this.setHTMLFontSize(); | ||
const { box, canvas, dpr, defaultStyle, defaultConfig } = this; | ||
const { box, canvas, dpr } = this; | ||
if (!box) | ||
@@ -906,25 +1172,2 @@ return; | ||
this.optimizeClarity(canvas, this.boxWidth, this.boxHeight); | ||
// 合并奖品和按钮一起渲染 | ||
this.cells = [...this.prizes]; | ||
if (this.button) | ||
this.cells[this.cols * this.rows - 1] = { ...this.button }; | ||
this.cells.forEach(cell => { | ||
cell.col = cell.col || 1; | ||
cell.row = cell.row || 1; | ||
}); | ||
// 计算所有边框信息, 并获取奖品区域 | ||
this.blockData = []; | ||
this.prizeArea = this.blocks.reduce(({ x, y, w, h }, block) => { | ||
const [paddingTop, paddingBottom, paddingLeft, paddingRight] = computePadding(block).map(n => n * dpr); | ||
this.blockData.push([x, y, w, h, block.borderRadius ? this.getLength(block.borderRadius) * dpr : 0, block.background]); | ||
return { | ||
x: x + paddingLeft, | ||
y: y + paddingTop, | ||
w: w - paddingLeft - paddingRight, | ||
h: h - paddingTop - paddingBottom | ||
}; | ||
}, { x: 0, y: 0, w: this.boxWidth, h: this.boxHeight }); | ||
// 计算单一奖品格子的宽度和高度 | ||
this.cellWidth = (this.prizeArea.w - defaultConfig.gutter * (this.cols - 1)) / this.cols; | ||
this.cellHeight = (this.prizeArea.h - defaultConfig.gutter * (this.rows - 1)) / this.rows; | ||
const endCallBack = () => { | ||
@@ -1040,9 +1283,29 @@ // 开始首次渲染 | ||
draw() { | ||
const { ctx, dpr, defaultStyle, activeStyle } = this; | ||
const { ctx, dpr, _defaultConfig, _defaultStyle, _activeStyle } = this; | ||
// 清空画布 | ||
ctx.clearRect(0, 0, this.boxWidth, this.boxWidth); | ||
// 绘制所有边框 | ||
this.blockData.forEach(([x, y, w, h, r, background]) => { | ||
drawRoundRect(ctx, x, y, w, h, r, this.handleBackground(x, y, w, h, background)); | ||
// 合并奖品和按钮 | ||
this.cells = [...this.prizes]; | ||
if (this.button) | ||
this.cells[this.cols * this.rows - 1] = this.button; | ||
this.cells.forEach(cell => { | ||
cell.col = cell.col || 1; | ||
cell.row = cell.row || 1; | ||
}); | ||
// 计算获取奖品区域的几何信息 | ||
this.prizeArea = this.blocks.reduce(({ x, y, w, h }, block) => { | ||
const [paddingTop, paddingBottom, paddingLeft, paddingRight] = computePadding(block).map(n => n * dpr); | ||
const r = block.borderRadius ? this.getLength(block.borderRadius) * dpr : 0; | ||
// 绘制边框 | ||
drawRoundRect(ctx, x, y, w, h, r, this.handleBackground(x, y, w, h, block.background)); | ||
return { | ||
x: x + paddingLeft, | ||
y: y + paddingTop, | ||
w: w - paddingLeft - paddingRight, | ||
h: h - paddingTop - paddingBottom | ||
}; | ||
}, { x: 0, y: 0, w: this.boxWidth, h: this.boxHeight }); | ||
// 计算单一奖品格子的宽度和高度 | ||
this.cellWidth = (this.prizeArea.w - _defaultConfig.gutter * (this.cols - 1)) / this.cols; | ||
this.cellHeight = (this.prizeArea.h - _defaultConfig.gutter * (this.rows - 1)) / this.rows; | ||
// 绘制所有格子 | ||
@@ -1053,3 +1316,3 @@ this.cells.forEach((prize, cellIndex) => { | ||
// 处理阴影 (暂时先用any, 这里后续要优化) | ||
const shadow = (isActive ? activeStyle.shadow : (prize.shadow || defaultStyle.shadow)) | ||
const shadow = (isActive ? _activeStyle.shadow : (prize.shadow || _defaultStyle.shadow)) | ||
.replace(/px/g, '') // 清空px字符串 | ||
@@ -1068,3 +1331,3 @@ .split(',')[0].split(' ') // 防止有人声明多个阴影, 截取第一个阴影 | ||
} | ||
drawRoundRect(ctx, x, y, width, height, prize.borderRadius ? this.getLength(prize.borderRadius) * dpr : this.getLength(defaultStyle.borderRadius), this.handleBackground(x, y, width, height, prize.background, isActive)); | ||
drawRoundRect(ctx, x, y, width, height, this.getLength(prize.borderRadius ? prize.borderRadius : _defaultStyle.borderRadius) * dpr, this.handleBackground(x, y, width, height, prize.background, isActive)); | ||
// 清空阴影 | ||
@@ -1089,22 +1352,22 @@ ctx.shadowColor = 'rgba(255, 255, 255, 0)'; | ||
// 字体样式 | ||
let style = isActive && activeStyle.fontStyle | ||
? activeStyle.fontStyle | ||
: (font.fontStyle || defaultStyle.fontStyle); | ||
let style = isActive && _activeStyle.fontStyle | ||
? _activeStyle.fontStyle | ||
: (font.fontStyle || _defaultStyle.fontStyle); | ||
// 字体加粗 | ||
let fontWeight = isActive && activeStyle.fontWeight | ||
? activeStyle.fontWeight | ||
: (font.fontWeight || defaultStyle.fontWeight); | ||
let fontWeight = isActive && _activeStyle.fontWeight | ||
? _activeStyle.fontWeight | ||
: (font.fontWeight || _defaultStyle.fontWeight); | ||
// 字体大小 | ||
let size = isActive && activeStyle.fontSize | ||
? this.getLength(activeStyle.fontSize) | ||
: this.getLength(font.fontSize || defaultStyle.fontSize); | ||
let size = isActive && _activeStyle.fontSize | ||
? this.getLength(_activeStyle.fontSize) | ||
: this.getLength(font.fontSize || _defaultStyle.fontSize); | ||
// 字体行高 | ||
const lineHeight = isActive && activeStyle.lineHeight | ||
? activeStyle.lineHeight | ||
: font.lineHeight || defaultStyle.lineHeight || font.fontSize || defaultStyle.fontSize; | ||
const lineHeight = isActive && _activeStyle.lineHeight | ||
? _activeStyle.lineHeight | ||
: font.lineHeight || _defaultStyle.lineHeight || font.fontSize || _defaultStyle.fontSize; | ||
ctx.font = `${fontWeight} ${size * dpr}px ${style}`; | ||
ctx.fillStyle = (isActive && activeStyle.fontColor) ? activeStyle.fontColor : (font.fontColor || defaultStyle.fontColor); | ||
ctx.fillStyle = (isActive && _activeStyle.fontColor) ? _activeStyle.fontColor : (font.fontColor || _defaultStyle.fontColor); | ||
let lines = [], text = String(font.text); | ||
// 计算文字换行 | ||
if (font.hasOwnProperty('wordWrap') ? font.wordWrap : defaultStyle.wordWrap) { | ||
if (font.hasOwnProperty('wordWrap') ? font.wordWrap : _defaultStyle.wordWrap) { | ||
text = removeEnter(text); | ||
@@ -1115,3 +1378,3 @@ let str = ''; | ||
let currWidth = ctx.measureText(str).width; | ||
let maxWidth = this.getWidth(font.lengthLimit || defaultStyle.lengthLimit, prize.col); | ||
let maxWidth = this.getWidth(font.lengthLimit || _defaultStyle.lengthLimit, prize.col); | ||
if (currWidth > maxWidth) { | ||
@@ -1146,4 +1409,4 @@ lines.push(str.slice(0, -1)); | ||
handleBackground(x, y, width, height, background, isActive = false) { | ||
const { ctx, defaultStyle, activeStyle } = this; | ||
background = isActive ? activeStyle.background : (background || defaultStyle.background); | ||
const { ctx, _defaultStyle, _activeStyle } = this; | ||
background = isActive ? _activeStyle.background : (background || _defaultStyle.background); | ||
// 处理线性渐变 | ||
@@ -1179,6 +1442,6 @@ if (background.includes('linear-gradient')) { | ||
run(num = 0) { | ||
const { currIndex, prizes, prizeFlag, startTime, defaultConfig } = this; | ||
const { currIndex, prizes, prizeFlag, startTime, _defaultConfig } = this; | ||
let interval = Date.now() - startTime; | ||
// 先完全旋转, 再停止 | ||
if (interval >= defaultConfig.accelerationTime && prizeFlag !== undefined) { | ||
if (interval >= _defaultConfig.accelerationTime && prizeFlag !== undefined) { | ||
// 记录帧率 | ||
@@ -1195,3 +1458,3 @@ this.FPS = interval / num; | ||
} | ||
this.currIndex = (currIndex + quad.easeIn(interval, 0.1, defaultConfig.speed, defaultConfig.accelerationTime)) % prizes.length; | ||
this.currIndex = (currIndex + quad.easeIn(interval, 0.1, _defaultConfig.speed, _defaultConfig.accelerationTime)) % prizes.length; | ||
this.draw(); | ||
@@ -1204,5 +1467,5 @@ this.animationId = window.requestAnimationFrame(this.run.bind(this, num + 1)); | ||
slowDown() { | ||
const { prizes, prizeFlag, stopIndex, endIndex, defaultConfig } = this; | ||
const { prizes, prizeFlag, stopIndex, endIndex, _defaultConfig } = this; | ||
let interval = Date.now() - this.endTime; | ||
if (interval > defaultConfig.decelerationTime) { | ||
if (interval > _defaultConfig.decelerationTime) { | ||
this.startTime = 0; | ||
@@ -1212,3 +1475,3 @@ this.endCallback?.({ ...prizes.find((prize, index) => index === prizeFlag) }); | ||
} | ||
this.currIndex = quad.easeOut(interval, stopIndex, endIndex, defaultConfig.decelerationTime) % prizes.length; | ||
this.currIndex = quad.easeOut(interval, stopIndex, endIndex, _defaultConfig.decelerationTime) % prizes.length; | ||
this.draw(); | ||
@@ -1233,8 +1496,9 @@ this.animationId = window.requestAnimationFrame(this.slowDown.bind(this)); | ||
getGeometricProperty([x, y, col, row]) { | ||
const { defaultConfig, cellWidth, cellHeight } = this; | ||
const { cellWidth, cellHeight } = this; | ||
const gutter = this._defaultConfig.gutter; | ||
let res = [ | ||
this.prizeArea.x + (cellWidth + defaultConfig.gutter) * x, | ||
this.prizeArea.y + (cellHeight + defaultConfig.gutter) * y | ||
this.prizeArea.x + (cellWidth + gutter) * x, | ||
this.prizeArea.y + (cellHeight + gutter) * y | ||
]; | ||
col && row && res.push(cellWidth * col + defaultConfig.gutter * (col - 1), cellHeight * row + defaultConfig.gutter * (row - 1)); | ||
col && row && res.push(cellWidth * col + gutter * (col - 1), cellHeight * row + gutter * (row - 1)); | ||
return res; | ||
@@ -1264,3 +1528,3 @@ } | ||
if (isExpectType(width, 'string')) | ||
return this.changeUnits(width, { denominator: this.cellWidth * col + this.defaultConfig.gutter * (col - 1) }); | ||
return this.changeUnits(width, { denominator: this.cellWidth * col + this._defaultConfig.gutter * (col - 1) }); | ||
return 0; | ||
@@ -1278,3 +1542,3 @@ } | ||
if (isExpectType(height, 'string')) | ||
return this.changeUnits(height, { denominator: this.cellHeight * row + this.defaultConfig.gutter * (row - 1) }); | ||
return this.changeUnits(height, { denominator: this.cellHeight * row + this._defaultConfig.gutter * (row - 1) }); | ||
return 0; | ||
@@ -1288,3 +1552,3 @@ } | ||
getOffsetX(width, col = 1) { | ||
return (this.cellWidth * col + this.defaultConfig.gutter * (col - 1) - width) / 2; | ||
return (this.cellWidth * col + this._defaultConfig.gutter * (col - 1) - width) / 2; | ||
} | ||
@@ -1291,0 +1555,0 @@ } |
@@ -1,1 +0,1 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});class t{constructor(){this.htmlFontSize=16,this.dpr=1,this.setDpr(),this.setHTMLFontSize()}setDpr(){window.dpr=this.dpr=1.3*(window.devicePixelRatio||2)}setHTMLFontSize(){this.htmlFontSize=+getComputedStyle(document.documentElement).fontSize.slice(0,-2)}optimizeClarity(t,i,e){const{dpr:s}=this,h=t=>(t*s-t)/(t*s)*(s/2)*100;t.style.transform=`scale(${1/s}) translate(\n ${-h(i)}%, ${-h(e)}%\n )`}changeUnits(t,{denominator:i=1,clean:e=!1}){return Number(t.replace(/^(\-*[0-9.]*)([a-z%]*)$/,((t,s,h)=>{switch(h){case"%":s*=i/100;break;case"px":s*=1;break;case"rem":s*=this.htmlFontSize;break;default:s*=1}return e||"%"===h?s:s*this.dpr})))}observer(t){if("object"!=typeof t||null===t)return t;Object.keys(t).forEach((i=>{this.defineReactive(t,i,t[i])}))}defineReactive(t,i,e){this.observer(e),Object.defineProperty(t,i,{get:()=>(console.log("get",i),e),set(t){console.log("set",i,e),t!==e&&(e=t,this.observer(e))}})}}const i=(t,...i)=>i.some((i=>Object.prototype.toString.call(t).slice(8,-1).toLowerCase()===i)),e=t=>[].filter.call(t,(t=>"\n"!==t)).join(""),s=t=>Math.PI/180*t,h=(t,i)=>[+(Math.cos(t)*i).toFixed(8),+(Math.sin(t)*i).toFixed(8)],n=(t,i)=>{let e=-t/i;return[e,-e*t+i]},r=(t,i,e,a,o=!0)=>{if(Math.abs(a-e).toFixed(8)>=s(180).toFixed(8)){let s=(a+e)/2;return o?(r(t,i,e,s,o),r(t,i,s,a,o)):(r(t,i,s,a,o),r(t,i,e,s,o)),!1}o||([e,a]=[a,e]);const[l,d]=h(e,i),[c,g]=h(a,i),[f,u]=n(l,d),[m,p]=n(c,g);let b=(p-u)/(f-m),w=(m*u-f*p)/(m-f);isNaN(b)&&(Math.abs(l)===+i.toFixed(8)&&(b=l),Math.abs(c)===+i.toFixed(8)&&(b=c)),f===1/0||f===-1/0?w=m*b+p:m!==1/0&&m!==-1/0||(w=f*b+u),t.lineTo(l,d),t.arcTo(b,w,c,g,i)},a=(t,i,e,s,h,n,r)=>{let a=Math.min(s,h);n>a/2&&(n=a/2),t.beginPath(),t.fillStyle=r,t.moveTo(i+n,e),t.lineTo(i+n,e),t.lineTo(i+s-n,e),t.arcTo(i+s,e,i+s,e+n,n),t.lineTo(i+s,e+h-n),t.arcTo(i+s,e+h,i+s-n,e+h,n),t.lineTo(i+n,e+h),t.arcTo(i,e+h,i,e+h-n,n),t.lineTo(i,e+n),t.arcTo(i,e,i+n,e,n),t.closePath(),t.fill()},o=function(t,i,e,s){return t>=s&&(t=s),e*(t/=s)*t+i},l=function(t,i,e,s){return t>=s&&(t=s),-e*(t/=s)*(t-2)+i};exports.LuckyGrid=class extends t{constructor(t,i={}){super(),this.rows=3,this.cols=3,this.blocks=[],this.prizes=[],this.defaultConfig={gutter:5,speed:20,accelerationTime:2500,decelerationTime:2500},this.defaultStyle={borderRadius:20,fontColor:"#000",fontSize:"18px",fontStyle:"microsoft yahei ui,microsoft yahei,simsun,sans-serif",fontWeight:"400",background:"#fff",shadow:"",wordWrap:!0,lengthLimit:"90%"},this.activeStyle={background:"#ffce98",shadow:""},this.boxWidth=0,this.boxHeight=0,this.cellWidth=0,this.cellHeight=0,this.startTime=0,this.endTime=0,this.currIndex=0,this.stopIndex=0,this.endIndex=0,this.demo=!1,this.timer=0,this.animationId=0,this.FPS=16.6,this.cells=[],this.cellImgs=[],this.blockData=[],this.box=document.querySelector(t),this.canvas=document.createElement("canvas"),this.box.appendChild(this.canvas),this.ctx=this.canvas.getContext("2d"),this.setData(i);let e=[[]];this.prizes&&(e=this.prizes.map((t=>t.imgs))),this.button&&(e[this.cols*this.rows-1]=this.button.imgs),this.init(e)}setData(t){this.rows=Number(t.rows)||3,this.cols=Number(t.cols)||3,this.blocks=t.blocks||[],this.prizes=t.prizes||[],this.button=t.button,this.startCallback=t.start,this.endCallback=t.end;const i=this.defaultConfig,e=this.defaultStyle,s=this.activeStyle;for(let e in t.defaultConfig)i[e]=t.defaultConfig[e];i.gutter=this.getLength(i.gutter)*this.dpr,i.speed/=40;for(let i in t.defaultStyle)e[i]=t.defaultStyle[i];e.borderRadius=this.getLength(e.borderRadius)*this.dpr;for(let i in t.activeStyle)s[i]=t.activeStyle[i]}init(t){this.setDpr(),this.setHTMLFontSize();const{box:e,canvas:s,dpr:h,defaultStyle:n,defaultConfig:r}=this;if(!e)return;this.boxWidth=s.width=e.offsetWidth*h,this.boxHeight=s.height=e.offsetHeight*h,this.optimizeClarity(s,this.boxWidth,this.boxHeight),this.cells=[...this.prizes],this.button&&(this.cells[this.cols*this.rows-1]={...this.button}),this.cells.forEach((t=>{t.col=t.col||1,t.row=t.row||1})),this.blockData=[],this.prizeArea=this.blocks.reduce((({x:t,y:e,w:s,h:n},r)=>{const[a,o,l,d]=(t=>{let e=t.padding.replace(/px/g,"").split(" ").map((t=>~~t))||[0],s=0,h=0,n=0,r=0;switch(e.length){case 1:s=h=n=r=e[0];break;case 2:s=h=e[0],n=r=e[1];break;case 3:s=e[0],n=r=e[1],h=e[2];break;default:s=e[0],h=e[1],n=e[2],r=e[3]}const a={paddingTop:s,paddingBottom:h,paddingLeft:n,paddingRight:r};for(let e in a)a[e]=t.hasOwnProperty(e)&&i(t[e],"string","number")?~~String(t[e]).replace(/px/g,""):a[e];return[s,h,n,r]})(r).map((t=>t*h));return this.blockData.push([t,e,s,n,r.borderRadius?this.getLength(r.borderRadius)*h:0,r.background]),{x:t+l,y:e+a,w:s-l-d,h:n-a-o}}),{x:0,y:0,w:this.boxWidth,h:this.boxHeight}),this.cellWidth=(this.prizeArea.w-r.gutter*(this.cols-1))/this.cols,this.cellHeight=(this.prizeArea.h-r.gutter*(this.rows-1))/this.rows;const a=()=>{this.draw(),this.demo&&this.walk(),this.button&&(s.onclick=t=>{const[i,e,s,h]=this.getGeometricProperty([this.button.x,this.button.y,this.button.col||1,this.button.row||1]);if(t.offsetX<i||t.offsetY<e||t.offsetX>i+s||t.offsetY>e+h)return!1;this.startTime||this.startCallback?.(t)})};let o=0,l=0;i(t,"array")&&(this.draw(),t.forEach(((t,i)=>{if(!t)return!1;t.forEach(((t,e)=>{l++,this.loadAndCacheImg(i,e,(()=>{o++,l===o&&a.call(this)}))}))}))),l||a.call(this)}loadAndCacheImg(t,i,e){const s=this.cells[t];if(!s||!s.imgs)return;const h=s.imgs[i];this.cellImgs[t]||(this.cellImgs[t]=[]);let n=new Image;this.cellImgs[t][i]={defaultImg:n},n.src=h.src;let r=0,a=1;if(n.onload=()=>{r++,r===a&&e.call(this)},!h.hasOwnProperty("activeSrc"))return;a++;let o=new Image;this.cellImgs[t][i].activeImg=o,o.src=h.activeSrc,o.onload=()=>{r++,r===a&&e.call(this)}}computedWidthAndHeight(t,i,e){if(!i.width&&!i.height)return[t.width,t.height];if(i.width&&!i.height){let s=this.getWidth(i.width,e.col);return[s,t.height*(s/t.width)]}if(!i.width&&i.height){let s=this.getHeight(i.height,e.row);return[t.width*(s/t.height),s]}return[this.getWidth(i.width,e.col),this.getHeight(i.height,e.row)]}draw(){const{ctx:t,dpr:i,defaultStyle:s,activeStyle:h}=this;t.clearRect(0,0,this.boxWidth,this.boxWidth),this.blockData.forEach((([i,e,s,h,n,r])=>{a(t,i,e,s,h,n,this.handleBackground(i,e,s,h,r))})),this.cells.forEach(((n,r)=>{let[o,l,d,c]=this.getGeometricProperty([n.x,n.y,n.col,n.row]);const g=r===this.currIndex%this.prizes.length>>0,f=(g?h.shadow:n.shadow||s.shadow).replace(/px/g,"").split(",")[0].split(" ").map(((t,e)=>e<3?Number(t)*i:t));4===f.length&&(t.shadowColor=f[3],t.shadowOffsetX=f[0],t.shadowOffsetY=f[1],t.shadowBlur=f[2],f[0]>0?d-=f[0]:(d+=f[0],o-=f[0]),f[1]>0?c-=f[1]:(c+=f[1],l-=f[1])),a(t,o,l,d,c,n.borderRadius?this.getLength(n.borderRadius)*i:this.getLength(s.borderRadius),this.handleBackground(o,l,d,c,n.background,g)),t.shadowColor="rgba(255, 255, 255, 0)",t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=0,n.imgs&&n.imgs.forEach(((i,e)=>{if(!this.cellImgs[r])return!1;const s=this.cellImgs[r][e];if(!s)return!1;const h=g&&s.activeImg||s.defaultImg,[a,d]=this.computedWidthAndHeight(h,i,n);t.drawImage(h,o+this.getOffsetX(a,n.col),l+this.getHeight(i.top,n.row),a,d)})),n.fonts&&n.fonts.forEach((r=>{let a=g&&h.fontStyle?h.fontStyle:r.fontStyle||s.fontStyle,d=g&&h.fontWeight?h.fontWeight:r.fontWeight||s.fontWeight,c=g&&h.fontSize?this.getLength(h.fontSize):this.getLength(r.fontSize||s.fontSize);const f=g&&h.lineHeight?h.lineHeight:r.lineHeight||s.lineHeight||r.fontSize||s.fontSize;t.font=`${d} ${c*i}px ${a}`,t.fillStyle=g&&h.fontColor?h.fontColor:r.fontColor||s.fontColor;let u=[],m=String(r.text);if(r.hasOwnProperty("wordWrap")?r.wordWrap:s.wordWrap){m=e(m);let i="";for(let e=0;e<m.length;e++){i+=m[e],t.measureText(i).width>this.getWidth(r.lengthLimit||s.lengthLimit,n.col)&&(u.push(i.slice(0,-1)),i=m[e])}i&&u.push(i),u.length||u.push(m)}else u=m.split("\n");u.forEach(((e,s)=>{t.fillText(e,o+this.getOffsetX(t.measureText(e).width,n.col),l+this.getHeight(r.top,n.row)+(s+1)*this.getLength(f)*i)}))}))}))}handleBackground(t,i,e,s,h,n=!1){const{ctx:r,defaultStyle:a,activeStyle:o}=this;return(h=n?o.background:h||a.background).includes("linear-gradient")&&(h=((t,i,e,s,h,n)=>{const r=/linear-gradient\((.+)\)/.exec(n)[1].split(",").map((t=>t.trim()));let a=r.shift(),o=[0,0,0,0];if(a.includes("deg")){a=a.slice(0,-3)%360;const t=t=>Math.tan(t/180*Math.PI);a>=0&&a<45?o=[i,e+h,i+s,e+h-s*t(a-0)]:a>=45&&a<90?o=[i,e+h,i+s-h*t(a-45),e]:a>=90&&a<135?o=[i+s,e+h,i+s-h*t(a-90),e]:a>=135&&a<180?o=[i+s,e+h,i,e+s*t(a-135)]:a>=180&&a<225?o=[i+s,e,i,e+s*t(a-180)]:a>=225&&a<270?o=[i+s,e,i+h*t(a-225),e+h]:a>=270&&a<315?o=[i,e,i+h*t(a-270),e+h]:a>=315&&a<360&&(o=[i,e,i+s,e+h-s*t(a-315)])}else a.includes("top")?o=[i,e+h,i,e]:a.includes("bottom")?o=[i,e,i,e+h]:a.includes("left")?o=[i+s,e,i,e]:a.includes("right")&&(o=[i,e,i+s,e]);const l=t.createLinearGradient(...o.map((t=>t>>0)));return r.reduce(((t,i,e)=>{const s=i.split(" ");return 1===s.length?t.addColorStop(e,s[0]):2===s.length&&t.addColorStop(...s),t}),l)})(r,t,i,e,s,h)),h}play(){this.startTime||(clearInterval(this.timer),cancelAnimationFrame(this.animationId),this.startTime=Date.now(),this.prizeFlag=void 0,this.run())}stop(t){this.prizeFlag=t%this.prizes.length}run(t=0){const{currIndex:i,prizes:e,prizeFlag:s,startTime:h,defaultConfig:n}=this;let r=Date.now()-h;if(r>=n.accelerationTime&&void 0!==s)return this.FPS=r/t,this.endTime=Date.now(),this.stopIndex=i,this.endIndex=5*e.length+s-(i>>0),cancelAnimationFrame(this.animationId),this.slowDown();this.currIndex=(i+o(r,.1,n.speed,n.accelerationTime))%e.length,this.draw(),this.animationId=window.requestAnimationFrame(this.run.bind(this,t+1))}slowDown(){const{prizes:t,prizeFlag:i,stopIndex:e,endIndex:s,defaultConfig:h}=this;let n=Date.now()-this.endTime;if(n>h.decelerationTime)return this.startTime=0,this.endCallback?.({...t.find(((t,e)=>e===i))}),cancelAnimationFrame(this.animationId);this.currIndex=l(n,e,s,h.decelerationTime)%t.length,this.draw(),this.animationId=window.requestAnimationFrame(this.slowDown.bind(this))}walk(){clearInterval(this.timer),this.timer=window.setInterval((()=>{this.currIndex+=1,this.draw()}),1300)}getGeometricProperty([t,i,e,s]){const{defaultConfig:h,cellWidth:n,cellHeight:r}=this;let a=[this.prizeArea.x+(n+h.gutter)*t,this.prizeArea.y+(r+h.gutter)*i];return e&&s&&a.push(n*e+h.gutter*(e-1),r*s+h.gutter*(s-1)),a}getLength(t){return i(t,"number")?t:i(t,"string")?this.changeUnits(t,{clean:!0}):0}getWidth(t,e=1){return i(t,"number")?t*this.dpr:i(t,"string")?this.changeUnits(t,{denominator:this.cellWidth*e+this.defaultConfig.gutter*(e-1)}):0}getHeight(t,e=1){return i(t,"number")?t*this.dpr:i(t,"string")?this.changeUnits(t,{denominator:this.cellHeight*e+this.defaultConfig.gutter*(e-1)}):0}getOffsetX(t,i=1){return(this.cellWidth*i+this.defaultConfig.gutter*(i-1)-t)/2}},exports.LuckyWheel=class extends t{constructor(t,i={}){super(),this.blocks=[],this.prizes=[],this.buttons=[],this.defaultConfig={gutter:"0px",offsetDegree:0,speed:20,accelerationTime:2500,decelerationTime:2500},this.defaultStyle={fontSize:"18px",fontColor:"#000",fontStyle:"microsoft yahei ui,microsoft yahei,simsun,sans-serif",fontWeight:"400",background:"#fff",wordWrap:!0,lengthLimit:"90%"},this.Radius=0,this.prizeRadius=0,this.prizeDeg=0,this.prizeRadian=0,this.rotateDeg=0,this.maxBtnRadius=0,this.startTime=0,this.endTime=0,this.stopDeg=0,this.endDeg=0,this.animationId=0,this.FPS=16.6,this.prizeImgs=[[]],this.btnImgs=[[]],this.box=document.querySelector(t),this.canvas=document.createElement("canvas"),this.box.appendChild(this.canvas),this.ctx=this.canvas.getContext("2d"),this.setData(i);let e=[[]];this.prizes&&(e=this.prizes.map((t=>t.imgs))),this.buttons&&e.push(...this.buttons.map((t=>t.imgs))),this.init(e)}setData(t){this.blocks=t.blocks||[],this.prizes=t.prizes||[],this.buttons=t.buttons||[],this.startCallback=t.start,this.endCallback=t.end;for(let i in t.defaultConfig)this.defaultConfig[i]=t.defaultConfig[i];for(let i in t.defaultStyle)this.defaultStyle[i]=t.defaultStyle[i]}init(t){this.setDpr(),this.setHTMLFontSize();const{box:e,canvas:s,ctx:h,dpr:n}=this;if(!e)return;s.width=s.height=e.offsetWidth*n,this.Radius=s.width/2,this.optimizeClarity(s,2*this.Radius,2*this.Radius),h.translate(this.Radius,this.Radius);const r=()=>{this.draw(),s.onclick=t=>{h.beginPath(),h.arc(0,0,this.maxBtnRadius,0,2*Math.PI,!1),h.isPointInPath(t.offsetX,t.offsetY)&&(this.startTime||this.startCallback?.(t))}};let a=0,o=0;i(t,"array")&&(this.draw(),t.forEach(((t,i)=>{if(!t)return!1;t.forEach(((t,e)=>{o++,this.loadAndCacheImg(i,e,(()=>{a++,o===a&&r.call(this)}))}))}))),o||r.call(this)}loadAndCacheImg(t,i,e){const s=t<this.prizes.length,h=s?"prizes":"buttons",n=s?"prizeImgs":"btnImgs";t=s?t:t-this.prizes.length;const r=this[h][t];if(!r||!r.imgs)return;const a=r.imgs[i];if(!a)return;let o=new Image;this[n][t]||(this[n][t]=[]),this[n][t][i]=o,o.src=a.src,o.onload=()=>e.call(this)}computedWidthAndHeight(t,i,e,s){if(!i.width&&!i.height)return[t.width,t.height];if(i.width&&!i.height){let s=this.getWidth(i.width,e);return[s,t.height*(s/t.width)]}if(!i.width&&i.height){let e=this.getHeight(i.height,s);return[t.width*(e/t.height),e]}return[this.getWidth(i.width,e),this.getHeight(i.height,s)]}draw(){const{ctx:t,dpr:i,defaultConfig:n,defaultStyle:a}=this;t.clearRect(-this.Radius,-this.Radius,2*this.Radius,2*this.Radius),this.prizeRadius=this.blocks.reduce(((e,s)=>(t.beginPath(),t.fillStyle=s.background,t.arc(0,0,e,0,2*Math.PI,!1),t.fill(),e-this.getLength(s.padding.split(" ")[0])*i)),this.Radius),this.prizeDeg=360/this.prizes.length,this.prizeRadian=s(this.prizeDeg);let o=s(-90+this.rotateDeg+n.offsetDegree);const l=i=>this.getOffsetX(t.measureText(i).width),d=(t,e,s)=>{const h=t.lineHeight||a.lineHeight||t.fontSize||a.fontSize;return this.getHeight(t.top,e)+(s+1)*this.getLength(h)*i};t.save(),this.prizes.forEach(((c,g)=>{let f=o+g*this.prizeRadian,u=this.prizeRadius-this.maxBtnRadius;((t,i,e,n,a,o,l)=>{i||(i=o);let d=s(90/Math.PI/e*o),c=s(90/Math.PI/i*o),g=n+d,f=a-d,u=n+c,m=a-c;t.beginPath(),t.fillStyle=l,t.moveTo(...h(g,e)),r(t,e,g,f,!0),m>u?r(t,i,u,m,!1):t.lineTo(...h((n+a)/2,o/2/Math.abs(Math.sin((n-a)/2)))),t.closePath(),t.fill()})(t,this.maxBtnRadius,this.prizeRadius,f-this.prizeRadian/2,f+this.prizeRadian/2,this.getLength(n.gutter)*i,c.background||a.background||"rgba(0, 0, 0, 0)");let m=Math.cos(f)*this.prizeRadius,p=Math.sin(f)*this.prizeRadius;t.translate(m,p),t.rotate(f+s(90)),c.imgs&&c.imgs.forEach(((i,e)=>{if(!this.prizeImgs[g])return;const s=this.prizeImgs[g][e];if(!s)return;const[h,n]=this.computedWidthAndHeight(s,i,this.prizeRadian*this.prizeRadius,u);t.drawImage(s,this.getOffsetX(h),this.getHeight(i.top,u),h,n)})),c.fonts&&c.fonts.forEach((s=>{let h=s.fontColor||a.fontColor,r=s.fontWeight||a.fontWeight,o=this.getLength(s.fontSize||a.fontSize),c=s.fontStyle||a.fontStyle;t.fillStyle=h,t.font=`${r} ${o*i}px ${c}`;let g=[],f=String(s.text);if(s.hasOwnProperty("wordWrap")?s.wordWrap:a.wordWrap){f=e(f);let h="";for(let e=0;e<f.length;e++){h+=f[e];let r=t.measureText(h).width,o=(this.prizeRadius-d(s,u,g.length))*Math.tan(this.prizeRadian/2)*2-this.getLength(n.gutter)*i;r>this.getWidth(s.lengthLimit||a.lengthLimit,o)&&(g.push(h.slice(0,-1)),h=f[e])}h&&g.push(h),g.length||g.push(f)}else g=f.split("\n");g.filter((t=>!!t)).forEach(((i,e)=>{t.fillText(i,l(i),d(s,u,e))}))})),t.rotate(s(360)-f-s(90)),t.translate(-m,-p)})),t.restore(),this.buttons.forEach(((e,s)=>{let h=this.getHeight(e.radius);this.maxBtnRadius=Math.max(this.maxBtnRadius,h),t.beginPath(),t.fillStyle=e.background||"rgba(0, 0, 0, 0)",t.arc(0,0,h,0,2*Math.PI,!1),t.fill(),e.pointer&&(t.beginPath(),t.fillStyle=e.background||"rgba(0, 0, 0, 0)",t.moveTo(-h,0),t.lineTo(h,0),t.lineTo(0,2*-h),t.closePath(),t.fill()),e.imgs&&e.imgs.forEach(((i,n)=>{if(!this.btnImgs[s])return;const r=this.btnImgs[s][n];if(!r)return;const[a,o]=this.computedWidthAndHeight(r,i,2*this.getHeight(e.radius),2*this.getHeight(e.radius));t.drawImage(r,this.getOffsetX(a),this.getHeight(i.top,h),a,o)})),e.fonts&&e.fonts.forEach((e=>{let s=e.fontColor||a.fontColor,n=e.fontWeight||a.fontWeight,r=this.getLength(e.fontSize||a.fontSize),o=e.fontStyle||a.fontStyle;t.fillStyle=s,t.font=`${n} ${r*i}px ${o}`,String(e.text).split("\n").forEach(((i,s)=>{t.fillText(i,l(i),d(e,h,s))}))}))}))}play(){this.startTime||(cancelAnimationFrame(this.animationId),this.startTime=Date.now(),this.prizeFlag=void 0,this.run())}stop(t){this.prizeFlag=Number(t)%this.prizes.length}run(t=0){const{prizeFlag:i,prizeDeg:e,rotateDeg:s,defaultConfig:h}=this;let n=Date.now()-this.startTime;if(n>=h.accelerationTime&&void 0!==i)return this.FPS=n/t,this.endTime=Date.now(),this.stopDeg=s,this.endDeg=1800-i*e-s-h.offsetDegree,cancelAnimationFrame(this.animationId),this.slowDown();this.rotateDeg=(s+o(n,0,h.speed,h.accelerationTime))%360,this.draw(),this.animationId=window.requestAnimationFrame(this.run.bind(this,t+1))}slowDown(){const{prizes:t,prizeFlag:i,stopDeg:e,endDeg:s,defaultConfig:h}=this;let n=Date.now()-this.endTime;if(n>=h.decelerationTime)return this.startTime=0,this.endCallback?.({...t.find(((t,e)=>e===i))}),cancelAnimationFrame(this.animationId);this.rotateDeg=l(n,e,s,h.decelerationTime)%360,this.draw(),this.animationId=window.requestAnimationFrame(this.slowDown.bind(this))}getLength(t){return i(t,"number")?t:i(t,"string")?this.changeUnits(t,{clean:!0}):0}getWidth(t,e=this.prizeRadian*this.prizeRadius){return i(t,"number")?t*this.dpr:i(t,"string")?this.changeUnits(t,{denominator:e}):0}getHeight(t,e=this.prizeRadius){return i(t,"number")?t*this.dpr:i(t,"string")?this.changeUnits(t,{denominator:e}):0}getOffsetX(t){return-t/2}}; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});class t{constructor(){this.htmlFontSize=16,this.dpr=1,this.subs={},this.setDpr(),this.setHTMLFontSize(),this.resetArrayPropo()}setDpr(){window.dpr=this.dpr=1.3*(window.devicePixelRatio||2)}setHTMLFontSize(){this.htmlFontSize=+getComputedStyle(document.documentElement).fontSize.slice(0,-2)}optimizeClarity(t,i,e){const{dpr:s}=this,h=t=>(t*s-t)/(t*s)*(s/2)*100;t.style.transform=`scale(${1/s}) translate(\n ${-h(i)}%, ${-h(e)}%\n )`}changeUnits(t,{denominator:i=1,clean:e=!1}){return Number(t.replace(/^(\-*[0-9.]*)([a-z%]*)$/,((t,s,h)=>{switch(h){case"%":s*=i/100;break;case"px":s*=1;break;case"rem":s*=this.htmlFontSize;break;default:s*=1}return e||"%"===h?s:s*this.dpr})))}draw(){}observer(t){t&&"object"==typeof t&&Object.keys(t).forEach((i=>{this.defineReactive(t,i,t[i])}))}defineReactive(t,i,e){this.observer(e),Object.defineProperty(t,i,{get:()=>e,set:t=>{let s=e;t!==e&&(e=t,this.observer(e),this.subs[i]&&this.subs[i].call(this,e,s),this.draw())}})}$set(t,i,e){t&&"object"==typeof t&&this.defineReactive(t,i,e)}$computed(t,i,e){Object.defineProperty(t,i,{get:()=>e.call(this)})}$watch(t,i){this.subs[t]=i}resetArrayPropo(){const t=this,i=Array.prototype,e=Object.create(i);["push","pop","shift","unshift","sort","splice","reverse"].forEach((s=>{e[s]=function(){t.draw(),i[s].call(this,...arguments)}}))}}const i=(t,...i)=>i.some((i=>Object.prototype.toString.call(t).slice(8,-1).toLowerCase()===i)),e=t=>[].filter.call(t,(t=>"\n"!==t)).join(""),s=t=>Math.PI/180*t,h=(t,i)=>[+(Math.cos(t)*i).toFixed(8),+(Math.sin(t)*i).toFixed(8)],n=(t,i)=>{let e=-t/i;return[e,-e*t+i]},r=(t,i,e,o,a=!0)=>{if(Math.abs(o-e).toFixed(8)>=s(180).toFixed(8)){let s=(o+e)/2;return a?(r(t,i,e,s,a),r(t,i,s,o,a)):(r(t,i,s,o,a),r(t,i,e,s,a)),!1}a||([e,o]=[o,e]);const[l,d]=h(e,i),[c,g]=h(o,i),[f,u]=n(l,d),[m,p]=n(c,g);let w=(p-u)/(f-m),b=(m*u-f*p)/(m-f);isNaN(w)&&(Math.abs(l)===+i.toFixed(8)&&(w=l),Math.abs(c)===+i.toFixed(8)&&(w=c)),f===1/0||f===-1/0?b=m*w+p:m!==1/0&&m!==-1/0||(b=f*w+u),t.lineTo(l,d),t.arcTo(w,b,c,g,i)},o=(t,i,e,s,h,n,r)=>{let o=Math.min(s,h);n>o/2&&(n=o/2),t.beginPath(),t.fillStyle=r,t.moveTo(i+n,e),t.lineTo(i+n,e),t.lineTo(i+s-n,e),t.arcTo(i+s,e,i+s,e+n,n),t.lineTo(i+s,e+h-n),t.arcTo(i+s,e+h,i+s-n,e+h,n),t.lineTo(i+n,e+h),t.arcTo(i,e+h,i,e+h-n,n),t.lineTo(i,e+n),t.arcTo(i,e,i+n,e,n),t.closePath(),t.fill()},a=function(t,i,e,s){return t>=s&&(t=s),e*(t/=s)*t+i},l=function(t,i,e,s){return t>=s&&(t=s),-e*(t/=s)*(t-2)+i};exports.LuckyGrid=class extends t{constructor(t,i={}){super(),this.rows=3,this.cols=3,this.blocks=[],this.prizes=[],this.defaultConfig={},this._defaultConfig={gutter:5,speed:20,accelerationTime:2500,decelerationTime:2500},this.defaultStyle={},this._defaultStyle={borderRadius:20,fontColor:"#000",fontSize:"18px",fontStyle:"microsoft yahei ui,microsoft yahei,simsun,sans-serif",fontWeight:"400",lineHeight:"",background:"#fff",shadow:"",wordWrap:!0,lengthLimit:"90%"},this.activeStyle={},this._activeStyle={background:"#ffce98",shadow:"",fontStyle:"",fontWeight:"",fontSize:"",lineHeight:"",fontColor:""},this.boxWidth=0,this.boxHeight=0,this.cellWidth=0,this.cellHeight=0,this.startTime=0,this.endTime=0,this.currIndex=0,this.stopIndex=0,this.endIndex=0,this.demo=!1,this.timer=0,this.animationId=0,this.FPS=16.6,this.cells=[],this.cellImgs=[],this.box=document.querySelector(t),this.canvas=document.createElement("canvas"),this.box.appendChild(this.canvas),this.ctx=this.canvas.getContext("2d"),this.initData(i),this.initComputed(),this.initWatch();let e=[[]];this.prizes&&(e=this.prizes.map((t=>t.imgs))),this.button&&(e[this.cols*this.rows-1]=this.button.imgs),this.init(e)}initData(t){this.$set(this,"rows",Number(t.rows)||3),this.$set(this,"cols",Number(t.cols)||3),this.$set(this,"blocks",t.blocks||[]),this.$set(this,"prizes",t.prizes||[]),this.$set(this,"button",t.button),this.$set(this,"defaultConfig",t.defaultConfig||{}),this.$set(this,"defaultStyle",t.defaultStyle||{}),this.$set(this,"activeStyle",t.activeStyle||{}),this.$set(this,"startCallback",t.start),this.$set(this,"endCallback",t.end)}initComputed(){this.$computed(this,"_defaultConfig",(()=>{const t={gutter:5,speed:20,accelerationTime:2500,decelerationTime:2500,...this.defaultConfig};return t.gutter=this.getLength(t.gutter)*this.dpr,t.speed=t.speed/40,t})),this.$computed(this,"_defaultStyle",(()=>({borderRadius:20,fontColor:"#000",fontSize:"18px",fontStyle:"microsoft yahei ui,microsoft yahei,simsun,sans-serif",fontWeight:"400",background:"#fff",shadow:"",wordWrap:!0,lengthLimit:"90%",...this.defaultStyle}))),this.$computed(this,"_activeStyle",(()=>({background:"#ffce98",shadow:"",...this.activeStyle})))}initWatch(){this.$watch("prizes",((t,i)=>{let e=[];return i?t&&t.forEach(((t,s)=>{let h=[];const n=i[s];n?t.imgs&&t.imgs.forEach(((t,i)=>{if(!n.imgs)return h[i]=t;const e=n.imgs[i];e&&this.cellImgs[s][i]?t.src!==e.src&&(h[i]=t):h[i]=t})):h=t.imgs||[],e[s]=h})):e=t.map((t=>t.imgs)),this.init(e)})),this.$watch("button",((t,i)=>{let e=[],s=this.cols*this.rows-1;if(i&&i.imgs){if(t.imgs){const h=[];t.imgs.forEach(((t,e)=>{if(!i.imgs)return h[e]=t;const n=i.imgs[e];n&&this.cellImgs[s][e]?t.src!==n.src&&(h[e]=t):h[e]=t})),e[s]=h}}else e[s]=t.imgs;return this.init(e)}))}init(t){this.setDpr(),this.setHTMLFontSize();const{box:e,canvas:s,dpr:h}=this;if(!e)return;this.boxWidth=s.width=e.offsetWidth*h,this.boxHeight=s.height=e.offsetHeight*h,this.optimizeClarity(s,this.boxWidth,this.boxHeight);const n=()=>{this.draw(),this.demo&&this.walk(),this.button&&(s.onclick=t=>{const[i,e,s,h]=this.getGeometricProperty([this.button.x,this.button.y,this.button.col||1,this.button.row||1]);if(t.offsetX<i||t.offsetY<e||t.offsetX>i+s||t.offsetY>e+h)return!1;this.startTime||this.startCallback?.(t)})};let r=0,o=0;i(t,"array")&&(this.draw(),t.forEach(((t,i)=>{if(!t)return!1;t.forEach(((t,e)=>{o++,this.loadAndCacheImg(i,e,(()=>{r++,o===r&&n.call(this)}))}))}))),o||n.call(this)}loadAndCacheImg(t,i,e){const s=this.cells[t];if(!s||!s.imgs)return;const h=s.imgs[i];this.cellImgs[t]||(this.cellImgs[t]=[]);let n=new Image;this.cellImgs[t][i]={defaultImg:n},n.src=h.src;let r=0,o=1;if(n.onload=()=>{r++,r===o&&e.call(this)},!h.hasOwnProperty("activeSrc"))return;o++;let a=new Image;this.cellImgs[t][i].activeImg=a,a.src=h.activeSrc,a.onload=()=>{r++,r===o&&e.call(this)}}computedWidthAndHeight(t,i,e){if(!i.width&&!i.height)return[t.width,t.height];if(i.width&&!i.height){let s=this.getWidth(i.width,e.col);return[s,t.height*(s/t.width)]}if(!i.width&&i.height){let s=this.getHeight(i.height,e.row);return[t.width*(s/t.height),s]}return[this.getWidth(i.width,e.col),this.getHeight(i.height,e.row)]}draw(){const{ctx:t,dpr:s,_defaultConfig:h,_defaultStyle:n,_activeStyle:r}=this;t.clearRect(0,0,this.boxWidth,this.boxWidth),this.cells=[...this.prizes],this.button&&(this.cells[this.cols*this.rows-1]=this.button),this.cells.forEach((t=>{t.col=t.col||1,t.row=t.row||1})),this.prizeArea=this.blocks.reduce((({x:e,y:h,w:n,h:r},a)=>{const[l,d,c,g]=(t=>{let e=t.padding.replace(/px/g,"").split(" ").map((t=>~~t))||[0],s=0,h=0,n=0,r=0;switch(e.length){case 1:s=h=n=r=e[0];break;case 2:s=h=e[0],n=r=e[1];break;case 3:s=e[0],n=r=e[1],h=e[2];break;default:s=e[0],h=e[1],n=e[2],r=e[3]}const o={paddingTop:s,paddingBottom:h,paddingLeft:n,paddingRight:r};for(let e in o)o[e]=t.hasOwnProperty(e)&&i(t[e],"string","number")?~~String(t[e]).replace(/px/g,""):o[e];return[s,h,n,r]})(a).map((t=>t*s)),f=a.borderRadius?this.getLength(a.borderRadius)*s:0;return o(t,e,h,n,r,f,this.handleBackground(e,h,n,r,a.background)),{x:e+c,y:h+l,w:n-c-g,h:r-l-d}}),{x:0,y:0,w:this.boxWidth,h:this.boxHeight}),this.cellWidth=(this.prizeArea.w-h.gutter*(this.cols-1))/this.cols,this.cellHeight=(this.prizeArea.h-h.gutter*(this.rows-1))/this.rows,this.cells.forEach(((i,h)=>{let[a,l,d,c]=this.getGeometricProperty([i.x,i.y,i.col,i.row]);const g=h===this.currIndex%this.prizes.length>>0,f=(g?r.shadow:i.shadow||n.shadow).replace(/px/g,"").split(",")[0].split(" ").map(((t,i)=>i<3?Number(t)*s:t));4===f.length&&(t.shadowColor=f[3],t.shadowOffsetX=f[0],t.shadowOffsetY=f[1],t.shadowBlur=f[2],f[0]>0?d-=f[0]:(d+=f[0],a-=f[0]),f[1]>0?c-=f[1]:(c+=f[1],l-=f[1])),o(t,a,l,d,c,this.getLength(i.borderRadius?i.borderRadius:n.borderRadius)*s,this.handleBackground(a,l,d,c,i.background,g)),t.shadowColor="rgba(255, 255, 255, 0)",t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=0,i.imgs&&i.imgs.forEach(((e,s)=>{if(!this.cellImgs[h])return!1;const n=this.cellImgs[h][s];if(!n)return!1;const r=g&&n.activeImg||n.defaultImg,[o,d]=this.computedWidthAndHeight(r,e,i);t.drawImage(r,a+this.getOffsetX(o,i.col),l+this.getHeight(e.top,i.row),o,d)})),i.fonts&&i.fonts.forEach((h=>{let o=g&&r.fontStyle?r.fontStyle:h.fontStyle||n.fontStyle,d=g&&r.fontWeight?r.fontWeight:h.fontWeight||n.fontWeight,c=g&&r.fontSize?this.getLength(r.fontSize):this.getLength(h.fontSize||n.fontSize);const f=g&&r.lineHeight?r.lineHeight:h.lineHeight||n.lineHeight||h.fontSize||n.fontSize;t.font=`${d} ${c*s}px ${o}`,t.fillStyle=g&&r.fontColor?r.fontColor:h.fontColor||n.fontColor;let u=[],m=String(h.text);if(h.hasOwnProperty("wordWrap")?h.wordWrap:n.wordWrap){m=e(m);let s="";for(let e=0;e<m.length;e++){s+=m[e],t.measureText(s).width>this.getWidth(h.lengthLimit||n.lengthLimit,i.col)&&(u.push(s.slice(0,-1)),s=m[e])}s&&u.push(s),u.length||u.push(m)}else u=m.split("\n");u.forEach(((e,n)=>{t.fillText(e,a+this.getOffsetX(t.measureText(e).width,i.col),l+this.getHeight(h.top,i.row)+(n+1)*this.getLength(f)*s)}))}))}))}handleBackground(t,i,e,s,h,n=!1){const{ctx:r,_defaultStyle:o,_activeStyle:a}=this;return(h=n?a.background:h||o.background).includes("linear-gradient")&&(h=((t,i,e,s,h,n)=>{const r=/linear-gradient\((.+)\)/.exec(n)[1].split(",").map((t=>t.trim()));let o=r.shift(),a=[0,0,0,0];if(o.includes("deg")){o=o.slice(0,-3)%360;const t=t=>Math.tan(t/180*Math.PI);o>=0&&o<45?a=[i,e+h,i+s,e+h-s*t(o-0)]:o>=45&&o<90?a=[i,e+h,i+s-h*t(o-45),e]:o>=90&&o<135?a=[i+s,e+h,i+s-h*t(o-90),e]:o>=135&&o<180?a=[i+s,e+h,i,e+s*t(o-135)]:o>=180&&o<225?a=[i+s,e,i,e+s*t(o-180)]:o>=225&&o<270?a=[i+s,e,i+h*t(o-225),e+h]:o>=270&&o<315?a=[i,e,i+h*t(o-270),e+h]:o>=315&&o<360&&(a=[i,e,i+s,e+h-s*t(o-315)])}else o.includes("top")?a=[i,e+h,i,e]:o.includes("bottom")?a=[i,e,i,e+h]:o.includes("left")?a=[i+s,e,i,e]:o.includes("right")&&(a=[i,e,i+s,e]);const l=t.createLinearGradient(...a.map((t=>t>>0)));return r.reduce(((t,i,e)=>{const s=i.split(" ");return 1===s.length?t.addColorStop(e,s[0]):2===s.length&&t.addColorStop(...s),t}),l)})(r,t,i,e,s,h)),h}play(){this.startTime||(clearInterval(this.timer),cancelAnimationFrame(this.animationId),this.startTime=Date.now(),this.prizeFlag=void 0,this.run())}stop(t){this.prizeFlag=t%this.prizes.length}run(t=0){const{currIndex:i,prizes:e,prizeFlag:s,startTime:h,_defaultConfig:n}=this;let r=Date.now()-h;if(r>=n.accelerationTime&&void 0!==s)return this.FPS=r/t,this.endTime=Date.now(),this.stopIndex=i,this.endIndex=5*e.length+s-(i>>0),cancelAnimationFrame(this.animationId),this.slowDown();this.currIndex=(i+a(r,.1,n.speed,n.accelerationTime))%e.length,this.draw(),this.animationId=window.requestAnimationFrame(this.run.bind(this,t+1))}slowDown(){const{prizes:t,prizeFlag:i,stopIndex:e,endIndex:s,_defaultConfig:h}=this;let n=Date.now()-this.endTime;if(n>h.decelerationTime)return this.startTime=0,this.endCallback?.({...t.find(((t,e)=>e===i))}),cancelAnimationFrame(this.animationId);this.currIndex=l(n,e,s,h.decelerationTime)%t.length,this.draw(),this.animationId=window.requestAnimationFrame(this.slowDown.bind(this))}walk(){clearInterval(this.timer),this.timer=window.setInterval((()=>{this.currIndex+=1,this.draw()}),1300)}getGeometricProperty([t,i,e,s]){const{cellWidth:h,cellHeight:n}=this,r=this._defaultConfig.gutter;let o=[this.prizeArea.x+(h+r)*t,this.prizeArea.y+(n+r)*i];return e&&s&&o.push(h*e+r*(e-1),n*s+r*(s-1)),o}getLength(t){return i(t,"number")?t:i(t,"string")?this.changeUnits(t,{clean:!0}):0}getWidth(t,e=1){return i(t,"number")?t*this.dpr:i(t,"string")?this.changeUnits(t,{denominator:this.cellWidth*e+this._defaultConfig.gutter*(e-1)}):0}getHeight(t,e=1){return i(t,"number")?t*this.dpr:i(t,"string")?this.changeUnits(t,{denominator:this.cellHeight*e+this._defaultConfig.gutter*(e-1)}):0}getOffsetX(t,i=1){return(this.cellWidth*i+this._defaultConfig.gutter*(i-1)-t)/2}},exports.LuckyWheel=class extends t{constructor(t,i={}){super(),this.blocks=[],this.prizes=[],this.buttons=[],this.defaultConfig={},this._defaultConfig={gutter:"0px",offsetDegree:0,speed:20,accelerationTime:2500,decelerationTime:2500},this.defaultStyle={},this._defaultStyle={fontSize:"18px",fontColor:"#000",fontStyle:"microsoft yahei ui,microsoft yahei,simsun,sans-serif",fontWeight:"400",lineHeight:"",background:"#fff",wordWrap:!0,lengthLimit:"90%"},this.Radius=0,this.prizeRadius=0,this.prizeDeg=0,this.prizeRadian=0,this.rotateDeg=0,this.maxBtnRadius=0,this.startTime=0,this.endTime=0,this.stopDeg=0,this.endDeg=0,this.animationId=0,this.FPS=16.6,this.prizeImgs=[[]],this.btnImgs=[[]],this.box=document.querySelector(t),this.canvas=document.createElement("canvas"),this.box.appendChild(this.canvas),this.ctx=this.canvas.getContext("2d"),this.initData(i),this.initComputed(),this.initWatch();let e=[[]];this.prizes&&(e=this.prizes.map((t=>t.imgs))),this.buttons&&e.push(...this.buttons.map((t=>t.imgs))),this.init(e)}initData(t){this.$set(this,"blocks",t.blocks||[]),this.$set(this,"prizes",t.prizes||[]),this.$set(this,"buttons",t.buttons||[]),this.$set(this,"defaultConfig",t.defaultConfig||{}),this.$set(this,"defaultStyle",t.defaultStyle||{}),this.$set(this,"startCallback",t.start),this.$set(this,"endCallback",t.end)}initComputed(){this.$computed(this,"_defaultConfig",(()=>({gutter:"0px",offsetDegree:0,speed:20,accelerationTime:2500,decelerationTime:2500,...this.defaultConfig}))),this.$computed(this,"_defaultStyle",(()=>({fontSize:"18px",fontColor:"#000",fontStyle:"microsoft yahei ui,microsoft yahei,simsun,sans-serif",fontWeight:"400",background:"#fff",wordWrap:!0,lengthLimit:"90%",...this.defaultStyle})))}initWatch(){this.$watch("prizes",((t,i)=>{let e=[];return i?t&&t.forEach(((t,s)=>{let h=[];const n=i[s];n?t.imgs&&t.imgs.forEach(((t,i)=>{if(!n.imgs)return h[i]=t;const e=n.imgs[i];e&&this.prizeImgs[s]&&this.prizeImgs[s][i]?t.src!==e.src&&(h[i]=t):h[i]=t})):h=t.imgs||[],e[s]=h})):e=t.map((t=>t.imgs)),this.init(e)})),this.$watch("buttons",((t,i)=>{let e=[];return i?t&&t.forEach(((t,s)=>{let h=[];const n=i[s];n&&n.imgs?t.imgs&&t.imgs.forEach(((t,i)=>{if(!n.imgs)return h[i]=t;const e=n.imgs[i];e&&this.btnImgs[s]&&this.btnImgs[s][i]?t.src!==e.src&&(h[i]=t):h[i]=t})):h=t.imgs||[],e[s]=h})):e=t.map((t=>t.imgs)),this.init([...new Array(this.prizes.length).fill(void 0),...e])}))}init(t){this.setDpr(),this.setHTMLFontSize();const{box:e,canvas:s,ctx:h,dpr:n}=this;if(!e)return;s.width=s.height=e.offsetWidth*n,this.Radius=s.width/2,this.optimizeClarity(s,2*this.Radius,2*this.Radius),h.translate(this.Radius,this.Radius);const r=()=>{this.draw(),s.onclick=t=>{h.beginPath(),h.arc(0,0,this.maxBtnRadius,0,2*Math.PI,!1),h.isPointInPath(t.offsetX,t.offsetY)&&(this.startTime||this.startCallback?.(t))}};let o=0,a=0;i(t,"array")&&(this.draw(),t.forEach(((t,i)=>{if(!t)return!1;t.forEach(((t,e)=>{a++,this.loadAndCacheImg(i,e,(()=>{o++,a===o&&r.call(this)}))}))}))),a||r.call(this)}loadAndCacheImg(t,i,e){const s=t<this.prizes.length,h=s?"prizes":"buttons",n=s?"prizeImgs":"btnImgs";t=s?t:t-this.prizes.length;const r=this[h][t];if(!r||!r.imgs)return;const o=r.imgs[i];if(!o)return;let a=new Image;this[n][t]||(this[n][t]=[]),this[n][t][i]=a,a.src=o.src,a.onload=()=>e.call(this)}computedWidthAndHeight(t,i,e,s){if(!i.width&&!i.height)return[t.width,t.height];if(i.width&&!i.height){let s=this.getWidth(i.width,e);return[s,t.height*(s/t.width)]}if(!i.width&&i.height){let e=this.getHeight(i.height,s);return[t.width*(e/t.height),e]}return[this.getWidth(i.width,e),this.getHeight(i.height,s)]}draw(){const{ctx:t,dpr:i,_defaultConfig:n,_defaultStyle:o}=this;t.clearRect(-this.Radius,-this.Radius,2*this.Radius,2*this.Radius),this.prizeRadius=this.blocks.reduce(((e,s)=>(t.beginPath(),t.fillStyle=s.background,t.arc(0,0,e,0,2*Math.PI,!1),t.fill(),e-this.getLength(s.padding.split(" ")[0])*i)),this.Radius),this.prizeDeg=360/this.prizes.length,this.prizeRadian=s(this.prizeDeg);let a=s(-90+this.rotateDeg+n.offsetDegree);const l=i=>this.getOffsetX(t.measureText(i).width),d=(t,e,s)=>{const h=t.lineHeight||o.lineHeight||t.fontSize||o.fontSize;return this.getHeight(t.top,e)+(s+1)*this.getLength(h)*i};t.save(),this.prizes.forEach(((c,g)=>{let f=a+g*this.prizeRadian,u=this.prizeRadius-this.maxBtnRadius;((t,i,e,n,o,a,l)=>{i||(i=a);let d=s(90/Math.PI/e*a),c=s(90/Math.PI/i*a),g=n+d,f=o-d,u=n+c,m=o-c;t.beginPath(),t.fillStyle=l,t.moveTo(...h(g,e)),r(t,e,g,f,!0),m>u?r(t,i,u,m,!1):t.lineTo(...h((n+o)/2,a/2/Math.abs(Math.sin((n-o)/2)))),t.closePath(),t.fill()})(t,this.maxBtnRadius,this.prizeRadius,f-this.prizeRadian/2,f+this.prizeRadian/2,this.getLength(n.gutter)*i,c.background||o.background||"rgba(0, 0, 0, 0)");let m=Math.cos(f)*this.prizeRadius,p=Math.sin(f)*this.prizeRadius;t.translate(m,p),t.rotate(f+s(90)),c.imgs&&c.imgs.forEach(((i,e)=>{if(!this.prizeImgs[g])return;const s=this.prizeImgs[g][e];if(!s)return;const[h,n]=this.computedWidthAndHeight(s,i,this.prizeRadian*this.prizeRadius,u);t.drawImage(s,this.getOffsetX(h),this.getHeight(i.top,u),h,n)})),c.fonts&&c.fonts.forEach((s=>{let h=s.fontColor||o.fontColor,r=s.fontWeight||o.fontWeight,a=this.getLength(s.fontSize||o.fontSize),c=s.fontStyle||o.fontStyle;t.fillStyle=h,t.font=`${r} ${a*i}px ${c}`;let g=[],f=String(s.text);if(s.hasOwnProperty("wordWrap")?s.wordWrap:o.wordWrap){f=e(f);let h="";for(let e=0;e<f.length;e++){h+=f[e];let r=t.measureText(h).width,a=(this.prizeRadius-d(s,u,g.length))*Math.tan(this.prizeRadian/2)*2-this.getLength(n.gutter)*i;r>this.getWidth(s.lengthLimit||o.lengthLimit,a)&&(g.push(h.slice(0,-1)),h=f[e])}h&&g.push(h),g.length||g.push(f)}else g=f.split("\n");g.filter((t=>!!t)).forEach(((i,e)=>{t.fillText(i,l(i),d(s,u,e))}))})),t.rotate(s(360)-f-s(90)),t.translate(-m,-p)})),t.restore(),this.buttons.forEach(((e,s)=>{let h=this.getHeight(e.radius);this.maxBtnRadius=Math.max(this.maxBtnRadius,h),t.beginPath(),t.fillStyle=e.background||"rgba(0, 0, 0, 0)",t.arc(0,0,h,0,2*Math.PI,!1),t.fill(),e.pointer&&(t.beginPath(),t.fillStyle=e.background||"rgba(0, 0, 0, 0)",t.moveTo(-h,0),t.lineTo(h,0),t.lineTo(0,2*-h),t.closePath(),t.fill()),e.imgs&&e.imgs.forEach(((i,n)=>{if(!this.btnImgs[s])return;const r=this.btnImgs[s][n];if(!r)return;const[o,a]=this.computedWidthAndHeight(r,i,2*this.getHeight(e.radius),2*this.getHeight(e.radius));t.drawImage(r,this.getOffsetX(o),this.getHeight(i.top,h),o,a)})),e.fonts&&e.fonts.forEach((e=>{let s=e.fontColor||o.fontColor,n=e.fontWeight||o.fontWeight,r=this.getLength(e.fontSize||o.fontSize),a=e.fontStyle||o.fontStyle;t.fillStyle=s,t.font=`${n} ${r*i}px ${a}`,String(e.text).split("\n").forEach(((i,s)=>{t.fillText(i,l(i),d(e,h,s))}))}))}))}play(){this.startTime||(cancelAnimationFrame(this.animationId),this.startTime=Date.now(),this.prizeFlag=void 0,this.run())}stop(t){this.prizeFlag=Number(t)%this.prizes.length}run(t=0){const{prizeFlag:i,prizeDeg:e,rotateDeg:s,_defaultConfig:h}=this;let n=Date.now()-this.startTime;if(n>=h.accelerationTime&&void 0!==i)return this.FPS=n/t,this.endTime=Date.now(),this.stopDeg=s,this.endDeg=1800-i*e-s-h.offsetDegree,cancelAnimationFrame(this.animationId),this.slowDown();this.rotateDeg=(s+a(n,0,h.speed,h.accelerationTime))%360,this.draw(),this.animationId=window.requestAnimationFrame(this.run.bind(this,t+1))}slowDown(){const{prizes:t,prizeFlag:i,stopDeg:e,endDeg:s,_defaultConfig:h}=this;let n=Date.now()-this.endTime;if(n>=h.decelerationTime)return this.startTime=0,this.endCallback?.({...t.find(((t,e)=>e===i))}),cancelAnimationFrame(this.animationId);this.rotateDeg=l(n,e,s,h.decelerationTime)%360,this.draw(),this.animationId=window.requestAnimationFrame(this.slowDown.bind(this))}getLength(t){return i(t,"number")?t:i(t,"string")?this.changeUnits(t,{clean:!0}):0}getWidth(t,e=this.prizeRadian*this.prizeRadius){return i(t,"number")?t*this.dpr:i(t,"string")?this.changeUnits(t,{denominator:e}):0}getHeight(t,e=this.prizeRadius){return i(t,"number")?t*this.dpr:i(t,"string")?this.changeUnits(t,{denominator:e}):0}getOffsetX(t){return-t/2}}; |
@@ -1,1 +0,1 @@ | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).LuckDraw={})}(this,(function(t){"use strict";class e{constructor(){this.htmlFontSize=16,this.dpr=1,this.setDpr(),this.setHTMLFontSize()}setDpr(){window.dpr=this.dpr=1.3*(window.devicePixelRatio||2)}setHTMLFontSize(){this.htmlFontSize=+getComputedStyle(document.documentElement).fontSize.slice(0,-2)}optimizeClarity(t,e,i){const{dpr:s}=this,h=t=>(t*s-t)/(t*s)*(s/2)*100;t.style.transform=`scale(${1/s}) translate(\n ${-h(e)}%, ${-h(i)}%\n )`}changeUnits(t,{denominator:e=1,clean:i=!1}){return Number(t.replace(/^(\-*[0-9.]*)([a-z%]*)$/,((t,s,h)=>{switch(h){case"%":s*=e/100;break;case"px":s*=1;break;case"rem":s*=this.htmlFontSize;break;default:s*=1}return i||"%"===h?s:s*this.dpr})))}observer(t){if("object"!=typeof t||null===t)return t;Object.keys(t).forEach((e=>{this.defineReactive(t,e,t[e])}))}defineReactive(t,e,i){this.observer(i),Object.defineProperty(t,e,{get:()=>(console.log("get",e),i),set(t){console.log("set",e,i),t!==i&&(i=t,this.observer(i))}})}}const i=(t,...e)=>e.some((e=>Object.prototype.toString.call(t).slice(8,-1).toLowerCase()===e)),s=t=>[].filter.call(t,(t=>"\n"!==t)).join(""),h=t=>Math.PI/180*t,n=(t,e)=>[+(Math.cos(t)*e).toFixed(8),+(Math.sin(t)*e).toFixed(8)],r=(t,e)=>{let i=-t/e;return[i,-i*t+e]},o=(t,e,i,s,a=!0)=>{if(Math.abs(s-i).toFixed(8)>=h(180).toFixed(8)){let h=(s+i)/2;return a?(o(t,e,i,h,a),o(t,e,h,s,a)):(o(t,e,h,s,a),o(t,e,i,h,a)),!1}a||([i,s]=[s,i]);const[l,d]=n(i,e),[c,g]=n(s,e),[f,u]=r(l,d),[m,p]=r(c,g);let b=(p-u)/(f-m),w=(m*u-f*p)/(m-f);isNaN(b)&&(Math.abs(l)===+e.toFixed(8)&&(b=l),Math.abs(c)===+e.toFixed(8)&&(b=c)),f===1/0||f===-1/0?w=m*b+p:m!==1/0&&m!==-1/0||(w=f*b+u),t.lineTo(l,d),t.arcTo(b,w,c,g,e)},a=(t,e,i,s,h,n,r)=>{let o=Math.min(s,h);n>o/2&&(n=o/2),t.beginPath(),t.fillStyle=r,t.moveTo(e+n,i),t.lineTo(e+n,i),t.lineTo(e+s-n,i),t.arcTo(e+s,i,e+s,i+n,n),t.lineTo(e+s,i+h-n),t.arcTo(e+s,i+h,e+s-n,i+h,n),t.lineTo(e+n,i+h),t.arcTo(e,i+h,e,i+h-n,n),t.lineTo(e,i+n),t.arcTo(e,i,e+n,i,n),t.closePath(),t.fill()},l=function(t,e,i,s){return t>=s&&(t=s),i*(t/=s)*t+e},d=function(t,e,i,s){return t>=s&&(t=s),-i*(t/=s)*(t-2)+e};t.LuckyGrid=class extends e{constructor(t,e={}){super(),this.rows=3,this.cols=3,this.blocks=[],this.prizes=[],this.defaultConfig={gutter:5,speed:20,accelerationTime:2500,decelerationTime:2500},this.defaultStyle={borderRadius:20,fontColor:"#000",fontSize:"18px",fontStyle:"microsoft yahei ui,microsoft yahei,simsun,sans-serif",fontWeight:"400",background:"#fff",shadow:"",wordWrap:!0,lengthLimit:"90%"},this.activeStyle={background:"#ffce98",shadow:""},this.boxWidth=0,this.boxHeight=0,this.cellWidth=0,this.cellHeight=0,this.startTime=0,this.endTime=0,this.currIndex=0,this.stopIndex=0,this.endIndex=0,this.demo=!1,this.timer=0,this.animationId=0,this.FPS=16.6,this.cells=[],this.cellImgs=[],this.blockData=[],this.box=document.querySelector(t),this.canvas=document.createElement("canvas"),this.box.appendChild(this.canvas),this.ctx=this.canvas.getContext("2d"),this.setData(e);let i=[[]];this.prizes&&(i=this.prizes.map((t=>t.imgs))),this.button&&(i[this.cols*this.rows-1]=this.button.imgs),this.init(i)}setData(t){this.rows=Number(t.rows)||3,this.cols=Number(t.cols)||3,this.blocks=t.blocks||[],this.prizes=t.prizes||[],this.button=t.button,this.startCallback=t.start,this.endCallback=t.end;const e=this.defaultConfig,i=this.defaultStyle,s=this.activeStyle;for(let i in t.defaultConfig)e[i]=t.defaultConfig[i];e.gutter=this.getLength(e.gutter)*this.dpr,e.speed/=40;for(let e in t.defaultStyle)i[e]=t.defaultStyle[e];i.borderRadius=this.getLength(i.borderRadius)*this.dpr;for(let e in t.activeStyle)s[e]=t.activeStyle[e]}init(t){this.setDpr(),this.setHTMLFontSize();const{box:e,canvas:s,dpr:h,defaultStyle:n,defaultConfig:r}=this;if(!e)return;this.boxWidth=s.width=e.offsetWidth*h,this.boxHeight=s.height=e.offsetHeight*h,this.optimizeClarity(s,this.boxWidth,this.boxHeight),this.cells=[...this.prizes],this.button&&(this.cells[this.cols*this.rows-1]={...this.button}),this.cells.forEach((t=>{t.col=t.col||1,t.row=t.row||1})),this.blockData=[],this.prizeArea=this.blocks.reduce((({x:t,y:e,w:s,h:n},r)=>{const[o,a,l,d]=(t=>{let e=t.padding.replace(/px/g,"").split(" ").map((t=>~~t))||[0],s=0,h=0,n=0,r=0;switch(e.length){case 1:s=h=n=r=e[0];break;case 2:s=h=e[0],n=r=e[1];break;case 3:s=e[0],n=r=e[1],h=e[2];break;default:s=e[0],h=e[1],n=e[2],r=e[3]}const o={paddingTop:s,paddingBottom:h,paddingLeft:n,paddingRight:r};for(let e in o)o[e]=t.hasOwnProperty(e)&&i(t[e],"string","number")?~~String(t[e]).replace(/px/g,""):o[e];return[s,h,n,r]})(r).map((t=>t*h));return this.blockData.push([t,e,s,n,r.borderRadius?this.getLength(r.borderRadius)*h:0,r.background]),{x:t+l,y:e+o,w:s-l-d,h:n-o-a}}),{x:0,y:0,w:this.boxWidth,h:this.boxHeight}),this.cellWidth=(this.prizeArea.w-r.gutter*(this.cols-1))/this.cols,this.cellHeight=(this.prizeArea.h-r.gutter*(this.rows-1))/this.rows;const o=()=>{this.draw(),this.demo&&this.walk(),this.button&&(s.onclick=t=>{const[e,i,s,h]=this.getGeometricProperty([this.button.x,this.button.y,this.button.col||1,this.button.row||1]);if(t.offsetX<e||t.offsetY<i||t.offsetX>e+s||t.offsetY>i+h)return!1;this.startTime||this.startCallback?.(t)})};let a=0,l=0;i(t,"array")&&(this.draw(),t.forEach(((t,e)=>{if(!t)return!1;t.forEach(((t,i)=>{l++,this.loadAndCacheImg(e,i,(()=>{a++,l===a&&o.call(this)}))}))}))),l||o.call(this)}loadAndCacheImg(t,e,i){const s=this.cells[t];if(!s||!s.imgs)return;const h=s.imgs[e];this.cellImgs[t]||(this.cellImgs[t]=[]);let n=new Image;this.cellImgs[t][e]={defaultImg:n},n.src=h.src;let r=0,o=1;if(n.onload=()=>{r++,r===o&&i.call(this)},!h.hasOwnProperty("activeSrc"))return;o++;let a=new Image;this.cellImgs[t][e].activeImg=a,a.src=h.activeSrc,a.onload=()=>{r++,r===o&&i.call(this)}}computedWidthAndHeight(t,e,i){if(!e.width&&!e.height)return[t.width,t.height];if(e.width&&!e.height){let s=this.getWidth(e.width,i.col);return[s,t.height*(s/t.width)]}if(!e.width&&e.height){let s=this.getHeight(e.height,i.row);return[t.width*(s/t.height),s]}return[this.getWidth(e.width,i.col),this.getHeight(e.height,i.row)]}draw(){const{ctx:t,dpr:e,defaultStyle:i,activeStyle:h}=this;t.clearRect(0,0,this.boxWidth,this.boxWidth),this.blockData.forEach((([e,i,s,h,n,r])=>{a(t,e,i,s,h,n,this.handleBackground(e,i,s,h,r))})),this.cells.forEach(((n,r)=>{let[o,l,d,c]=this.getGeometricProperty([n.x,n.y,n.col,n.row]);const g=r===this.currIndex%this.prizes.length>>0,f=(g?h.shadow:n.shadow||i.shadow).replace(/px/g,"").split(",")[0].split(" ").map(((t,i)=>i<3?Number(t)*e:t));4===f.length&&(t.shadowColor=f[3],t.shadowOffsetX=f[0],t.shadowOffsetY=f[1],t.shadowBlur=f[2],f[0]>0?d-=f[0]:(d+=f[0],o-=f[0]),f[1]>0?c-=f[1]:(c+=f[1],l-=f[1])),a(t,o,l,d,c,n.borderRadius?this.getLength(n.borderRadius)*e:this.getLength(i.borderRadius),this.handleBackground(o,l,d,c,n.background,g)),t.shadowColor="rgba(255, 255, 255, 0)",t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=0,n.imgs&&n.imgs.forEach(((e,i)=>{if(!this.cellImgs[r])return!1;const s=this.cellImgs[r][i];if(!s)return!1;const h=g&&s.activeImg||s.defaultImg,[a,d]=this.computedWidthAndHeight(h,e,n);t.drawImage(h,o+this.getOffsetX(a,n.col),l+this.getHeight(e.top,n.row),a,d)})),n.fonts&&n.fonts.forEach((r=>{let a=g&&h.fontStyle?h.fontStyle:r.fontStyle||i.fontStyle,d=g&&h.fontWeight?h.fontWeight:r.fontWeight||i.fontWeight,c=g&&h.fontSize?this.getLength(h.fontSize):this.getLength(r.fontSize||i.fontSize);const f=g&&h.lineHeight?h.lineHeight:r.lineHeight||i.lineHeight||r.fontSize||i.fontSize;t.font=`${d} ${c*e}px ${a}`,t.fillStyle=g&&h.fontColor?h.fontColor:r.fontColor||i.fontColor;let u=[],m=String(r.text);if(r.hasOwnProperty("wordWrap")?r.wordWrap:i.wordWrap){m=s(m);let e="";for(let s=0;s<m.length;s++){e+=m[s],t.measureText(e).width>this.getWidth(r.lengthLimit||i.lengthLimit,n.col)&&(u.push(e.slice(0,-1)),e=m[s])}e&&u.push(e),u.length||u.push(m)}else u=m.split("\n");u.forEach(((i,s)=>{t.fillText(i,o+this.getOffsetX(t.measureText(i).width,n.col),l+this.getHeight(r.top,n.row)+(s+1)*this.getLength(f)*e)}))}))}))}handleBackground(t,e,i,s,h,n=!1){const{ctx:r,defaultStyle:o,activeStyle:a}=this;return(h=n?a.background:h||o.background).includes("linear-gradient")&&(h=((t,e,i,s,h,n)=>{const r=/linear-gradient\((.+)\)/.exec(n)[1].split(",").map((t=>t.trim()));let o=r.shift(),a=[0,0,0,0];if(o.includes("deg")){o=o.slice(0,-3)%360;const t=t=>Math.tan(t/180*Math.PI);o>=0&&o<45?a=[e,i+h,e+s,i+h-s*t(o-0)]:o>=45&&o<90?a=[e,i+h,e+s-h*t(o-45),i]:o>=90&&o<135?a=[e+s,i+h,e+s-h*t(o-90),i]:o>=135&&o<180?a=[e+s,i+h,e,i+s*t(o-135)]:o>=180&&o<225?a=[e+s,i,e,i+s*t(o-180)]:o>=225&&o<270?a=[e+s,i,e+h*t(o-225),i+h]:o>=270&&o<315?a=[e,i,e+h*t(o-270),i+h]:o>=315&&o<360&&(a=[e,i,e+s,i+h-s*t(o-315)])}else o.includes("top")?a=[e,i+h,e,i]:o.includes("bottom")?a=[e,i,e,i+h]:o.includes("left")?a=[e+s,i,e,i]:o.includes("right")&&(a=[e,i,e+s,i]);const l=t.createLinearGradient(...a.map((t=>t>>0)));return r.reduce(((t,e,i)=>{const s=e.split(" ");return 1===s.length?t.addColorStop(i,s[0]):2===s.length&&t.addColorStop(...s),t}),l)})(r,t,e,i,s,h)),h}play(){this.startTime||(clearInterval(this.timer),cancelAnimationFrame(this.animationId),this.startTime=Date.now(),this.prizeFlag=void 0,this.run())}stop(t){this.prizeFlag=t%this.prizes.length}run(t=0){const{currIndex:e,prizes:i,prizeFlag:s,startTime:h,defaultConfig:n}=this;let r=Date.now()-h;if(r>=n.accelerationTime&&void 0!==s)return this.FPS=r/t,this.endTime=Date.now(),this.stopIndex=e,this.endIndex=5*i.length+s-(e>>0),cancelAnimationFrame(this.animationId),this.slowDown();this.currIndex=(e+l(r,.1,n.speed,n.accelerationTime))%i.length,this.draw(),this.animationId=window.requestAnimationFrame(this.run.bind(this,t+1))}slowDown(){const{prizes:t,prizeFlag:e,stopIndex:i,endIndex:s,defaultConfig:h}=this;let n=Date.now()-this.endTime;if(n>h.decelerationTime)return this.startTime=0,this.endCallback?.({...t.find(((t,i)=>i===e))}),cancelAnimationFrame(this.animationId);this.currIndex=d(n,i,s,h.decelerationTime)%t.length,this.draw(),this.animationId=window.requestAnimationFrame(this.slowDown.bind(this))}walk(){clearInterval(this.timer),this.timer=window.setInterval((()=>{this.currIndex+=1,this.draw()}),1300)}getGeometricProperty([t,e,i,s]){const{defaultConfig:h,cellWidth:n,cellHeight:r}=this;let o=[this.prizeArea.x+(n+h.gutter)*t,this.prizeArea.y+(r+h.gutter)*e];return i&&s&&o.push(n*i+h.gutter*(i-1),r*s+h.gutter*(s-1)),o}getLength(t){return i(t,"number")?t:i(t,"string")?this.changeUnits(t,{clean:!0}):0}getWidth(t,e=1){return i(t,"number")?t*this.dpr:i(t,"string")?this.changeUnits(t,{denominator:this.cellWidth*e+this.defaultConfig.gutter*(e-1)}):0}getHeight(t,e=1){return i(t,"number")?t*this.dpr:i(t,"string")?this.changeUnits(t,{denominator:this.cellHeight*e+this.defaultConfig.gutter*(e-1)}):0}getOffsetX(t,e=1){return(this.cellWidth*e+this.defaultConfig.gutter*(e-1)-t)/2}},t.LuckyWheel=class extends e{constructor(t,e={}){super(),this.blocks=[],this.prizes=[],this.buttons=[],this.defaultConfig={gutter:"0px",offsetDegree:0,speed:20,accelerationTime:2500,decelerationTime:2500},this.defaultStyle={fontSize:"18px",fontColor:"#000",fontStyle:"microsoft yahei ui,microsoft yahei,simsun,sans-serif",fontWeight:"400",background:"#fff",wordWrap:!0,lengthLimit:"90%"},this.Radius=0,this.prizeRadius=0,this.prizeDeg=0,this.prizeRadian=0,this.rotateDeg=0,this.maxBtnRadius=0,this.startTime=0,this.endTime=0,this.stopDeg=0,this.endDeg=0,this.animationId=0,this.FPS=16.6,this.prizeImgs=[[]],this.btnImgs=[[]],this.box=document.querySelector(t),this.canvas=document.createElement("canvas"),this.box.appendChild(this.canvas),this.ctx=this.canvas.getContext("2d"),this.setData(e);let i=[[]];this.prizes&&(i=this.prizes.map((t=>t.imgs))),this.buttons&&i.push(...this.buttons.map((t=>t.imgs))),this.init(i)}setData(t){this.blocks=t.blocks||[],this.prizes=t.prizes||[],this.buttons=t.buttons||[],this.startCallback=t.start,this.endCallback=t.end;for(let e in t.defaultConfig)this.defaultConfig[e]=t.defaultConfig[e];for(let e in t.defaultStyle)this.defaultStyle[e]=t.defaultStyle[e]}init(t){this.setDpr(),this.setHTMLFontSize();const{box:e,canvas:s,ctx:h,dpr:n}=this;if(!e)return;s.width=s.height=e.offsetWidth*n,this.Radius=s.width/2,this.optimizeClarity(s,2*this.Radius,2*this.Radius),h.translate(this.Radius,this.Radius);const r=()=>{this.draw(),s.onclick=t=>{h.beginPath(),h.arc(0,0,this.maxBtnRadius,0,2*Math.PI,!1),h.isPointInPath(t.offsetX,t.offsetY)&&(this.startTime||this.startCallback?.(t))}};let o=0,a=0;i(t,"array")&&(this.draw(),t.forEach(((t,e)=>{if(!t)return!1;t.forEach(((t,i)=>{a++,this.loadAndCacheImg(e,i,(()=>{o++,a===o&&r.call(this)}))}))}))),a||r.call(this)}loadAndCacheImg(t,e,i){const s=t<this.prizes.length,h=s?"prizes":"buttons",n=s?"prizeImgs":"btnImgs";t=s?t:t-this.prizes.length;const r=this[h][t];if(!r||!r.imgs)return;const o=r.imgs[e];if(!o)return;let a=new Image;this[n][t]||(this[n][t]=[]),this[n][t][e]=a,a.src=o.src,a.onload=()=>i.call(this)}computedWidthAndHeight(t,e,i,s){if(!e.width&&!e.height)return[t.width,t.height];if(e.width&&!e.height){let s=this.getWidth(e.width,i);return[s,t.height*(s/t.width)]}if(!e.width&&e.height){let i=this.getHeight(e.height,s);return[t.width*(i/t.height),i]}return[this.getWidth(e.width,i),this.getHeight(e.height,s)]}draw(){const{ctx:t,dpr:e,defaultConfig:i,defaultStyle:r}=this;t.clearRect(-this.Radius,-this.Radius,2*this.Radius,2*this.Radius),this.prizeRadius=this.blocks.reduce(((i,s)=>(t.beginPath(),t.fillStyle=s.background,t.arc(0,0,i,0,2*Math.PI,!1),t.fill(),i-this.getLength(s.padding.split(" ")[0])*e)),this.Radius),this.prizeDeg=360/this.prizes.length,this.prizeRadian=h(this.prizeDeg);let a=h(-90+this.rotateDeg+i.offsetDegree);const l=e=>this.getOffsetX(t.measureText(e).width),d=(t,i,s)=>{const h=t.lineHeight||r.lineHeight||t.fontSize||r.fontSize;return this.getHeight(t.top,i)+(s+1)*this.getLength(h)*e};t.save(),this.prizes.forEach(((c,g)=>{let f=a+g*this.prizeRadian,u=this.prizeRadius-this.maxBtnRadius;((t,e,i,s,r,a,l)=>{e||(e=a);let d=h(90/Math.PI/i*a),c=h(90/Math.PI/e*a),g=s+d,f=r-d,u=s+c,m=r-c;t.beginPath(),t.fillStyle=l,t.moveTo(...n(g,i)),o(t,i,g,f,!0),m>u?o(t,e,u,m,!1):t.lineTo(...n((s+r)/2,a/2/Math.abs(Math.sin((s-r)/2)))),t.closePath(),t.fill()})(t,this.maxBtnRadius,this.prizeRadius,f-this.prizeRadian/2,f+this.prizeRadian/2,this.getLength(i.gutter)*e,c.background||r.background||"rgba(0, 0, 0, 0)");let m=Math.cos(f)*this.prizeRadius,p=Math.sin(f)*this.prizeRadius;t.translate(m,p),t.rotate(f+h(90)),c.imgs&&c.imgs.forEach(((e,i)=>{if(!this.prizeImgs[g])return;const s=this.prizeImgs[g][i];if(!s)return;const[h,n]=this.computedWidthAndHeight(s,e,this.prizeRadian*this.prizeRadius,u);t.drawImage(s,this.getOffsetX(h),this.getHeight(e.top,u),h,n)})),c.fonts&&c.fonts.forEach((h=>{let n=h.fontColor||r.fontColor,o=h.fontWeight||r.fontWeight,a=this.getLength(h.fontSize||r.fontSize),c=h.fontStyle||r.fontStyle;t.fillStyle=n,t.font=`${o} ${a*e}px ${c}`;let g=[],f=String(h.text);if(h.hasOwnProperty("wordWrap")?h.wordWrap:r.wordWrap){f=s(f);let n="";for(let s=0;s<f.length;s++){n+=f[s];let o=t.measureText(n).width,a=(this.prizeRadius-d(h,u,g.length))*Math.tan(this.prizeRadian/2)*2-this.getLength(i.gutter)*e;o>this.getWidth(h.lengthLimit||r.lengthLimit,a)&&(g.push(n.slice(0,-1)),n=f[s])}n&&g.push(n),g.length||g.push(f)}else g=f.split("\n");g.filter((t=>!!t)).forEach(((e,i)=>{t.fillText(e,l(e),d(h,u,i))}))})),t.rotate(h(360)-f-h(90)),t.translate(-m,-p)})),t.restore(),this.buttons.forEach(((i,s)=>{let h=this.getHeight(i.radius);this.maxBtnRadius=Math.max(this.maxBtnRadius,h),t.beginPath(),t.fillStyle=i.background||"rgba(0, 0, 0, 0)",t.arc(0,0,h,0,2*Math.PI,!1),t.fill(),i.pointer&&(t.beginPath(),t.fillStyle=i.background||"rgba(0, 0, 0, 0)",t.moveTo(-h,0),t.lineTo(h,0),t.lineTo(0,2*-h),t.closePath(),t.fill()),i.imgs&&i.imgs.forEach(((e,n)=>{if(!this.btnImgs[s])return;const r=this.btnImgs[s][n];if(!r)return;const[o,a]=this.computedWidthAndHeight(r,e,2*this.getHeight(i.radius),2*this.getHeight(i.radius));t.drawImage(r,this.getOffsetX(o),this.getHeight(e.top,h),o,a)})),i.fonts&&i.fonts.forEach((i=>{let s=i.fontColor||r.fontColor,n=i.fontWeight||r.fontWeight,o=this.getLength(i.fontSize||r.fontSize),a=i.fontStyle||r.fontStyle;t.fillStyle=s,t.font=`${n} ${o*e}px ${a}`,String(i.text).split("\n").forEach(((e,s)=>{t.fillText(e,l(e),d(i,h,s))}))}))}))}play(){this.startTime||(cancelAnimationFrame(this.animationId),this.startTime=Date.now(),this.prizeFlag=void 0,this.run())}stop(t){this.prizeFlag=Number(t)%this.prizes.length}run(t=0){const{prizeFlag:e,prizeDeg:i,rotateDeg:s,defaultConfig:h}=this;let n=Date.now()-this.startTime;if(n>=h.accelerationTime&&void 0!==e)return this.FPS=n/t,this.endTime=Date.now(),this.stopDeg=s,this.endDeg=1800-e*i-s-h.offsetDegree,cancelAnimationFrame(this.animationId),this.slowDown();this.rotateDeg=(s+l(n,0,h.speed,h.accelerationTime))%360,this.draw(),this.animationId=window.requestAnimationFrame(this.run.bind(this,t+1))}slowDown(){const{prizes:t,prizeFlag:e,stopDeg:i,endDeg:s,defaultConfig:h}=this;let n=Date.now()-this.endTime;if(n>=h.decelerationTime)return this.startTime=0,this.endCallback?.({...t.find(((t,i)=>i===e))}),cancelAnimationFrame(this.animationId);this.rotateDeg=d(n,i,s,h.decelerationTime)%360,this.draw(),this.animationId=window.requestAnimationFrame(this.slowDown.bind(this))}getLength(t){return i(t,"number")?t:i(t,"string")?this.changeUnits(t,{clean:!0}):0}getWidth(t,e=this.prizeRadian*this.prizeRadius){return i(t,"number")?t*this.dpr:i(t,"string")?this.changeUnits(t,{denominator:e}):0}getHeight(t,e=this.prizeRadius){return i(t,"number")?t*this.dpr:i(t,"string")?this.changeUnits(t,{denominator:e}):0}getOffsetX(t){return-t/2}},Object.defineProperty(t,"__esModule",{value:!0})})); | ||
!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports):"function"==typeof define&&define.amd?define(["exports"],i):i((t="undefined"!=typeof globalThis?globalThis:t||self).LuckyCanvas={})}(this,(function(t){"use strict";class i{constructor(){this.htmlFontSize=16,this.dpr=1,this.subs={},this.setDpr(),this.setHTMLFontSize(),this.resetArrayPropo()}setDpr(){window.dpr=this.dpr=1.3*(window.devicePixelRatio||2)}setHTMLFontSize(){this.htmlFontSize=+getComputedStyle(document.documentElement).fontSize.slice(0,-2)}optimizeClarity(t,i,e){const{dpr:s}=this,h=t=>(t*s-t)/(t*s)*(s/2)*100;t.style.transform=`scale(${1/s}) translate(\n ${-h(i)}%, ${-h(e)}%\n )`}changeUnits(t,{denominator:i=1,clean:e=!1}){return Number(t.replace(/^(\-*[0-9.]*)([a-z%]*)$/,((t,s,h)=>{switch(h){case"%":s*=i/100;break;case"px":s*=1;break;case"rem":s*=this.htmlFontSize;break;default:s*=1}return e||"%"===h?s:s*this.dpr})))}draw(){}observer(t){t&&"object"==typeof t&&Object.keys(t).forEach((i=>{this.defineReactive(t,i,t[i])}))}defineReactive(t,i,e){this.observer(e),Object.defineProperty(t,i,{get:()=>e,set:t=>{let s=e;t!==e&&(e=t,this.observer(e),this.subs[i]&&this.subs[i].call(this,e,s),this.draw())}})}$set(t,i,e){t&&"object"==typeof t&&this.defineReactive(t,i,e)}$computed(t,i,e){Object.defineProperty(t,i,{get:()=>e.call(this)})}$watch(t,i){this.subs[t]=i}resetArrayPropo(){const t=this,i=Array.prototype,e=Object.create(i);["push","pop","shift","unshift","sort","splice","reverse"].forEach((s=>{e[s]=function(){t.draw(),i[s].call(this,...arguments)}}))}}const e=(t,...i)=>i.some((i=>Object.prototype.toString.call(t).slice(8,-1).toLowerCase()===i)),s=t=>[].filter.call(t,(t=>"\n"!==t)).join(""),h=t=>Math.PI/180*t,n=(t,i)=>[+(Math.cos(t)*i).toFixed(8),+(Math.sin(t)*i).toFixed(8)],r=(t,i)=>{let e=-t/i;return[e,-e*t+i]},o=(t,i,e,s,a=!0)=>{if(Math.abs(s-e).toFixed(8)>=h(180).toFixed(8)){let h=(s+e)/2;return a?(o(t,i,e,h,a),o(t,i,h,s,a)):(o(t,i,h,s,a),o(t,i,e,h,a)),!1}a||([e,s]=[s,e]);const[l,d]=n(e,i),[c,g]=n(s,i),[f,u]=r(l,d),[m,p]=r(c,g);let w=(p-u)/(f-m),b=(m*u-f*p)/(m-f);isNaN(w)&&(Math.abs(l)===+i.toFixed(8)&&(w=l),Math.abs(c)===+i.toFixed(8)&&(w=c)),f===1/0||f===-1/0?b=m*w+p:m!==1/0&&m!==-1/0||(b=f*w+u),t.lineTo(l,d),t.arcTo(w,b,c,g,i)},a=(t,i,e,s,h,n,r)=>{let o=Math.min(s,h);n>o/2&&(n=o/2),t.beginPath(),t.fillStyle=r,t.moveTo(i+n,e),t.lineTo(i+n,e),t.lineTo(i+s-n,e),t.arcTo(i+s,e,i+s,e+n,n),t.lineTo(i+s,e+h-n),t.arcTo(i+s,e+h,i+s-n,e+h,n),t.lineTo(i+n,e+h),t.arcTo(i,e+h,i,e+h-n,n),t.lineTo(i,e+n),t.arcTo(i,e,i+n,e,n),t.closePath(),t.fill()},l=function(t,i,e,s){return t>=s&&(t=s),e*(t/=s)*t+i},d=function(t,i,e,s){return t>=s&&(t=s),-e*(t/=s)*(t-2)+i};t.LuckyGrid=class extends i{constructor(t,i={}){super(),this.rows=3,this.cols=3,this.blocks=[],this.prizes=[],this.defaultConfig={},this._defaultConfig={gutter:5,speed:20,accelerationTime:2500,decelerationTime:2500},this.defaultStyle={},this._defaultStyle={borderRadius:20,fontColor:"#000",fontSize:"18px",fontStyle:"microsoft yahei ui,microsoft yahei,simsun,sans-serif",fontWeight:"400",lineHeight:"",background:"#fff",shadow:"",wordWrap:!0,lengthLimit:"90%"},this.activeStyle={},this._activeStyle={background:"#ffce98",shadow:"",fontStyle:"",fontWeight:"",fontSize:"",lineHeight:"",fontColor:""},this.boxWidth=0,this.boxHeight=0,this.cellWidth=0,this.cellHeight=0,this.startTime=0,this.endTime=0,this.currIndex=0,this.stopIndex=0,this.endIndex=0,this.demo=!1,this.timer=0,this.animationId=0,this.FPS=16.6,this.cells=[],this.cellImgs=[],this.box=document.querySelector(t),this.canvas=document.createElement("canvas"),this.box.appendChild(this.canvas),this.ctx=this.canvas.getContext("2d"),this.initData(i),this.initComputed(),this.initWatch();let e=[[]];this.prizes&&(e=this.prizes.map((t=>t.imgs))),this.button&&(e[this.cols*this.rows-1]=this.button.imgs),this.init(e)}initData(t){this.$set(this,"rows",Number(t.rows)||3),this.$set(this,"cols",Number(t.cols)||3),this.$set(this,"blocks",t.blocks||[]),this.$set(this,"prizes",t.prizes||[]),this.$set(this,"button",t.button),this.$set(this,"defaultConfig",t.defaultConfig||{}),this.$set(this,"defaultStyle",t.defaultStyle||{}),this.$set(this,"activeStyle",t.activeStyle||{}),this.$set(this,"startCallback",t.start),this.$set(this,"endCallback",t.end)}initComputed(){this.$computed(this,"_defaultConfig",(()=>{const t={gutter:5,speed:20,accelerationTime:2500,decelerationTime:2500,...this.defaultConfig};return t.gutter=this.getLength(t.gutter)*this.dpr,t.speed=t.speed/40,t})),this.$computed(this,"_defaultStyle",(()=>({borderRadius:20,fontColor:"#000",fontSize:"18px",fontStyle:"microsoft yahei ui,microsoft yahei,simsun,sans-serif",fontWeight:"400",background:"#fff",shadow:"",wordWrap:!0,lengthLimit:"90%",...this.defaultStyle}))),this.$computed(this,"_activeStyle",(()=>({background:"#ffce98",shadow:"",...this.activeStyle})))}initWatch(){this.$watch("prizes",((t,i)=>{let e=[];return i?t&&t.forEach(((t,s)=>{let h=[];const n=i[s];n?t.imgs&&t.imgs.forEach(((t,i)=>{if(!n.imgs)return h[i]=t;const e=n.imgs[i];e&&this.cellImgs[s][i]?t.src!==e.src&&(h[i]=t):h[i]=t})):h=t.imgs||[],e[s]=h})):e=t.map((t=>t.imgs)),this.init(e)})),this.$watch("button",((t,i)=>{let e=[],s=this.cols*this.rows-1;if(i&&i.imgs){if(t.imgs){const h=[];t.imgs.forEach(((t,e)=>{if(!i.imgs)return h[e]=t;const n=i.imgs[e];n&&this.cellImgs[s][e]?t.src!==n.src&&(h[e]=t):h[e]=t})),e[s]=h}}else e[s]=t.imgs;return this.init(e)}))}init(t){this.setDpr(),this.setHTMLFontSize();const{box:i,canvas:s,dpr:h}=this;if(!i)return;this.boxWidth=s.width=i.offsetWidth*h,this.boxHeight=s.height=i.offsetHeight*h,this.optimizeClarity(s,this.boxWidth,this.boxHeight);const n=()=>{this.draw(),this.demo&&this.walk(),this.button&&(s.onclick=t=>{const[i,e,s,h]=this.getGeometricProperty([this.button.x,this.button.y,this.button.col||1,this.button.row||1]);if(t.offsetX<i||t.offsetY<e||t.offsetX>i+s||t.offsetY>e+h)return!1;this.startTime||this.startCallback?.(t)})};let r=0,o=0;e(t,"array")&&(this.draw(),t.forEach(((t,i)=>{if(!t)return!1;t.forEach(((t,e)=>{o++,this.loadAndCacheImg(i,e,(()=>{r++,o===r&&n.call(this)}))}))}))),o||n.call(this)}loadAndCacheImg(t,i,e){const s=this.cells[t];if(!s||!s.imgs)return;const h=s.imgs[i];this.cellImgs[t]||(this.cellImgs[t]=[]);let n=new Image;this.cellImgs[t][i]={defaultImg:n},n.src=h.src;let r=0,o=1;if(n.onload=()=>{r++,r===o&&e.call(this)},!h.hasOwnProperty("activeSrc"))return;o++;let a=new Image;this.cellImgs[t][i].activeImg=a,a.src=h.activeSrc,a.onload=()=>{r++,r===o&&e.call(this)}}computedWidthAndHeight(t,i,e){if(!i.width&&!i.height)return[t.width,t.height];if(i.width&&!i.height){let s=this.getWidth(i.width,e.col);return[s,t.height*(s/t.width)]}if(!i.width&&i.height){let s=this.getHeight(i.height,e.row);return[t.width*(s/t.height),s]}return[this.getWidth(i.width,e.col),this.getHeight(i.height,e.row)]}draw(){const{ctx:t,dpr:i,_defaultConfig:h,_defaultStyle:n,_activeStyle:r}=this;t.clearRect(0,0,this.boxWidth,this.boxWidth),this.cells=[...this.prizes],this.button&&(this.cells[this.cols*this.rows-1]=this.button),this.cells.forEach((t=>{t.col=t.col||1,t.row=t.row||1})),this.prizeArea=this.blocks.reduce((({x:s,y:h,w:n,h:r},o)=>{const[l,d,c,g]=(t=>{let i=t.padding.replace(/px/g,"").split(" ").map((t=>~~t))||[0],s=0,h=0,n=0,r=0;switch(i.length){case 1:s=h=n=r=i[0];break;case 2:s=h=i[0],n=r=i[1];break;case 3:s=i[0],n=r=i[1],h=i[2];break;default:s=i[0],h=i[1],n=i[2],r=i[3]}const o={paddingTop:s,paddingBottom:h,paddingLeft:n,paddingRight:r};for(let i in o)o[i]=t.hasOwnProperty(i)&&e(t[i],"string","number")?~~String(t[i]).replace(/px/g,""):o[i];return[s,h,n,r]})(o).map((t=>t*i)),f=o.borderRadius?this.getLength(o.borderRadius)*i:0;return a(t,s,h,n,r,f,this.handleBackground(s,h,n,r,o.background)),{x:s+c,y:h+l,w:n-c-g,h:r-l-d}}),{x:0,y:0,w:this.boxWidth,h:this.boxHeight}),this.cellWidth=(this.prizeArea.w-h.gutter*(this.cols-1))/this.cols,this.cellHeight=(this.prizeArea.h-h.gutter*(this.rows-1))/this.rows,this.cells.forEach(((e,h)=>{let[o,l,d,c]=this.getGeometricProperty([e.x,e.y,e.col,e.row]);const g=h===this.currIndex%this.prizes.length>>0,f=(g?r.shadow:e.shadow||n.shadow).replace(/px/g,"").split(",")[0].split(" ").map(((t,e)=>e<3?Number(t)*i:t));4===f.length&&(t.shadowColor=f[3],t.shadowOffsetX=f[0],t.shadowOffsetY=f[1],t.shadowBlur=f[2],f[0]>0?d-=f[0]:(d+=f[0],o-=f[0]),f[1]>0?c-=f[1]:(c+=f[1],l-=f[1])),a(t,o,l,d,c,this.getLength(e.borderRadius?e.borderRadius:n.borderRadius)*i,this.handleBackground(o,l,d,c,e.background,g)),t.shadowColor="rgba(255, 255, 255, 0)",t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=0,e.imgs&&e.imgs.forEach(((i,s)=>{if(!this.cellImgs[h])return!1;const n=this.cellImgs[h][s];if(!n)return!1;const r=g&&n.activeImg||n.defaultImg,[a,d]=this.computedWidthAndHeight(r,i,e);t.drawImage(r,o+this.getOffsetX(a,e.col),l+this.getHeight(i.top,e.row),a,d)})),e.fonts&&e.fonts.forEach((h=>{let a=g&&r.fontStyle?r.fontStyle:h.fontStyle||n.fontStyle,d=g&&r.fontWeight?r.fontWeight:h.fontWeight||n.fontWeight,c=g&&r.fontSize?this.getLength(r.fontSize):this.getLength(h.fontSize||n.fontSize);const f=g&&r.lineHeight?r.lineHeight:h.lineHeight||n.lineHeight||h.fontSize||n.fontSize;t.font=`${d} ${c*i}px ${a}`,t.fillStyle=g&&r.fontColor?r.fontColor:h.fontColor||n.fontColor;let u=[],m=String(h.text);if(h.hasOwnProperty("wordWrap")?h.wordWrap:n.wordWrap){m=s(m);let i="";for(let s=0;s<m.length;s++){i+=m[s],t.measureText(i).width>this.getWidth(h.lengthLimit||n.lengthLimit,e.col)&&(u.push(i.slice(0,-1)),i=m[s])}i&&u.push(i),u.length||u.push(m)}else u=m.split("\n");u.forEach(((s,n)=>{t.fillText(s,o+this.getOffsetX(t.measureText(s).width,e.col),l+this.getHeight(h.top,e.row)+(n+1)*this.getLength(f)*i)}))}))}))}handleBackground(t,i,e,s,h,n=!1){const{ctx:r,_defaultStyle:o,_activeStyle:a}=this;return(h=n?a.background:h||o.background).includes("linear-gradient")&&(h=((t,i,e,s,h,n)=>{const r=/linear-gradient\((.+)\)/.exec(n)[1].split(",").map((t=>t.trim()));let o=r.shift(),a=[0,0,0,0];if(o.includes("deg")){o=o.slice(0,-3)%360;const t=t=>Math.tan(t/180*Math.PI);o>=0&&o<45?a=[i,e+h,i+s,e+h-s*t(o-0)]:o>=45&&o<90?a=[i,e+h,i+s-h*t(o-45),e]:o>=90&&o<135?a=[i+s,e+h,i+s-h*t(o-90),e]:o>=135&&o<180?a=[i+s,e+h,i,e+s*t(o-135)]:o>=180&&o<225?a=[i+s,e,i,e+s*t(o-180)]:o>=225&&o<270?a=[i+s,e,i+h*t(o-225),e+h]:o>=270&&o<315?a=[i,e,i+h*t(o-270),e+h]:o>=315&&o<360&&(a=[i,e,i+s,e+h-s*t(o-315)])}else o.includes("top")?a=[i,e+h,i,e]:o.includes("bottom")?a=[i,e,i,e+h]:o.includes("left")?a=[i+s,e,i,e]:o.includes("right")&&(a=[i,e,i+s,e]);const l=t.createLinearGradient(...a.map((t=>t>>0)));return r.reduce(((t,i,e)=>{const s=i.split(" ");return 1===s.length?t.addColorStop(e,s[0]):2===s.length&&t.addColorStop(...s),t}),l)})(r,t,i,e,s,h)),h}play(){this.startTime||(clearInterval(this.timer),cancelAnimationFrame(this.animationId),this.startTime=Date.now(),this.prizeFlag=void 0,this.run())}stop(t){this.prizeFlag=t%this.prizes.length}run(t=0){const{currIndex:i,prizes:e,prizeFlag:s,startTime:h,_defaultConfig:n}=this;let r=Date.now()-h;if(r>=n.accelerationTime&&void 0!==s)return this.FPS=r/t,this.endTime=Date.now(),this.stopIndex=i,this.endIndex=5*e.length+s-(i>>0),cancelAnimationFrame(this.animationId),this.slowDown();this.currIndex=(i+l(r,.1,n.speed,n.accelerationTime))%e.length,this.draw(),this.animationId=window.requestAnimationFrame(this.run.bind(this,t+1))}slowDown(){const{prizes:t,prizeFlag:i,stopIndex:e,endIndex:s,_defaultConfig:h}=this;let n=Date.now()-this.endTime;if(n>h.decelerationTime)return this.startTime=0,this.endCallback?.({...t.find(((t,e)=>e===i))}),cancelAnimationFrame(this.animationId);this.currIndex=d(n,e,s,h.decelerationTime)%t.length,this.draw(),this.animationId=window.requestAnimationFrame(this.slowDown.bind(this))}walk(){clearInterval(this.timer),this.timer=window.setInterval((()=>{this.currIndex+=1,this.draw()}),1300)}getGeometricProperty([t,i,e,s]){const{cellWidth:h,cellHeight:n}=this,r=this._defaultConfig.gutter;let o=[this.prizeArea.x+(h+r)*t,this.prizeArea.y+(n+r)*i];return e&&s&&o.push(h*e+r*(e-1),n*s+r*(s-1)),o}getLength(t){return e(t,"number")?t:e(t,"string")?this.changeUnits(t,{clean:!0}):0}getWidth(t,i=1){return e(t,"number")?t*this.dpr:e(t,"string")?this.changeUnits(t,{denominator:this.cellWidth*i+this._defaultConfig.gutter*(i-1)}):0}getHeight(t,i=1){return e(t,"number")?t*this.dpr:e(t,"string")?this.changeUnits(t,{denominator:this.cellHeight*i+this._defaultConfig.gutter*(i-1)}):0}getOffsetX(t,i=1){return(this.cellWidth*i+this._defaultConfig.gutter*(i-1)-t)/2}},t.LuckyWheel=class extends i{constructor(t,i={}){super(),this.blocks=[],this.prizes=[],this.buttons=[],this.defaultConfig={},this._defaultConfig={gutter:"0px",offsetDegree:0,speed:20,accelerationTime:2500,decelerationTime:2500},this.defaultStyle={},this._defaultStyle={fontSize:"18px",fontColor:"#000",fontStyle:"microsoft yahei ui,microsoft yahei,simsun,sans-serif",fontWeight:"400",lineHeight:"",background:"#fff",wordWrap:!0,lengthLimit:"90%"},this.Radius=0,this.prizeRadius=0,this.prizeDeg=0,this.prizeRadian=0,this.rotateDeg=0,this.maxBtnRadius=0,this.startTime=0,this.endTime=0,this.stopDeg=0,this.endDeg=0,this.animationId=0,this.FPS=16.6,this.prizeImgs=[[]],this.btnImgs=[[]],this.box=document.querySelector(t),this.canvas=document.createElement("canvas"),this.box.appendChild(this.canvas),this.ctx=this.canvas.getContext("2d"),this.initData(i),this.initComputed(),this.initWatch();let e=[[]];this.prizes&&(e=this.prizes.map((t=>t.imgs))),this.buttons&&e.push(...this.buttons.map((t=>t.imgs))),this.init(e)}initData(t){this.$set(this,"blocks",t.blocks||[]),this.$set(this,"prizes",t.prizes||[]),this.$set(this,"buttons",t.buttons||[]),this.$set(this,"defaultConfig",t.defaultConfig||{}),this.$set(this,"defaultStyle",t.defaultStyle||{}),this.$set(this,"startCallback",t.start),this.$set(this,"endCallback",t.end)}initComputed(){this.$computed(this,"_defaultConfig",(()=>({gutter:"0px",offsetDegree:0,speed:20,accelerationTime:2500,decelerationTime:2500,...this.defaultConfig}))),this.$computed(this,"_defaultStyle",(()=>({fontSize:"18px",fontColor:"#000",fontStyle:"microsoft yahei ui,microsoft yahei,simsun,sans-serif",fontWeight:"400",background:"#fff",wordWrap:!0,lengthLimit:"90%",...this.defaultStyle})))}initWatch(){this.$watch("prizes",((t,i)=>{let e=[];return i?t&&t.forEach(((t,s)=>{let h=[];const n=i[s];n?t.imgs&&t.imgs.forEach(((t,i)=>{if(!n.imgs)return h[i]=t;const e=n.imgs[i];e&&this.prizeImgs[s]&&this.prizeImgs[s][i]?t.src!==e.src&&(h[i]=t):h[i]=t})):h=t.imgs||[],e[s]=h})):e=t.map((t=>t.imgs)),this.init(e)})),this.$watch("buttons",((t,i)=>{let e=[];return i?t&&t.forEach(((t,s)=>{let h=[];const n=i[s];n&&n.imgs?t.imgs&&t.imgs.forEach(((t,i)=>{if(!n.imgs)return h[i]=t;const e=n.imgs[i];e&&this.btnImgs[s]&&this.btnImgs[s][i]?t.src!==e.src&&(h[i]=t):h[i]=t})):h=t.imgs||[],e[s]=h})):e=t.map((t=>t.imgs)),this.init([...new Array(this.prizes.length).fill(void 0),...e])}))}init(t){this.setDpr(),this.setHTMLFontSize();const{box:i,canvas:s,ctx:h,dpr:n}=this;if(!i)return;s.width=s.height=i.offsetWidth*n,this.Radius=s.width/2,this.optimizeClarity(s,2*this.Radius,2*this.Radius),h.translate(this.Radius,this.Radius);const r=()=>{this.draw(),s.onclick=t=>{h.beginPath(),h.arc(0,0,this.maxBtnRadius,0,2*Math.PI,!1),h.isPointInPath(t.offsetX,t.offsetY)&&(this.startTime||this.startCallback?.(t))}};let o=0,a=0;e(t,"array")&&(this.draw(),t.forEach(((t,i)=>{if(!t)return!1;t.forEach(((t,e)=>{a++,this.loadAndCacheImg(i,e,(()=>{o++,a===o&&r.call(this)}))}))}))),a||r.call(this)}loadAndCacheImg(t,i,e){const s=t<this.prizes.length,h=s?"prizes":"buttons",n=s?"prizeImgs":"btnImgs";t=s?t:t-this.prizes.length;const r=this[h][t];if(!r||!r.imgs)return;const o=r.imgs[i];if(!o)return;let a=new Image;this[n][t]||(this[n][t]=[]),this[n][t][i]=a,a.src=o.src,a.onload=()=>e.call(this)}computedWidthAndHeight(t,i,e,s){if(!i.width&&!i.height)return[t.width,t.height];if(i.width&&!i.height){let s=this.getWidth(i.width,e);return[s,t.height*(s/t.width)]}if(!i.width&&i.height){let e=this.getHeight(i.height,s);return[t.width*(e/t.height),e]}return[this.getWidth(i.width,e),this.getHeight(i.height,s)]}draw(){const{ctx:t,dpr:i,_defaultConfig:e,_defaultStyle:r}=this;t.clearRect(-this.Radius,-this.Radius,2*this.Radius,2*this.Radius),this.prizeRadius=this.blocks.reduce(((e,s)=>(t.beginPath(),t.fillStyle=s.background,t.arc(0,0,e,0,2*Math.PI,!1),t.fill(),e-this.getLength(s.padding.split(" ")[0])*i)),this.Radius),this.prizeDeg=360/this.prizes.length,this.prizeRadian=h(this.prizeDeg);let a=h(-90+this.rotateDeg+e.offsetDegree);const l=i=>this.getOffsetX(t.measureText(i).width),d=(t,e,s)=>{const h=t.lineHeight||r.lineHeight||t.fontSize||r.fontSize;return this.getHeight(t.top,e)+(s+1)*this.getLength(h)*i};t.save(),this.prizes.forEach(((c,g)=>{let f=a+g*this.prizeRadian,u=this.prizeRadius-this.maxBtnRadius;((t,i,e,s,r,a,l)=>{i||(i=a);let d=h(90/Math.PI/e*a),c=h(90/Math.PI/i*a),g=s+d,f=r-d,u=s+c,m=r-c;t.beginPath(),t.fillStyle=l,t.moveTo(...n(g,e)),o(t,e,g,f,!0),m>u?o(t,i,u,m,!1):t.lineTo(...n((s+r)/2,a/2/Math.abs(Math.sin((s-r)/2)))),t.closePath(),t.fill()})(t,this.maxBtnRadius,this.prizeRadius,f-this.prizeRadian/2,f+this.prizeRadian/2,this.getLength(e.gutter)*i,c.background||r.background||"rgba(0, 0, 0, 0)");let m=Math.cos(f)*this.prizeRadius,p=Math.sin(f)*this.prizeRadius;t.translate(m,p),t.rotate(f+h(90)),c.imgs&&c.imgs.forEach(((i,e)=>{if(!this.prizeImgs[g])return;const s=this.prizeImgs[g][e];if(!s)return;const[h,n]=this.computedWidthAndHeight(s,i,this.prizeRadian*this.prizeRadius,u);t.drawImage(s,this.getOffsetX(h),this.getHeight(i.top,u),h,n)})),c.fonts&&c.fonts.forEach((h=>{let n=h.fontColor||r.fontColor,o=h.fontWeight||r.fontWeight,a=this.getLength(h.fontSize||r.fontSize),c=h.fontStyle||r.fontStyle;t.fillStyle=n,t.font=`${o} ${a*i}px ${c}`;let g=[],f=String(h.text);if(h.hasOwnProperty("wordWrap")?h.wordWrap:r.wordWrap){f=s(f);let n="";for(let s=0;s<f.length;s++){n+=f[s];let o=t.measureText(n).width,a=(this.prizeRadius-d(h,u,g.length))*Math.tan(this.prizeRadian/2)*2-this.getLength(e.gutter)*i;o>this.getWidth(h.lengthLimit||r.lengthLimit,a)&&(g.push(n.slice(0,-1)),n=f[s])}n&&g.push(n),g.length||g.push(f)}else g=f.split("\n");g.filter((t=>!!t)).forEach(((i,e)=>{t.fillText(i,l(i),d(h,u,e))}))})),t.rotate(h(360)-f-h(90)),t.translate(-m,-p)})),t.restore(),this.buttons.forEach(((e,s)=>{let h=this.getHeight(e.radius);this.maxBtnRadius=Math.max(this.maxBtnRadius,h),t.beginPath(),t.fillStyle=e.background||"rgba(0, 0, 0, 0)",t.arc(0,0,h,0,2*Math.PI,!1),t.fill(),e.pointer&&(t.beginPath(),t.fillStyle=e.background||"rgba(0, 0, 0, 0)",t.moveTo(-h,0),t.lineTo(h,0),t.lineTo(0,2*-h),t.closePath(),t.fill()),e.imgs&&e.imgs.forEach(((i,n)=>{if(!this.btnImgs[s])return;const r=this.btnImgs[s][n];if(!r)return;const[o,a]=this.computedWidthAndHeight(r,i,2*this.getHeight(e.radius),2*this.getHeight(e.radius));t.drawImage(r,this.getOffsetX(o),this.getHeight(i.top,h),o,a)})),e.fonts&&e.fonts.forEach((e=>{let s=e.fontColor||r.fontColor,n=e.fontWeight||r.fontWeight,o=this.getLength(e.fontSize||r.fontSize),a=e.fontStyle||r.fontStyle;t.fillStyle=s,t.font=`${n} ${o*i}px ${a}`,String(e.text).split("\n").forEach(((i,s)=>{t.fillText(i,l(i),d(e,h,s))}))}))}))}play(){this.startTime||(cancelAnimationFrame(this.animationId),this.startTime=Date.now(),this.prizeFlag=void 0,this.run())}stop(t){this.prizeFlag=Number(t)%this.prizes.length}run(t=0){const{prizeFlag:i,prizeDeg:e,rotateDeg:s,_defaultConfig:h}=this;let n=Date.now()-this.startTime;if(n>=h.accelerationTime&&void 0!==i)return this.FPS=n/t,this.endTime=Date.now(),this.stopDeg=s,this.endDeg=1800-i*e-s-h.offsetDegree,cancelAnimationFrame(this.animationId),this.slowDown();this.rotateDeg=(s+l(n,0,h.speed,h.accelerationTime))%360,this.draw(),this.animationId=window.requestAnimationFrame(this.run.bind(this,t+1))}slowDown(){const{prizes:t,prizeFlag:i,stopDeg:e,endDeg:s,_defaultConfig:h}=this;let n=Date.now()-this.endTime;if(n>=h.decelerationTime)return this.startTime=0,this.endCallback?.({...t.find(((t,e)=>e===i))}),cancelAnimationFrame(this.animationId);this.rotateDeg=d(n,e,s,h.decelerationTime)%360,this.draw(),this.animationId=window.requestAnimationFrame(this.slowDown.bind(this))}getLength(t){return e(t,"number")?t:e(t,"string")?this.changeUnits(t,{clean:!0}):0}getWidth(t,i=this.prizeRadian*this.prizeRadius){return e(t,"number")?t*this.dpr:e(t,"string")?this.changeUnits(t,{denominator:i}):0}getHeight(t,i=this.prizeRadius){return e(t,"number")?t*this.dpr:e(t,"string")?this.changeUnits(t,{denominator:i}):0}getOffsetX(t){return-t/2}},Object.defineProperty(t,"__esModule",{value:!0})})); |
{ | ||
"name": "lucky-canvas", | ||
"version": "1.0.1", | ||
"version": "1.0.2", | ||
"description": "一个基于原生 js 的(大转盘抽奖 / 九宫格抽奖)插件", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
<div align="center"> | ||
<img src="./logo.png" width="200" alt="logo" /> | ||
<img src="./web.svg" width="200" alt="logo" /> | ||
<h1>lucky-canvas 抽奖插件</h1> | ||
@@ -12,24 +12,21 @@ <p>一个基于 JavaScript 的 ( 大转盘 / 九宫格 ) 抽奖插件</p> | ||
<p> | ||
<a href="https://github.com/luckdraw/lucky-canvas/stargazers" target="_black"> | ||
<img src="https://img.shields.io/github/stars/luckdraw/lucky-canvas?&logo=github" alt="stars" /> | ||
<a href="https://github.com/LuckDraw/lucky-canvas/stargazers" target="_black"> | ||
<img src="https://img.shields.io/github/stars/luckdraw/lucky-canvas?color=%23ffca28&logo=github&style=flat-square" alt="stars" /> | ||
</a> | ||
<a href="https://github.com/luckdraw/lucky-canvas/network/members" target="_black"> | ||
<img src="https://img.shields.io/github/forks/luckdraw/lucky-canvas?logo=github" alt="forks" /> | ||
<img src="https://img.shields.io/github/forks/luckdraw/lucky-canvas?color=%23ffca28&logo=github&style=flat-square" alt="forks" /> | ||
</a> | ||
<a href="https://www.npmjs.com/package/lucky-canvas" target="_black"> | ||
<img src="https://img.shields.io/github/package-json/v/luckdraw/lucky-canvas?&logo=npm" alt="version" /> | ||
<img src="https://img.shields.io/github/package-json/v/luckdraw/lucky-canvas?color=%23ffca28&logo=npm&style=flat-square" alt="version" /> | ||
</a> | ||
<a href="https://www.npmjs.com/package/lucky-canvas" target="_black"> | ||
<img src="https://img.shields.io/npm/dt/lucky-canvas?&logo=npm" alt="downloads" /> | ||
<img src="https://img.shields.io/npm/dm/lucky-canvas?color=%23ffca28&logo=npm&style=flat-square" alt="downloads" /> | ||
</a> | ||
<a href="https://github.com/luckdraw/lucky-canvas/tree/master/dist" target="_black"> | ||
<img src="https://img.shields.io/github/size/luckdraw/lucky-canvas/dist/lucky-canvas.umd.min.js?&logo=npm" alt="size" /> | ||
</a> | ||
</p> | ||
<p> | ||
<a href="https://github.com/buuing" target="_black"> | ||
<img src="https://img.shields.io/badge/Author-%20buuing%20-7289da.svg?&logo=github" alt="author" /> | ||
<img src="https://img.shields.io/badge/Author-%20buuing%20-7289da.svg?&logo=github&style=flat-square" alt="author" /> | ||
</a> | ||
<a href="https://github.com/luckdraw/lucky-canvas/blob/master/LICENSE" target="_black"> | ||
<img src="https://img.shields.io/github/license/luckdraw/lucky-canvas?&logo=github" alt="license" /> | ||
<img src="https://img.shields.io/github/license/luckdraw/lucky-canvas?color=%232dce89&logo=github&style=flat-square" alt="license" /> | ||
</a> | ||
@@ -63,3 +60,3 @@ </p> | ||
// 大转盘抽奖 | ||
let luckyWheel = new LuckDraw.LuckyWheel('#my-lucky', { | ||
let luckyWheel = new LuckyCanvas.LuckyWheel('#my-lucky', { | ||
// ...你的配置 | ||
@@ -69,3 +66,3 @@ }) | ||
// 九宫格抽奖 | ||
let luckyGrid = new LuckDraw.LuckyGrid('#my-lucky', { | ||
let luckyGrid = new LuckyCanvas.LuckyGrid('#my-lucky', { | ||
// ...你的配置 | ||
@@ -72,0 +69,0 @@ }) |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
173700
3181
0
74