Implement unique ids, and fix issue with Base.deserialize()

Gradient and Symbol were overriding each other in the dictionary, and dictionary entries could not contain references to other dictionary entries.

Closes 
This commit is contained in:
Jürg Lehni 2015-05-11 19:39:39 +02:00
parent 783d1622b9
commit 27bb8a356f
9 changed files with 64 additions and 23 deletions

View file

@ -6,15 +6,20 @@
<link rel="stylesheet" href="../css/style.css">
<script type="text/javascript" src="../../dist/paper-full.js"></script>
<script type="text/paperscript" canvas="canvas1">
var path = new Path.Circle(view.center, view.bounds.height * 0.4);
var path = new Path.Circle({
center: view.center,
radius: view.bounds.height * 0.4
});
path.fillColor = {
// gradient: [['yellow', 'red', 'black'], true],
stops: ['yellow', 'red', 'black'],
radial: true,
origin: path.position,
destination: path.bounds.rightCenter
}
path.strokeColor = 'black';
var symbol = new Symbol(path);
symbol.place(view.center);
window._json = project.exportJSON();
console.log(window._json);
</script>

View file

@ -392,7 +392,7 @@ Base.inject(/** @lends Base# */{
* The passed json data is recoursively traversed and converted, leaves
* first
*/
deserialize: function(json, create, _data) {
deserialize: function(json, create, _data, _isDictionary) {
var res = json,
isRoot = !_data;
// A _data side-car to deserialize that can hold any kind of
@ -405,22 +405,24 @@ Base.inject(/** @lends Base# */{
// deserialize all elements of the array.
var type = json[0],
// Handle stored dictionary specially, since we need to
// keep is a lookup table to retrieve referenced items from.
// keep a lookup table to retrieve referenced items from.
isDictionary = type === 'dictionary';
if (!isDictionary) {
// First see if this is perhaps a dictionary reference, and
// if so return its definition instead.
if (_data.dictionary && json.length == 1 && /^#/.test(type))
return _data.dictionary[type];
type = Base.exports[type];
}
// First see if this is perhaps a dictionary reference, and
// if so return its definition instead.
if (json.length == 1 && /^#/.test(type))
return _data.dictionary[type];
type = Base.exports[type];
res = [];
// We need to set the dictionary object before further
// deserialization, because serialized symbols may contain
// references to serialized gradients
if (_isDictionary)
_data.dictionary = res;
// Skip first type entry for arguments
for (var i = type ? 1 : 0, l = json.length; i < l; i++)
res.push(Base.deserialize(json[i], create, _data));
if (isDictionary) {
_data.dictionary = res[0];
} else if (type) {
res.push(Base.deserialize(json[i], create, _data,
isDictionary));
if (type) {
// Create serialized type and pass collected arguments to
// constructor().
var args = res;
@ -436,6 +438,9 @@ Base.inject(/** @lends Base# */{
}
} else if (Base.isPlainObject(json)) {
res = {};
// See above why we have to set this before Base.deserialize()
if (_isDictionary)
_data.dictionary = res;
for (var key in json)
res[key] = Base.deserialize(json[key], create, _data);
}

View file

@ -91,7 +91,7 @@ var Item = Base.extend(Emitter, /** @lends Item# */{
// Allow setting another project than the currently active one.
project = hasProps && props.project || paper.project;
if (!internal)
this._id = Item._id = (Item._id || 0) + 1;
this._id = UID.get();
// Inherit the applyMatrix setting from paper.settings.applyMatrix
this._applyMatrix = this._canApplyMatrix && paper.settings.applyMatrix;
// Handle matrix before everything else, to avoid issues with

View file

@ -51,6 +51,7 @@ var paper = new function(undefined) {
/*#*/ include('util/Formatter.js');
/*#*/ include('util/Numerical.js');
/*#*/ include('util/UID.js');
// Include Paper classes, which are later injected into PaperScope by setting
// them on the 'this' object, e.g.:

View file

@ -44,6 +44,9 @@ var CurveLocation = Base.extend(/** @lends CurveLocation# */{
initialize: function CurveLocation(curve, parameter, point, _curve2,
_parameter2, _point2, _distance) {
// Define this CurveLocation's unique id.
// NOTE: We do not use the same pool as the rest of the library here,
// since this is only required to be unique at runtime among other
// CurveLocation objects.
this._id = CurveLocation._id = (CurveLocation._id || 0) + 1;
this._curve = curve;
// Also store references to segment1 and segment2, in case path

View file

@ -61,7 +61,7 @@ var Symbol = Base.extend(/** @lends Symbol# */{
*/
initialize: function Symbol(item, dontCenter) {
// Define this Symbols's unique id.
this._id = Symbol._id = (Symbol._id || 0) + 1;
this._id = UID.get();
this.project = paper.project;
this.project.symbols.push(this);
if (item)

View file

@ -608,9 +608,6 @@ var Color = Base.extend(new function() {
}
// Default fallbacks: rgb, black
this._type = type || 'rgb';
// Define this gradient Color's unique id.
if (type === 'gradient')
this._id = Color._id = (Color._id || 0) + 1;
if (!components) {
// Produce a components array now, and parse values. Even if no
// values are defined, parsers are still called to produce

View file

@ -66,8 +66,8 @@ var Gradient = Base.extend(/** @lends Gradient# */{
// DOCS: Document #initialize()
initialize: function Gradient(stops, radial) {
// Define this Gradient's unique id.
this._id = Gradient._id = (Gradient._id || 0) + 1;
// Use UID here since Gradients are exported through dictionary.add().
this._id = UID.get();
if (stops && this._set(stops))
stops = radial = null;
if (!this._stops)

30
src/util/UID.js Normal file
View file

@ -0,0 +1,30 @@
/*
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
* Copyright (c) 2011 - 2014, Juerg Lehni & Jonathan Puckey
* http://scratchdisk.com/ & http://jonathanpuckey.com/
*
* Distributed under the MIT license. See LICENSE file for details.
*
* All rights reserved.
*/
/**
* @name UID
* @namespace
* @private
*/
var UID = {
_id: 1,
/**
* Returns the next unique id.
* @method get
* @return {Number} The next unique id
* @static
**/
get: function() {
return this._id++;
}
};