<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>
        <script src="vue.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/tween.js@16.3.4"></script>
        <script src="https://cdn.jsdelivr.net/npm/color-js@1.0.3"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.5/TweenLite.min.js"></script>
    </head>
    <body>
        <div>
        <h1>--状态动画与侦听器1--</h1>
        <div id="example1">
            <input v-model.number="number" type="number" step="20">
            <p>{{ animatedNumber }}</p>
        </div>
        <script>        
        var example1 = new Vue({
            el: '#example1',
            data: {
                number: 0,
                tweenedNumber: 0
            },
            computed: {
                animatedNumber: function() {
                    return this.tweenedNumber.toFixed(0);
                }
            },
            watch: {
                number: function(newValue) {
                    TweenLite.to(this.$data, 0.5, { tweenedNumber: newValue });
                }
            }
        })
        </script>
        </div>
        <div>
        <h1>--状态动画与侦听器2--</h1>
        <div id="example2">
          <input
            v-model="colorQuery"
            v-on:keyup.enter="updateColor"
            placeholder="Enter a color"
          >
          <button v-on:click="updateColor">Update</button>
          <p>Preview:</p>
          <span
            v-bind:style="{ backgroundColor: tweenedCSSColor }"
            class="example-7-color-preview"
          ></span>
          <p>{{ tweenedCSSColor }}</p>
        </div>
        <script>
        var Color = net.brehaut.Color
        var example2 = new Vue({
          el: '#example2',
          data: {
            colorQuery: '',
            color: {
              red: 0,
              green: 0,
              blue: 0,
              alpha: 1
            },
            tweenedColor: {}
          },
          created: function () {
            this.tweenedColor = Object.assign({}, this.color)
          },
          watch: {
            color: function () {
              function animate () {
                if (TWEEN.update()) {
                  requestAnimationFrame(animate)
                }
              }

              new TWEEN.Tween(this.tweenedColor)
                .to(this.color, 750)
                .start()

              animate()
            }
          },
          computed: {
            tweenedCSSColor: function () {
              return new Color({
                red: this.tweenedColor.red,
                green: this.tweenedColor.green,
                blue: this.tweenedColor.blue,
                alpha: this.tweenedColor.alpha
              }).toCSS()
            }
          },
          methods: {
            updateColor: function () {
              this.color = new Color(this.colorQuery).toRGB()
              this.colorQuery = ''
            }
          }
        })
        </script>
        <style>
        .example-7-color-preview {
          display: inline-block;
          width: 50px;
          height: 50px;
        }
        </style>
        </div>
        <div>
        <h1>--动态状态过渡--</h1>
        <div id="svg-polygon-demo" class="demo">
          <svg width="200" height="200" class="demo-svg">
            <polygon :points="points" class="demo-polygon"/>
            <circle cx="100" cy="100" r="90" class="demo-circle"/>
          </svg>
          <label>Sides: {{ sides }}</label>
          <input class="demo-range-input" type="range" min="3" max="500" v-model.number="sides">
          <label>Minimum Radius: {{ minRadius }}%</label>
          <input class="demo-range-input" type="range" min="0" max="90" v-model.number="minRadius">
          <label>Update Interval: {{ updateInterval }} milliseconds</label>
          <input class="demo-range-input" type="range" min="10" max="2000" v-model.number="updateInterval">
        </div>
        <script>
        new Vue({
          el: '#svg-polygon-demo',
          data: function () {
            var defaultSides = 10
            var stats = Array.apply(null, { length: defaultSides })
              .map(function () { return 100 })
            return {
              stats: stats,
              points: generatePoints(stats),
              sides: defaultSides,
              minRadius: 50,
              interval: null,
              updateInterval: 500
            }
          },
          watch: {
            sides: function (newSides, oldSides) {
              var sidesDifference = newSides - oldSides
              if (sidesDifference > 0) {
                for (var i = 1; i <= sidesDifference; i++) {
                  this.stats.push(this.newRandomValue())
                }
              } else {
                var absoluteSidesDifference = Math.abs(sidesDifference)
                for (var i = 1; i <= absoluteSidesDifference; i++) {
                  this.stats.shift()
                }
              }
            },
            stats: function (newStats) {
              TweenLite.to(
                this.$data,
                this.updateInterval / 1000,
                { points: generatePoints(newStats) }
              )
            },
            updateInterval: function () {
              this.resetInterval()
            }
          },
          mounted: function () {
            this.resetInterval()
          },
          methods: {
            randomizeStats: function () {
              var vm = this
              this.stats = this.stats.map(function () {
                return vm.newRandomValue()
              })
            },
            newRandomValue: function () {
              return Math.ceil(this.minRadius + Math.random() * (100 - this.minRadius))
            },
            resetInterval: function () {
              var vm = this
              clearInterval(this.interval)
              this.randomizeStats()
              this.interval = setInterval(function () {
                vm.randomizeStats()
              }, this.updateInterval)
            }
          }
        })

        function valueToPoint (value, index, total) {
          var x     = 0
          var y     = -value * 0.9
          var angle = Math.PI * 2 / total * index
          var cos   = Math.cos(angle)
          var sin   = Math.sin(angle)
          var tx    = x * cos - y * sin + 100
          var ty    = x * sin + y * cos + 100
          return { x: tx, y: ty }
        }

        function generatePoints (stats) {
          var total = stats.length
          return stats.map(function (stat, index) {
            var point = valueToPoint(stat, index, total)
            return point.x + ',' + point.y
          }).join(' ')
        }
        </script>
        <style>
        .demo-svg { display: block; }
        .demo-polygon { fill: #41B883; }
        .demo-circle {
          fill: transparent;
          stroke: #35495E;
        }
        .demo-range-input {
          display: block;
          width: 100%;
          margin-bottom: 15px;
        }
        </style>
        </div>
        <div>
        <h1>把过渡放到组件里</h1>
        <div id="example-8">
          <input v-model.number="firstNumber" type="number" step="20"> +
          <input v-model.number="secondNumber" type="number" step="20"> =
          {{ result }}
          <p>
            <animated-integer v-bind:value="firstNumber"></animated-integer> +
            <animated-integer v-bind:value="secondNumber"></animated-integer> =
            <animated-integer v-bind:value="result"></animated-integer>
          </p>
        </div>
        <script>
        Vue.component('animated-integer', {
          template: '<span>{{ tweeningValue }}</span>',
          props: {
            value: {
              type: Number,
              required: true
            }
          },
          data: function () {
            return {
              tweeningValue: 0
            }
          },
          watch: {
            value: function (newValue, oldValue) {
              this.tween(oldValue, newValue)
            }
          },
          mounted: function () {
            this.tween(0, this.value)
          },
          methods: {
            tween: function (startValue, endValue) {
              var vm = this
              function animate () {
                if (TWEEN.update()) {
                  requestAnimationFrame(animate)
                }
              }

              new TWEEN.Tween({ tweeningValue: startValue })
                .to({ tweeningValue: endValue }, 500)
                .onUpdate(function () {
                  vm.tweeningValue = this.tweeningValue.toFixed(0)
                })
                .start()

              animate()
            }
          }
        })
        new Vue({
          el: '#example-8',
          data: {
            firstNumber: 20,
            secondNumber: 40
          },
          computed: {
            result: function () {
              return this.firstNumber + this.secondNumber
            }
          }
        })
        </script>        
        </div>
    </body>
</html>