mirror of
https://github.com/konvajs/konva.git
synced 2025-11-24 08:46:44 +08:00
Merge branch 'seethroughtrees-feature/findOne'
This commit is contained in:
41
konva.d.ts
vendored
41
konva.d.ts
vendored
@@ -5,15 +5,34 @@ declare namespace Konva {
|
||||
var isDragReady: () => boolean;
|
||||
var DD: any;
|
||||
|
||||
type globalCompositeOperationType = '' |
|
||||
'source-over' | 'source-in' | 'source-out' | 'source-atop' |
|
||||
'destination-over' | 'destination-in' | 'destination-out' | 'destination-atop' |
|
||||
'lighter' | 'copy' | 'xor' | 'multiply' |
|
||||
'screen' | 'overlay' | 'darken' | 'lighten' |
|
||||
'color-dodge' | 'color-burn' | 'hard-light' | 'soft-light' |
|
||||
'difference' | 'exclusion' | 'hue' | 'saturation' |
|
||||
'color' | 'luminosity'
|
||||
;
|
||||
type globalCompositeOperationType =
|
||||
| ''
|
||||
| 'source-over'
|
||||
| 'source-in'
|
||||
| 'source-out'
|
||||
| 'source-atop'
|
||||
| 'destination-over'
|
||||
| 'destination-in'
|
||||
| 'destination-out'
|
||||
| 'destination-atop'
|
||||
| 'lighter'
|
||||
| 'copy'
|
||||
| 'xor'
|
||||
| 'multiply'
|
||||
| 'screen'
|
||||
| 'overlay'
|
||||
| 'darken'
|
||||
| 'lighten'
|
||||
| 'color-dodge'
|
||||
| 'color-burn'
|
||||
| 'hard-light'
|
||||
| 'soft-light'
|
||||
| 'difference'
|
||||
| 'exclusion'
|
||||
| 'hue'
|
||||
| 'saturation'
|
||||
| 'color'
|
||||
| 'luminosity';
|
||||
|
||||
export class Util {
|
||||
static getRandomColor(): string;
|
||||
@@ -323,8 +342,8 @@ declare namespace Konva {
|
||||
clipFunc(): (ctx: CanvasRenderingContext2D) => void;
|
||||
clipFunc(ctx: CanvasRenderingContext2D | undefined | null): void;
|
||||
destroyChildren(): void;
|
||||
find(selector?: string): Collection;
|
||||
findOne<T extends Node>(selector: string): T;
|
||||
find(selector?: string | ((Node) => boolean)): Collection;
|
||||
findOne<T extends Node>(selector: string | ((Node) => boolean)): T;
|
||||
getAllIntersections(pos: Vector2d): Shape[];
|
||||
hasChildren(): boolean;
|
||||
removeChildren(): void;
|
||||
|
||||
102
src/Container.js
102
src/Container.js
@@ -141,14 +141,18 @@
|
||||
return this;
|
||||
},
|
||||
/**
|
||||
* return a {@link Konva.Collection} of nodes that match the selector. Use '#' for id selections
|
||||
* and '.' for name selections. You can also select by type or class name. Pass multiple selectors
|
||||
* return a {@link Konva.Collection} of nodes that match the selector.
|
||||
* You can provide a string with '#' for id selections and '.' for name selections.
|
||||
* Or a function that will return true/false when a node is passed through. See example below.
|
||||
* With strings you can also select by type or class name. Pass multiple selectors
|
||||
* separated by a space.
|
||||
* @method
|
||||
* @memberof Konva.Container.prototype
|
||||
* @param {String} selector
|
||||
* @param {String | Function} selector
|
||||
* @returns {Collection}
|
||||
* @example
|
||||
*
|
||||
* Passing a string as a selector
|
||||
* // select node with id foo
|
||||
* var node = stage.find('#foo');
|
||||
*
|
||||
@@ -163,8 +167,58 @@
|
||||
*
|
||||
* // select node with an id of foo or a name of bar inside layer
|
||||
* var nodes = layer.find('#foo, .bar');
|
||||
*
|
||||
* Passing a function as a selector
|
||||
*
|
||||
* // get all Groups
|
||||
* var groups = stage.find(node => {
|
||||
* return node.getType() === 'Group';
|
||||
* });
|
||||
*
|
||||
* // get only Nodes with partial opacity
|
||||
* var alphaNodes = layer.find(node => {
|
||||
* return node.getType() === 'Node' && node.getAbsoluteOpacity() < 1;
|
||||
* });
|
||||
*/
|
||||
find: function(selector) {
|
||||
// protecting _generalFind to prevent user from accidentally adding
|
||||
// second argument and getting unexpected `findOne` result
|
||||
return this._generalFind(selector, false);
|
||||
},
|
||||
/**
|
||||
* return a first node from `find` method
|
||||
* @method
|
||||
* @memberof Konva.Container.prototype
|
||||
* @param {String | Function} selector
|
||||
* @returns {Konva.Node | Undefined}
|
||||
* @example
|
||||
* // select node with id foo
|
||||
* var node = stage.findOne('#foo');
|
||||
*
|
||||
* // select node with name bar inside layer
|
||||
* var nodes = layer.findOne('.bar');
|
||||
*
|
||||
* // select the first node to return true in a function
|
||||
* var node = stage.findOne(node => {
|
||||
* return node.getType() === 'Shape'
|
||||
* })
|
||||
*/
|
||||
findOne: function(selector) {
|
||||
var result = this._generalFind(selector, true);
|
||||
return result.length > 0 ? result[0] : undefined;
|
||||
},
|
||||
_generalFind: function(selector, findOne) {
|
||||
var retArr = [];
|
||||
|
||||
if (typeof selector === 'string') {
|
||||
retArr = this._findByString(selector, findOne);
|
||||
} else if (typeof selector === 'function') {
|
||||
retArr = this._findByFunction(selector, findOne);
|
||||
}
|
||||
|
||||
return Konva.Collection.toCollection(retArr);
|
||||
},
|
||||
_findByString: function(selector) {
|
||||
var retArr = [],
|
||||
selectorArr = selector.replace(/ /g, '').split(','),
|
||||
len = selectorArr.length,
|
||||
@@ -209,23 +263,33 @@
|
||||
}
|
||||
}
|
||||
|
||||
return Konva.Collection.toCollection(retArr);
|
||||
return retArr;
|
||||
},
|
||||
/**
|
||||
* return a first node from `find` method
|
||||
* @method
|
||||
* @memberof Konva.Container.prototype
|
||||
* @param {String} selector
|
||||
* @returns {Konva.Node}
|
||||
* @example
|
||||
* // select node with id foo
|
||||
* var node = stage.findOne('#foo');
|
||||
*
|
||||
* // select node with name bar inside layer
|
||||
* var nodes = layer.findOne('.bar');
|
||||
*/
|
||||
findOne: function(selector) {
|
||||
return this.find(selector)[0];
|
||||
// (fn: ((Node) => boolean, findOne?: boolean)
|
||||
_findByFunction: function(fn, findOne) {
|
||||
var retArr = [];
|
||||
|
||||
var addItems = function(el) {
|
||||
// escape function if we've already found one.
|
||||
if (findOne && retArr.length > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var children = el.getChildren();
|
||||
var clen = children.length;
|
||||
|
||||
if (fn(el)) {
|
||||
retArr = retArr.concat(el);
|
||||
}
|
||||
|
||||
for (var i = 0; i < clen; i++) {
|
||||
addItems(children[i]);
|
||||
}
|
||||
};
|
||||
|
||||
addItems(this);
|
||||
|
||||
return retArr;
|
||||
},
|
||||
_getNodeById: function(key) {
|
||||
var node = Konva.ids[key];
|
||||
|
||||
@@ -363,14 +363,14 @@
|
||||
var lineWidth = this._getTextWidth(line);
|
||||
if (fixedWidth && lineWidth > maxWidth) {
|
||||
/*
|
||||
* if width is fixed and line does not fit entirely
|
||||
* break the line into multiple fitting lines
|
||||
*/
|
||||
* if width is fixed and line does not fit entirely
|
||||
* break the line into multiple fitting lines
|
||||
*/
|
||||
while (line.length > 0) {
|
||||
/*
|
||||
* use binary search to find the longest substring that
|
||||
* that would fit in the specified width
|
||||
*/
|
||||
* use binary search to find the longest substring that
|
||||
* that would fit in the specified width
|
||||
*/
|
||||
var low = 0,
|
||||
high = line.length,
|
||||
match = '',
|
||||
@@ -414,9 +414,9 @@
|
||||
(fixedHeight && currentHeightPx + lineHeightPx > maxHeightPx)
|
||||
) {
|
||||
/*
|
||||
* stop wrapping if wrapping is disabled or if adding
|
||||
* one more line would overflow the fixed height
|
||||
*/
|
||||
* stop wrapping if wrapping is disabled or if adding
|
||||
* one more line would overflow the fixed height
|
||||
*/
|
||||
break;
|
||||
}
|
||||
line = line.slice(low);
|
||||
|
||||
@@ -291,7 +291,7 @@ suite('Container', function() {
|
||||
});
|
||||
|
||||
// ======================================================
|
||||
test('select shape by id and name with findOne', function() {
|
||||
test('select shape with findOne', function() {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer({
|
||||
id: 'myLayer'
|
||||
@@ -330,6 +330,10 @@ suite('Container', function() {
|
||||
assert.equal(node, undefined, 'node should be undefined');
|
||||
node = stage.findOne('#myLayer');
|
||||
assert.equal(node, layer, 'node type should be Layer');
|
||||
node = stage.findOne(function(node) {
|
||||
return node.getType() === 'Shape';
|
||||
});
|
||||
assert.equal(node, circle, 'findOne should work with functions');
|
||||
});
|
||||
|
||||
// ======================================================
|
||||
@@ -406,6 +410,37 @@ suite('Container', function() {
|
||||
);
|
||||
});
|
||||
|
||||
// ======================================================
|
||||
test('select shape by function', function() {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
|
||||
var rect = new Konva.Rect({
|
||||
x: 300,
|
||||
y: 100,
|
||||
width: 100,
|
||||
height: 50,
|
||||
fill: 'purple',
|
||||
stroke: 'black',
|
||||
strokeWidth: 4,
|
||||
name: 'myRect'
|
||||
});
|
||||
|
||||
layer.add(rect);
|
||||
stage.add(layer);
|
||||
|
||||
var fn = function(node) {
|
||||
return node.nodeType === 'Shape';
|
||||
};
|
||||
|
||||
var noOp = function(node) {
|
||||
return false;
|
||||
};
|
||||
|
||||
assert.equal(stage.find(fn)[0], rect);
|
||||
assert.equal(stage.find(noOp).length, 0);
|
||||
});
|
||||
|
||||
// ======================================================
|
||||
test('set x on an array of nodes', function() {
|
||||
var stage = addStage();
|
||||
|
||||
Reference in New Issue
Block a user