使用React和Konva在Canvas中计算线性渐变的角度?

3
我想将线性渐变中使用的角度→linear-gradient(140deg, rgba(165, 142, 251, 1), rgb(233, 191, 248)) 计算为 xy 坐标,以在Konva中使用,它基本上是Canvas的一个包装器。
我发现了一些相似的问题,但有一个警告,它们是针对原始的Canvas而不是Konva:
- https://dev59.com/mJfga4cB1Zd3GeqPAsfx - CSS convert gradient to the canvas version - Canvas to use liniear gradient background set with an angle - Calculate rotation of canvas gradient 但是当我尝试实现它们时,我得不到与CSS中相同的期望效果(请参见比较)。

linear-gradient comparison in konva vs css

代码与上面一些答案中发布的内容非常相似:
import { Stage, Layer, Rect } from "react-konva"

// linear-gradient(140deg, rgba(165, 142, 251, 1), rgb(233, 191, 248))
export default function App() {
    const width = window.innerWidth / 1.25 // random width
    const height = window.innerHeight / 1.5 // random height

    const x1 = 0
    const y1 = 0
    const angle = (140 / 180) * Math.PI
    const length = width
    const x2 = x1 + Math.cos(angle) * length
    const y2 = y1 + Math.sin(angle) * length

    return (
        <div className="App">
            <h1>Linear Gradient in Konva </h1>
            <Stage width={width} height={height}>
                <Layer>
                    <Rect
                        name="transparentBackground"
                        width={width}
                        height={height}
                        x={0}
                        y={0}
                        fillPriority="linear-gradient" // 'color', 'pattern', 'linear-gradient', 'radial-gradient'
                        /* linear-gradient */
                        fillLinearGradientStartPoint={{ x: x1, y: y1 }}
                        fillLinearGradientEndPoint={{ x: x2, y: y2 }}
                        fillLinearGradientColorStops={[
                            0,
                            "rgba(165, 142, 251, 1)",
                            1,
                            "rgb(233, 191, 248)",
                        ]}
                    />
                </Layer>
            </Stage>

            <h1>CSS Gradient </h1>
            <div
                style={{
                    marginTop: 10,
                    width,
                    height,
                    backgroundImage:
                        "linear-gradient(140deg, rgba(165, 142, 251, 1), rgb(233, 191, 248))",
                }}
            ></div>
        </div>
    )
}

我认为错误在于length,因为我不知道它应该是什么,它肯定不清楚。而且,我不确定x1y1坐标是否应该为零,因此可以删除。

我怎样才能获得相同的效果?

Codesandbox → https://codesandbox.io/s/linear-gradient-in-react-konva-cpgrk?file=/src/App.tsx

1个回答

4

我在游戏开发者的一个子板块/r/gamedev上找到了答案,尽管我不应该在那里问,但我还是这样做了,并且成功了

import { Stage, Layer, Rect } from "react-konva"

// linear-gradient(140deg, rgba(165, 142, 251, 1), rgb(233, 191, 248))
export default function App() {
    const width = window.innerWidth / 1.25 // random width
    const height = window.innerHeight / 1.5 // random height

    // Specify angle in degrees
    const angleInDeg = 140

    // Compute angle in radians - CSS starts from 180 degrees and goes clockwise
    // Math functions start from 0 and go anti-clockwise so we use 180 - angleInDeg to convert between the two
    const angle = ((180 - angleInDeg) / 180) * Math.PI

    // This computes the length such that the start/stop points will be at the corners
    const length =
        Math.abs(width * Math.sin(angle)) + Math.abs(height * Math.cos(angle))

    // Compute the actual x,y points based on the angle, length of the gradient line and the center of the div
    const halfx = (Math.sin(angle) * length) / 2.0
    const halfy = (Math.cos(angle) * length) / 2.0
    const cx = width / 2.0
    const cy = height / 2.0
    const x1 = cx - halfx
    const y1 = cy - halfy
    const x2 = cx + halfx
    const y2 = cy + halfy

    return (
        <div className="App">
            <h1>Linear Gradient in Konva </h1>
            <Stage width={width} height={height}>
                <Layer>
                    <Rect
                        name="transparentBackground"
                        width={width}
                        height={height}
                        x={0}
                        y={0}
                        fillPriority="linear-gradient" // 'color', 'pattern', 'linear-gradient', 'radial-gradient'
                        /* linear-gradient */
                        fillLinearGradientStartPoint={{ x: x1, y: y1 }}
                        fillLinearGradientEndPoint={{ x: x2, y: y2 }}
                        fillLinearGradientColorStops={[
                            0,
                            "rgba(165, 142, 251, 1)",
                            1,
                            "rgb(233, 191, 248)",
                        ]}
                    />
                </Layer>
            </Stage>

            <h1>CSS Gradient </h1>
            <div
                style={{
                    marginTop: 10,
                    width,
                    height,
                    backgroundImage: `linear-gradient(${angleInDeg}deg, rgba(165, 142, 251, 1), rgb(233, 191, 248))`,
                }}
            ></div>
        </div>
    )
}

Codesandbox → https://codesandbox.io/s/linear-gradient-in-react-konva-cpgrk?file=/src/App.tsx

Codesandbox是一个在线代码编辑器和调试工具,可以帮助开发人员轻松创建和共享基于Web的应用程序。上面的链接提供了一个使用React Konva实现线性渐变效果的示例代码,可以在Codesandbox中直接运行和修改。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接