forked from paperjs/paper.js
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSymbol.js
More file actions
151 lines (141 loc) · 4 KB
/
Copy pathSymbol.js
File metadata and controls
151 lines (141 loc) · 4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
* 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 Symbol
*
* @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 = Base.extend(/** @lends Symbol# */{
_class: 'Symbol',
/**
* Creates a Symbol item.
*
* @param {Item} item the source item which is copied as the definition of
* the symbol
* @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 from the path:
* var symbol = new Symbol(path);
*
* // Remove the path:
* path.remove();
*
* // 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();
*
* // 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 Symbol(item, dontCenter) {
// Define this Symbols's unique id.
this._id = Symbol._id = (Symbol._id || 0) + 1;
this.project = paper.project;
this.project.symbols.push(this);
if (item)
this.setDefinition(item, dontCenter);
// Hash to keep track of placed instances
this._instances = {};
},
_serialize: function(options, dictionary) {
return dictionary.add(this, function() {
return Base.serialize([this._class, this._definition],
options, false, dictionary);
});
},
// TODO: Symbol#remove()
// TODO: Symbol#name (accessible by name through project#symbols)
/**
* The project that this symbol belongs to.
*
* @type Project
* @readonly
* @name Symbol#project
*/
/**
* 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 PlacedSymbols of the change in our definition, so they
// can clear cached bounds.
Base.each(this._instances, function(item) {
item._changed(flags);
});
},
/**
* The symbol definition.
*
* @type Item
* @bean
*/
getDefinition: function() {
return this._definition;
},
setDefinition: function(item /*, dontCenter */) {
// 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;
this._definition = item;
// 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 (!arguments[1])
item.setPosition(new Point());
item._parentSymbol = this;
this._changed(/*#=*/ Change.GEOMETRY);
},
/**
* Places in instance of the symbol in the project.
*
* @param [position] The position of the placed symbol.
* @return {PlacedSymbol}
*/
place: function(position) {
return new PlacedSymbol(this, position);
},
/**
* Returns a copy of the symbol.
*
* @return {Symbol}
*/
clone: function() {
return new Symbol(this._definition.clone(false));
}
});