mirror of
https://github.com/konvajs/konva.git
synced 2025-06-28 05:58:29 +08:00
update CHANGELOG with new version
This commit is contained in:
parent
5f8e3a587f
commit
0e87ded7ba
@ -3,6 +3,13 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## Not released:
|
||||
|
||||
## [3.2.1][2019-03-18]
|
||||
|
||||
* Better `find` and `findOne` lookup. Now we should not care about duplicate ids.
|
||||
* Better typescript definitions
|
||||
|
||||
## [3.2.0][2019-03-10]
|
||||
|
||||
* new property `shape.hitStrokeWidth(10)`
|
||||
|
@ -12,11 +12,11 @@ Konva.document = {
|
||||
addEventListener: function() {}
|
||||
}
|
||||
};
|
||||
// Konva.window = new JSDOM(
|
||||
// '<!DOCTYPE html><html><head></head><body></body></html>'
|
||||
// ).window;
|
||||
// Konva.document = Konva.window.document;
|
||||
// Konva.window.Image = Canvas.Image;
|
||||
Konva.window = new JSDOM(
|
||||
'<!DOCTYPE html><html><head></head><body></body></html>'
|
||||
).window;
|
||||
Konva.document = Konva.window.document;
|
||||
Konva.window.Image = Canvas.Image;
|
||||
Konva._nodeCanvas = Canvas;
|
||||
|
||||
module.exports = Konva;
|
||||
|
@ -25,7 +25,7 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"canvas": "^1.6.7",
|
||||
"konva": "^2.5.1"
|
||||
"canvas": "^1.6.13",
|
||||
"konva": "^2.6.0"
|
||||
}
|
||||
}
|
||||
|
4
konva.min.js
vendored
4
konva.min.js
vendored
File diff suppressed because one or more lines are too long
119
src/Container.ts
119
src/Container.ts
@ -1,6 +1,6 @@
|
||||
import { Util, Collection } from './Util';
|
||||
import { Factory } from './Factory';
|
||||
import { Node, ids, names, NodeConfig } from './Node';
|
||||
import { Node, NodeConfig } from './Node';
|
||||
import { DD } from './DragAndDrop';
|
||||
import { getNumberValidator } from './Validators';
|
||||
|
||||
@ -224,105 +224,36 @@ export abstract class Container extends Node<ContainerConfig> {
|
||||
_generalFind(selector, findOne) {
|
||||
var retArr = [];
|
||||
|
||||
if (typeof selector === 'string') {
|
||||
retArr = this._findByString(selector);
|
||||
} else if (typeof selector === 'function') {
|
||||
retArr = this._findByFunction(selector, findOne);
|
||||
}
|
||||
this._descendants(node => {
|
||||
const valid = node._isMatch(selector);
|
||||
if (valid) {
|
||||
retArr.push(node);
|
||||
}
|
||||
if (valid && findOne) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
return Collection.toCollection(retArr);
|
||||
}
|
||||
_findByString(selector) {
|
||||
var retArr = [],
|
||||
selectorArr = selector.replace(/ /g, '').split(','),
|
||||
len = selectorArr.length,
|
||||
n,
|
||||
i,
|
||||
sel,
|
||||
arr,
|
||||
node,
|
||||
children,
|
||||
clen;
|
||||
|
||||
for (n = 0; n < len; n++) {
|
||||
sel = selectorArr[n];
|
||||
if (!Util.isValidSelector(sel)) {
|
||||
var message =
|
||||
'Selector "' +
|
||||
sel +
|
||||
'" is invalid. Allowed selectors examples are "#foo", ".bar" or "Group".\n' +
|
||||
'If you have a custom shape with such className, please change it to start with upper letter like "Triangle".\n' +
|
||||
'Konva is awesome, right?';
|
||||
Util.warn(message);
|
||||
private _descendants(fn) {
|
||||
let shouldStop = false;
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
const child = this.children[i];
|
||||
shouldStop = fn(child);
|
||||
if (shouldStop) {
|
||||
return true;
|
||||
}
|
||||
// id selector
|
||||
if (sel.charAt(0) === '#') {
|
||||
node = this._getNodeById(sel.slice(1));
|
||||
if (node) {
|
||||
retArr.push(node);
|
||||
}
|
||||
} else if (sel.charAt(0) === '.') {
|
||||
// name selector
|
||||
arr = this._getNodesByName(sel.slice(1));
|
||||
retArr = retArr.concat(arr);
|
||||
} else {
|
||||
// unrecognized selector, pass to children
|
||||
children = this.getChildren();
|
||||
clen = children.length;
|
||||
for (i = 0; i < clen; i++) {
|
||||
retArr = retArr.concat(children[i]._get(sel));
|
||||
}
|
||||
if (!child.hasChildren()) {
|
||||
continue;
|
||||
}
|
||||
shouldStop = (child as Container)._descendants(fn);
|
||||
if (shouldStop) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return retArr;
|
||||
}
|
||||
// (fn: ((Node) => boolean, findOne?: boolean)
|
||||
_findByFunction(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(key) {
|
||||
var node = ids[key];
|
||||
|
||||
if (node !== undefined && this.isAncestorOf(node)) {
|
||||
return node;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
_getNodesByName(key) {
|
||||
var arr = names[key] || [];
|
||||
return this._getDescendants(arr);
|
||||
}
|
||||
_get(selector) {
|
||||
var retArr = Node.prototype._get.call(this, selector);
|
||||
var children = this.getChildren();
|
||||
var len = children.length;
|
||||
for (var n = 0; n < len; n++) {
|
||||
retArr = retArr.concat(children[n]._get(selector));
|
||||
}
|
||||
return retArr;
|
||||
return false;
|
||||
}
|
||||
// extenders
|
||||
toObject() {
|
||||
|
21
src/Node.ts
21
src/Node.ts
@ -14,18 +14,10 @@ import {
|
||||
export const ids = {};
|
||||
export const names = {};
|
||||
|
||||
const ID_WARNING = `Duplicate id "{id}".
|
||||
Please do not use same id several times, it will break find() method look up.
|
||||
If you have duplicates it is better to use "name" property instead.
|
||||
`;
|
||||
|
||||
const _addId = function(node: Node, id) {
|
||||
if (!id) {
|
||||
return;
|
||||
}
|
||||
if (ids[id]) {
|
||||
Util.warn(ID_WARNING.replace('{id}', id));
|
||||
}
|
||||
ids[id] = node;
|
||||
};
|
||||
|
||||
@ -101,6 +93,8 @@ type globalCompositeOperationType =
|
||||
| 'luminosity';
|
||||
|
||||
export interface NodeConfig {
|
||||
// allow any custom attribute
|
||||
[index: string]: any;
|
||||
x?: number;
|
||||
y?: number;
|
||||
width?: number;
|
||||
@ -123,6 +117,7 @@ export interface NodeConfig {
|
||||
dragBoundFunc?: (pos: Vector2d) => Vector2d;
|
||||
preventDefault?: boolean;
|
||||
globalCompositeOperation?: globalCompositeOperationType;
|
||||
filters?: Array<Filter>;
|
||||
}
|
||||
|
||||
// CONSTANTS
|
||||
@ -1473,6 +1468,9 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
if (!selector) {
|
||||
return false;
|
||||
}
|
||||
if (typeof selector === 'function') {
|
||||
return selector(this);
|
||||
}
|
||||
var selectorArr = selector.replace(/ /g, '').split(','),
|
||||
len = selectorArr.length,
|
||||
n,
|
||||
@ -1501,7 +1499,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
if (this.hasName(sel.slice(1))) {
|
||||
return true;
|
||||
}
|
||||
} else if (this._get(sel).length !== 0) {
|
||||
} else if (this.className === selector || this.nodeType === selector) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1895,11 +1893,6 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
return Konva.dragDistance;
|
||||
}
|
||||
}
|
||||
_get(selector) {
|
||||
return this.className === selector || this.nodeType === selector
|
||||
? [this]
|
||||
: [];
|
||||
}
|
||||
_off(type, name?, callback?) {
|
||||
var evtListeners = this.eventListeners[type],
|
||||
i,
|
||||
|
@ -290,6 +290,50 @@ suite('Container', function() {
|
||||
assert.equal(node, rect);
|
||||
});
|
||||
|
||||
// ======================================================
|
||||
test('select should return elements in their order', function() {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
stage.add(layer);
|
||||
|
||||
// create circle before any nodes
|
||||
var circle = new Konva.Circle({
|
||||
radius: 50,
|
||||
fill: 'red',
|
||||
name: 'node'
|
||||
});
|
||||
|
||||
var group = new Konva.Group({
|
||||
name: 'node'
|
||||
});
|
||||
layer.add(group);
|
||||
|
||||
var rect = new Konva.Rect({
|
||||
x: 300,
|
||||
y: 100,
|
||||
width: 100,
|
||||
height: 50,
|
||||
fill: 'purple',
|
||||
stroke: 'black',
|
||||
strokeWidth: 4,
|
||||
name: 'node'
|
||||
});
|
||||
group.add(rect);
|
||||
group.add(circle);
|
||||
|
||||
// move circle
|
||||
circle.moveToBottom();
|
||||
|
||||
assert.equal(layer.findOne('.node'), group, 'group here');
|
||||
|
||||
var nodes = layer.find('.node');
|
||||
assert.equal(nodes[0], group, 'group first');
|
||||
assert.equal(nodes[1], circle, 'then circle');
|
||||
assert.equal(nodes[2], rect, 'then rect');
|
||||
|
||||
assert.equal(layer.findOne('Shape'), circle, 'circle is first');
|
||||
});
|
||||
|
||||
// ======================================================
|
||||
test('select shape with findOne', function() {
|
||||
var stage = addStage();
|
||||
@ -385,8 +429,8 @@ suite('Container', function() {
|
||||
|
||||
assert.equal(
|
||||
layer.find('#myCircle, Circle, .myRect, Rect').length,
|
||||
4,
|
||||
'should be 4 items in the array'
|
||||
2,
|
||||
'should be 2 items in the array'
|
||||
);
|
||||
assert.equal(
|
||||
layer.find('#myCircle, Circle, .myRect, Rect')[0]._id,
|
||||
@ -395,16 +439,6 @@ suite('Container', function() {
|
||||
);
|
||||
assert.equal(
|
||||
layer.find('#myCircle, Circle, .myRect, Rect')[1]._id,
|
||||
circle._id,
|
||||
'circle id is wrong'
|
||||
);
|
||||
assert.equal(
|
||||
layer.find('#myCircle, Circle, .myRect, Rect')[2]._id,
|
||||
rect._id,
|
||||
'rect id is wrong'
|
||||
);
|
||||
assert.equal(
|
||||
layer.find('#myCircle, Circle, .myRect, Rect')[3]._id,
|
||||
rect._id,
|
||||
'rect id is wrong'
|
||||
);
|
||||
@ -441,6 +475,42 @@ suite('Container', function() {
|
||||
assert.equal(stage.find(noOp).length, 0);
|
||||
});
|
||||
|
||||
// ======================================================
|
||||
test('select shape with duplicate id', function() {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
stage.add(layer);
|
||||
|
||||
var rect1 = new Konva.Rect({
|
||||
x: 300,
|
||||
y: 100,
|
||||
width: 100,
|
||||
height: 50,
|
||||
fill: 'purple',
|
||||
stroke: 'black',
|
||||
strokeWidth: 4,
|
||||
id: 'myRect'
|
||||
});
|
||||
layer.add(rect1);
|
||||
|
||||
var rect2 = new Konva.Rect({
|
||||
x: 300,
|
||||
y: 100,
|
||||
width: 100,
|
||||
height: 50,
|
||||
fill: 'purple',
|
||||
stroke: 'black',
|
||||
strokeWidth: 4,
|
||||
id: 'myRect'
|
||||
});
|
||||
layer.add(rect2);
|
||||
stage.draw();
|
||||
|
||||
assert.equal(stage.find('#myRect').length, 2);
|
||||
assert.equal(stage.find('#myRect')[0], rect1);
|
||||
assert.equal(stage.find('#myRect')[1], rect2);
|
||||
});
|
||||
|
||||
// ======================================================
|
||||
test('set x on an array of nodes', function() {
|
||||
var stage = addStage();
|
||||
|
@ -118,7 +118,8 @@ suite('Node', function() {
|
||||
assert.equal(layer.getAbsoluteOpacity(), 0.5);
|
||||
});
|
||||
|
||||
test('warn on duplicate id', function() {
|
||||
// we don't need this test any more
|
||||
test.skip('warn on duplicate id', function() {
|
||||
var oldWarn = Konva.Util.warn;
|
||||
var called = false;
|
||||
Konva.Util.warn = function() {
|
||||
|
Loading…
Reference in New Issue
Block a user