Sine CAShapeLayer as a mask of CALayer

一笑奈何 提交于 2019-12-21 16:51:15

问题


I'm trying to implement the next curious thing: I have a few dots and I'd like to link them with sine waves

Next method returns the array of dots for making plot:

- (NSArray *)plotPointsBetweenPoint:(CGPoint)pointA andPoint:(CGPoint)pointB {
  double H = fabs(pointB.y - pointA.y);
  double L = fabs(pointB.x - pointA.x);

  NSInteger granularity = 40;
  NSMutableArray *array = [NSMutableArray arrayWithCapacity:granularity + 1];
  for (int i = 0; i <= granularity; ++i) {
    CGFloat x = M_PI*(float)i/(granularity);
    CGFloat y = -cosf(x);
    CGFloat multiplier = pointA.y > pointB.y ? 1 : -1;
    CGPoint newPoint = CGPointMake(pointA.x + L*(float)i/granularity, pointA.y - multiplier*H*(1.0 + y)/2.0);
    [array addObject:[NSValue valueWithCGPoint:newPoint]];
  }
  return array;
}

After it I create the special UIBezierPath:

- (UIBezierPath *)sineWaveWithPoints:(NSArray *)points {
  UIBezierPath *path = [[UIBezierPath alloc] init];
  NSMutableArray *array = [NSMutableArray array];

  for (int i = 0; i < points.count - 1; ++i) {
    [array addObjectsFromArray:[self plotPointsBetweenPoint:[points[i] CGPointValue] andPoint:[points[i+1] CGPointValue]]];
  }
  [path moveToPoint:[array[0] CGPointValue]];
  for (NSValue *value in array) {
    CGPoint point = [value CGPointValue];
    [path addLineToPoint:point];
  }
  [path closePath];
  path.lineWidth = 2.0;
  [path stroke];
  return path;
}

Next I'm adding this path using CAShapeLayer:

CAGradientLayer *gradientLayer = [self gradientLayer];
CAShapeLayer *maskLine = [CAShapeLayer layer];
maskLine.path = [self sineWaveWithPoints:pointsArray].CGPath;
maskLine.lineWidth = self.plotWidth;
gradientLayer.mask = maskLine;
[self.view.layer addSublayer:gradientLayer];

So I'd like to have gradient sine wave between this points. What exactly is wrong in my actions?

Ideal:


回答1:


The program is behaving correctly - that is, it is doing exactly what you are telling it to do. The problem is that what you are telling it to do (in your code) is not what you say you want (in your words and picture in your question).

First thing you're doing wrong: you said closePath. So it's closing the path! That means that, having drawn the wave, it connects the last point back to the first point with a straight line, giving the shape that you show.

Second thing you're doing wrong: you are failing to manipulate the shape layer. You are making a vanilla CAShapeLayer and leaving it at its defaults. Well, the default is that the fillColor is black (and no strokeColor). You are not changing that. So you are getting your (incorrect) shape filled with black, and no stroke, and hence the resulting mask is the shape of the inside of your (incorrect) shape, giving the gradient mask shape that you show.



来源:https://stackoverflow.com/questions/22986815/sine-cashapelayer-as-a-mask-of-calayer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!