mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-05-16 15:50:47 -04:00
Implement getters / setters for #locked, #visible, #blendMode and #opacity, and call _changed() from setters.
This commit is contained in:
parent
0b8b0f9a08
commit
ca16e43c1f
3 changed files with 121 additions and 92 deletions
209
src/item/Item.js
209
src/item/Item.js
|
@ -194,6 +194,112 @@ var Item = this.Item = Base.extend({
|
||||||
this._style.initialize(style);
|
this._style.initialize(style);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
}, new function() { // Injection scope to produce getter setters for properties
|
||||||
|
// We need setters because we want to call _changed() if a property was
|
||||||
|
// modified.
|
||||||
|
return Base.each(['locked', 'visible', 'blendMode', 'opacity'],
|
||||||
|
function(name) {
|
||||||
|
var part = Base.capitalize(name),
|
||||||
|
name = '_' + name;
|
||||||
|
this['get' + part] = function() {
|
||||||
|
return this[name];
|
||||||
|
};
|
||||||
|
this['set' + part] = function(value) {
|
||||||
|
if (value != this[name]) {
|
||||||
|
this[name] = value;
|
||||||
|
// #locked does not change appearance, all others do:
|
||||||
|
this._changed(ChangeFlags.ATTRIBUTE
|
||||||
|
| (name !== '_locked' ? ChangeFlags.APPEARANCE : 0));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, {});
|
||||||
|
}, {
|
||||||
|
/** @lends Item# */
|
||||||
|
|
||||||
|
// Note: These properties have their getter / setters produced in the
|
||||||
|
// injection scope above.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether the item is locked.
|
||||||
|
*
|
||||||
|
* @name Item#locked
|
||||||
|
* @type Boolean
|
||||||
|
* @default false
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
|
_locked: false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether the item is visible. When set to {@code false}, the
|
||||||
|
* item won't be drawn.
|
||||||
|
*
|
||||||
|
* @name Item#visible
|
||||||
|
* @type Boolean
|
||||||
|
* @default true
|
||||||
|
*
|
||||||
|
* @example {@paperscript}
|
||||||
|
* // Hiding an item:
|
||||||
|
* var path = new Path.Circle(new Point(50, 50), 20);
|
||||||
|
* path.fillColor = 'red';
|
||||||
|
*
|
||||||
|
* // Hide the path:
|
||||||
|
* path.visible = false;
|
||||||
|
*/
|
||||||
|
_visible: true,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The blend mode of the item.
|
||||||
|
*
|
||||||
|
* @name Item#blendMode
|
||||||
|
* @type String('normal', 'multiply', 'screen', 'overlay', 'soft-light',
|
||||||
|
* 'hard-light', 'color-dodge', 'color-burn', 'darken', 'lighten',
|
||||||
|
* 'difference', 'exclusion', 'hue', 'saturation', 'luminosity', 'color',
|
||||||
|
* 'add', 'subtract', 'average', 'pin-light', 'negation')
|
||||||
|
* @default 'normal'
|
||||||
|
*
|
||||||
|
* @example {@paperscript}
|
||||||
|
* // Setting an item's blend mode:
|
||||||
|
*
|
||||||
|
* // Create a white rectangle in the background
|
||||||
|
* // with the same dimensions as the view:
|
||||||
|
* var background = new Path.Rectangle(view.bounds);
|
||||||
|
* background.fillColor = 'white';
|
||||||
|
*
|
||||||
|
* var circle = new Path.Circle(new Point(80, 50), 35);
|
||||||
|
* circle.fillColor = 'red';
|
||||||
|
*
|
||||||
|
* var circle2 = new Path.Circle(new Point(120, 50), 35);
|
||||||
|
* circle2.fillColor = 'blue';
|
||||||
|
*
|
||||||
|
* // Set the blend mode of circle2:
|
||||||
|
* circle2.blendMode = 'multiply';
|
||||||
|
*/
|
||||||
|
_blendMode: 'normal',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The opacity of the item as a value between {@code 0} and {@code 1}.
|
||||||
|
*
|
||||||
|
* @name Item#opacity
|
||||||
|
* @type Number
|
||||||
|
* @default 1
|
||||||
|
*
|
||||||
|
* @example {@paperscript}
|
||||||
|
* // Making an item 50% transparent:
|
||||||
|
* var circle = new Path.Circle(new Point(80, 50), 35);
|
||||||
|
* circle.fillColor = 'red';
|
||||||
|
*
|
||||||
|
* var circle2 = new Path.Circle(new Point(120, 50), 35);
|
||||||
|
* circle2.style = {
|
||||||
|
* fillColor: 'blue',
|
||||||
|
* strokeColor: 'green',
|
||||||
|
* strokeWidth: 10
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* // Make circle2 50% transparent:
|
||||||
|
* circle2.opacity = 0.5;
|
||||||
|
*/
|
||||||
|
_opacity: 1,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies whether an item is selected and will also return {@code true}
|
* Specifies whether an item is selected and will also return {@code true}
|
||||||
* if the item is partially selected (groups with some selected or partially
|
* if the item is partially selected (groups with some selected or partially
|
||||||
|
@ -205,6 +311,7 @@ var Item = this.Item = Base.extend({
|
||||||
* and bounding boxes of symbol and raster items.
|
* and bounding boxes of symbol and raster items.
|
||||||
*
|
*
|
||||||
* @type Boolean
|
* @type Boolean
|
||||||
|
* @default false
|
||||||
* @bean
|
* @bean
|
||||||
* @see Project#selectedItems
|
* @see Project#selectedItems
|
||||||
* @see Segment#selected
|
* @see Segment#selected
|
||||||
|
@ -239,34 +346,6 @@ var Item = this.Item = Base.extend({
|
||||||
_selected: false,
|
_selected: false,
|
||||||
|
|
||||||
// TODO: isFullySelected / setFullySelected
|
// TODO: isFullySelected / setFullySelected
|
||||||
// TODO: Change to getter / setters for these below that notify of changes
|
|
||||||
// through _changed()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies whether the item is locked.
|
|
||||||
*
|
|
||||||
* @type Boolean
|
|
||||||
* @default false
|
|
||||||
* @ignore
|
|
||||||
*/
|
|
||||||
locked: false,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies whether the item is visible. When set to {@code false}, the
|
|
||||||
* item won't be drawn.
|
|
||||||
*
|
|
||||||
* @type Boolean
|
|
||||||
* @default true
|
|
||||||
*
|
|
||||||
* @example {@paperscript}
|
|
||||||
* // Hiding an item:
|
|
||||||
* var path = new Path.Circle(new Point(50, 50), 20);
|
|
||||||
* path.fillColor = 'red';
|
|
||||||
*
|
|
||||||
* // Hide the path:
|
|
||||||
* path.visible = false;
|
|
||||||
*/
|
|
||||||
visible: true,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies whether the item defines a clip mask. This can only be set on
|
* Specifies whether the item defines a clip mask. This can only be set on
|
||||||
|
@ -276,7 +355,6 @@ var Item = this.Item = Base.extend({
|
||||||
* @type Boolean
|
* @type Boolean
|
||||||
* @default false
|
* @default false
|
||||||
* @bean
|
* @bean
|
||||||
* @ignore // ignoring this until we actually make use of it for drawing
|
|
||||||
*/
|
*/
|
||||||
isClipMask: function() {
|
isClipMask: function() {
|
||||||
return this._clipMask;
|
return this._clipMask;
|
||||||
|
@ -291,56 +369,7 @@ var Item = this.Item = Base.extend({
|
||||||
this._changed(ChangeFlags.ATTRIBUTE | ChangeFlags.APPEARANCE);
|
this._changed(ChangeFlags.ATTRIBUTE | ChangeFlags.APPEARANCE);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
_clipMask: false,
|
||||||
* The blend mode of the item.
|
|
||||||
*
|
|
||||||
* @type String('normal', 'multiply', 'screen', 'overlay', 'soft-light',
|
|
||||||
* 'hard-light', 'color-dodge', 'color-burn', 'darken', 'lighten',
|
|
||||||
* 'difference', 'exclusion', 'hue', 'saturation', 'luminosity', 'color',
|
|
||||||
* 'add', 'subtract', 'average', 'pin-light', 'negation')
|
|
||||||
* @default 'normal'
|
|
||||||
*
|
|
||||||
* @example {@paperscript}
|
|
||||||
* // Setting an item's blend mode:
|
|
||||||
*
|
|
||||||
* // Create a white rectangle in the background
|
|
||||||
* // with the same dimensions as the view:
|
|
||||||
* var background = new Path.Rectangle(view.bounds);
|
|
||||||
* background.fillColor = 'white';
|
|
||||||
*
|
|
||||||
* var circle = new Path.Circle(new Point(80, 50), 35);
|
|
||||||
* circle.fillColor = 'red';
|
|
||||||
*
|
|
||||||
* var circle2 = new Path.Circle(new Point(120, 50), 35);
|
|
||||||
* circle2.fillColor = 'blue';
|
|
||||||
*
|
|
||||||
* // Set the blend mode of circle2:
|
|
||||||
* circle2.blendMode = 'multiply';
|
|
||||||
*/
|
|
||||||
blendMode: 'normal',
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The opacity of the item as a value between {@code 0} and {@code 1}.
|
|
||||||
*
|
|
||||||
* @example {@paperscript}
|
|
||||||
* // Making an item 50% transparent:
|
|
||||||
* var circle = new Path.Circle(new Point(80, 50), 35);
|
|
||||||
* circle.fillColor = 'red';
|
|
||||||
*
|
|
||||||
* var circle2 = new Path.Circle(new Point(120, 50), 35);
|
|
||||||
* circle2.style = {
|
|
||||||
* fillColor: 'blue',
|
|
||||||
* strokeColor: 'green',
|
|
||||||
* strokeWidth: 10
|
|
||||||
* };
|
|
||||||
*
|
|
||||||
* // Make circle2 50% transparent:
|
|
||||||
* circle2.opacity = 0.5;
|
|
||||||
*
|
|
||||||
* @type Number
|
|
||||||
* @default 1
|
|
||||||
*/
|
|
||||||
opacity: 1,
|
|
||||||
|
|
||||||
// TODO: get/setIsolated (print specific feature)
|
// TODO: get/setIsolated (print specific feature)
|
||||||
// TODO: get/setKnockout (print specific feature)
|
// TODO: get/setKnockout (print specific feature)
|
||||||
|
@ -539,8 +568,8 @@ var Item = this.Item = Base.extend({
|
||||||
// Only copy over these fields if they are actually defined in 'this'
|
// Only copy over these fields if they are actually defined in 'this'
|
||||||
// TODO: Consider moving this to Base once it's useful in more than one
|
// TODO: Consider moving this to Base once it's useful in more than one
|
||||||
// place
|
// place
|
||||||
var keys = ['locked', 'visible', 'opacity', 'blendMode', '_clipMask',
|
var keys = ['_locked', '_visible', '_opacity', '_blendMode',
|
||||||
'_selected'];
|
'_clipMask', '_selected'];
|
||||||
for (var i = 0, l = keys.length; i < l; i++) {
|
for (var i = 0, l = keys.length; i < l; i++) {
|
||||||
var key = keys[i];
|
var key = keys[i];
|
||||||
if (this.hasOwnProperty(key))
|
if (this.hasOwnProperty(key))
|
||||||
|
@ -823,7 +852,7 @@ var Item = this.Item = Base.extend({
|
||||||
isEditable: function() {
|
isEditable: function() {
|
||||||
var item = this;
|
var item = this;
|
||||||
while (item) {
|
while (item) {
|
||||||
if (!item.visible || item.locked)
|
if (!item._visible || item._locked)
|
||||||
return false;
|
return false;
|
||||||
item = item._parent;
|
item = item._parent;
|
||||||
}
|
}
|
||||||
|
@ -993,7 +1022,7 @@ var Item = this.Item = Base.extend({
|
||||||
y2 = x2;
|
y2 = x2;
|
||||||
for (var i = 0, l = children.length; i < l; i++) {
|
for (var i = 0, l = children.length; i < l; i++) {
|
||||||
var child = children[i];
|
var child = children[i];
|
||||||
if (child.visible) {
|
if (child._visible) {
|
||||||
var rect = includeStroke
|
var rect = includeStroke
|
||||||
? child.getStrokeBounds()
|
? child.getStrokeBounds()
|
||||||
: child.getBounds();
|
: child.getBounds();
|
||||||
|
@ -1412,7 +1441,7 @@ var Item = this.Item = Base.extend({
|
||||||
// TODO: Optimize temporary canvas drawing to ignore parts that are
|
// TODO: Optimize temporary canvas drawing to ignore parts that are
|
||||||
// outside of the visible view.
|
// outside of the visible view.
|
||||||
draw: function(item, ctx, param) {
|
draw: function(item, ctx, param) {
|
||||||
if (!item.visible || item.opacity == 0)
|
if (!item._visible || item._opacity == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var tempCanvas, parentCtx;
|
var tempCanvas, parentCtx;
|
||||||
|
@ -1422,8 +1451,8 @@ var Item = this.Item = Base.extend({
|
||||||
// and strokeColor also need to be drawn on a temporary canvas first,
|
// and strokeColor also need to be drawn on a temporary canvas first,
|
||||||
// since otherwise their stroke is drawn half transparent over their
|
// since otherwise their stroke is drawn half transparent over their
|
||||||
// fill.
|
// fill.
|
||||||
if (item.blendMode !== 'normal'
|
if (item._blendMode !== 'normal'
|
||||||
|| item.opacity < 1
|
|| item._opacity < 1
|
||||||
&& !(item._segments && (!item.getFillColor()
|
&& !(item._segments && (!item.getFillColor()
|
||||||
|| !item.getStrokeColor()))) {
|
|| !item.getStrokeColor()))) {
|
||||||
var bounds = item.getStrokeBounds() || item.getBounds();
|
var bounds = item.getStrokeBounds() || item.getBounds();
|
||||||
|
@ -1467,17 +1496,17 @@ var Item = this.Item = Base.extend({
|
||||||
|
|
||||||
// If the item has a blendMode, use BlendMode#process to
|
// If the item has a blendMode, use BlendMode#process to
|
||||||
// composite its canvas on the parentCanvas.
|
// composite its canvas on the parentCanvas.
|
||||||
if (item.blendMode !== 'normal') {
|
if (item._blendMode !== 'normal') {
|
||||||
// The pixel offset of the temporary canvas to the parent
|
// The pixel offset of the temporary canvas to the parent
|
||||||
// canvas.
|
// canvas.
|
||||||
var pixelOffset = itemOffset.subtract(param.offset);
|
var pixelOffset = itemOffset.subtract(param.offset);
|
||||||
BlendMode.process(item.blendMode, ctx, parentCtx,
|
BlendMode.process(item._blendMode, ctx, parentCtx,
|
||||||
item.opacity, pixelOffset);
|
item._opacity, pixelOffset);
|
||||||
} else {
|
} else {
|
||||||
// Otherwise we just need to set the globalAlpha before drawing
|
// Otherwise we just need to set the globalAlpha before drawing
|
||||||
// the temporary canvas on the parent canvas.
|
// the temporary canvas on the parent canvas.
|
||||||
parentCtx.save();
|
parentCtx.save();
|
||||||
parentCtx.globalAlpha = item.opacity;
|
parentCtx.globalAlpha = item._opacity;
|
||||||
parentCtx.drawImage(tempCanvas,
|
parentCtx.drawImage(tempCanvas,
|
||||||
itemOffset.x, itemOffset.y);
|
itemOffset.x, itemOffset.y);
|
||||||
parentCtx.restore();
|
parentCtx.restore();
|
||||||
|
|
|
@ -1276,7 +1276,7 @@ var Path = this.Path = PathItem.extend({
|
||||||
// we will do it later when we composite the temporary
|
// we will do it later when we composite the temporary
|
||||||
// canvas.
|
// canvas.
|
||||||
if (!fillColor || !strokeColor)
|
if (!fillColor || !strokeColor)
|
||||||
ctx.globalAlpha = this.opacity;
|
ctx.globalAlpha = this._opacity;
|
||||||
if (fillColor) {
|
if (fillColor) {
|
||||||
ctx.fillStyle = fillColor.getCanvasStyle(ctx);
|
ctx.fillStyle = fillColor.getCanvasStyle(ctx);
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
|
|
|
@ -96,7 +96,7 @@ var PointText = this.PointText = TextItem.extend({
|
||||||
var fillColor = this.getFillColor();
|
var fillColor = this.getFillColor();
|
||||||
var strokeColor = this.getStrokeColor();
|
var strokeColor = this.getStrokeColor();
|
||||||
if (!fillColor || !strokeColor)
|
if (!fillColor || !strokeColor)
|
||||||
ctx.globalAlpha = this.opacity;
|
ctx.globalAlpha = this._opacity;
|
||||||
if (fillColor) {
|
if (fillColor) {
|
||||||
ctx.fillStyle = fillColor.getCanvasStyle(ctx);
|
ctx.fillStyle = fillColor.getCanvasStyle(ctx);
|
||||||
ctx.fillText(this.content, 0, 0);
|
ctx.fillText(this.content, 0, 0);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue