paper.js/src/item/SymbolDefinition.js

161 lines
4.7 KiB
JavaScript
Raw Normal View History

/*
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
* Copyright (c) 2011 - 2016, Juerg Lehni & Jonathan Puckey
2014-01-03 19:47:16 -05:00
* http://scratchdisk.com/ & http://jonathanpuckey.com/
*
2011-07-01 06:17:45 -04:00
* Distributed under the MIT license. See LICENSE file for details.
*
* All rights reserved.
*/
/**
* @name SymbolDefinition
*
* @class Symbols allow you to place multiple instances of an item in your
* project. This can save memory, since all instances of a symbol simply refer
* to the original item and it can speed up moving around complex objects, since
* internal properties such as segment lists and gradient positions don't need
* to be updated with every transformation.
*/
var SymbolDefinition = Base.extend(/** @lends SymbolDefinition# */{
_class: 'SymbolDefinition',
2014-08-16 13:24:54 -04:00
/**
* Creates a Symbol definition.
2014-08-16 13:24:54 -04:00
*
* @param {Item} item the source item which is removed from the scene graph
* and becomes the symbol's definition.
2014-08-16 13:24:54 -04:00
* @param {Boolean} [dontCenter=false]
*
* @example {@paperscript split=true height=240}
* // Placing 100 instances of a symbol:
* var path = new Path.Star(new Point(0, 0), 6, 5, 13);
* path.style = {
* fillColor: 'white',
* strokeColor: 'black'
* };
*
* // Create a symbol definition from the path:
* var definition = new SymbolDefinition(path);
2014-08-16 13:24:54 -04:00
*
* // Place 100 instances of the symbol definition:
2014-08-16 13:24:54 -04:00
* for (var i = 0; i < 100; i++) {
* // Place an instance of the symbol definition in the project:
* var instance = definition.place();
2014-08-16 13:24:54 -04:00
*
* // Move the instance to a random position within the view:
* instance.position = Point.random() * view.size;
*
* // Rotate the instance by a random amount between
* // 0 and 360 degrees:
* instance.rotate(Math.random() * 360);
*
* // Scale the instance between 0.25 and 1:
* instance.scale(0.25 + Math.random() * 0.75);
* }
*/
initialize: function SymbolDefinition(item, dontCenter) {
this._id = UID.get();
2014-08-16 13:24:54 -04:00
this.project = paper.project;
if (item)
this.setItem(item, dontCenter);
2014-08-16 13:24:54 -04:00
},
2014-08-16 13:24:54 -04:00
_serialize: function(options, dictionary) {
return dictionary.add(this, function() {
return Base.serialize([this._class, this._item],
2014-08-16 13:24:54 -04:00
options, false, dictionary);
});
},
2014-08-16 13:24:54 -04:00
/**
* The project that this symbol belongs to.
*
* @type Project
* @readonly
* @name SymbolDefinition#project
2014-08-16 13:24:54 -04:00
*/
2011-05-20 03:55:44 -04:00
2014-08-16 13:24:54 -04:00
/**
* Private notifier that is called whenever a change occurs in this symbol's
* definition.
*
2015-06-16 11:50:37 -04:00
* @param {ChangeFlag} flags describes what exactly has changed
2014-08-16 13:24:54 -04:00
*/
_changed: function(flags) {
if (flags & /*#=*/ChangeFlag.GEOMETRY)
2014-08-16 13:24:54 -04:00
// Clear cached bounds of all items that this symbol is linked to.
Item._clearBoundsCache(this);
if (flags & /*#=*/ChangeFlag.APPEARANCE)
this.project._changed(flags);
2014-08-16 13:24:54 -04:00
},
2014-08-16 13:24:54 -04:00
/**
* The item used as the symbol's definition.
2014-08-16 13:24:54 -04:00
*
* @bean
* @type Item
2014-08-16 13:24:54 -04:00
*/
getItem: function() {
return this._item;
2014-08-16 13:24:54 -04:00
},
setItem: function(item, _dontCenter) {
2014-08-16 13:24:54 -04:00
// Make sure we're not stealing another symbol's definition
2016-05-22 15:23:46 -04:00
if (item._symbol)
2014-08-16 13:24:54 -04:00
item = item.clone();
// Remove previous definition's reference to this symbol
if (this._item)
2016-05-22 15:23:46 -04:00
this._item._symbol = null;
this._item = item;
2014-08-16 13:24:54 -04:00
// Remove item from DOM, as it's embedded in Symbol now.
item.remove();
item.setSelected(false);
// Move position to 0, 0, so it's centered when placed.
if (!_dontCenter)
item.setPosition(new Point());
2016-05-22 15:23:46 -04:00
item._symbol = this;
2014-08-16 13:24:54 -04:00
this._changed(/*#=*/Change.GEOMETRY);
},
/**
* @bean
* @deprecated use {@link #getItem()} instead.
*/
getDefinition: '#getItem',
setDefinition: '#setItem',
2014-08-16 13:24:54 -04:00
/**
* Places in instance of the symbol in the project.
*
2015-09-21 10:54:33 -04:00
* @param {Point} [position] the position of the placed symbol
* @return {SymbolItem}
2014-08-16 13:24:54 -04:00
*/
place: function(position) {
return new SymbolItem(this, position);
2014-08-16 13:24:54 -04:00
},
2011-06-03 16:25:37 -04:00
2014-08-16 13:24:54 -04:00
/**
* Returns a copy of the symbol.
*
* @return {Symbol}
*/
clone: function() {
return new SymbolDefinition(this._item.clone(false));
2014-12-28 12:03:19 -05:00
},
/**
* Checks whether the symbol's definition is equal to the supplied symbol.
*
* @param {Symbol} symbol
* @return {Boolean} {@true if they are equal}
*/
equals: function(symbol) {
return symbol === this
|| symbol && this._item.equals(symbol._item)
2014-12-28 12:03:19 -05:00
|| false;
2014-08-16 13:24:54 -04:00
}
});