CGGradient:在角度上绘制线性渐变

Bay*_*Bay 5 iphone core-graphics objective-c ios

我正在尝试在一个角度上绘制线性CGGradient。因为不存在“ CGContextDrawLinearGradientWithAngle()”,所以我尝试使用CGContextDrawLinearGradient(CGContextRef,CGGradientRef,CGPoint起点,CGPoint终点,CGGradientDrawingOptions)。

考虑到这一点,我需要将角度(度)转换为起点和终点。我想模仿NSGradient的drawInBezierPath:angle。(不幸的是,作为AppKit的一部分,NSGradient不适用于iOS开发人员。)幸运的是,该文档告诉我们如何获得起始渐变

- (CGPoint)startingPointForAngle:(CGFloat)angle rect:(CGRect)rect { 
    CGPoint point = CGPointZero;
    if (angle < 90.0f)
        point = CGPointMake(CGRectGetMinX(rect), CGRectGetMaxY(rect));
    else if (angle < 180.0f)
        point = CGPointMake(CGRectGetMaxX(rect), CGRectGetMaxY(rect));
    else if (angle < 270.0f)
        point = CGPointMake(CGRectGetMaxX(rect), CGRectGetMinY(rect));
    else
        point = CGPointMake(CGRectGetMinX(rect), CGRectGetMinY(rect));

    return point;
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,文档没有告诉我们如何获得终点。(使用矩形的高度或宽度,因为该距离仅适用于某些角度。)那里的几个位置告诉我们如何找到终点。不幸的是,在计算终点之前需要知道距离。然而,需要计算终点以获得距离。显然还有更多,因为NSGradient似乎已经弄清楚了。

- (CGPoint)endingPointForAngle:(CGFloat)angle rect:(CGRect)rect startingPoint:(CGPoint)startingPoint {
    //http://www.zahniser.net/~russell/computer/index.php?title=Angle%20and%20Coordinates
    //(x + distance * cos(a), y + distance * sin(a))
    CGFloat angleInRadians = (CGFloat)M_PI/180.0f * angle;
    CGFloat distance = ????????;
    CGPoint point = CGPointMake(startingPoint.x + distance * cosf(angleInRadians), startingPoint.y + distance * sinf(angleInRadians));
    return point;
}

CGPoint startingGradientPoint = [self startingPointForAngle:self.fillGradientAngle rect:rect];
CGPoint endingGradientPoint = [self endingPointForAngle:self.fillGradientAngle rect:rect startingPoint:startingGradientPoint];
CGContextDrawLinearGradient(graphicsContext, self.fillGradient, startingGradientPoint, endingGradientPoint, 0);
Run Code Online (Sandbox Code Playgroud)

有任何想法吗。

Rup*_*ick 0

我不是 100% 确定这个渐变是如何工作的,但从你所写的内容来看,我假设你基本上只想要从起点到它到达矩形侧面的一条线的长度。

如果是这种情况,您只需要做一些三角学。我们将距离称为 x,将角度称为 a。

0 到 45 度之间:宽度 = xcos(a) 因此 x = 宽度/cos(a)

45 度到 90 度之间:高度 = xsin(a) 所以 x = 高度/sin(a)

在 90 到 135 度之间,我们已经移动到一个新的角落。这里 x = 高度/cos(a-90)。

135 到 180 之间 x = 宽度/sin(a-90)

在 180 到 225 之间,我们再次移动了角落。这里 x = 宽度/cos(a-180)。

225 到 270 之间 x = 高度/sin(a-180)

最后一个角!270 到 315 之间 x = 高度/sin(a-270)

最后在 315 和 360 之间 x = width/cos(a-270)

其中一些可能会简化,但最容易想到的是从左下角开始指向右侧并逆时针扫过的线,这就是起点计算中出现的情况。