Fix fill pattern for Konva.Text when the pattern has an offset or rotation. close #852

This commit is contained in:
Anton Lavrenov 2021-05-06 14:53:02 -05:00
parent 8359287949
commit ef6fbf2e14
6 changed files with 87 additions and 22 deletions

View File

@ -15,6 +15,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Removed `Konva.UA`, `Konva._parseUA` (it was used for old browser detection)
- Fixed Arrow head position when an arrow has tension
- `textPath.getKerning()` is removed
- Fix `a` command parsing for `Konva.Path`
- Fix fill pattern for `Konva.Text` when the pattern has an offset or rotation
## 7.2.5

View File

@ -704,21 +704,21 @@ export class SceneContext extends Context {
fillPatternScaleX = shape.getFillPatternScaleX(),
fillPatternScaleY = shape.getFillPatternScaleY();
if (fillPatternX || fillPatternY) {
this.translate(fillPatternX || 0, fillPatternY || 0);
}
// if (fillPatternX || fillPatternY) {
// this.translate(fillPatternX || 0, fillPatternY || 0);
// }
if (fillPatternRotation) {
this.rotate(fillPatternRotation);
}
// if (fillPatternRotation) {
// this.rotate(fillPatternRotation);
// }
if (fillPatternScaleX || fillPatternScaleY) {
// this.scale(fillPatternScaleX, fillPatternScaleY);
}
if (fillPatternOffsetX || fillPatternOffsetY) {
this.translate(-1 * fillPatternOffsetX, -1 * fillPatternOffsetY);
}
// if (fillPatternOffsetX || fillPatternOffsetY) {
// this.translate(-1 * fillPatternOffsetX, -1 * fillPatternOffsetY);
// }
this.setAttr('fillStyle', shape._getFillPattern());
shape._fillFunc(this);

View File

@ -1,4 +1,5 @@
import { Util } from './Util';
import { Konva } from './Global';
import { Transform, Util } from './Util';
import { Factory } from './Factory';
import { Node, NodeConfig } from './Node';
import {
@ -256,13 +257,25 @@ export class Shape<
this.fillPatternRepeat() || 'repeat'
);
if (pattern && pattern.setTransform) {
const tr = new Transform();
tr.translate(this.fillPatternX(), this.fillPatternX());
tr.rotate(Konva.getAngle(this.fillPatternRotation()));
tr.scale(this.fillPatternScaleX(), this.fillPatternScaleY());
tr.translate(
-1 * this.fillPatternOffsetX(),
-1 * this.fillPatternOffsetY()
);
const m = tr.getMatrix();
pattern.setTransform({
a: this.fillPatternScaleX(), // Horizontal scaling. A value of 1 results in no scaling.
b: 0, // Vertical skewing.
c: 0, // Horizontal skewing.
d: this.fillPatternScaleY(), // Vertical scaling. A value of 1 results in no scaling.
e: 0, // Horizontal translation (moving).
f: 0, // Vertical translation (moving).
a: m[0], // Horizontal scaling. A value of 1 results in no scaling.
b: m[1], // Vertical skewing.
c: m[2], // Horizontal skewing.
d: m[3],
e: m[4], // Horizontal translation (moving).
f: m[5], // Vertical translation (moving).
});
}
return pattern;
@ -846,7 +859,7 @@ Shape.prototype.on.call(
Shape.prototype.on.call(
Shape.prototype,
'fillPriorityChange.konva fillPatternImageChange.konva fillPatternRepeatChange.konva fillPatternScaleXChange.konva fillPatternScaleYChange.konva',
'fillPriorityChange.konva fillPatternImageChange.konva fillPatternRepeatChange.konva fillPatternScaleXChange.konva fillPatternScaleYChange.konva fillPatternOffsetX.konva fillPatternOffsetY.konva fillPatternRotation.konva',
_clearFillPatternCache
);

View File

@ -56,7 +56,7 @@ export class Arrow extends Line<ArrowConfig> {
var dx, dy;
if (fromTension) {
const lastPoints = [
const lp = [
tp[tp.length - 4],
tp[tp.length - 3],
tp[tp.length - 2],
@ -68,11 +68,16 @@ export class Arrow extends Line<ArrowConfig> {
tp[tp.length - 4],
tp[tp.length - 3],
'C',
lastPoints
lp
);
const previous = Path.getPointOnQuadraticBezier(
Math.min(1, 1 - length / lastLength),
...lastPoints
lp[0],
lp[1],
lp[2],
lp[3],
lp[4],
lp[5]
);
dx = points[n - 2] - previous.x;

View File

@ -1294,6 +1294,53 @@ describe('Text', function () {
});
});
it('image gradient for text with offset', function (done) {
if (isNode) {
// skip in NodeJS because it has not transform API on gradients
return done();
}
const oldRatio = Konva.pixelRatio;
Konva.pixelRatio = 1;
loadImage('darth-vader.jpg', (imageObj) => {
var stage = addStage();
var layer = new Konva.Layer();
var text = new Konva.Text({
text: 'Hello, this is some good text',
fontSize: 30,
fillPatternImage: imageObj,
fillPatternOffsetX: 50,
fillPatternRotation: 0,
});
layer.add(text);
stage.add(layer);
var canvas = createCanvas();
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'green';
ctx.font = 'normal normal 30px Arial';
ctx.textBaseline = 'middle';
var grd = ctx.createPattern(imageObj, 'repeat');
grd.setTransform({
a: 1,
b: 0,
c: 0,
d: 1,
e: -50,
f: 0,
});
ctx.fillStyle = grd;
ctx.fillText(text.text(), 0, 15);
compareLayerAndCanvas(layer, canvas, 200);
Konva.pixelRatio = oldRatio;
done();
});
});
it('image gradient for text with scale', function (done) {
const oldRatio = Konva.pixelRatio;
Konva.pixelRatio = 1;

View File

@ -27,8 +27,6 @@ afterEach(function () {
clearTimeout(stage.dblTimeout);
});
console.log(isFailed);
if (!isFailed && !isManual) {
Konva.stages.forEach(function (stage) {
stage.destroy();