mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-01 02:38:43 -05:00
Refactor Format literal to Formatter class that keeps precision stored.
This commit is contained in:
parent
8da8f116d1
commit
fbe8a558bd
13 changed files with 116 additions and 107 deletions
|
@ -120,11 +120,11 @@ var Matrix = this.Matrix = Base.extend(/** @lends Matrix# */{
|
|||
* @return {String} A string representation of this transform.
|
||||
*/
|
||||
toString: function() {
|
||||
var format = Format.number;
|
||||
return '[[' + [format(this._a), format(this._b),
|
||||
format(this._tx)].join(', ') + '], ['
|
||||
+ [format(this._c), format(this._d),
|
||||
format(this._ty)].join(', ') + ']]';
|
||||
var f = Formatter.instance;
|
||||
return '[[' + [f.number(this._a), f.number(this._b),
|
||||
f.number(this._tx)].join(', ') + '], ['
|
||||
+ [f.number(this._c), f.number(this._d),
|
||||
f.number(this._ty)].join(', ') + ']]';
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -224,18 +224,16 @@ var Point = this.Point = Base.extend(/** @lends Point# */{
|
|||
* @return {String} A string representation of the point.
|
||||
*/
|
||||
toString: function() {
|
||||
var format = Format.number;
|
||||
return '{ x: ' + format(this.x) + ', y: ' + format(this.y) + ' }';
|
||||
var f = Formatter.instance;
|
||||
return '{ x: ' + f.number(this.x) + ', y: ' + f.number(this.y) + ' }';
|
||||
},
|
||||
|
||||
_serialize: function(options) {
|
||||
var format = Format.number,
|
||||
precision = options.precision;
|
||||
// For speed reasons, we directly call Format.number() here with
|
||||
// precision, instead of converting array through Base.serialize() which
|
||||
// makes a copy.
|
||||
return [format(this.x, precision),
|
||||
format(this.y, precision)];
|
||||
var f = options.formatter;
|
||||
// For speed reasons, we directly call formatter.number() here, instead
|
||||
// of converting array through Base.serialize() which makes a copy.
|
||||
return [f.number(this.x),
|
||||
f.number(this.y)];
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -210,22 +210,21 @@ var Rectangle = this.Rectangle = Base.extend(/** @lends Rectangle# */{
|
|||
* @return {String} A string representation of this rectangle.
|
||||
*/
|
||||
toString: function() {
|
||||
var format = Format.number;
|
||||
return '{ x: ' + format(this.x)
|
||||
+ ', y: ' + format(this.y)
|
||||
+ ', width: ' + format(this.width)
|
||||
+ ', height: ' + format(this.height)
|
||||
var f = Formatter.instance;
|
||||
return '{ x: ' + f.number(this.x)
|
||||
+ ', y: ' + f.number(this.y)
|
||||
+ ', width: ' + f.number(this.width)
|
||||
+ ', height: ' + f.number(this.height)
|
||||
+ ' }';
|
||||
},
|
||||
|
||||
_serialize: function(options) {
|
||||
var format = Format.number,
|
||||
precision = options.precision;
|
||||
var f = options.formatter;
|
||||
// See Point#_serialize()
|
||||
return [format(this.x, precision),
|
||||
format(this.y, precision),
|
||||
format(this.width, precision),
|
||||
format(this.height, precision)];
|
||||
return [f.number(this.x),
|
||||
f.number(this.y),
|
||||
f.number(this.width),
|
||||
f.number(this.height)];
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -846,6 +845,8 @@ var LinkedRectangle = Rectangle.extend({
|
|||
};
|
||||
}, /** @lends Rectangle# */{
|
||||
/**
|
||||
* {@grouptitle Item Bounds}
|
||||
*
|
||||
* Specifies whether an item's bounds are selected and will also
|
||||
* mark the item as selected.
|
||||
*
|
||||
|
|
|
@ -171,17 +171,16 @@ var Size = this.Size = Base.extend(/** @lends Size# */{
|
|||
* @return {String} A string representation of the size.
|
||||
*/
|
||||
toString: function() {
|
||||
var format = Format.number;
|
||||
return '{ width: ' + format(this.width)
|
||||
+ ', height: ' + format(this.height) + ' }';
|
||||
var f = Formatter.instance;
|
||||
return '{ width: ' + f.number(this.width)
|
||||
+ ', height: ' + f.number(this.height) + ' }';
|
||||
},
|
||||
|
||||
_serialize: function(options) {
|
||||
var format = Format.number,
|
||||
precision = options.precision;
|
||||
var f = options.formatter;
|
||||
// See Point#_serialize()
|
||||
return [format(this.width, precision),
|
||||
format(this.height, precision)];
|
||||
return [f.number(this.width),
|
||||
f.number(this.height)];
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -44,7 +44,7 @@ this.Base = Base.inject(/** @lends Base# */{
|
|||
if (!/^_/.test(key)) {
|
||||
var type = typeof value;
|
||||
this.push(key + ': ' + (type === 'number'
|
||||
? Format.number(value)
|
||||
? Formatter.instance.number(value)
|
||||
: type === 'string' ? "'" + value + "'" : value));
|
||||
}
|
||||
}, []).join(', ') + ' }';
|
||||
|
@ -270,9 +270,11 @@ this.Base = Base.inject(/** @lends Base# */{
|
|||
*/
|
||||
serialize: function(obj, options, compact, dictionary) {
|
||||
options = options || {};
|
||||
|
||||
var root = !dictionary,
|
||||
res;
|
||||
if (root) {
|
||||
options.formatter = new Formatter(options.precision);
|
||||
// Create a simple dictionary object that handles all the
|
||||
// storing and retrieving of dictionary definitions and
|
||||
// references, e.g. for symbols and gradients. Items that want
|
||||
|
@ -325,7 +327,7 @@ this.Base = Base.inject(/** @lends Base# */{
|
|||
res[i] = Base.serialize(obj[i], options, compact,
|
||||
dictionary);
|
||||
} else if (typeof obj === 'number') {
|
||||
res = Format.number(obj, options.precision);
|
||||
res = options.formatter.number(obj, options.precision);
|
||||
} else {
|
||||
res = obj;
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ var paper = new function() {
|
|||
/*#*/ include('tool/Tool.js');
|
||||
/*#*/ } // options.browser
|
||||
|
||||
/*#*/ include('util/Format.js');
|
||||
/*#*/ include('util/Formatter.js');
|
||||
/*#*/ include('util/CanvasProvider.js');
|
||||
/*#*/ include('util/Numerical.js');
|
||||
/*#*/ include('util/BlendMode.js');
|
||||
|
|
|
@ -223,7 +223,8 @@ var CurveLocation = this.CurveLocation = Base.extend(/** @lends CurveLocation# *
|
|||
*/
|
||||
toString: function() {
|
||||
var parts = [],
|
||||
point = this.getPoint();
|
||||
point = this.getPoint(),
|
||||
f = Formatter.instance;
|
||||
if (point)
|
||||
parts.push('point: ' + point);
|
||||
var index = this.getIndex();
|
||||
|
@ -231,9 +232,9 @@ var CurveLocation = this.CurveLocation = Base.extend(/** @lends CurveLocation# *
|
|||
parts.push('index: ' + index);
|
||||
var parameter = this.getParameter();
|
||||
if (parameter != null)
|
||||
parts.push('parameter: ' + Format.number(parameter));
|
||||
parts.push('parameter: ' + f.number(parameter));
|
||||
if (this._distance != null)
|
||||
parts.push('distance: ' + Format.number(this._distance));
|
||||
parts.push('distance: ' + f.number(this._distance));
|
||||
return '{ ' + parts.join(', ') + ' }';
|
||||
}
|
||||
});
|
||||
|
|
|
@ -206,8 +206,8 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
|
|||
getPathData: function(/* precision */) {
|
||||
var segments = this._segments,
|
||||
style = this._style,
|
||||
format = Format.point,
|
||||
precision = arguments[0],
|
||||
f = Formatter.instance,
|
||||
parts = [];
|
||||
|
||||
// TODO: Add support for H/V and/or relative commands, where appropriate
|
||||
|
@ -220,21 +220,21 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
|
|||
if (handle1.isZero() && handle2.isZero()) {
|
||||
if (!skipLine) {
|
||||
// L = absolute lineto: moving to a point with drawing
|
||||
parts.push('L' + format(point2, precision));
|
||||
parts.push('L' + f.point(point2, precision));
|
||||
}
|
||||
} else {
|
||||
// c = relative curveto: handle1, handle2 + end - start,
|
||||
// end - start
|
||||
var end = point2.subtract(point1);
|
||||
parts.push('c' + format(handle1, precision)
|
||||
+ ' ' + format(end.add(handle2), precision)
|
||||
+ ' ' + format(end, precision));
|
||||
parts.push('c' + f.point(handle1, precision)
|
||||
+ ' ' + f.point(end.add(handle2), precision)
|
||||
+ ' ' + f.point(end, precision));
|
||||
}
|
||||
}
|
||||
|
||||
if (segments.length === 0)
|
||||
return '';
|
||||
parts.push('M' + format(segments[0]._point));
|
||||
parts.push('M' + f.point(segments[0]._point));
|
||||
for (i = 0, l = segments.length - 1; i < l; i++)
|
||||
addCurve(segments[i], segments[i + 1], false);
|
||||
// We only need to draw the connecting curve if it is not a line, and if
|
||||
|
|
|
@ -688,15 +688,15 @@ var Color = this.Color = Base.extend(new function() {
|
|||
var properties = types[this._type],
|
||||
parts = [],
|
||||
isGradient = this._type === 'gradient',
|
||||
format = Format.number;
|
||||
f = Formatter.instance;
|
||||
for (var i = 0, l = properties.length; i < l; i++) {
|
||||
var value = this._components[i];
|
||||
if (value != null)
|
||||
parts.push(properties[i] + ': '
|
||||
+ (isGradient ? value : format(value)));
|
||||
+ (isGradient ? value : f.number(value)));
|
||||
}
|
||||
if (this._alpha != null)
|
||||
parts.push('alpha: ' + format(this._alpha));
|
||||
parts.push('alpha: ' + f.number(this._alpha));
|
||||
return '{ ' + parts.join(', ') + ' }';
|
||||
},
|
||||
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
* Paper.js DOM to a SVG DOM.
|
||||
*/
|
||||
new function() {
|
||||
// Shortcut to Format.number
|
||||
var format = Format.number,
|
||||
var formatter = Formatter.instance,
|
||||
namespaces = {
|
||||
href: 'http://www.w3.org/1999/xlink'
|
||||
};
|
||||
|
@ -26,7 +25,7 @@ new function() {
|
|||
var val = attrs[key],
|
||||
namespace = namespaces[key];
|
||||
if (typeof val === 'number')
|
||||
val = format(val);
|
||||
val = formatter.number(val);
|
||||
if (namespace) {
|
||||
node.setAttributeNS(namespace, key, val);
|
||||
} else {
|
||||
|
@ -72,11 +71,11 @@ new function() {
|
|||
angle = decomposed.rotation,
|
||||
scale = decomposed.scaling;
|
||||
if (trans && !trans.isZero())
|
||||
parts.push('translate(' + Format.point(trans) + ')');
|
||||
parts.push('translate(' + formatter.point(trans) + ')');
|
||||
if (!Numerical.isZero(scale.x - 1) || !Numerical.isZero(scale.y - 1))
|
||||
parts.push('scale(' + Format.point(scale) +')');
|
||||
parts.push('scale(' + formatter.point(scale) +')');
|
||||
if (angle)
|
||||
parts.push('rotate(' + format(angle) + ')');
|
||||
parts.push('rotate(' + formatter.number(angle) + ')');
|
||||
attrs.transform = parts.join(' ');
|
||||
} else {
|
||||
attrs.transform = 'matrix(' + matrix.getValues().join(',') + ')';
|
||||
|
@ -223,7 +222,7 @@ new function() {
|
|||
case 'polygon':
|
||||
var parts = [];
|
||||
for(i = 0, l = segments.length; i < l; i++)
|
||||
parts.push(Format.point(segments[i]._point));
|
||||
parts.push(formatter.point(segments[i]._point));
|
||||
attrs = {
|
||||
points: parts.join(' ')
|
||||
};
|
||||
|
@ -296,8 +295,8 @@ new function() {
|
|||
break;
|
||||
}
|
||||
if (angle) {
|
||||
attrs.transform = 'rotate(' + format(angle) + ','
|
||||
+ Format.point(center) + ')';
|
||||
attrs.transform = 'rotate(' + formatter.number(angle) + ','
|
||||
+ formatter.point(center) + ')';
|
||||
// Tell applyStyle() that to transform the gradient the other way
|
||||
item._gradientMatrix = new Matrix().rotate(-angle, center);
|
||||
}
|
||||
|
@ -320,7 +319,7 @@ new function() {
|
|||
bounds = definition.getBounds();
|
||||
if (!symbolNode) {
|
||||
symbolNode = createElement('symbol', {
|
||||
viewBox: Format.rectangle(bounds)
|
||||
viewBox: formatter.rectangle(bounds)
|
||||
});
|
||||
symbolNode.appendChild(exportSvg(definition));
|
||||
setDefinition(symbol, symbolNode);
|
||||
|
@ -328,8 +327,8 @@ new function() {
|
|||
attrs.href = '#' + symbolNode.id;
|
||||
attrs.x += bounds.x;
|
||||
attrs.y += bounds.y;
|
||||
attrs.width = format(bounds.width);
|
||||
attrs.height = format(bounds.height);
|
||||
attrs.width = formatter.number(bounds.width);
|
||||
attrs.height = formatter.number(bounds.height);
|
||||
return createElement('use', attrs);
|
||||
}
|
||||
|
||||
|
@ -431,7 +430,7 @@ new function() {
|
|||
: entry.type === 'array'
|
||||
? value.join(',')
|
||||
: entry.type === 'number'
|
||||
? format(value)
|
||||
? formatter.number(value)
|
||||
: value;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
/**
|
||||
* @name Format
|
||||
* @namespace
|
||||
* @private
|
||||
*/
|
||||
var Format = new function() {
|
||||
// Cache for precision values, linking prec -> Math.pow(10, prec)
|
||||
var precisions = {};
|
||||
|
||||
function number(val, prec) {
|
||||
prec = prec
|
||||
? precisions[prec] || (precisions[prec] = Math.pow(10, prec))
|
||||
: 100000; // Default is 5
|
||||
return Math.round(val * prec) / prec;
|
||||
}
|
||||
|
||||
function point(val, prec, separator) {
|
||||
return number(val.x, prec) + (separator || ',') + number(val.y, prec);
|
||||
}
|
||||
|
||||
function size(val, prec, separator) {
|
||||
return number(val.width, prec) + (separator || ',')
|
||||
+ number(val.height, prec);
|
||||
}
|
||||
|
||||
function rectangle(val, prec, separator) {
|
||||
return point(val, prec, separator) + (separator || ',')
|
||||
+ size(val, prec, separator);
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Utility function for rendering numbers as strings at a precision of
|
||||
* up to the amount of fractional digits.
|
||||
*
|
||||
* @param {Number} num the number to be converted to a string
|
||||
* @param {Number} [precision=5] the amount of fractional digits.
|
||||
*/
|
||||
number: number,
|
||||
point: point,
|
||||
size: size,
|
||||
rectangle: rectangle
|
||||
};
|
||||
};
|
51
src/util/Formatter.js
Normal file
51
src/util/Formatter.js
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
|
||||
* http://paperjs.org/
|
||||
*
|
||||
* Copyright (c) 2011 - 2013, Juerg Lehni & Jonathan Puckey
|
||||
* http://lehni.org/ & http://jonathanpuckey.com/
|
||||
*
|
||||
* Distributed under the MIT license. See LICENSE file for details.
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @name Formatter
|
||||
* @private
|
||||
*/
|
||||
var Formatter = Base.extend({
|
||||
/**
|
||||
* @param {Number} [precision=5] the amount of fractional digits.
|
||||
*/
|
||||
initialize: function(precision) {
|
||||
this.precision = precision || 5;
|
||||
this.multiplier = Math.pow(10, this.precision);
|
||||
},
|
||||
|
||||
/**
|
||||
* Utility function for rendering numbers as strings at a precision of
|
||||
* up to the amount of fractional digits.
|
||||
*
|
||||
* @param {Number} num the number to be converted to a string
|
||||
*/
|
||||
number: function(val) {
|
||||
return Math.round(val * this.multiplier) / this.multiplier;
|
||||
},
|
||||
|
||||
point: function(val, separator) {
|
||||
return this.number(val.x) + (separator || ',') + this.number(val.y);
|
||||
},
|
||||
|
||||
size: function(val, separator) {
|
||||
return this.number(val.width) + (separator || ',')
|
||||
+ this.number(val.height);
|
||||
},
|
||||
|
||||
rectangle: function(val, separator) {
|
||||
return this.point(val, separator) + (separator || ',')
|
||||
+ this.size(val, separator);
|
||||
}
|
||||
});
|
||||
|
||||
Formatter.instance = new Formatter(5);
|
|
@ -60,14 +60,16 @@ function asyncTest(testName, expected) {
|
|||
}
|
||||
|
||||
function compareNumbers(number1, number2, message, precision) {
|
||||
equals(Format.number(number1, precision),
|
||||
Format.number(number2, precision), message);
|
||||
var formatter = new Formatter(precision);
|
||||
equals(formatter.number(number1, precision),
|
||||
formatter.number(number2, precision), message);
|
||||
}
|
||||
|
||||
function compareArrays(array1, array2, message, precision) {
|
||||
var formatter = new Formatter(precision);
|
||||
function format(array) {
|
||||
return Base.each(array, function(value, index) {
|
||||
this[index] = Format.number(value, precision);
|
||||
this[index] = formatter.number(value, precision);
|
||||
}, []).toString();
|
||||
}
|
||||
equals(format(array1), format(array2), message);
|
||||
|
|
Loading…
Reference in a new issue