summaryrefslogtreecommitdiffstats
path: root/src/number.js
blob: ba95151e57209bd2881dc284a5acbc31253db6e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// Module for unit convertions
SVG.Number = SVG.invent({
  // Initialize
  create: function (value, unit) {
    // initialize defaults
    this.value = 0
    this.unit = unit || ''

    // parse value
    if (typeof value === 'number') {
      // ensure a valid numeric value
      this.value = isNaN(value) ? 0 : !isFinite(value) ? (value < 0 ? -3.4e+38 : +3.4e+38) : value
    } else if (typeof value === 'string') {
      unit = value.match(SVG.regex.numberAndUnit)

      if (unit) {
        // make value numeric
        this.value = parseFloat(unit[1])

        // normalize
        if (unit[5] === '%') { this.value /= 100 } else if (unit[5] === 's') {
          this.value *= 1000
        }

        // store unit
        this.unit = unit[5]
      }
    } else {
      if (value instanceof SVG.Number) {
        this.value = value.valueOf()
        this.unit = value.unit
      }
    }
  },
  // Add methods
  extend: {
    // Stringalize
    toString: function () {
      return (this.unit === '%' ? ~~(this.value * 1e8) / 1e6
        : this.unit === 's' ? this.value / 1e3
        : this.value
      ) + this.unit
    },
    toJSON: function () {
      return this.toString()
    },   // Convert to primitive
    valueOf: function () {
      return this.value
    },
    // Add number
    plus: function (number) {
      number = new SVG.Number(number)
      return new SVG.Number(this + number, this.unit || number.unit)
    },
    // Subtract number
    minus: function (number) {
      number = new SVG.Number(number)
      return new SVG.Number(this - number, this.unit || number.unit)
    },
    // Multiply number
    times: function (number) {
      number = new SVG.Number(number)
      return new SVG.Number(this * number, this.unit || number.unit)
    },
    // Divide number
    divide: function (number) {
      number = new SVG.Number(number)
      return new SVG.Number(this / number, this.unit || number.unit)
    },
    // Convert to different unit
    to: function (unit) {
      var number = new SVG.Number(this)

      if (typeof unit === 'string') {
        number.unit = unit
      }

      return number
    },
    // Make number morphable
    morph: function (number) {
      this.destination = new SVG.Number(number)

      if (number.relative) {
        this.destination.value += this.value
      }

      return this
    },
    // Get morphed number at given position
    at: function (pos) {
      // Make sure a destination is defined
      if (!this.destination) throw new Error('No destination set')

      // Generate new morphed number
      return new SVG.Number(this.destination)
          .minus(this)
          .times(pos)
          .plus(this)
    }

  }
})