// Module for unit convertions SVG.Number = SVG.invent({ // Initialize create: function (value, unit) { unit = Array.isArray(value) ? value[1] : unit value = Array.isArray(value) ? value[0] : value // 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 toArray: function () { return [this.value, this.unit] }, 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) }, // 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) return this // Generate new morphed number return new SVG.Number(this.destination) .minus(this) .times(pos) .plus(this) } } })