mirror of
https://github.com/konvajs/konva.git
synced 2026-01-02 20:42:42 +08:00
continued prep work for v4.0.0. removed detectionType property because new event engine uses one strategy. added new drawBuffer method so that you can redraw the buffer without redrawing the visible canvas. changed alpha to opacity.
This commit is contained in:
@@ -63,19 +63,21 @@ Kinetic.Container = Kinetic.Node.extend({
|
||||
child._id = Kinetic.Global.idCounter++;
|
||||
child.index = this.children.length;
|
||||
child.parent = this;
|
||||
|
||||
|
||||
// set color key
|
||||
var shapes = Kinetic.Global.shapes;
|
||||
var key;
|
||||
while (true) {
|
||||
key = Kinetic.Type._getRandomColorKey();
|
||||
if (key && !(key in shapes)) {
|
||||
break;
|
||||
}
|
||||
if(child.nodeType === 'Shape') {
|
||||
var shapes = Kinetic.Global.shapes;
|
||||
var key;
|
||||
while(true) {
|
||||
key = Kinetic.Type._getRandomColorKey();
|
||||
if(key && !( key in shapes)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
child.colorKey = key;
|
||||
shapes[key] = child;
|
||||
}
|
||||
|
||||
child.colorKey = key;
|
||||
shapes[key] = child;
|
||||
|
||||
this.children.push(child);
|
||||
var stage = child.getStage();
|
||||
@@ -247,13 +249,15 @@ Kinetic.Container = Kinetic.Node.extend({
|
||||
var children = this.children;
|
||||
for(var n = 0; n < children.length; n++) {
|
||||
var child = children[n];
|
||||
if(child.nodeType === 'Shape') {
|
||||
if(child.isVisible() && stage.isVisible()) {
|
||||
child._draw(canvas);
|
||||
if(canvas.name !== 'buffer' || child.getListening()) {
|
||||
if(child.nodeType === 'Shape') {
|
||||
if(child.isVisible()) {
|
||||
child._draw(canvas);
|
||||
}
|
||||
}
|
||||
else {
|
||||
child.draw(canvas);
|
||||
}
|
||||
}
|
||||
else {
|
||||
child.draw(canvas);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -10,6 +10,8 @@ Kinetic.Filters = {};
|
||||
Kinetic.Plugins = {};
|
||||
Kinetic.Global = {
|
||||
BUBBLE_WHITELIST: ['mousedown', 'mousemove', 'mouseup', 'mouseover', 'mouseout', 'click', 'dblclick', 'touchstart', 'touchmove', 'touchend', 'tap', 'dbltap', 'dragstart', 'dragmove', 'dragend'],
|
||||
BUFFER_WHITELIST: ['fill', 'stroke', 'textFill', 'textStroke'],
|
||||
BUFFER_BLACKLIST: ['shadow'],
|
||||
stages: [],
|
||||
idCounter: 0,
|
||||
tempNodes: {},
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* @param {Boolean} [config.listening] whether or not the node is listening for events
|
||||
* @param {String} [config.id] unique id
|
||||
* @param {String} [config.name] non-unique name
|
||||
* @param {Number} [config.alpha] determines node opacity. Can be any number between 0 and 1
|
||||
* @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1
|
||||
* @param {Object} [config.scale]
|
||||
* @param {Number} [config.scale.x]
|
||||
* @param {Number} [config.scale.y]
|
||||
|
||||
31
src/Layer.js
31
src/Layer.js
@@ -15,7 +15,7 @@
|
||||
* @param {Boolean} [config.listening] whether or not the node is listening for events
|
||||
* @param {String} [config.id] unique id
|
||||
* @param {String} [config.name] non-unique name
|
||||
* @param {Number} [config.alpha] determines node opacity. Can be any number between 0 and 1
|
||||
* @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1
|
||||
* @param {Object} [config.scale]
|
||||
* @param {Number} [config.scale.x]
|
||||
* @param {Number} [config.scale.y]
|
||||
@@ -59,6 +59,15 @@ Kinetic.Layer = Kinetic.Container.extend({
|
||||
draw: function(canvas) {
|
||||
this._draw(canvas);
|
||||
},
|
||||
/**
|
||||
* draw children nodes on buffer. this includes any groups
|
||||
* or shapes
|
||||
* @name drawBuffer
|
||||
* @methodOf Kinetic.Layer.prototype
|
||||
*/
|
||||
drawBuffer: function() {
|
||||
this.draw(this.bufferCanvas);
|
||||
},
|
||||
/**
|
||||
* set before draw handler
|
||||
* @name beforeDraw
|
||||
@@ -151,7 +160,9 @@ Kinetic.Layer = Kinetic.Container.extend({
|
||||
|
||||
if(this.attrs.clearBeforeDraw) {
|
||||
canvas.clear();
|
||||
this.bufferCanvas.clear();
|
||||
if(canvas.name !== 'buffer') {
|
||||
this.bufferCanvas.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if(this.isVisible()) {
|
||||
@@ -160,10 +171,18 @@ Kinetic.Layer = Kinetic.Container.extend({
|
||||
this.attrs.drawFunc.call(this);
|
||||
}
|
||||
|
||||
// draw children on front canvas
|
||||
this._drawChildren(canvas);
|
||||
// draw children on back canvas
|
||||
this._drawChildren(this.bufferCanvas);
|
||||
if(canvas.name !== 'buffer') {
|
||||
this._drawChildren(canvas);
|
||||
if(this.getListening()) {
|
||||
this._drawChildren(this.bufferCanvas);
|
||||
}
|
||||
}
|
||||
// buffer canvas
|
||||
else {
|
||||
if(this.getListening()) {
|
||||
this._drawChildren(canvas);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// after draw handler
|
||||
|
||||
47
src/Node.js
47
src/Node.js
@@ -13,7 +13,7 @@
|
||||
* @param {Boolean} [config.listening] whether or not the node is listening for events
|
||||
* @param {String} [config.id] unique id
|
||||
* @param {String} [config.name] non-unique name
|
||||
* @param {Number} [config.alpha] determines node opacity. Can be any number between 0 and 1
|
||||
* @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1
|
||||
* @param {Object} [config.scale]
|
||||
* @param {Number} [config.scale.x]
|
||||
* @param {Number} [config.scale.y]
|
||||
@@ -37,7 +37,7 @@ Kinetic.Node = Kinetic.Class.extend({
|
||||
visible: true,
|
||||
listening: true,
|
||||
name: undefined,
|
||||
alpha: 1,
|
||||
opacity: 1,
|
||||
x: 0,
|
||||
y: 0,
|
||||
scale: {
|
||||
@@ -561,19 +561,19 @@ Kinetic.Node = Kinetic.Class.extend({
|
||||
this.parent._setChildrenIndices();
|
||||
},
|
||||
/**
|
||||
* get absolute alpha
|
||||
* @name getAbsoluteAlpha
|
||||
* get absolute opacity
|
||||
* @name getAbsoluteOpacity
|
||||
* @methodOf Kinetic.Node.prototype
|
||||
*/
|
||||
getAbsoluteAlpha: function() {
|
||||
var absAlpha = 1;
|
||||
getAbsoluteOpacity: function() {
|
||||
var absOpacity = 1;
|
||||
var node = this;
|
||||
// traverse upwards
|
||||
while(node.nodeType !== 'Stage') {
|
||||
absAlpha *= node.attrs.alpha;
|
||||
absOpacity *= node.attrs.opacity;
|
||||
node = node.parent;
|
||||
}
|
||||
return absAlpha;
|
||||
return absOpacity;
|
||||
},
|
||||
/**
|
||||
* determine if node is currently in drag and drop mode
|
||||
@@ -650,7 +650,7 @@ Kinetic.Node = Kinetic.Class.extend({
|
||||
},
|
||||
/**
|
||||
* transition node to another state. Any property that can accept a real
|
||||
* number can be transitioned, including x, y, rotation, alpha, strokeWidth,
|
||||
* number can be transitioned, including x, y, rotation, opacity, strokeWidth,
|
||||
* radius, scale.x, scale.y, offset.x, offset.y, etc.
|
||||
* @name transitionTo
|
||||
* @methodOf Kinetic.Node.prototype
|
||||
@@ -1079,7 +1079,7 @@ Kinetic.Node._addGetter = function(constructor, attr) {
|
||||
};
|
||||
};
|
||||
// add getters setters
|
||||
Kinetic.Node.addGettersSetters(Kinetic.Node, ['x', 'y', 'scale', 'detectionType', 'rotation', 'alpha', 'name', 'id', 'offset', 'draggable', 'dragConstraint', 'dragBounds', 'listening']);
|
||||
Kinetic.Node.addGettersSetters(Kinetic.Node, ['x', 'y', 'scale', 'rotation', 'opacity', 'name', 'id', 'offset', 'draggable', 'dragConstraint', 'dragBounds', 'listening']);
|
||||
Kinetic.Node.addSetters(Kinetic.Node, ['rotationDeg']);
|
||||
|
||||
/**
|
||||
@@ -1096,13 +1096,6 @@ Kinetic.Node.addSetters(Kinetic.Node, ['rotationDeg']);
|
||||
* @param {Number} y
|
||||
*/
|
||||
|
||||
/**
|
||||
* set detection type
|
||||
* @name setDetectionType
|
||||
* @methodOf Kinetic.Node.prototype
|
||||
* @param {String} type can be path or pixel
|
||||
*/
|
||||
|
||||
/**
|
||||
* set node rotation in radians
|
||||
* @name setRotation
|
||||
@@ -1111,12 +1104,12 @@ Kinetic.Node.addSetters(Kinetic.Node, ['rotationDeg']);
|
||||
*/
|
||||
|
||||
/**
|
||||
* set alpha. Alpha values range from 0 to 1.
|
||||
* A node with an alpha of 0 is fully transparent, and a node
|
||||
* with an alpha of 1 is fully opaque
|
||||
* @name setAlpha
|
||||
* set opacity. Opacity values range from 0 to 1.
|
||||
* A node with an opacity of 0 is fully transparent, and a node
|
||||
* with an opacity of 1 is fully opaque
|
||||
* @name setOpacity
|
||||
* @methodOf Kinetic.Node.prototype
|
||||
* @param {Object} alpha
|
||||
* @param {Object} opacity
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -1192,12 +1185,6 @@ Kinetic.Node.addSetters(Kinetic.Node, ['rotationDeg']);
|
||||
* @methodOf Kinetic.Node.prototype
|
||||
*/
|
||||
|
||||
/**
|
||||
* get detection type. Can be path or pixel
|
||||
* @name getDetectionType
|
||||
* @methodOf Kinetic.Node.prototype
|
||||
*/
|
||||
|
||||
/**
|
||||
* get rotation in radians
|
||||
* @name getRotation
|
||||
@@ -1205,8 +1192,8 @@ Kinetic.Node.addSetters(Kinetic.Node, ['rotationDeg']);
|
||||
*/
|
||||
|
||||
/**
|
||||
* get alpha.
|
||||
* @name getAlpha
|
||||
* get opacity.
|
||||
* @name getOpacity
|
||||
* @methodOf Kinetic.Node.prototype
|
||||
*/
|
||||
|
||||
|
||||
69
src/Shape.js
69
src/Shape.js
@@ -33,17 +33,15 @@
|
||||
* @config {Obect} [config.shadow.blur.offset]
|
||||
* @config {Number} [config.shadow.blur.offset.x]
|
||||
* @config {Number} [config.shadow.blur.offset.y]
|
||||
* @config {Number} [config.shadow.alpha] shadow alpha. Can be any real number
|
||||
* @config {Number} [config.shadow.opacity] shadow opacity. Can be any real number
|
||||
* between 0 and 1
|
||||
* @config {String} [config.detectionType] shape detection type. Can be path or pixel.
|
||||
* The default is path because it performs better
|
||||
* @param {Number} [config.x]
|
||||
* @param {Number} [config.y]
|
||||
* @param {Boolean} [config.visible]
|
||||
* @param {Boolean} [config.listening] whether or not the node is listening for events
|
||||
* @param {String} [config.id] unique id
|
||||
* @param {String} [config.name] non-unique name
|
||||
* @param {Number} [config.alpha] determines node opacity. Can be any number between 0 and 1
|
||||
* @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1
|
||||
* @param {Object} [config.scale]
|
||||
* @param {Number} [config.scale.x]
|
||||
* @param {Number} [config.scale.y]
|
||||
@@ -63,10 +61,6 @@
|
||||
*/
|
||||
Kinetic.Shape = Kinetic.Node.extend({
|
||||
init: function(config) {
|
||||
this.setDefaultAttrs({
|
||||
detectionType: 'path'
|
||||
});
|
||||
|
||||
this.nodeType = 'Shape';
|
||||
this.appliedShadow = false;
|
||||
|
||||
@@ -287,7 +281,7 @@ Kinetic.Shape = Kinetic.Node.extend({
|
||||
_applyShadow: function(context) {
|
||||
var s = this.attrs.shadow;
|
||||
if(s) {
|
||||
var aa = this.getAbsoluteAlpha();
|
||||
var aa = this.getAbsoluteOpacity();
|
||||
// defaults
|
||||
var color = s.color ? s.color : 'black';
|
||||
var blur = s.blur ? s.blur : 5;
|
||||
@@ -296,8 +290,8 @@ Kinetic.Shape = Kinetic.Node.extend({
|
||||
y: 0
|
||||
};
|
||||
|
||||
if(s.alpha) {
|
||||
context.globalAlpha = s.alpha * aa;
|
||||
if(s.opacity) {
|
||||
context.globalAlpha = s.opacity * aa;
|
||||
}
|
||||
context.shadowColor = color;
|
||||
context.shadowBlur = blur;
|
||||
@@ -320,22 +314,7 @@ Kinetic.Shape = Kinetic.Node.extend({
|
||||
var pos = Kinetic.Type._getXY(Array.prototype.slice.call(arguments));
|
||||
var stage = this.getStage();
|
||||
|
||||
// path detection
|
||||
if(this.attrs.detectionType === 'path') {
|
||||
var pathCanvas = stage.pathCanvas;
|
||||
var pathCanvasContext = pathCanvas.getContext();
|
||||
|
||||
this._draw(pathCanvas);
|
||||
|
||||
return pathCanvasContext.isPointInPath(pos.x, pos.y);
|
||||
}
|
||||
|
||||
// pixel detection
|
||||
if(this.imageData) {
|
||||
var w = stage.attrs.width;
|
||||
var alpha = this.imageData.data[((w * pos.y) + pos.x) * 4 + 3];
|
||||
return (alpha);
|
||||
}
|
||||
// TODO: need to re-implement
|
||||
|
||||
// default
|
||||
return false;
|
||||
@@ -362,34 +341,44 @@ Kinetic.Shape = Kinetic.Node.extend({
|
||||
}
|
||||
|
||||
/*
|
||||
* pre styles include alpha, linejoin
|
||||
* pre styles include opacity, linejoin
|
||||
*/
|
||||
var absAlpha = this.getAbsoluteAlpha();
|
||||
if(absAlpha !== 1) {
|
||||
context.globalAlpha = absAlpha;
|
||||
var absOpacity = this.getAbsoluteOpacity();
|
||||
if(absOpacity !== 1) {
|
||||
context.globalAlpha = absOpacity;
|
||||
}
|
||||
this.applyLineJoin(context);
|
||||
|
||||
// draw the shape
|
||||
this.appliedShadow = false;
|
||||
|
||||
var wl = Kinetic.Global.BUFFER_WHITELIST;
|
||||
var bl = Kinetic.Global.BUFFER_BLACKLIST;
|
||||
var attrs = {};
|
||||
if(canvas.name === 'buffer') {
|
||||
var fill = this.attrs.fill;
|
||||
var stroke = this.attrs.stroke;
|
||||
|
||||
if(fill) {
|
||||
this.attrs.fill = '#' + this.colorKey;
|
||||
for(var n = 0; n < wl.length; n++) {
|
||||
var key = wl[n];
|
||||
attrs[key] = this.attrs[key];
|
||||
if(this.attrs[key]) {
|
||||
this.attrs[key] = '#' + this.colorKey;
|
||||
}
|
||||
}
|
||||
if(stroke) {
|
||||
this.attrs.stroke = '#' + this.colorKey;
|
||||
for(var n = 0; n < bl.length; n++) {
|
||||
var key = bl[n];
|
||||
attrs[key] = this.attrs[key];
|
||||
this.attrs[key] = '';
|
||||
}
|
||||
context.globalAlpha = 1;
|
||||
}
|
||||
|
||||
this.attrs.drawFunc.call(this, canvas.getContext());
|
||||
|
||||
if(canvas.name === 'buffer') {
|
||||
this.attrs.fill = fill;
|
||||
this.attrs.stroke = stroke;
|
||||
var bothLists = wl.concat(bl);
|
||||
for(var n = 0; n < bothLists.length; n++) {
|
||||
var key = bothLists[n];
|
||||
this.attrs[key] = attrs[key];
|
||||
}
|
||||
}
|
||||
|
||||
context.restore();
|
||||
|
||||
14
src/Stage.js
14
src/Stage.js
@@ -15,7 +15,7 @@
|
||||
* @param {Boolean} [config.listening] whether or not the node is listening for events
|
||||
* @param {String} [config.id] unique id
|
||||
* @param {String} [config.name] non-unique name
|
||||
* @param {Number} [config.alpha] determines node opacity. Can be any number between 0 and 1
|
||||
* @param {Number} [config.opacity] determines node opacity. Can be any number between 0 and 1
|
||||
* @param {Object} [config.scale]
|
||||
* @param {Number} [config.scale.x]
|
||||
* @param {Number} [config.scale.y]
|
||||
@@ -401,12 +401,14 @@ Kinetic.Stage = Kinetic.Container.extend({
|
||||
for(var n = layers.length - 1; n >= 0; n--) {
|
||||
var layer = layers[n];
|
||||
var p = layer.bufferCanvas.context.getImageData(pos.x, pos.y, 1, 1).data;
|
||||
var colorKey = Kinetic.Type._rgbToHex(p[0], p[1], p[2]);
|
||||
shape = Kinetic.Global.shapes[colorKey];
|
||||
var isDragging = Kinetic.Global.drag.moving;
|
||||
if(p[3] === 255) {
|
||||
var colorKey = Kinetic.Type._rgbToHex(p[0], p[1], p[2]);
|
||||
shape = Kinetic.Global.shapes[colorKey];
|
||||
var isDragging = Kinetic.Global.drag.moving;
|
||||
|
||||
if(shape) {
|
||||
return shape;
|
||||
if(shape) {
|
||||
return shape;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -92,8 +92,6 @@ Kinetic.Canvas.prototype = {
|
||||
*/
|
||||
strip: function() {
|
||||
var context = this.context;
|
||||
context.drawImage = function() {
|
||||
};
|
||||
},
|
||||
/**
|
||||
* toDataURL
|
||||
|
||||
@@ -252,7 +252,7 @@ Kinetic.Type = {
|
||||
}
|
||||
},
|
||||
_rgbToHex: function(r, g, b) {
|
||||
return ((r << 16) | (g << 8) | b).toString(16);
|
||||
return ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
|
||||
},
|
||||
_getRandomColorKey: function() {
|
||||
var r = Math.round(Math.random() * 255);
|
||||
|
||||
Reference in New Issue
Block a user