1

I have been working with a roulette design, where i need a wheel, so i am using winwheel.js library.

wheel;


wheelSpinning = false;

  constructor() {
  }

  ngAfterViewInit() {
    this.initWheel();
  }

  initWheel() {
    this.wheel = new Winwheel({
      'numSegments': 8,   // Specify number of segments.
      'outerRadius': 212,  // Set radius to so wheel fits the background.
      'innerRadius': 150,  // Set inner radius to make wheel hollow.
      'pointerAngle': 90,
      'pointerGuide':        // Turn pointer guide on.
      {
        'display': true,
        'strokeStyle': 'red',
        'lineWidth': 3
      },
      'segments':       // Define segments including colour and text.
      [
        { 'fillStyle': '#eae56f', 'text': 'Prize 1' },
        { 'fillStyle': '#89f26e', 'text': 'Prize 2' },
        { 'fillStyle': '#7de6ef', 'text': 'Prize 3' },
        { 'fillStyle': '#e7706f', 'text': 'Prize 4' },
        { 'fillStyle': '#eae56f', 'text': 'Prize 5' },
        { 'fillStyle': '#89f26e', 'text': 'Prize 6' },
        { 'fillStyle': '#7de6ef', 'text': 'Prize 7' },
        { 'fillStyle': '#e7706f', 'text': 'Prize 8' }
      ],
      'animation':           // Define spin to stop animation.
      {
        'type': 'spinToStop',
        'duration': 5,
        'spins': 8,
        'callbackFinished': 'alertPrize()'
      }
    });
  }

  public alertPrize() {
    console.log('wheel');
  }

  // -------------------------------------------------------
  // Click handler for spin button.
  // -------------------------------------------------------
  startSpin() {
    // Ensure that spinning can't be clicked again while already running.
    if (this.wheelSpinning === false) {
      this.wheel.startAnimation();
      this.wheelSpinning = true;
    }
  }

  // -------------------------------------------------------
  // Function for reset button.
  // -------------------------------------------------------
  resetWheel() {
    this.wheel.stopAnimation(false);  // Stop the animation, false as param so does not call callback function.
    this.wheel.rotationAngle = 0;     // Re-set the wheel angle to 0 degrees.
    this.wheel.draw();                // Call draw to render changes to the wheel.

    this.wheelSpinning = false;          // Reset to false to power buttons and spin can be clicked again.
  }

Everything is working fine, but after the wheel has stopped spinning, it needs a callback function so that we can write our logic after the wheel has stopped spinning, so i am passing it like this,

'callbackFinished': 'alertPrize()'

but in this case alertPrize needs to in global scope so that winwheel.js can access this function. Since my alert function is declared inside component so it is not accessbile to winwheel js.

If i define my function inside index.html like this, then it is accessible, since it is in global scope

   <script>
    function alertPrize() {
      console.log('wheel');
    }  
  </script>

But i want the alertPrize() inside the component so that i can write some logic inside it.

Is there a way to tackle this problem.

JRG
  • 4,037
  • 3
  • 23
  • 34
chandradot99
  • 3,616
  • 6
  • 27
  • 45

1 Answers1

2

I ended up modifying the library Winwheel.js at line 2266 to remove the eval function that parses the function string to a simple function callback:

eval(winwheelToDrawDuringAnimation.animation.callbackFinished);

to

winwheelToDrawDuringAnimation.animation.callbackFinished();

Then in your code

'callbackFinished': 'alertPrize()' becomes 'callbackFinished': this.alertPrize.bind(this)

where I bind the component scope to the callback so that it can access component class properties and methods.

Perhaps a better way would have been to fork the git repo and make this change there but I didn't because the repo isn't on bower or npm.