代码之家  ›  专栏  ›  技术社区  ›  Sixten Otto

用石英二维/核心图形完成此绘图的最佳方法?

  •  2
  • Sixten Otto  · 技术社区  · 15 年前

    作为应用程序中某个视图的背景,我想在其框架内绘制一个相当简单的矩形边框。这基本上是一个矩形渐变:一条围绕框架的黑线,在大约10-20像素的范围内逐渐变白。不幸的是,据我所知,核心图形不提供矩形渐变 CGGradient CGShading )所以我想知道最好的方法是什么。

    我想到两个:

    1. 画一系列同心矩形,每一个后面的颜色更浅,每边插入1个。我想不出一个更简单的方法,但我必须自己做所有的梯度计算,这可能是很多图形操作。
    2. 使用 CG-梯度 在线性模式下,每侧一次。但要使其起作用,我想我需要先为每一侧设置一个梯形裁剪区域,以便在拐角处斜接渐变。

    好像在那儿 应该 是一种使用路径选通来实现这一点的方法,但似乎没有一种方法来定义在每一方面都不同的模式。

    2 回复  |  直到 15 年前
        1
  •  3
  •   James Eichele Bernard Igiri    15 年前

    我会选择2:

    在线性模式下使用cgGradient,每边一次。但要使其起作用,我想我需要先为每一侧设置一个梯形裁剪区域,以便在拐角处斜接渐变。

    使用 NSBezierPath 创建梯形区域非常简单,只需执行四次绘图操作。

    下面是创建左侧梯形区域的基本代码:

    NSRect outer = [self bounds];
    NSPoint outerPoint[4];
    outerPoint[0] = NSMakePoint(0, 0);
    outerPoint[1] = NSMakePoint(0, outer.size.height);
    outerPoint[2] = NSMakePoint(outer.size.width, outer.size.height);
    outerPoint[3] = NSMakePoint(outer.size.width, 0);
    
    NSRect inner = NSInsetRect([self bounds], borderSize, borderSize);
    NSPoint innerPoint[4];
    innerPoint[0] = inner.origin;
    innerPoint[1] = NSMakePoint(inner.origin.x,
                                inner.origin.y + inner.size.height);
    innerPoint[2] = NSMakePoint(inner.origin.x + inner.size.width,
                                inner.origin.y + inner.size.height);
    innerPoint[3] = NSMakePoint(inner.origin.x + inner.size.width,
                                inner.origin.y);
    
    NSBezierPath leftSidePath = [[NSBezierPath bezierPath] retain];
    [leftSidePath moveToPoint:outerPoint[0]];
    [leftSidePath lineToPoint:outerPoint[1]];
    [leftSidePath lineToPoint:innerPoint[1]];
    [leftSidePath lineToPoint:innerPoint[0]];
    [leftSidePath lineToPoint:outerPoint[0]];
    
    // ... etc.
    
    [leftSidePath release];
    
        2
  •  0
  •   arri    15 年前

    像这样的事情也能奏效。 基本上:不要使用剪切路径,只需使用BlendMode。 在这个例子中,梯度缓存在一个CGlayer中。

     CGContextRef ctx = UIGraphicsGetCurrentContext();
     CGColorSpaceRef cspace = CGColorSpaceCreateDeviceRGB();
    
     CGContextSetRGBFillColor(ctx, 1.0, 1.0, 1.0, 1.0);
     CGContextFillRect(ctx,self.bounds);
    
     CGFloat w = self.bounds.size.width;
     CGFloat h = self.bounds.size.height;
     CGFloat dh = (w-h)/2;
    
     CGLayerRef l = CGLayerCreateWithContext(ctx,CGSizeMake(h,48.0f),NULL);
     CGContextRef lctx = CGLayerGetContext(l);
    
     float comp[] = { .2,.5,1.0,1.0,1.0,1.0,1.0,1.0};
     CGGradientRef gradient = CGGradientCreateWithColorComponents(cspace, comp, NULL, 2);
     CGContextDrawLinearGradient(lctx, gradient,CGPointMake(0,0),CGPointMake(0,48), 0);
    
     CGContextSaveGState(ctx);
     CGContextSetBlendMode(ctx,kCGBlendModeDarken);
     for(int n=1;n<5;n++)
     {
      CGContextTranslateCTM(ctx,w/2.0,h/2.0);
      CGContextRotateCTM(ctx, M_PI_2);
      CGContextTranslateCTM(ctx,-w/2.0,-h/2.0);
      CGContextDrawLayerAtPoint(ctx,CGPointMake((n%2)*dh,(n%2)*-dh),l);
     }
     CGContextRestoreGState(ctx);