Использование globalCompositeOperation для маскирования группы фигур в React Konva - PullRequest
0 голосов
/ 04 сентября 2018

Мой проект использует React Konva (https://github.com/konvajs/react-konva)

Я пытаюсь нарисовать несколько фигур в Group и использовать это, чтобы замаскировать изображение «ниже».

Когда мой компонент рисует одну фигуру с применением globalCompositeOperation, он дает ожидаемый результат. Вот код:

render() {
        return (

            <Group >
                <Group>
                    <Image 
                        image={this.state.image} 
                        ref={node => { this.image = node; }} 
                    />
                    <Group>
                        <Rect fill={"#555555"} 
                            width={200} height={200} 
                            x={100} y={100} 
                            globalCompositeOperation={"destination-in"}
                        />
                    </Group>
                </Group>
            </Group>
        )

    }

И результат: enter image description here

Обратите внимание, как изображение обрезается до прямоугольника, показывая текстовый слой ниже.

Однако, как только фигура перемещается внутри группы, и я применяю globalCompositeOperation, маскирование не происходит. Соответствующая часть кода:

<Group>
            <Image 
                image={this.state.image} 
                ref={node => { this.image = node; }} 
            />
            <Group globalCompositeOperation={"destination-in"}>
                <Rect fill={"#555555"} 
                    width={200} height={200} 
                    x={100} y={100} 
                />
            </Group>
        </Group>

И результат:

enter image description here

Это странно, поскольку в документации Konva указано, что Group действительно имеет свойство globalCompositeOperation (см. https://konvajs.github.io/api/Konva.Group.html#globalCompositeOperation__anchor).

Есть идеи, как заставить (Реагировать) Конву применять globalCompositeOperation на уровне Group, а не только на уровне Shape?

1 Ответ

0 голосов
/ 04 сентября 2018

Ах, только что нашел решение.

Похоже, что весь Group должен быть кэширован перед применением globalCompositeOperation. Я предполагаю, что это означает, что Группа сначала будет сплющена / растеризована.

В моем компоненте React я достиг решения следующим образом:

 import React from 'react';
import { Image, Group, Rect } from 'react-konva';

class CutoutImage extends React.Component {
    state = {
        image: null,
        mask: null
    }

    componentDidMount() {
        const image = new window.Image();
        image.src = "/images/frisbee.jpg";
        image.onload = () => {
            this.setState({ image });
        }
    }

    componentDidUpdate() {
        if (this.image) {
            this.image.cache();
        }
        if (this.mask) {
            this.mask.cache();
        }
    }

    render() {
        return (

            <Group>
                <Image 
                    image={this.state.image} 
                    ref={node => { this.image = node; }} 
                />
                <Group 
                    globalCompositeOperation={"destination-in"} 
                    ref={node => {this.mask = node; }}
                    >
                    <Rect fill={"#555555"} 
                        width={200} height={200} 
                        x={100} y={100} 
                    />
                    <Rect fill={"#dddddd"} 
                        width={200} height={200} 
                        x={300} y={300} 
                    />
                    <Rect fill={"#dddddd"} 
                        width={200} height={100} 
                        x={150} y={350} 
                    />
                </Group>
            </Group>
        )

    }

}
export default CutoutImage;

И результат:

enter image description here

...