javascriptsvgkonvajskonva

Unexpected positioning of fillPattern on a Path node


I noticed that when I create a rectangle, and set its fillPattern to be some image, the fill starts from the top-left of the rectangle.

fill starts as expected at the top-left corner of the node

function addRectangle() {
    window.rect = new Konva.Rect({
        width: 400,
        height: 400,
        x: 200,
        y: 200,
        stroke: 'grey',
        strokeWidth: 1,
        fillPatternRepeat: 'no-repeat',
    });
    const img = new Image();
    img.src = imageSource;
    img.onload = function() {
        rect.fillPatternImage(img);
        firstLayer.add(rect);
    }
}

But when I add fillPattern to a Path node, which has a data attibute making it visually into the same rectangle as above, the fillPattern starts at (0,0) of some global coordinate system and not in top-left corner of my Path node.

fill starts 200 units above and to the left of the node

function addPath() {
    window.path = new Konva.Path({
        data: 'M 200 200 L 600 200 L 600 600 L 200 600 Z',
        stroke: 'grey',
        strokeWidth: 1,
        fillPatternRepeat: 'no-repeat',
    })
    const img = new Image();
    img.src = imageSource;
    img.onload = function() {
        path.fillPatternImage(img);
        firstLayer.add(path);
    }
}

The pattern image is a 300 by 300 black square.

const imageSource = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAIAAAD2HxkiAAABHUlEQVR4nO3BAQ0AAADCoPdPbQ43oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAnAyAYAAFGw74oAAAAAElFTkSuQmCC";

Do I understand correctly that this is caused by the path fill being drawn from the global (0,0), and not the local (0,0)? Is this intended behavior or a bug? Is there an easy way to account for this? I'm using konva v8.3.2.


Solution

  • The Konva.Path actually has an origin of its own and the path is drawn relative to that origin. In the instantiation of the path you do not specify the path origin.

        window.path = new Konva.Path({
            data: 'M 200 200 L 600 200 L 600 600 L 200 600 Z',
            stroke: 'grey',
            strokeWidth: 1,
            fillPatternRepeat: 'no-repeat',
        })
    

    Please modify to

        window.path = new Konva.Path({
            x: 200, y: 200,   // <<<< note the x and y
            data: 'M 200 200 L 600 200 L 600 600 L 200 600 Z',
            stroke: 'grey',
            strokeWidth: 1,
            fillPatternRepeat: 'no-repeat',
        })
    

    and adjust your path data accordingly.