UNPKG

vue-spin-the-wheel

Version:

Component "Wheel of Names" for Vue

216 lines (215 loc) 7.49 kB
import { ref as C, computed as z, onMounted as _, onUpdated as $, watch as p, defineComponent as L, openBlock as R, createElementBlock as k, createElementVNode as P, normalizeStyle as T, unref as f, renderSlot as D, toDisplayString as F } from "vue"; function O(t, d) { const c = []; for (; t !== ""; ) { let i = t.substr(0, d); if (t.charAt(d) !== "" && t.charAt(d) !== " ") { const e = i.lastIndexOf(" "); e !== -1 && (i = i.substr(0, e)); } t = t.replace(i, "").trim(), c.push(i); } return c; } const q = { radius: 250, // Radius of a circle textRadius: 190, // The distance between the prize location and the center of the circle textLength: 6, // Prize text 1 line of characters, maximum 2 lines textDirection: "horizontal", // Prize Text Direction lineHeight: 20, // Text line height borderWidth: 0, // Outer border of circle borderColor: "transparent", // The color of the outer border btnText: "Spin", // The text of the start button btnWidth: 140, // Button width fontSize: 34 // Prize text font size }; function Z(t) { const d = C(), c = z(() => Object.assign(q, t.canvas || {})); let i, e; function g() { if (i = d.value, i.getContext) { const { radius: o, textRadius: r, borderWidth: n, borderColor: l, fontSize: v } = c.value; if (!o || !r || !n || !l || !v) throw new Error("radius, textRadius, borderWidth, borderColor, and fontSize are required"); const h = Math.PI / (t.prizes.length / 2); e = i.getContext("2d"), e.clearRect(0, 0, o * 2, o * 2), e.strokeStyle = l, e.lineWidth = n * 2, e.font = `${v}px Arial`, t.prizes.forEach((u, m) => { w(u, m, h, o, r, n); }); } } function w(o, r, n, l, v, h = 0) { const u = r * n - Math.PI / 2; e.fillStyle = o.bgColor, e.beginPath(), e.arc(l, l, l - h, u, u + n, !1), e.stroke(), e.arc(l, l, 0, u + n, u, !0), e.fill(), e.save(), e.fillStyle = o.color, e.translate(l + Math.cos(u + n / 2) * v, l + Math.sin(u + n / 2) * v), S(u, n, o.name), e.restore(); } function S(o, r, n) { const { lineHeight: l, textLength: v, textDirection: h } = c.value; if (!l || !v || !h) throw new Error("lineHeight, textLength, and textDirection are required"); const u = O(n, v); u && (h === "vertical" ? e.rotate(o + r / 2 + Math.PI) : e.rotate(o + r / 2 + Math.PI / 2), u.forEach((m, I) => x(m, I, h, l, u.length))); } function x(o, r, n, l, v = 0) { let h = -e.measureText(o).width / 2, u = (r + 1) * l; n === "vertical" && (h = 0, u = (r + 1) * l - v * l / 2), e.fillText(o, h, u); } return _(() => { t.type === "canvas" && g(); }), $(() => { t.type === "canvas" && g(); }), { wheelEl: d, canvasConfig: c, drawCanvas: g }; } function j(t, d) { const c = C(!1), i = C(0), e = C(), g = z(() => t.useWeight ? 100 : t.prizes.reduce((a, s) => a + (s.probability || 0), 0)), w = z(() => { if (t.useWeight) return 0; const a = [...t.prizes].sort((y, E) => { const M = String(y.probability).split(".")[1], W = String(E.probability).split(".")[1], A = M ? M.length : 0; return (W ? W.length : 0) - A; }), s = String(a[0].probability).split(".")[1], b = s ? s.length : 0; return [1, 10, 100, 1e3, 1e4][b > 4 ? 4 : b]; }), S = z(() => { const a = []; return t.prizes.forEach((s) => { const b = t.useWeight ? s.weight || 0 : (s.probability || 0) * w.value; console.log(a, b, t, s); const y = new Array(b).fill(s.id); a.push(...y); }), a; }), x = z(() => c.value ? t.duration / 1e3 : 0), o = z(() => ({ "-webkit-transform": `rotateZ(${i.value}deg)`, transform: `rotateZ(${i.value}deg)`, "-webkit-transition-duration": `${x.value}s`, "transition-duration": `${x.value}s`, "-webkit-transition-timing-function:": t.timingFun, "transition-timing-function": t.timingFun })), r = z(() => { let a = t.angleBase * 360; return t.angleBase < 0 && (a -= 360), a; }), n = z(() => !t.disabled && !c.value && g.value === 100); p(() => t.prizeId, (a) => { if (!c.value) return; let s = B(a); t.angleBase < 0 && (s -= 360); const b = i.value; let y = t.angleBase * 360 + s; const E = 360 * Math.floor((y - b) / 360); t.angleBase >= 0 ? y += Math.abs(E) : y += -360 - E, i.value = y; }), l(); function l() { if (g.value !== 100) throw new Error("Prizes Is Error: Sum of probabilities is not 100!"); return !0; } function v() { if (n.value) { if (t.verify) { d("rotateStart", h); return; } d("rotateStart"), h(); } } function h() { c.value = !0; const a = t.prizeId || I(); i.value = r.value + B(a); } function u() { c.value = !1, i.value %= 360, d("rotateEnd", e.value); } function m(a, s) { return a = Math.ceil(a), s = Math.floor(s), Math.floor(Math.random() * (s - a + 1)) + a; } function I() { const a = S.value.length; return S.value[m(0, a - 1)]; } function B(a) { const s = 360 / t.prizes.length, b = t.prizes.findIndex((y) => y.id === a); return e.value = t.prizes[b], 360 - (s * b + s / 2); } return { handleRotate: v, rotateStyle: o, onRotateEnd: u }; } const H = { class: "fw-container" }, N = ["width", "height"], U = { class: "fw-btn" }, V = /* @__PURE__ */ L({ __name: "index", props: { type: { default: "canvas" }, useWeight: { type: Boolean, default: !1 }, disabled: { type: Boolean, default: !1 }, canRotate: { type: Boolean, default: !1 }, verify: { type: Boolean, default: !1 }, canvas: null, duration: { default: 6e3 }, timingFun: { default: "cubic-bezier(0.36, 0.95, 0.64, 1)" }, angleBase: { default: 10 }, prizeId: { default: 0 }, prizes: { default: () => [] } }, emits: ["rotateStart", "rotateEnd"], setup(t, { expose: d, emit: c }) { const i = t, { wheelEl: e, canvasConfig: g } = Z(i), { handleRotate: w, rotateStyle: S, onRotateEnd: x } = j(i, c); return d({ startRotate: () => { console.log("startRotate"), w(); } }), (o, r) => (R(), k("div", H, [ P("div", { class: "fw-wheel", style: T(f(S)), onTransitionend: r[0] || (r[0] = //@ts-ignore (...n) => f(x) && f(x)(...n)), "on:webkitTransitionend": r[1] || (r[1] = //@ts-ignore (...n) => f(x) && f(x)(...n)) }, [ t.type === "canvas" ? (R(), k("canvas", { key: 0, ref_key: "wheelEl", ref: e, width: (f(g).radius || 1) * 2, height: (f(g).radius || 1) * 2 }, null, 8, N)) : D(o.$slots, "wheel", { key: 1 }, void 0, !0) ], 36), P("div", U, [ t.type === "canvas" ? (R(), k("div", { key: 0, class: "fw-btn__btn", style: T({ width: f(g).btnWidth + "px", height: f(g).btnWidth + "px" }), onClick: r[2] || (r[2] = //@ts-ignore (...n) => f(w) && f(w)(...n)) }, F(f(g).btnText), 5)) : (R(), k("div", { key: 1, class: "fw-btn__image", onClick: r[3] || (r[3] = //@ts-ignore (...n) => f(w) && f(w)(...n)) }, [ D(o.$slots, "button", {}, void 0, !0) ])) ]) ])); } }), X = (t, d) => { const c = t.__vccOpts || t; for (const [i, e] of d) c[i] = e; return c; }, J = /* @__PURE__ */ X(V, [["__scopeId", "data-v-45b073d4"]]); export { J as SpinTheWheel };