2011-05-16 08:33:15 -04:00
|
|
|
/*
|
|
|
|
* Paper.js
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-05-16 08:33:15 -04:00
|
|
|
* This file is part of Paper.js, a JavaScript Vector Graphics Library,
|
|
|
|
* based on Scriptographer.org and designed to be largely API compatible.
|
|
|
|
* http://paperjs.org/
|
|
|
|
* http://scriptographer.org/
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-05-16 08:33:15 -04:00
|
|
|
* Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
|
|
|
|
* http://lehni.org/ & http://jonathanpuckey.com/
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-07-01 06:17:45 -04:00
|
|
|
* Distributed under the MIT license. See LICENSE file for details.
|
|
|
|
*
|
2011-05-16 08:33:15 -04:00
|
|
|
* All rights reserved.
|
|
|
|
*/
|
|
|
|
|
2011-06-22 18:56:05 -04:00
|
|
|
/**
|
|
|
|
* @name Symbol
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-06-22 18:56:05 -04:00
|
|
|
* @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 Symbol = this.Symbol = Base.extend(/** @lends Symbol# */{
|
2011-05-23 12:28:48 -04:00
|
|
|
/**
|
|
|
|
* Creates a Symbol item.
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-05-23 12:28:48 -04:00
|
|
|
* @param {Item} item the source item which is copied as the definition of
|
|
|
|
* the symbol
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-06-03 16:25:37 -04:00
|
|
|
* @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'
|
|
|
|
* };
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-06-03 16:25:37 -04:00
|
|
|
* // Create a symbol from the path:
|
|
|
|
* var symbol = new Symbol(path);
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-06-03 16:25:37 -04:00
|
|
|
* // Remove the path:
|
|
|
|
* path.remove();
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-06-03 16:25:37 -04:00
|
|
|
* // Place 100 instances of the symbol:
|
|
|
|
* for (var i = 0; i < 100; i++) {
|
|
|
|
* // Place an instance of the symbol in the project:
|
|
|
|
* var instance = symbol.place();
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-06-03 16:25:37 -04:00
|
|
|
* // Move the instance to a random position within the view:
|
|
|
|
* instance.position = Point.random() * view.size;
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-06-03 16:25:37 -04:00
|
|
|
* // Rotate the instance by a random amount between
|
|
|
|
* // 0 and 360 degrees:
|
|
|
|
* instance.rotate(Math.random() * 360);
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-06-03 16:25:37 -04:00
|
|
|
* // Scale the instance between 0.25 and 1:
|
|
|
|
* instance.scale(0.25 + Math.random() * 0.75);
|
|
|
|
* }
|
2011-05-23 12:28:48 -04:00
|
|
|
*/
|
2011-05-16 08:33:15 -04:00
|
|
|
initialize: function(item) {
|
|
|
|
this.project = paper.project;
|
|
|
|
this.project.symbols.push(this);
|
|
|
|
this.setDefinition(item);
|
2011-07-04 15:27:42 -04:00
|
|
|
// Hash to keep track of placed instances
|
|
|
|
this._instances = {};
|
2011-05-16 08:33:15 -04:00
|
|
|
},
|
|
|
|
|
2011-05-27 07:28:13 -04:00
|
|
|
// TODO: Symbol#remove()
|
2011-06-01 05:49:43 -04:00
|
|
|
// TODO: Symbol#name (accessible by name through project#symbols)
|
2011-05-27 07:28:13 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The project that this symbol belongs to.
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-05-27 07:28:13 -04:00
|
|
|
* @type Project
|
|
|
|
* @readonly
|
|
|
|
* @name Symbol#project
|
|
|
|
*/
|
2011-05-20 03:55:44 -04:00
|
|
|
|
2011-07-04 15:27:42 -04:00
|
|
|
/**
|
|
|
|
* Private notifier that is called whenever a change occurs in this symbol's
|
|
|
|
* definition.
|
|
|
|
*
|
|
|
|
* @param {ChangeFlag} flags describes what exactly has changed.
|
|
|
|
*/
|
|
|
|
_changed: function(flags) {
|
|
|
|
// Notify all PlacedItems of the change in our definition, so they
|
|
|
|
// can clear cached bounds.
|
|
|
|
Base.each(this._instances, function(item) {
|
|
|
|
item._changed(flags);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2011-05-23 12:28:48 -04:00
|
|
|
/**
|
|
|
|
* The symbol definition.
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-05-23 12:28:48 -04:00
|
|
|
* @type Item
|
|
|
|
* @bean
|
|
|
|
*/
|
2011-05-16 08:33:15 -04:00
|
|
|
getDefinition: function() {
|
|
|
|
return this._definition;
|
|
|
|
},
|
|
|
|
|
|
|
|
setDefinition: function(item) {
|
2011-07-04 15:27:42 -04:00
|
|
|
// Make sure we're not steatling another symbol's definition
|
|
|
|
if (item._parentSymbol)
|
|
|
|
item = item.clone();
|
|
|
|
// Remove previous definition's reference to this symbol
|
|
|
|
if (this._definition)
|
|
|
|
delete this._definition._parentSymbol;
|
2011-05-16 08:33:15 -04:00
|
|
|
this._definition = item;
|
2011-06-19 11:13:38 -04:00
|
|
|
// Remove item from DOM, as it's embedded in Symbol now.
|
|
|
|
item.remove();
|
2011-07-04 15:27:42 -04:00
|
|
|
// Move position to 0, 0, so it's centered when placed.
|
2011-05-16 08:33:15 -04:00
|
|
|
item.setPosition(new Point());
|
2011-07-04 15:27:42 -04:00
|
|
|
item._parentSymbol = this;
|
2012-11-05 21:11:44 -05:00
|
|
|
this._changed(/*#=*/ Change.GEOMETRY);
|
2011-05-23 12:28:48 -04:00
|
|
|
},
|
|
|
|
|
2011-06-03 16:25:37 -04:00
|
|
|
/**
|
|
|
|
* Places in instance of the symbol in the project.
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-06-03 16:25:37 -04:00
|
|
|
* @param [position] The position of the placed symbol.
|
|
|
|
* @return {PlacedSymbol}
|
|
|
|
*/
|
|
|
|
place: function(position) {
|
|
|
|
return new PlacedSymbol(this, position);
|
|
|
|
},
|
|
|
|
|
2011-05-23 12:28:48 -04:00
|
|
|
/**
|
|
|
|
* Returns a copy of the symbol.
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-05-23 12:28:48 -04:00
|
|
|
* @return {Symbol}
|
|
|
|
*/
|
|
|
|
clone: function() {
|
|
|
|
return new Symbol(this._definition.clone());
|
2011-05-16 08:33:15 -04:00
|
|
|
}
|
|
|
|
});
|