简体   繁体   English

SwiftUI:在矩形上拉伸 LinearGradient

[英]SwiftUI: stretch LinearGradient on a rectangle

I am trying to render a linear gradient on a rectangle.我正在尝试在矩形上渲染线性渐变。 Here is the code:这是代码:

Rectangle()
        .foregroundColor(Color.red)
        .overlay(
            LinearGradient(gradient: Gradient(colors: [.red, .yellow, .blue]), startPoint: .topLeading, endPoint: .bottomTrailing)
        )
        .frame(width: 300, height: 200)
        .position(x: 170, y: 120)

When I render it on square, everything looks correct:当我在正方形上渲染它时,一切看起来都是正确的:

广场很棒

When I render it on a rectangle, however, it stops looking like it's going from topLeading corner to bottomTrailing.然而,当我在一个矩形上渲染它时,它看起来不再像是从 topLeading 角到 bottomTrailing。 It just looks like it's the same one which was clipped:它看起来就像被剪掉的一样:

在此处输入图像描述

Here is how it's rendered in svg (blue is not the same it seems, but that's not the important part), and how I want it to look in swift:这是它在 svg 中的呈现方式(蓝色看起来不一样,但这不是重要的部分),以及我希望它在 swift 中的外观:

在此处输入图像描述

The yellow diagonal should go directly from one corner to another, since I am specifying startPoint: .topLeading, endPoint: .bottomTrailing .黄色对角线应该是 go 直接从一个角到另一个角,因为我指定startPoint: .topLeading, endPoint: .bottomTrailing It says here SwiftUI diagonal LinearGradient in a rectangle that this is a standard behaviour, and that's ok - I'm not trying to say SwiftUI renders it incorrectly, I just need a way to make it look like in svg.它在这里说SwiftUI 对角线 LinearGradient 在一个矩形中,这是一种标准行为,这没关系 - 我并不是想说 SwiftUI 渲染它不正确,我只需要一种方法让它看起来像 ZAE8EB96DF05E789AC39EA28F。

What a fun problem:)多么有趣的问题:)

The "naive" approach would be to render the gradient as a square and then either rotate it or squeeze or stretch it to fit the rectangle. “天真的”方法是将渐变渲染为正方形,然后旋转它或挤压或拉伸它以适应矩形。 Rotating requires more maths so here's the "squeezing" version:旋转需要更多的数学运算,所以这里是“挤压”版本:

struct ContentView: View {
    var body: some View {
        
        Rectangle()
            .overlay(
                GeometryReader { g in
                    LinearGradient(
                        gradient: Gradient(colors: [.red, .yellow, .blue]),
                        startPoint: .topLeading,
                        endPoint: .bottomTrailing
                    )
                    .frame(width: g.size.width, height: g.size.width)
                    .scaleEffect(x: 1.0, y: g.size.height / g.size.width, anchor: .top)
                }
            )
            .frame(width: 300, height: 200)
        
    }
}

Notes:笔记:

  • To do the squeeze, we need to know the proportions of the rectangle, you were already using an overlay() and overlays are bounded by the Rectangle() in this case, so we can just read the size with the GeometryReader();要进行挤压,我们需要知道矩形的比例,您已经使用了一个 overlay(),并且在这种情况下,覆盖由 Rectangle() 限制,所以我们可以使用 GeometryReader() 读取大小;
  • We need to start with the gradient applied to a square and there is a couple of ways to do squares.我们需要从应用于正方形的渐变开始,有几种方法可以制作正方形。 As we already know the size of the rectangle, I went with a square with a side equal to the width of the enclosing rectangle;正如我们已经知道矩形的大小,我选择了一个边长等于封闭矩形宽度的正方形;
  • Then we apply the scaleEffect(), squeezing the height of the square to the height of the rectangle.然后我们应用 scaleEffect(),将正方形的高度压缩到矩形的高度。

Please let me know if that's what you were looking for or if there is a better way to do to this!请让我知道这是否是您正在寻找的,或者是否有更好的方法来做到这一点!

Cheers, –Baglan干杯,-巴格兰

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM