diff --git a/CHANGELOG.md b/CHANGELOG.md index f57c3331..b22dd784 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Not released][Not released] +## Added +- Custom clip function + ## [0.14.0][2016-06-17] ### Fixed diff --git a/konva.d.ts b/konva.d.ts index 11ecf629..7ed0057c 100644 --- a/konva.d.ts +++ b/konva.d.ts @@ -283,6 +283,8 @@ declare module Konva { clipX(clipX: number) : Container; clipY(): number; clipY(clipY: number) : Container; + clipFunct(): number; + clipFunct(clipFunc: Function) : Container; destroyChildren() : void; find(selector? : string): Collection; getAllIntersections(pos: Vector2d): Node[]; diff --git a/resources/doc-includes/ContainerParams.txt b/resources/doc-includes/ContainerParams.txt index 8a572776..6b9d7237 100644 --- a/resources/doc-includes/ContainerParams.txt +++ b/resources/doc-includes/ContainerParams.txt @@ -3,3 +3,4 @@ * @param {Number} [config.clipY] set clip y * @param {Number} [config.clipWidth] set clip width * @param {Number} [config.clipHeight] set clip height + * @param {Function} [config.clipFunc] set clip func diff --git a/src/Container.js b/src/Container.js index 2bc628c8..88381225 100644 --- a/src/Container.js +++ b/src/Container.js @@ -368,17 +368,21 @@ context = canvas && canvas.getContext(), clipWidth = this.getClipWidth(), clipHeight = this.getClipHeight(), - hasClip = clipWidth && clipHeight, + clipFunc = this.getClipFunc(), + hasClip = clipWidth && clipHeight || clipFunc, clipX, clipY; if (hasClip && layer) { - clipX = this.getClipX(); - clipY = this.getClipY(); - context.save(); layer._applyTransform(this, context); context.beginPath(); - context.rect(clipX, clipY, clipWidth, clipHeight); + if (clipFunc) { + clipFunc.call(this, context, this); + } else { + clipX = this.getClipX(); + clipY = this.getClipY(); + context.rect(clipX, clipY, clipWidth, clipHeight); + } context.clip(); context.reset(); } @@ -539,5 +543,23 @@ * container.clipHeight(100); */ + Konva.Factory.addGetterSetter(Konva.Container, 'clipFunc'); + /** + * get/set clip function + * @name clipFunc + * @method + * @memberof Konva.Container.prototype + * @param {Function} function + * @returns {Function} + * @example + * // get clip function + * var clipFunction = container.clipFunc(); + * + * // set clip height + * container.clipFunc(function(ctx) { + * ctx.rect(0, 0, 100, 100); + * }); + */ + Konva.Collection.mapMethods(Konva.Container); })(); diff --git a/test/unit/Container-test.js b/test/unit/Container-test.js index ece89548..0deab4da 100644 --- a/test/unit/Container-test.js +++ b/test/unit/Container-test.js @@ -24,6 +24,42 @@ suite('Container', function() { layer.draw(); }); + // ====================================================== + test.only('clip function', function() { + var stage = addStage(); + + // cliped by circle is the same as draw circle + var layer = new Konva.Layer(); + stage.add(layer); + var circle = new Konva.Circle({ + fill: 'green', + x: 50, y: 50, + radius: 40 + }); + layer.add(circle); + + + layer.draw(); + + var clipedLayer = new Konva.Layer({ + clipFunc: function(ctx) { + ctx.arc(50, 50, 40, 0, Math.PI * 2, false); + } + }); + stage.add(clipedLayer); + var rect = new Konva.Rect({ + x: 10, + y: 10, + fill: 'green', + width: 200, + height: 200 + }); + clipedLayer.add(rect); + stage.draw(); + + compareLayers(layer, clipedLayer, 150); + }); + // ====================================================== test('adder validation', function() { var stage = addStage();