5

我有问题在我的绘图中实现“浮雕/阴影效果”。手指绘画功能目前在我的自定义下运行良好UIView,下面是我的drawRect方法代码:

使用所有方法编辑代码:

- (void)drawRect:(CGRect)rect
{
    CGPoint mid1 = midPoint(previousPoint1, previousPoint2); 
    CGPoint mid2 = midPoint(currentPoint, previousPoint1);

    CGContextRef context = UIGraphicsGetCurrentContext(); 
    [self.layer renderInContext:context];

    CGContextMoveToPoint(context, mid1.x, mid1.y);
    CGContextAddQuadCurveToPoint(context, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y); 
    CGContextSetLineCap(context, kCGLineCapRound);
    CGContextSetLineWidth(context, self.lineWidth);
    CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor);
    CGContextSaveGState(context);

    // for shadow  effects
    CGContextSetShadowWithColor(context, CGSizeMake(0, 2),3, self.lineColor.CGColor);
    CGContextStrokePath(context);
    [super drawRect:rect];
}

CGPoint midPoint(CGPoint p1, CGPoint p2)
{
    return CGPointMake((p1.x + p2.x) * 0.5, (p1.y + p2.y) * 0.5);
}


-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

    UITouch *touch = [touches anyObject];

    previousPoint1 = [touch previousLocationInView:self];
    previousPoint2 = [touch previousLocationInView:self];
    currentPoint = [touch locationInView:self];

    [self touchesMoved:touches withEvent:event];
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{

    UITouch *touch  = [touches anyObject];

    previousPoint2  = previousPoint1;
    previousPoint1  = [touch previousLocationInView:self];
    currentPoint    = [touch locationInView:self];


    // calculate mid point
    CGPoint mid1    = midPoint(previousPoint1, previousPoint2); 
    CGPoint mid2    = midPoint(currentPoint, previousPoint1);

    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, mid1.x, mid1.y);
    CGPathAddQuadCurveToPoint(path, NULL, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y);
    CGRect bounds = CGPathGetBoundingBox(path);
    CGPathRelease(path);

    CGRect drawBox = bounds;

    //Pad our values so the bounding box respects our line width
    drawBox.origin.x        -= self.lineWidth * 2;
    drawBox.origin.y        -= self.lineWidth * 2;
    drawBox.size.width      += self.lineWidth * 4;
    drawBox.size.height     += self.lineWidth * 4;

    UIGraphicsBeginImageContext(drawBox.size);
    [self.layer renderInContext:UIGraphicsGetCurrentContext()];
    curImage = UIGraphicsGetImageFromCurrentImageContext();
    [curImage retain];
    UIGraphicsEndImageContext();



   [self setNeedsDisplayInRect:drawBox];

}

当我实现这个时,我得到了 dot dot dot 的绘画效果......

见下图(没有任何阴影或浮雕效果)。如果您对如何添加这些效果有任何想法,请给我一些建议。我该如何解决这个问题?

在此处输入图像描述

4

3 回答 3

4

看来您正在创建数百甚至数千个单独的路径,每个 drawRect 上都有一个。您确实可以使用这些方法将它们弄平,[self.layer renderInContext]但我认为这不是解决问题的好方法。相反,我认为您想要做的是创建一个 UIBezierPath 来跟踪手指,将路径附加到该手指并将 UIBezierPath 绘制到屏幕上。如果您创建两个图层(或视图),您可以将最上面的一个(透明)设置为“绘制”。当用户抬起手指时,您将整个 UIBezierPath 渲染到第二层(连同之前绘制的数据)并创建一个新的 UIBezierPath 来绘制下一个手指跟踪。这样,当您跟踪某人的手指时,您只需更新一层(最上面一层)。这将有助于防止设备减慢绘制过多路径的速度。

虽然,我会说,您当前的方法确实会产生看起来很酷的“3D”效果。

于 2012-06-22T12:49:23.193 回答
0

阴影是在边框上创建的,您正在绘制小段线,这会产生这种效果。您需要创建一条路径,然后对其进行一次描边。此代码可能会对您有所帮助:)

for (int i=0; i<[currentPath count]; i++) 
{
    CGPoint mid1 = [[self midPoint:[currentPath objectAtIndex:i+1]  :[currentPath objectAtIndex:i]] CGPointValue]; 
    CGPoint mid2 = [[self midPoint:[currentPath objectAtIndex:i+2] :[currentPath objectAtIndex:i+1]] CGPointValue];
    CGContextMoveToPoint(context, mid1.x, mid1.y);
    CGContextAddQuadCurveToPoint(context, [[currentPath objectAtIndex:i+1] CGPointValue].x, [[currentPath objectAtIndex:i+1] CGPointValue].y, mid2.x, mid2.y); 
    CGContextSetShadow(context, CGSizeMake(-2, -2), 3);

    CGContextSetLineCap(context, kCGLineCapRound);
    CGContextSetStrokeColorWithColor(context,[color CGColor]);              
    CGContextSetLineWidth(context, linewidth);              

    i+=2;
}
CGContextStrokePath(context);

试试这种方式..这个解决方案可能会解决你的问题..首先创建你的路径,在它完全创建后,抚摸它。发生这种情况是因为在您描边的每条小线处,因此创建的阴影在其边界上制作了一个点,因此您得到了这种效果。

于 2012-06-25T04:50:44.693 回答
0

我不确定浮雕,但是如果您想要对逐渐更新的绘图应用阴影,那么一个不错的方法是使用CALayers (link to a tutorial)。基本上,您的渐进式绘图将更新透明图像(不尝试在该图像中绘制任何阴影),并且该图像将被配置为通过其 CALayer 以投影方式显示。

于 2012-06-22T12:58:10.220 回答