vendor: 42,480 bytes, lines 1-1402
1/** 2 * spin-wheel (ESM) v5.0.2 3 * https://github.com/CrazyTim/spin-wheel#readme 4 * Copyright (c) CrazyTim 2024. 5 * Distributed under the MIT license. 6 */ 7var N = Object.defineProperty; 8var M = Object.getOwnPropertySymbols; 9var j = Object.prototype.hasOwnProperty, 10 H = Object.prototype.propertyIsEnumerable; 11var R = Math.pow, 12 w = (i, e, t) => e in i ? N(i, e, { 13 enumerable: !0, 14 configurable: !0, 15 writable: !0, 16 value: t 17 }) : i[e] = t, 18 L = (i, e) => { 19 for (var t in e || (e = {})) 20 j.call(e, t) && w(i, t, e[t]); 21 if (M) 22 for (var t of M(e)) 23 H.call(e, t) && w(i, t, e[t]); 24 return i 25 }; 26function x(i=0, e=0, t=14) { 27 return parseFloat((Math.random() * (e - i) + i).toFixed(t)) 28} 29function m(i=0) { 30 return i * Math.PI / 180 31} 32function I(i, e, t) { 33 return e < t ? e <= i && i < t : e <= i || i < t 34} 35function E(i, e, t, s) { 36 s.save(), 37 s.font = `1px ${e}`; 38 let n = s.measureText(i).width; 39 return s.restore(), t / n 40} 41function W(i={ 42 x: 0, 43 y: 0 44}, e, t, s) { 45 return R(i.x - e, 2) + R(i.y - t, 2) <= R(s, 2) 46} 47function v(i={ 48 x: 0, 49 y: 0 50}, e={}, t=1) { 51 let s = e.getBoundingClientRect(); 52 return { 53 x: (i.x - s.left) * t, 54 y: (i.y - s.top) * t 55 } 56} 57function A(i, e, t, s) { 58 let n = i - t, 59 r = e - s, 60 a = Math.atan2(-r, -n); 61 return a *= 180 / Math.PI, a < 0 && (a += 360), a 62} 63function X(i=0, e=0) { 64 let t = i + e, 65 s; 66 return t > 0 ? s = t % 360 : s = 360 + t % 360, s === 360 && (s = 0), s 67} 68function P(i=0, e=0) { 69 let t = 180 - e; 70 return 180 - X(i, t) 71} 72function T(i=0, e=0, t=1) { 73 let s = (i % 360 + e) % 360; 74 return s = Y(s), s = (t === 1 ? 360 - s : 360 + s) % 360, s *= t, i + s 75} 76function b(i) { 77 return typeof i == "object" && !Array.isArray(i) && i !== null 78} 79function u(i) { 80 return typeof i == "number" && !Number.isNaN(i) 81} 82function l({val: i, isValid: e, errorMessage: t, defaultValue: s, action: n=null}) { 83 if (e) 84 return n ? n() : i; 85 if (i === void 0) 86 return s; 87 throw new Error(t) 88} 89function Y(i=0) { 90 return Number(i.toFixed(9)) 91} 92function k(i) { 93 return Math.sin(i * Math.PI / 2) 94} 95function z(i={}, e={}) { 96 if (window.ResizeObserver) { 97 let t = new ResizeObserver(() => { 98 e({ 99 redraw: !0 100 }) 101 }); 102 return t.observe(i), { 103 stop: () => { 104 t.unobserve(i), 105 t.disconnect() 106 } 107 } 108 } 109 return window.addEventListener("resize", e), { 110 stop: () => { 111 window.removeEventListener("resize", e) 112 } 113 } 114} 115var p = Object.freeze({ 116 left: "left", 117 right: "right", 118 center: "center" 119 }), 120 o = Object.freeze({ 121 wheel: { 122 borderColor: "#000", 123 borderWidth: 1, 124 debug: !1, 125 image: null, 126 isInteractive: !0, 127 itemBackgroundColors: ["#fff"], 128 itemLabelAlign: p.right, 129 itemLabelBaselineOffset: 0, 130 itemLabelColors: ["#000"], 131 itemLabelFont: "sans-serif", 132 itemLabelFontSizeMax: 500, 133 itemLabelRadius: .85, 134 itemLabelRadiusMax: .2, 135 itemLabelRotation: 0, 136 itemLabelStrokeColor: "#fff", 137 itemLabelStrokeWidth: 0, 138 items: [], 139 lineColor: "#000", 140 lineWidth: 1, 141 pixelRatio: 0, 142 radius: .95, 143 rotation: 0, 144 rotationResistance: -35, 145 rotationSpeedMax: 300, 146 offset: { 147 x: 0, 148 y: 0 149 }, 150 onCurrentIndexChange: null, 151 onRest: null, 152 onSpin: null, 153 overlayImage: null, 154 pointerAngle: 0 155 }, 156 item: { 157 backgroundColor: null, 158 image: null, 159 imageOpacity: 1, 160 imageRadius: .5, 161 imageRotation: 0, 162 imageScale: 1, 163 label: "", 164 labelColor: null, 165 value: null, 166 weight: 1 167 } 168 }), 169 c = Object.freeze({ 170 pointerLineColor: "#ff00ff", 171 labelBoundingBoxColor: "#ff00ff", 172 labelRadiusColor: "#00ff00", 173 dragPointHue: 300 174 }); 175function V(i={}) { 176 $(i), 177 i._handler_onResize = z(i._canvasContainer, ({redraw: t=!0}) => { 178 i.resize(), 179 t && i.draw(performance.now()) 180 }); 181 let e = () => { 182 i._mediaQueryList = window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`), 183 i._mediaQueryList.addEventListener("change", i._handler_onDevicePixelRatioChange, { 184 once: !0 185 }) 186 }; 187 i._handler_onDevicePixelRatioChange = () => { 188 i.resize(), 189 e() 190 }, 191 e() 192} 193function F(i={}) { 194 let e = i.canvas; 195 "PointerEvent" in window ? (e.removeEventListener("pointerdown", i._handler_onPointerDown), e.removeEventListener("pointermove", i._handler_onPointerMoveRefreshCursor)) : (e.removeEventListener("touchstart", i._handler_onTouchStart), e.removeEventListener("mousedown", i._handler_onMouseDown), e.removeEventListener("mousemove", i._handler_onMouseMoveRefreshCursor)), 196 i._handler_onResize.stop(), 197 i._mediaQueryList.removeEventListener("change", i._handler_onDevicePixelRatioChange) 198} 199function $(i={}) { 200 let e = i.canvas; 201 i._handler_onPointerMoveRefreshCursor = (t={}) => { 202 let s = { 203 x: t.clientX, 204 y: t.clientY 205 }; 206 i._isCursorOverWheel = i.wheelHitTest(s), 207 i.refreshCursor() 208 }, 209 i._handler_onMouseMoveRefreshCursor = (t={}) => { 210 let s = { 211 x: t.clientX, 212 y: t.clientY 213 }; 214 i._isCursorOverWheel = i.wheelHitTest(s), 215 i.refreshCursor() 216 }, 217 i._handler_onPointerDown = (t={}) => { 218 let s = { 219 x: t.clientX, 220 y: t.clientY 221 }; 222 if (!i.isInteractive || !i.wheelHitTest(s)) 223 return; 224 t.preventDefault(), 225 i.dragStart(s), 226 e.setPointerCapture(t.pointerId), 227 e.addEventListener("pointermove", n), 228 e.addEventListener("pointerup", r), 229 e.addEventListener("pointercancel", r), 230 e.addEventListener("pointerout", r); 231 function n(a={}) { 232 a.preventDefault(), 233 i.dragMove({ 234 x: a.clientX, 235 y: a.clientY 236 }) 237 } 238 function r(a={}) { 239 a.preventDefault(), 240 e.releasePointerCapture(a.pointerId), 241 e.removeEventListener("pointermove", n), 242 e.removeEventListener("pointerup", r), 243 e.removeEventListener("pointercancel", r), 244 e.removeEventListener("pointerout", r), 245 i.dragEnd() 246 } 247 }, 248 i._handler_onMouseDown = (t={}) => { 249 let s = { 250 x: t.clientX, 251 y: t.clientY 252 }; 253 if (!i.isInteractive || !i.wheelHitTest(s)) 254 return; 255 i.dragStart(s), 256 document.addEventListener("mousemove", n), 257 document.addEventListener("mouseup", r); 258 function n(a={}) { 259 a.preventDefault(), 260 i.dragMove({ 261 x: a.clientX, 262 y: a.clientY 263 }) 264 } 265 function r(a={}) { 266 a.preventDefault(), 267 document.removeEventListener("mousemove", n), 268 document.removeEventListener("mouseup", r), 269 i.dragEnd() 270 } 271 }, 272 i._handler_onTouchStart = (t={}) => { 273 let s = { 274 x: t.targetTouches[0].clientX, 275 y: t.targetTouches[0].clientY 276 }; 277 if (!i.isInteractive || !i.wheelHitTest(s)) 278 return; 279 t.preventDefault(), 280 i.dragStart(s), 281 e.addEventListener("touchmove", n), 282 e.addEventListener("touchend", r), 283 e.addEventListener("touchcancel", r); 284 function n(a={}) { 285 a.preventDefault(), 286 i.dragMove({ 287 x: a.targetTouches[0].clientX, 288 y: a.targetTouches[0].clientY 289 }) 290 } 291 function r(a={}) { 292 a.preventDefault(), 293 e.removeEventListener("touchmove", n), 294 e.removeEventListener("touchend", r), 295 e.removeEventListener("touchcancel", r), 296 i.dragEnd() 297 } 298 }, 299 "PointerEvent" in window ? (e.addEventListener("pointerdown", i._handler_onPointerDown), e.addEventListener("pointermove", i._handler_onPointerMoveRefreshCursor)) : (e.addEventListener("touchstart", i._handler_onTouchStart), e.addEventListener("mousedown", i._handler_onMouseDown), e.addEventListener("mousemove", i._handler_onMouseMoveRefreshCursor)) 300} 301var S = class { 302 constructor(e, t={}) 303 { 304 if (!b(e)) 305 throw new Error("wheel must be an instance of Wheel"); 306 if (!b(t) && t !== null) 307 throw new Error("props must be an Object or null"); 308 this._wheel = e; 309 for (let s of Object.keys(o.item)) 310 this["_" + s] = o.item[s]; 311 t ? this.init(t) : this.init(o.item) 312 } 313 init(e={}) 314 { 315 this.backgroundColor = e.backgroundColor, 316 this.image = e.image, 317 this.imageOpacity = e.imageOpacity, 318 this.imageRadius = e.imageRadius, 319 this.imageRotation = e.imageRotation, 320 this.imageScale = e.imageScale, 321 this.label = e.label, 322 this.labelColor = e.labelColor, 323 this.value = e.value, 324 this.weight = e.weight 325 } 326 get backgroundColor() 327 { 328 return this._backgroundColor 329 } 330 set backgroundColor(e) 331 { 332 typeof e == "string" ? this._backgroundColor = e : this._backgroundColor = o.item.backgroundColor, 333 this._wheel.refresh() 334 } 335 get image() 336 { 337 return this._image 338 } 339 set image(e) 340 { 341 e instanceof HTMLImageElement ? this._image = e : this._image = o.item.image, 342 this._wheel.refresh() 343 } 344 get imageOpacity() 345 { 346 return this._imageOpacity 347 } 348 set imageOpacity(e) 349 { 350 typeof e == "number" ? this._imageOpacity = e : this._imageOpacity = o.item.imageOpacity, 351 this._wheel.refresh() 352 } 353 get imageRadius() 354 { 355 return this._imageRadius 356 } 357 set imageRadius(e) 358 { 359 typeof e == "number" ? this._imageRadius = e : this._imageRadius = o.item.imageRadius, 360 this._wheel.refresh() 361 } 362 get imageRotation() 363 { 364 return this._imageRotation 365 } 366 set imageRotation(e) 367 { 368 typeof e == "number" ? this._imageRotation = e : this._imageRotation = o.item.imageRotation, 369 this._wheel.refresh() 370 } 371 get imageScale() 372 { 373 return this._imageScale 374 } 375 set imageScale(e) 376 { 377 typeof e == "number" ? this._imageScale = e : this._imageScale = o.item.imageScale, 378 this._wheel.refresh() 379 } 380 get label() 381 { 382 return this._label 383 } 384 set label(e) 385 { 386 typeof e == "string" ? this._label = e : this._label = o.item.label, 387 this._wheel.refresh() 388 } 389 get labelColor() 390 { 391 return this._labelColor 392 } 393 set labelColor(e) 394 { 395 typeof e == "string" ? this._labelColor = e : this._labelColor = o.item.labelColor, 396 this._wheel.refresh() 397 } 398 get value() 399 { 400 return this._value 401 } 402 set value(e) 403 { 404 e !== void 0 ? this._value = e : this._value = o.item.value 405 } 406 get weight() 407 { 408 return this._weight 409 } 410 set weight(e) 411 { 412 typeof e == "number" ? this._weight = e : this._weight = o.item.weight 413 } 414 getIndex() 415 { 416 let e = this._wheel.items.findIndex(t => t === this); 417 if (e === -1) 418 throw new Error("Item not found in parent Wheel"); 419 return e 420 } 421 getCenterAngle() 422 { 423 let e = this._wheel.getItemAngles()[this.getIndex()]; 424 return e.start + (e.end - e.start) / 2 425 } 426 getStartAngle() 427 { 428 return this._wheel.getItemAngles()[this.getIndex()].start 429 } 430 getEndAngle() 431 { 432 return this._wheel.getItemAngles()[this.getIndex()].end 433 } 434 getRandomAngle() 435 { 436 return x(this.getStartAngle(), this.getEndAngle()) 437 } 438} 439; 440var B = class { 441 constructor(e, t={}) 442 { 443 if (!(e instanceof Element)) 444 throw new Error("container must be an instance of Element"); 445 if (!b(t) && t !== null) 446 throw new Error("props must be an Object or null"); 447 this._frameRequestId = null, 448 this._rotationSpeed = 0, 449 this._rotationDirection = 1, 450 this._spinToTimeEnd = null, 451 this._lastSpinFrameTime = null, 452 this._isCursorOverWheel = !1, 453 this.add(e); 454 for (let s of Object.keys(o.wheel)) 455 this["_" + s] = o.wheel[s]; 456 t ? this.init(t) : this.init(o.wheel) 457 } 458 init(e={}) 459 { 460 this._isInitialising = !0, 461 this.borderColor = e.borderColor, 462 this.borderWidth = e.borderWidth, 463 this.debug = e.debug, 464 this.image = e.image, 465 this.isInteractive = e.isInteractive, 466 this.itemBackgroundColors = e.itemBackgroundColors, 467 this.itemLabelAlign = e.itemLabelAlign, 468 this.itemLabelBaselineOffset = e.itemLabelBaselineOffset, 469 this.itemLabelColors = e.itemLabelColors, 470 this.itemLabelFont = e.itemLabelFont, 471 this.itemLabelFontSizeMax = e.itemLabelFontSizeMax, 472 this.itemLabelRadius = e.itemLabelRadius, 473 this.itemLabelRadiusMax = e.itemLabelRadiusMax, 474 this.itemLabelRotation = e.itemLabelRotation, 475 this.itemLabelStrokeColor = e.itemLabelStrokeColor, 476 this.itemLabelStrokeWidth = e.itemLabelStrokeWidth, 477 this.items = e.items, 478 this.lineColor = e.lineColor, 479 this.lineWidth = e.lineWidth, 480 this.pixelRatio = e.pixelRatio, 481 this.rotationSpeedMax = e.rotationSpeedMax, 482 this.radius = e.radius, 483 this.rotation = e.rotation, 484 this.rotationResistance = e.rotationResistance, 485 this.offset = e.offset, 486 this.onCurrentIndexChange = e.onCurrentIndexChange, 487 this.onRest = e.onRest, 488 this.onSpin = e.onSpin, 489 this.overlayImage = e.overlayImage, 490 this.pointerAngle = e.pointerAngle 491 } 492 add(e) 493 { 494 this._canvasContainer = e, 495 this.canvas = document.createElement("canvas"), 496 this.canvas.style.display = "block", 497 this._context = this.canvas.getContext("2d"), 498 this._canvasContainer.append(this.canvas), 499 V(this), 500 this._isInitialising === !1 && this.resize() 501 } 502 remove() 503 { 504 this.canvas !== null && (this._frameRequestId !== null && window.cancelAnimationFrame(this._frameRequestId), F(this), this._canvasContainer.removeChild(this.canvas), this._canvasContainer = null, this.canvas = null, this._context = null) 505 } 506 resize() 507 { 508 if (this.canvas === null) 509 return; 510 this.canvas.style.width = this._canvasContainer.clientWidth + "px", 511 this.canvas.style.height = this._canvasContainer.clientHeight + "px"; 512 let [e, t] = [this._canvasContainer.clientWidth * this.getActualPixelRatio(), this._canvasContainer.clientHeight * this.getActualPixelRatio()]; 513 this.canvas.width = e, 514 this.canvas.height = t; 515 let s = Math.min(e, t), 516 n = { 517 w: s - s * this._offset.x, 518 h: s - s * this._offset.y 519 }, 520 r = Math.min(e / n.w, t / n.h); 521 this._size = Math.max(n.w * r, n.h * r), 522 this._center = { 523 x: e / 2 + e * this._offset.x, 524 y: t / 2 + t * this._offset.y 525 }, 526 this._actualRadius = this._size / 2 * this.radius, 527 this._itemLabelFontSize = this.itemLabelFontSizeMax * (this._size / 500), 528 this._labelMaxWidth = this._actualRadius * (this.itemLabelRadius - this.itemLabelRadiusMax), 529 this.itemLabelAlign === "center" && (this._labelMaxWidth *= 2); 530 for (let a of this._items) 531 this._itemLabelFontSize = Math.min(this._itemLabelFontSize, E(a.label, this.itemLabelFont, this._labelMaxWidth, this._context)); 532 this.refresh() 533 } 534 draw(e=0) 535 { 536 if (this._frameRequestId = null, this._context === null || this.canvas === null) 537 return; 538 let t = this._context; 539 t.clearRect(0, 0, this.canvas.width, this.canvas.height), 540 this.animateRotation(e); 541 let s = this.getItemAngles(this._rotation), 542 n = this.getScaledNumber(this._borderWidth); 543 t.textBaseline = "middle", 544 t.textAlign = this.itemLabelAlign, 545 t.font = this._itemLabelFontSize + "px " + this.itemLabelFont; 546 for (let [r, a] of s.entries()) { 547 let d = this._items[r], 548 h = new Path2D; 549 h.moveTo(this._center.x, this._center.y), 550 h.arc(this._center.x, this._center.y, this._actualRadius - n / 2, m(a.start + -90), m(a.end + -90)), 551 d.path = h 552 } 553 this.drawItemBackgrounds(t, s), 554 this.drawItemImages(t, s), 555 this.drawItemLines(t, s), 556 this.drawItemLabels(t, s), 557 this.drawBorder(t), 558 this.drawImage(t, this._image, !1), 559 this.drawImage(t, this._overlayImage, !0), 560 this.drawDebugPointerLine(t), 561 this._isInitialising = !1 562 } 563 drawItemBackgrounds(e, t=[]) 564 { 565 var s; 566 for (let [n, r] of t.entries()) { 567 let a = this._items[n]; 568 e.fillStyle = (s = a.backgroundColor) != null ? s : this._itemBackgroundColors[n % this._itemBackgroundColors.length], 569 e.fill(a.path) 570 } 571 } 572 drawItemImages(e, t=[]) 573 { 574 for (let [s, n] of t.entries()) { 575 let r = this._items[s]; 576 if (r.image === null) 577 continue; 578 e.save(), 579 e.clip(r.path); 580 let a = n.start + (n.end - n.start) / 2; 581 e.translate(this._center.x + Math.cos(m(a + -90)) * (this._actualRadius * r.imageRadius), this._center.y + Math.sin(m(a + -90)) * (this._actualRadius * r.imageRadius)), 582 e.rotate(m(a + r.imageRotation)), 583 e.globalAlpha = r.imageOpacity; 584 let d = this._size / 500 * r.image.width * r.imageScale, 585 h = this._size / 500 * r.image.height * r.imageScale, 586 C = -d / 2, 587 _ = -h / 2; 588 e.drawImage(r.image, C, _, d, h), 589 e.restore() 590 } 591 } 592 drawImage(e, t, s=!1) 593 { 594 if (t === null) 595 return; 596 e.translate(this._center.x, this._center.y), 597 s || e.rotate(m(this._rotation)); 598 let n = s ? this._size : this._size * this.radius, 599 r = -(n / 2); 600 e.drawImage(t, r, r, n, n), 601 e.resetTransform() 602 } 603 drawDebugPointerLine(e) 604 { 605 !this.debug || (e.translate(this._center.x, this._center.y), e.rotate(m(this._pointerAngle + -90)), e.beginPath(), e.moveTo(0, 0), e.lineTo(this._actualRadius * 2, 0), e.strokeStyle = c.pointerLineColor, e.lineWidth = this.getScaledNumber(2), e.stroke(), e.resetTransform()) 606 } 607 drawBorder(e) 608 { 609 if (this._borderWidth <= 0) 610 return; 611 let t = this.getScaledNumber(this._borderWidth), 612 s = this._borderColor || "transparent"; 613 if (e.beginPath(), e.strokeStyle = s, e.lineWidth = t, e.arc(this._center.x, this._center.y, this._actualRadius - t / 2, 0, 2 * Math.PI), e.stroke(), this.debug) { 614 let n = this.getScaledNumber(1); 615 e.beginPath(), 616 e.strokeStyle = e.strokeStyle = c.labelRadiusColor, 617 e.lineWidth = n, 618 e.arc(this._center.x, this._center.y, this._actualRadius * this.itemLabelRadius, 0, 2 * Math.PI), 619 e.stroke(), 620 e.beginPath(), 621 e.strokeStyle = e.strokeStyle = c.labelRadiusColor, 622 e.lineWidth = n, 623 e.arc(this._center.x, this._center.y, this._actualRadius * this.itemLabelRadiusMax, 0, 2 * Math.PI), 624 e.stroke() 625 } 626 } 627 drawItemLines(e, t=[]) 628 { 629 if (this._lineWidth <= 0) 630 return; 631 let s = this.getScaledNumber(this._lineWidth), 632 n = this.getScaledNumber(this._borderWidth); 633 e.translate(this._center.x, this._center.y); 634 for (let r of t) 635 e.rotate(m(r.start + -90)), 636 e.beginPath(), 637 e.moveTo(0, 0), 638 e.lineTo(this._actualRadius - n, 0), 639 e.strokeStyle = this.lineColor, 640 e.lineWidth = s, 641 e.stroke(), 642 e.rotate(-m(r.start + -90)); 643 e.resetTransform() 644 } 645 drawItemLabels(e, t=[]) 646 { 647 let s = this._itemLabelFontSize * -this.itemLabelBaselineOffset, 648 n = this.getScaledNumber(1), 649 r = this.getScaledNumber(this._itemLabelStrokeWidth * 2); 650 for (let [a, d] of t.entries()) { 651 let h = this._items[a], 652 C = h.labelColor || this._itemLabelColors[a % this._itemLabelColors.length] || "transparent"; 653 if (h.label.trim() === "" || C === "transparent") 654 continue; 655 e.save(), 656 e.clip(h.path); 657 let _ = d.start + (d.end - d.start) / 2; 658 if (e.translate(this._center.x + Math.cos(m(_ + -90)) * (this._actualRadius * this.itemLabelRadius), this._center.y + Math.sin(m(_ + -90)) * (this._actualRadius * this.itemLabelRadius)), e.rotate(m(_ + -90)), e.rotate(m(this.itemLabelRotation)), this.debug) { 659 e.save(); 660 let f = 0; 661 this.itemLabelAlign === "left" ? f = this._labelMaxWidth : this.itemLabelAlign === "center" && (f = this._labelMaxWidth / 2), 662 e.beginPath(), 663 e.moveTo(f, 0), 664 e.lineTo(-this._labelMaxWidth + f, 0), 665 e.strokeStyle = c.labelBoundingBoxColor, 666 e.lineWidth = n, 667 e.stroke(), 668 e.strokeRect(f, -this._itemLabelFontSize / 2, -this._labelMaxWidth, this._itemLabelFontSize), 669 e.restore() 670 } 671 if (this._itemLabelStrokeWidth > 0 && (e.lineWidth = r, e.strokeStyle = this._itemLabelStrokeColor, e.lineJoin = "round", e.strokeText(h.label, 0, s)), e.fillStyle = C, e.fillText(h.label, 0, s), this.debug) { 672 let f = this.getScaledNumber(2); 673 e.beginPath(), 674 e.arc(0, 0, f, 0, 2 * Math.PI), 675 e.fillStyle = c.labelRadiusColor, 676 e.fill() 677 } 678 e.restore() 679 } 680 } 681 drawDebugDragPoints(e) 682 { 683 var r; 684 if (!this.debug || !((r = this._dragEvents) != null && r.length)) 685 return; 686 let t = [...this._dragEvents].reverse(), 687 s = this.getScaledNumber(.5), 688 n = this.getScaledNumber(4); 689 for (let [a, d] of t.entries()) { 690 let h = a / this._dragEvents.length * 100; 691 e.beginPath(), 692 e.arc(d.x, d.y, n, 0, 2 * Math.PI), 693 e.fillStyle = `hsl(${c.dragPointHue},100%,${h}%)`, 694 e.strokeStyle = "#000", 695 e.lineWidth = s, 696 e.fill(), 697 e.stroke() 698 } 699 } 700 animateRotation(e=0) 701 { 702 if (this._spinToTimeEnd !== null) { 703 if (e >= this._spinToTimeEnd) { 704 this.rotation = this._spinToEndRotation, 705 this._spinToTimeEnd = null, 706 this.raiseEvent_onRest(); 707 return 708 } 709 let t = this._spinToTimeEnd - this._spinToTimeStart, 710 s = (e - this._spinToTimeStart) / t; 711 s = s < 0 ? 0 : s; 712 let n = this._spinToEndRotation - this._spinToStartRotation; 713 this.rotation = this._spinToStartRotation + n * this._spinToEasingFunction(s), 714 this.refresh(); 715 return 716 } 717 if (this._lastSpinFrameTime !== null) { 718 let t = e - this._lastSpinFrameTime; 719 t > 0 && (this.rotation += t / 1e3 * this._rotationSpeed % 360, this._rotationSpeed = this.getRotationSpeedPlusDrag(t), this._rotationSpeed === 0 ? (this.raiseEvent_onRest(), this._lastSpinFrameTime = null) : this._lastSpinFrameTime = e), 720 this.refresh(); 721 return 722 } 723 } 724 getRotationSpeedPlusDrag(e=0) 725 { 726 let t = this._rotationSpeed + this.rotationResistance * (e / 1e3) * this._rotationDirection; 727 return this._rotationDirection === 1 && t < 0 || this._rotationDirection === -1 && t >= 0 ? 0 : t 728 } 729 spin(e=0) 730 { 731 if (!u(e)) 732 throw new Error("rotationSpeed must be a number"); 733 this._dragEvents = [], 734 this.beginSpin(e, "spin") 735 } 736 spinTo(e=0, t=0, s=null) 737 { 738 if (!u(e)) 739 throw new Error("Error: rotation must be a number"); 740 if (!u(t)) 741 throw new Error("Error: duration must be a number"); 742 this.stop(), 743 this._dragEvents = [], 744 this.animate(e, t, s), 745 this.raiseEvent_onSpin({ 746 method: "spinto", 747 targetRotation: e, 748 duration: t 749 }) 750 } 751 spinToItem(e=0, t=0, s=!0, n=1, r=1, a=null) 752 { 753 this.stop(), 754 this._dragEvents = []; 755 let d = s ? this.items[e].getCenterAngle() : this.items[e].getRandomAngle(), 756 h = T(this.rotation, d - this._pointerAngle, r); 757 h += n * 360 * r, 758 this.animate(h, t, a), 759 this.raiseEvent_onSpin({ 760 method: "spintoitem", 761 targetItemIndex: e, 762 targetRotation: h, 763 duration: t 764 }) 765 } 766 animate(e, t, s) 767 { 768 this._spinToStartRotation = this.rotation, 769 this._spinToEndRotation = e, 770 this._spinToTimeStart = performance.now(), 771 this._spinToTimeEnd = this._spinToTimeStart + t, 772 this._spinToEasingFunction = s || k, 773 this.refresh() 774 } 775 stop() 776 { 777 this._spinToTimeEnd = null, 778 this._rotationSpeed = 0, 779 this._lastSpinFrameTime = null 780 } 781 getScaledNumber(e) 782 { 783 return e / 500 * this._size 784 } 785 getActualPixelRatio() 786 { 787 return this._pixelRatio !== 0 ? this._pixelRatio : window.devicePixelRatio 788 } 789 wheelHitTest(e={ 790 x: 0, 791 y: 0 792 }) 793 { 794 if (this.canvas === null) 795 return !1; 796 let t = v(e, this.canvas, this.getActualPixelRatio()); 797 return W(t, this._center.x, this._center.y, this._actualRadius) 798 } 799 refreshCursor() 800 { 801 if (this.canvas !== null) { 802 if (this.isInteractive) { 803 if (this.isDragging) { 804 this.canvas.style.cursor = "grabbing"; 805 return 806 } 807 if (this._isCursorOverWheel) { 808 this.canvas.style.cursor = "grab"; 809 return 810 } 811 } 812 this.canvas.style.cursor = "" 813 } 814 } 815 getAngleFromCenter(e={ 816 x: 0, 817 y: 0 818 }) 819 { 820 return (A(this._center.x, this._center.y, e.x, e.y) + 90) % 360 821 } 822 getCurrentIndex() 823 { 824 return this._currentIndex 825 } 826 refreshCurrentIndex(e=[]) 827 { 828 this._items.length === 0 && (this._currentIndex = -1); 829 for (let [t, s] of e.entries()) 830 if (!!I(this._pointerAngle, s.start % 360, s.end % 360)) { 831 if (this._currentIndex === t) 832 break; 833 this._currentIndex = t, 834 this._isInitialising || this.raiseEvent_onCurrentIndexChange(); 835 break 836 } 837 } 838 getItemAngles(e=0) 839 { 840 let t = 0; 841 for (let d of this.items) 842 t += d.weight; 843 let s = 360 / t, 844 n, 845 r = e, 846 a = []; 847 for (let d of this._items) 848 n = d.weight * s, 849 a.push({ 850 start: r, 851 end: r + n 852 }), 853 r += n; 854 return this._items.length > 1 && (a[a.length - 1].end = a[0].start + 360), a 855 } 856 refresh() 857 { 858 this._frameRequestId === null && (this._frameRequestId = window.requestAnimationFrame(e => this.draw(e))) 859 } 860 limitSpeed(e=0, t=0) 861 { 862 let s = Math.min(e, t); 863 return Math.max(s, -t) 864 } 865 beginSpin(e=0, t="") 866 { 867 this.stop(), 868 this._rotationSpeed = this.limitSpeed(e, this._rotationSpeedMax), 869 this._lastSpinFrameTime = performance.now(), 870 this._rotationDirection = this._rotationSpeed >= 0 ? 1 : -1, 871 this._rotationSpeed !== 0 && this.raiseEvent_onSpin({ 872 method: t, 873 rotationSpeed: this._rotationSpeed, 874 rotationResistance: this._rotationResistance 875 }), 876 this.refresh() 877 } 878 refreshAriaLabel() 879 { 880 if (this.canvas === null) 881 return; 882 this.canvas.setAttribute("role", "img"); 883 let e = this.items.length >= 2 ? ` The wheel has ${this.items.length} slices.` : ""; 884 this.canvas.setAttribute("aria-label", "An image of a spinning prize wheel." + e) 885 } 886 get borderColor() 887 { 888 return this._borderColor 889 } 890 set borderColor(e) 891 { 892 this._borderColor = l({ 893 val: e, 894 isValid: typeof e == "string", 895 errorMessage: "Wheel.borderColor must be a string", 896 defaultValue: o.wheel.borderColor 897 }), 898 this.refresh() 899 } 900 get borderWidth() 901 { 902 return this._borderWidth 903 } 904 set borderWidth(e) 905 { 906 this._borderWidth = l({ 907 val: e, 908 isValid: u(e), 909 errorMessage: "Wheel.borderWidth must be a number", 910 defaultValue: o.wheel.borderWidth 911 }), 912 this.refresh() 913 } 914 get debug() 915 { 916 return this._debug 917 } 918 set debug(e) 919 { 920 this._debug = l({ 921 val: e, 922 isValid: typeof e == "boolean", 923 errorMessage: "Wheel.debug must be a boolean", 924 defaultValue: o.wheel.debug 925 }), 926 this.refresh() 927 } 928 get image() 929 { 930 return this._image 931 } 932 set image(e) 933 { 934 this._image = l({ 935 val: e, 936 isValid: e instanceof HTMLImageElement || e === null, 937 errorMessage: "Wheel.image must be a HTMLImageElement or null", 938 defaultValue: o.wheel.image 939 }), 940 this.refresh() 941 } 942 get isInteractive() 943 { 944 return this._isInteractive 945 } 946 set isInteractive(e) 947 { 948 this._isInteractive = l({ 949 val: e, 950 isValid: typeof e == "boolean", 951 errorMessage: "Wheel.isInteractive must be a boolean", 952 defaultValue: o.wheel.isInteractive 953 }), 954 this.refreshCursor() 955 } 956 get itemBackgroundColors() 957 { 958 return this._itemBackgroundColors 959 } 960 set itemBackgroundColors(e) 961 { 962 this._itemBackgroundColors = l({ 963 val: e, 964 isValid: Array.isArray(e), 965 errorMessage: "Wheel.itemBackgroundColors must be an array", 966 defaultValue: o.wheel.itemBackgroundColors 967 }), 968 this.refresh() 969 } 970 get itemLabelAlign() 971 { 972 return this._itemLabelAlign 973 } 974 set itemLabelAlign(e) 975 { 976 this._itemLabelAlign = l({ 977 val: e, 978 isValid: typeof e == "string" && (e === p.left || e === p.right || e === p.center), 979 errorMessage: "Wheel.itemLabelAlign must be one of Constants.AlignText", 980 defaultValue: o.wheel.itemLabelAlign 981 }), 982 this.resize() 983 } 984 get itemLabelBaselineOffset() 985 { 986 return this._itemLabelBaselineOffset 987 } 988 set itemLabelBaselineOffset(e) 989 { 990 this._itemLabelBaselineOffset = l({ 991 val: e, 992 isValid: u(e), 993 errorMessage: "Wheel.itemLabelBaselineOffset must be a number", 994 defaultValue: o.wheel.itemLabelBaselineOffset 995 }), 996 this.resize() 997 } 998 get itemLabelColors() 999 { 1000 return this._itemLabelColors 1001 } 1002 set itemLabelColors(e) 1003 { 1004 this._itemLabelColors = l({ 1005 val: e, 1006 isValid: Array.isArray(e), 1007 errorMessage: "Wheel.itemLabelColors must be an array", 1008 defaultValue: o.wheel.itemLabelColors 1009 }), 1010 this.refresh() 1011 } 1012 get itemLabelFont() 1013 { 1014 return this._itemLabelFont 1015 } 1016 set itemLabelFont(e) 1017 { 1018 this._itemLabelFont = l({ 1019 val: e, 1020 isValid: typeof e == "string", 1021 errorMessage: "Wheel.itemLabelFont must be a string", 1022 defaultValue: o.wheel.itemLabelFont 1023 }), 1024 this.resize() 1025 } 1026 get itemLabelFontSizeMax() 1027 { 1028 return this._itemLabelFontSizeMax 1029 } 1030 set itemLabelFontSizeMax(e) 1031 { 1032 this._itemLabelFontSizeMax = l({ 1033 val: e, 1034 isValid: u(e), 1035 errorMessage: "Wheel.itemLabelFontSizeMax must be a number", 1036 defaultValue: o.wheel.itemLabelFontSizeMax 1037 }), 1038 this.resize() 1039 } 1040 get itemLabelRadius() 1041 { 1042 return this._itemLabelRadius 1043 } 1044 set itemLabelRadius(e) 1045 { 1046 this._itemLabelRadius = l({ 1047 val: e, 1048 isValid: u(e), 1049 errorMessage: "Wheel.itemLabelRadius must be a number", 1050 defaultValue: o.wheel.itemLabelRadius 1051 }), 1052 this.resize() 1053 } 1054 get itemLabelRadiusMax() 1055 { 1056 return this._itemLabelRadiusMax 1057 } 1058 set itemLabelRadiusMax(e) 1059 { 1060 this._itemLabelRadiusMax = l({ 1061 val: e, 1062 isValid: u(e), 1063 errorMessage: "Wheel.itemLabelRadiusMax must be a number", 1064 defaultValue: o.wheel.itemLabelRadiusMax 1065 }), 1066 this.resize() 1067 } 1068 get itemLabelRotation() 1069 { 1070 return this._itemLabelRotation 1071 } 1072 set itemLabelRotation(e) 1073 { 1074 this._itemLabelRotation = l({ 1075 val: e, 1076 isValid: u(e), 1077 errorMessage: "Wheel.itemLabelRotation must be a number", 1078 defaultValue: o.wheel.itemLabelRotation 1079 }), 1080 this.refresh() 1081 } 1082 get itemLabelStrokeColor() 1083 { 1084 return this._itemLabelStrokeColor 1085 } 1086 set itemLabelStrokeColor(e) 1087 { 1088 this._itemLabelStrokeColor = l({ 1089 val: e, 1090 isValid: typeof e == "string", 1091 errorMessage: "Wheel.itemLabelStrokeColor must be a string", 1092 defaultValue: o.wheel.itemLabelStrokeColor 1093 }), 1094 this.refresh() 1095 } 1096 get itemLabelStrokeWidth() 1097 { 1098 return this._itemLabelStrokeWidth 1099 } 1100 set itemLabelStrokeWidth(e) 1101 { 1102 this._itemLabelStrokeWidth = l({ 1103 val: e, 1104 isValid: u(e), 1105 errorMessage: "Wheel.itemLabelStrokeWidth must be a number", 1106 defaultValue: o.wheel.itemLabelStrokeWidth 1107 }), 1108 this.refresh() 1109 } 1110 get items() 1111 { 1112 return this._items 1113 } 1114 set items(e) 1115 { 1116 this._items = l({ 1117 val: e, 1118 isValid: Array.isArray(e), 1119 errorMessage: "Wheel.items must be an array of Items", 1120 defaultValue: o.wheel.items, 1121 action: () => { 1122 let t = []; 1123 for (let s of e) 1124 t.push(new S(this, s)); 1125 return t 1126 } 1127 }), 1128 this.refreshAriaLabel(), 1129 this.refreshCurrentIndex(this.getItemAngles(this._rotation)), 1130 this.resize() 1131 } 1132 get lineColor() 1133 { 1134 return this._lineColor 1135 } 1136 set lineColor(e) 1137 { 1138 this._lineColor = l({ 1139 val: e, 1140 isValid: typeof e == "string", 1141 errorMessage: "Wheel.lineColor must be a string", 1142 defaultValue: o.wheel.lineColor 1143 }), 1144 this.refresh() 1145 } 1146 get lineWidth() 1147 { 1148 return this._lineWidth 1149 } 1150 set lineWidth(e) 1151 { 1152 this._lineWidth = l({ 1153 val: e, 1154 isValid: u(e), 1155 errorMessage: "Wheel.lineWidth must be a number", 1156 defaultValue: o.wheel.lineWidth 1157 }), 1158 this.refresh() 1159 } 1160 get offset() 1161 { 1162 return this._offset 1163 } 1164 set offset(e) 1165 { 1166 this._offset = l({ 1167 val: e, 1168 isValid: b(e), 1169 errorMessage: "Wheel.offset must be an object", 1170 defaultValue: o.wheel.offset 1171 }), 1172 this.resize() 1173 } 1174 get onCurrentIndexChange() 1175 { 1176 return this._onCurrentIndexChange 1177 } 1178 set onCurrentIndexChange(e) 1179 { 1180 this._onCurrentIndexChange = l({ 1181 val: e, 1182 isValid: typeof e == "function" || e === null, 1183 errorMessage: "Wheel.onCurrentIndexChange must be a function or null", 1184 defaultValue: o.wheel.onCurrentIndexChange 1185 }) 1186 } 1187 get onRest() 1188 { 1189 return this._onRest 1190 } 1191 set onRest(e) 1192 { 1193 this._onRest = l({ 1194 val: e, 1195 isValid: typeof e == "function" || e === null, 1196 errorMessage: "Wheel.onRest must be a function or null", 1197 defaultValue: o.wheel.onRest 1198 }) 1199 } 1200 get onSpin() 1201 { 1202 return this._onSpin 1203 } 1204 set onSpin(e) 1205 { 1206 this._onSpin = l({ 1207 val: e, 1208 isValid: typeof e == "function" || e === null, 1209 errorMessage: "Wheel.onSpin must be a function or null", 1210 defaultValue: o.wheel.onSpin 1211 }) 1212 } 1213 get overlayImage() 1214 { 1215 return this._overlayImage 1216 } 1217 set overlayImage(e) 1218 { 1219 this._overlayImage = l({ 1220 val: e, 1221 isValid: e instanceof HTMLImageElement || e === null, 1222 errorMessage: "Wheel.overlayImage must be a HTMLImageElement or null", 1223 defaultValue: o.wheel.overlayImage 1224 }), 1225 this.refresh() 1226 } 1227 get pixelRatio() 1228 { 1229 return this._pixelRatio 1230 } 1231 set pixelRatio(e) 1232 { 1233 this._pixelRatio = l({ 1234 val: e, 1235 isValid: u(e), 1236 errorMessage: "Wheel.pixelRatio must be a number", 1237 defaultValue: o.wheel.pixelRatio 1238 }), 1239 this._dragEvents = [], 1240 this.resize() 1241 } 1242 get pointerAngle() 1243 { 1244 return this._pointerAngle 1245 } 1246 set pointerAngle(e) 1247 { 1248 this._pointerAngle = l({ 1249 val: e, 1250 isValid: u(e) && e >= 0, 1251 errorMessage: "Wheel.pointerAngle must be a number between 0 and 360", 1252 defaultValue: o.wheel.pointerAngle, 1253 action: () => e % 360 1254 }), 1255 this.debug && this.refresh() 1256 } 1257 get radius() 1258 { 1259 return this._radius 1260 } 1261 set radius(e) 1262 { 1263 this._radius = l({ 1264 val: e, 1265 isValid: u(e), 1266 errorMessage: "Wheel.radius must be a number", 1267 defaultValue: o.wheel.radius 1268 }), 1269 this.resize() 1270 } 1271 get rotation() 1272 { 1273 return this._rotation 1274 } 1275 set rotation(e) 1276 { 1277 this._rotation = l({ 1278 val: e, 1279 isValid: u(e), 1280 errorMessage: "Wheel.rotation must be a number", 1281 defaultValue: o.wheel.rotation 1282 }), 1283 this.refreshCurrentIndex(this.getItemAngles(this._rotation)), 1284 this.refresh() 1285 } 1286 get rotationResistance() 1287 { 1288 return this._rotationResistance 1289 } 1290 set rotationResistance(e) 1291 { 1292 this._rotationResistance = l({ 1293 val: e, 1294 isValid: u(e), 1295 errorMessage: "Wheel.rotationResistance must be a number", 1296 defaultValue: o.wheel.rotationResistance 1297 }) 1298 } 1299 get rotationSpeed() 1300 { 1301 return this._rotationSpeed 1302 } 1303 get rotationSpeedMax() 1304 { 1305 return this._rotationSpeedMax 1306 } 1307 set rotationSpeedMax(e) 1308 { 1309 this._rotationSpeedMax = l({ 1310 val: e, 1311 isValid: u(e) && e >= 0, 1312 errorMessage: "Wheel.rotationSpeedMax must be a number >= 0", 1313 defaultValue: o.wheel.rotationSpeedMax 1314 }) 1315 } 1316 dragStart(e={ 1317 x: 0, 1318 y: 0 1319 }) 1320 { 1321 if (this.canvas === null) 1322 return; 1323 let t = v(e, this.canvas, this.getActualPixelRatio()); 1324 this.isDragging = !0, 1325 this.stop(), 1326 this._dragEvents = [{ 1327 distance: 0, 1328 x: t.x, 1329 y: t.y, 1330 now: performance.now() 1331 }], 1332 this.refreshCursor() 1333 } 1334 dragMove(e={ 1335 x: 0, 1336 y: 0 1337 }) 1338 { 1339 if (this.canvas === null) 1340 return; 1341 let t = v(e, this.canvas, this.getActualPixelRatio()), 1342 s = this.getAngleFromCenter(t), 1343 n = this._dragEvents[0], 1344 r = this.getAngleFromCenter(n), 1345 a = P(r, s); 1346 this._dragEvents.unshift({ 1347 distance: a, 1348 x: t.x, 1349 y: t.y, 1350 now: performance.now() 1351 }), 1352 this.debug && this._dragEvents.length >= 40 && this._dragEvents.pop(), 1353 this.rotation += a 1354 } 1355 dragEnd() 1356 { 1357 this.isDragging = !1; 1358 let e = 0, 1359 t = performance.now(); 1360 for (let [s, n] of this._dragEvents.entries()) { 1361 if (!this.isDragEventTooOld(t, n)) { 1362 e += n.distance; 1363 continue 1364 } 1365 this._dragEvents.length = s, 1366 this.debug && this.refresh(); 1367 break 1368 } 1369 this.refreshCursor(), 1370 e !== 0 && this.beginSpin(e * (1e3 / 250), "interact") 1371 } 1372 isDragEventTooOld(e=0, t={}) 1373 { 1374 return e - t.now > 250 1375 } 1376 raiseEvent_onCurrentIndexChange(e={}) 1377 { 1378 var t; 1379 (t = this.onCurrentIndexChange) == null || t.call(this, L({ 1380 type: "currentIndexChange", 1381 currentIndex: this._currentIndex 1382 }, e)) 1383 } 1384 raiseEvent_onRest(e={}) 1385 { 1386 var t; 1387 (t = this.onRest) == null || t.call(this, L({ 1388 type: "rest", 1389 currentIndex: this._currentIndex, 1390 rotation: this._rotation 1391 }, e)) 1392 } 1393 raiseEvent_onSpin(e={}) 1394 { 1395 var t; 1396 (t = this.onSpin) == null || t.call(this, L({ 1397 type: "spin" 1398 }, e)) 1399 } 1400} 1401; 1402export { B as Wheel };
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.