mirror of
https://github.com/konvajs/konva.git
synced 2025-09-18 09:50:05 +08:00
feat: add support for miter-limit
This commit is contained in:
@@ -304,6 +304,12 @@ export class Context {
|
||||
this.setAttr('lineJoin', lineJoin);
|
||||
}
|
||||
}
|
||||
_applyMiterLimit(shape: Shape) {
|
||||
const miterLimit = shape.attrs.miterLimit;
|
||||
if (miterLimit != null) {
|
||||
this.setAttr('miterLimit', miterLimit);
|
||||
}
|
||||
}
|
||||
|
||||
setAttr(attr: string, val) {
|
||||
this._context[attr] = val;
|
||||
|
21
src/Shape.ts
21
src/Shape.ts
@@ -66,6 +66,7 @@ export interface ShapeConfig extends NodeConfig {
|
||||
strokeEnabled?: boolean;
|
||||
lineJoin?: LineJoin;
|
||||
lineCap?: LineCap;
|
||||
miterLimit?: number;
|
||||
sceneFunc?: (con: Context, shape: Shape) => void;
|
||||
hitFunc?: (con: Context, shape: Shape) => void;
|
||||
shadowColor?: string;
|
||||
@@ -637,6 +638,7 @@ export class Shape<
|
||||
bufferContext.clear();
|
||||
bufferContext.save();
|
||||
bufferContext._applyLineJoin(this);
|
||||
bufferContext._applyMiterLimit(this);
|
||||
// layer might be undefined if we are using cache before adding to layer
|
||||
const o = this.getAbsoluteTransform(top).getMatrix();
|
||||
bufferContext.transform(o[0], o[1], o[2], o[3], o[4], o[5]);
|
||||
@@ -660,6 +662,7 @@ export class Shape<
|
||||
);
|
||||
} else {
|
||||
context._applyLineJoin(this);
|
||||
context._applyMiterLimit(this);
|
||||
|
||||
if (!cachingSelf) {
|
||||
const o = this.getAbsoluteTransform(top).getMatrix();
|
||||
@@ -710,6 +713,7 @@ export class Shape<
|
||||
}
|
||||
context.save();
|
||||
context._applyLineJoin(this);
|
||||
context._applyMiterLimit(this);
|
||||
|
||||
const selfCache = this === top;
|
||||
if (!selfCache) {
|
||||
@@ -828,6 +832,7 @@ export class Shape<
|
||||
hitFunc: GetSet<ShapeConfigHandler<this>, this>;
|
||||
lineCap: GetSet<LineCap, this>;
|
||||
lineJoin: GetSet<LineJoin, this>;
|
||||
miterLimit: GetSet<number, this>;
|
||||
perfectDrawEnabled: GetSet<boolean, this>;
|
||||
sceneFunc: GetSet<ShapeConfigHandler<this>, this>;
|
||||
shadowColor: GetSet<string, this>;
|
||||
@@ -1084,6 +1089,22 @@ Factory.addGetterSetter(Shape, 'lineCap');
|
||||
* shape.lineCap('round');
|
||||
*/
|
||||
|
||||
Factory.addGetterSetter(Shape, 'miterLimit');
|
||||
|
||||
/**
|
||||
* get/set miterLimit.
|
||||
* @name Konva.Shape#miterLimit
|
||||
* @method
|
||||
* @param {Number} miterLimit
|
||||
* @returns {Number}
|
||||
* @example
|
||||
* // get miter limit
|
||||
* var miterLimit = shape.miterLimit();
|
||||
*
|
||||
* // set miter limit
|
||||
* shape.miterLimit(10);
|
||||
*/
|
||||
|
||||
Factory.addGetterSetter(Shape, 'sceneFunc');
|
||||
|
||||
/**
|
||||
|
@@ -971,6 +971,9 @@ describe('Shape', function () {
|
||||
rect.strokeWidth(8);
|
||||
assert.equal(rect.strokeWidth(), 8);
|
||||
|
||||
rect.miterLimit(5);
|
||||
assert.equal(rect.miterLimit(), 5);
|
||||
|
||||
const f = () => {};
|
||||
rect.sceneFunc(f);
|
||||
assert.equal(rect.sceneFunc(), f);
|
||||
@@ -2408,4 +2411,59 @@ describe('Shape', function () {
|
||||
const hitShape = layer.getIntersection({ x: 150, y: 150 });
|
||||
assert.equal(hitShape, null);
|
||||
});
|
||||
|
||||
it('miterLimit with buffer canvas', function () {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
|
||||
// Sharp triangle with opacity to force buffer canvas usage
|
||||
var triangle = new Konva.Shape({
|
||||
x: 100,
|
||||
y: 50,
|
||||
sceneFunc: function (ctx, shape) {
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(140, 5);
|
||||
ctx.lineTo(0, 70);
|
||||
ctx.lineTo(220, 70);
|
||||
ctx.closePath();
|
||||
ctx.fillStrokeShape(shape);
|
||||
},
|
||||
fill: 'yellow',
|
||||
stroke: 'orange',
|
||||
strokeWidth: 10,
|
||||
lineJoin: 'miter',
|
||||
miterLimit: 3,
|
||||
opacity: 0.7, // Forces buffer canvas usage
|
||||
});
|
||||
|
||||
layer.add(triangle);
|
||||
stage.add(layer);
|
||||
|
||||
// Create expected result using native canvas with buffer approach
|
||||
var canvas = createCanvas();
|
||||
var context = canvas.getContext('2d');
|
||||
|
||||
// Draw on buffer first
|
||||
context.beginPath();
|
||||
context.translate(100, 50);
|
||||
context.moveTo(140, 5);
|
||||
context.lineTo(0, 70);
|
||||
context.lineTo(220, 70);
|
||||
context.closePath();
|
||||
context.fillStyle = 'yellow';
|
||||
context.strokeStyle = 'orange';
|
||||
context.lineWidth = 10;
|
||||
context.lineJoin = 'miter';
|
||||
context.miterLimit = 3;
|
||||
context.fill();
|
||||
context.stroke();
|
||||
|
||||
// Apply opacity by drawing to final canvas
|
||||
var finalCanvas = createCanvas();
|
||||
var finalContext = finalCanvas.getContext('2d');
|
||||
finalContext.globalAlpha = 0.7;
|
||||
finalContext.drawImage(canvas, 0, 0);
|
||||
|
||||
compareLayerAndCanvas(layer, finalCanvas, 200);
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user