Konva-React Text Fill с изображением или градиентом не работает - PullRequest
0 голосов
/ 08 января 2019

Я пытаюсь заполнить текст в Konvajs (konva-реагировать) чем-нибудь, кроме цвета. По умолчанию используется цвет, даже когда я устанавливаю приоритет заливки «линейный градиент» при попытке заполнения градиентом. Я попытался установить прозрачную заливку. Это все еще не показывает изображение или градиент. Вот код для попытки заполнить изображение.

import React, { Component } from 'react'
import Konva from "konva"
import {
  Stage,
  Layer,
  Image,
  Text
} from "react-konva"
import './App.css'


class Text2 extends React.Component {
  state = {
    text: "Happy New Year!",
    image: new window.Image(),
    ready: true
  }

  componentDidMount() {
    console.log("text path componentDidMount")
    console.log(this.state.image.src === null)
    this.state.image.src = 'http://localhost:3004/silver-metal-background-01.jpg'

    this.state.image.onload = e => {
      console.log('silver image loaded')
      this.state.ready = true
      console.log(this.TextNode)
    }

  }

  render = () => {
    var text =
      this.state.ready === false
      ? <React.Fragment></React.Fragment>
      :  <Text
          ref={node => {
            this.TextNode = node
          }}
          name="happyNewYear"
          x={32}
          y={175}
          text={this.state.text}
          fontFamily='Sigmar One'
          fontSize={36}
          fontWeight='bold'
          draggable={true}
          fill={this.state.image}
          stroke='red'
          strokeWidth={2}
          scaleX={1}
          scaleY={1}
          opacity={1}
        />

    return (
      <React.Fragment>
        { text }
      </React.Fragment>
    );
  }
}

class App extends Component {
render = () => {

  return (
    <React.Fragment>
      <Stage
        ref={node => {
          this.stage = node
        }}
        x={0}
        y={0}
        width={window.innerWidth} 
        height={window.innerHeight}            
      >
        <Layer
          ref={node => {
            this.layer = node
          }}
        >
          <Text2 />
        </Layer>
      </Stage>
    </React.Fragment>
  )
}

export default App

Вот код, пытающийся заполнить градиентом.

import React, { Component } from 'react'
import Konva from "konva"
import {
  Stage,
  Layer,
  Image,
  Text
} from "react-konva"
import './App.css'


class Text2 extends React.Component {
  state = {
    text: "Happy New Year!"
  }

  componentDidMount() {
    console.log("text path componentDidMount")

  }

  render = () => {
    var text =
      this.state.ready === false
      ? <React.Fragment></React.Fragment>
      :  <Text
          ref={node => {
            this.TextNode = node
          }}
          name="happyNewYear"
          x={32}
          y={175}
          text={this.state.text}
          fontFamily='Sigmar One'
          fontSize={36}
          fontWeight='bold'
          draggable={true}
          fillLinearGradientStartPoint={ {x : 0, y : 0} }
          fillLinearGradientEndPoint={ {x : 100, y : 100} }
          fillLinearGradientColorStops={[0, 'rgba(0,0,0,0.7)', 1, 'rgba(255,255,255,0.5)']}
          fillEnabled={true}
          fillPriority='linear-gradient'
          stroke='red'
          strokeWidth={2}
          scaleX={1}
          scaleY={1}
          opacity={1}
        />

    return (
      <React.Fragment>
        { text }
      </React.Fragment>
    );
  }
}

class App extends Component {
render = () => {

  return (
    <React.Fragment>
      <Stage
        ref={node => {
          this.stage = node
        }}
        x={0}
        y={0}
        width={window.innerWidth} 
        height={window.innerHeight}            
      >
        <Layer
          ref={node => {
            this.layer = node
          }}
        >
          <Text2 />
        </Layer>
      </Stage>
    </React.Fragment>
  )
}

export default App

1 Ответ

0 голосов
/ 09 января 2019

Линейный градиент должен прекрасно работать в вашем коде. Демо: https://codesandbox.io/s/ykpmjmynvj

Но я обнаружил, что в коде Konva есть ошибка для шаблона и радиального градиента. Это должно быть исправлено в следующем выпуске. До выпуска вы можете использовать этот обходной путь:

Вы можете использовать внешний холст для рисования заполненного текста с помощью globalCompositeOperation. Затем используйте этот холст как Konva.Image.

Как заполнить текст в Canvas изображением?

import React, { Component } from "react";
import { render } from "react-dom";
import { Stage, Layer, Image } from "react-konva";

class Text2 extends React.Component {
  state = {
    text: "Happy New Year!",
    canvas: null
  };

  componentDidMount() {
    var image = new window.Image();
    image.onload = () => {
      const canvas = document.createElement("canvas");
      const ctx = canvas.getContext("2d");

      ctx.save();
      ctx.beginPath();

      // put text on canvas
      ctx.font = "20px Verdana";
      ctx.fillText(this.state.text, 10, 20);
      ctx.fill();

      // use compositing to draw the background image
      // only where the text has been drawn
      ctx.beginPath();
      ctx.globalCompositeOperation = "source-in";
      ctx.drawImage(image, 0, 0);
      ctx.restore();

      this.setState({
        canvas: canvas
      });
    };
    image.src =
      "https://uploads.codesandbox.io/uploads/user/9fa343fe-4c37-4683-bd9c-39d985ca18bb/SHmg-gold-metal-background-02.jpg";
  }

  render = () => {
    return <Image image={this.state.canvas} draggable={true} />;
  };
}

class App extends Component {
  render = () => {
    return (
      <React.Fragment>
        <Stage
          ref={node => {
            this.stage = node;
          }}
          x={0}
          y={0}
          width={window.innerWidth}
          height={window.innerHeight}
        >
          <Layer
            ref={node => {
              this.layer = node;
            }}
          >
            <Text2 />
          </Layer>
        </Stage>
      </React.Fragment>
    );
  };
}

render(<App />, document.getElementById("root"));

https://codesandbox.io/s/xojz9q1k3p

...