Как я могу подкрасить изображение с помощью реакции-конвы? - PullRequest
0 голосов
/ 25 марта 2020

Я создал класс для загрузки изображений на холст с помощью прослушивателей событий на основе примера URLImage на веб-сайте Konva.

У меня есть PNG, состоящий полностью из белых пикселей на прозрачном фоне. Я хочу тонировать белые пиксели в цвет solid (например, красный, фиолетовый или голубой). Я посмотрел на пример фильтров , но у меня возникли проблемы с пониманием того, как эти конкретные части сочетаются друг с другом.

Как я могу сделать это с помощью response-konva.Image (используя, например, , <Image filters={[...]} image={...} ref={node => {this.imageNode = node;} />)?

Вот класс TypeScript, о котором я упоминал выше:

// import Konva from 'konva';
import React from 'react';
import {Image} from 'react-konva';

type ImgProps = {
    color?: string,
    src: string,
    x?: number,
    y?: number,
};

type ImgState = {
    image: any,
};

class Img extends React.Component<ImgProps, ImgState> {
    private image: HTMLImageElement | undefined;
    // private imageNode: Konva.Image | null = null;

    constructor(props: any) {
        super(props);

        this.state = {
            image: undefined,
        };
    }

    public componentDidMount = () => {
        this.loadImage();
    }

    public componentDidUpdate = (oldProps: ImgProps) => {
        if (oldProps.src !== this.props.src) {
            this.loadImage();
        }
    }

    public componentWillUnmount = () => {
        if (this.image) {
            this.image.removeEventListener('load', this.handleLoad);
        }
    }

    public render = (): React.ReactNode => {
        return (
            <Image
                image={this.state.image}
                // ref={node => {this.imageNode = node;}}
                x={this.props.x}
                y={this.props.y}
            />
        );
    }

    private loadImage = () => {
        // Save to `this` to remove `load` handler on unmount.
        this.image = new window.Image();
        this.image.src = this.props.src;
        this.image.addEventListener('load', this.handleLoad);
    }

    private handleLoad = () => {
        // After setState react-konva will update canvas and redraw the layer
        // because the `image` property has changed.
        this.setState({
            image: this.image,
        });

        // if (this.imageNode) {
        //     ...
        // }
    };
}

export default Img;

1 Ответ

1 голос
/ 27 марта 2020

Я понял это. Используя объект Konva.Image, который можно установить с помощью ref, как показано в вопросе, вы должны сделать что-то вроде следующего:

this.imageNode.cache();
this.imageNode.red(255);
this.imageNode.green(0);
this.imageNode.blue(0);

В приведенном выше примере класса это может быть в handleLoad или в любом месте, имеющем доступ к этому объекту.

Затем выполните рендеринг со свойством filters, как в следующем примере, где Image - это Konva.Image объект:

<Image
    image={this.state.image}
    filters={[Konva.Filters.RGB]}
    ref={node => {this.imageNode = node;}}
/>

В документации для Konva.Image.cache() указано (выделено):

узел кэша для повышения производительности рисования, , применение фильтров или создание более точных областей попадания , Для всех базовых c размеров будет автоматически определен размер холста кэша.

Документация для инвертирования изображения состояний (выделено мое):

Чтобы применить фильтр к Konva.Image, мы должны кэшировать его сначала с функцией cache().

...