动画Bezier曲线,就像在iPhone屏幕上绘制一样
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动画Bezier曲线,就像在iPhone屏幕上绘制一样相关的知识,希望对你有一定的参考价值。
我想绘制一条泰姬陵墓葬轮廓的bezier路径。
Q1。我怎么能在XCode中绘制它?我可以轻松地在PS中做到这一点,但我发现很难在编程中以XCode方式进行,特别是获取控制点的坐标。
Q2。此外,当屏幕尺寸变化时,如何固定点的坐标?
Q3。我怎么能像看不见的铅笔画在屏幕上那样动画呢?
如何在UIKit
中画出一条bezier路径?
创建一个UIBezierPath
对象,然后使用various methods on it to construct your path。
我怀疑你最感兴趣的方法是:
- qazxsw poi(相当不言自明,将当前点移动到给定点)
moveToPoint:
(添加一条直线,从当前点开始到给定点结束)addLineToPoint:
(添加贝塞尔曲线,启动当前点,设置终点和控制点)addCurveToPoint:controlPoint1:controlPoint2:
从当前点开始,使用设定的终点和控制点添加二次曲线。
例如,像这样的东西将创建一个带有二次曲线的简单贝塞尔曲线路径:
addQuadCurveToPoint:controlPoint:
但是,如果您习惯使用Photoshop之类的东西来创建路径,那么UIBezierPath* yourPath = [UIBezierPath bezierPath]; // create the bezier path
[yourPath moveToPoint:CGPointMake(100, 100)]; // move to your starting point
[yourPath addQuadCurveToPoint:CGPointMake(300, 500) controlPoint:CGPointMake(500, 350)]; // add a new quad curve to the point
可以让您使用“所见即所得”的方法创建贝塞尔路径。
您可以将此may be interested in PaintCode添加到UIBezierPath
的path
属性,以便在屏幕上显示。
CAShapeLayer
然后,您可以在形状图层上轻松设置CAShapeLayer* yourShapeLayer = [CAShapeLayer layer]; // create your shape layer
yourShapeLayer.frame = CGRectMake(0, 0, 300, 500); // assign it's frame
yourShapeLayer.path = yourPath.CGPath; // add your path to the shape layer
yourShapeLayer.fillColor = [UIColor clearColor].CGColor; // prevent the shape layer from filling
[self.view.layer addSublayer:yourShapeLayer]; // add the shape layer to the view
和strokeColor
属性,以便自定义路径的描边方式。
lineWidth
你应该得到这样的东西:
yourShapeLayer.strokeColor = [UIColor redColor].CGColor; // red stroke color
yourShapeLayer.lineWidth = 5.0; // 5 point stroke width
我怎么能像看不见的铅笔画在屏幕上那样动画呢?
您可以轻松创建一个,可以动画CABasicAnimation
的strokeStart
或strokeEnd
属性,以实现您想要的动画。
这可能会导致线条“被绘制”到屏幕上的动画效果。
例如,此代码将导致CAShapeLayer
属性从strokeEnd
动画到0.0
,从而创建所需的效果:
1.0
yourShapeLayer.strokeStart = 0.0; // reset stroke start before animating
CABasicAnimation* strokeAnim = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; // create animation that changes the strokeEnd property
strokeAnim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; // give it a nice timing function
strokeAnim.duration = 2.0; // duration of the animation
strokeAnim.fromValue = @(0.0); // provide the start value for the animation, wrapped in an NSNumber literal.
strokeAnim.toValue = @(1.0); // provide the end value for the animation, wrapped in an NSNumber literal.
[yourShapeLayer addAnimation:strokeAnim forKey:@"strokeAnim"]; // add animation to layer
如何缩放此路径以使用不同大小的屏幕?
我通常喜欢解决这个问题的方法是在给定的固定帧中定义路径点(比如说500 x 500点),然后根据屏幕大小生成比例因子(在你的情况下,你想要缩放到屏幕的宽度)。
所以我们要做的就是生成比例因子。
然后,我们只需要通过这个比例因子将CGFloat sf = self.view.frame.size.width/500.0; // The factor to scale the path by
中的所有点加倍。例如,采用我们之前的路径:
UIBezierPath
现在,我们所要做的就是在我们的bezier路径点进行编程,好像我们总是在500 x 500帧中绘制它(我的点已经很好地适应了它)。
您还需要更改UIBezierPath* yourPath = [UIBezierPath bezierPath]; // create the bezier path
[yourPath moveToPoint:CGPointMake(100.0*sf, 100.0*sf)]; // move to your starting point
[yourPath addQuadCurveToPoint:CGPointMake(300.0*sf, 500.0*sf) controlPoint:CGPointMake(500.0*sf, 350.0*sf)];
的大小,使其平方并占据整个屏幕宽度。
CAShapeLayer
最后,您想将yourShapeLayer.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.width);
定位到屏幕的中心。您可以通过将图层的CAShapeLayer
属性设置为视图的position
来轻松完成此操作。
center
现在,您的路径应始终缩放以占据屏幕的宽度。
yourShapeLayer.position = self.view.center;
(我在图层中添加了灰色背景,仅用于说明缩放)
我在2010年写了这篇博文:https://github.com/hamishknight/Drawing-Scaling-Animating-UIBezierPaths。
它的要点是这样的:
- 使用您想要绘制的形状创建Animating the Drawing of a CGPath With CAShapeLayer或
UIBezierPath
。使用方法CGPath
,moveToPoint:
,addLineToPoint:
等来创建形状。 - 创建一个
addCurveToPoint:controlPoint1:controlPoint2:
并指定图层的CGShapeLayer
属性的路径。 - 将图层添加到视图/图层层次结构中(例如,在视图控制器中:
path
)。您还必须为图层指定有效的大小和位置([self.view.layer addSublayer:shapeLayer];
)。 - 将图层的
frame
属性设置为0到1。
originaluser2发布的答案解决了一切。如果要为不同的设备屏幕调整贝塞尔曲线路径,也可以尝试这种方式:
您可以简单地继承UIView并自定义其drawRect方法:
strokeEnd
框架50x50:
- (void)drawRect: (CGRect)frame
{
//// Bezier Drawing
UIBezierPath* bezierPath = [UIBezierPath bezierPath];
[bezierPath moveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.23370 * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.65441 * CGRectGetHeight(frame))];
[bezierPath addCurveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.49457 * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.33088 * CGRectGetHeight(frame)) controlPoint1: CGPointMake(CGRectGetMinX(frame) + 0.23370 * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.65441 * CGRectGetHeight(frame)) controlPoint2: CGPointMake(CGRectGetMinX(frame) + 0.35870 * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.33088 * CGRectGetHeight(frame))];
[bezierPath addCurveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.77717 * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.65441 * CGRectGetHeight(frame)) controlPoint1: CGPointMake(CGRectGetMinX(frame) + 0.63043 * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.33088 * CGRectGetHeight(frame)) controlPoint2: CGPointMake(CGRectGetMinX(frame) + 0.77717 * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.65441 * CGRectGetHeight(frame))];
[UIColor.blackColor setStroke];
bezierPath.lineWidth = 1;
[bezierPath stroke];
}
框架100x100:
涂鸦鼠标轨迹-使用Greensock的Bezier插件绘制Bezier曲线
ActionScript 3 Scribble Mouse Trail - 使用Greensock的Bezier插件绘制Bezier曲线