在swift中将CAShapelayer转换为特定大小
我正在尝试制作一个带有bezier路径的CAShapeLayer,它以视图展开(当然是动画的)。 我知道我可以用CATransform3DMakeScale(,,)来改变路径的大小。但是这不允许我使路径成为精确的大小(以点为单位)。
有人知道怎么做这个吗?
你会用优秀的老式数学来做到这一点。
简单解决方案
用不同的方式表达你的问题:你有一个大小的东西(路径/形状层),你想要缩放它,使它成为另一个大小。
要知道要沿X和Y(单独)缩放多少,可以将当前大小除以要适合的大小。 您可以使用获取路径的边界框
let boundingBox = CGPathGetBoundingBox(path)
我假设你已经有一些你要缩放它的大小(这里我称之为containsSize)。
使用这两个,您可以通过将要缩放的尺寸除以要缩放的尺寸来计算两个缩放系数
let xScaleFactor = containingSize.width / boundingBox.width let yScaleFactor = containingSize.height / boundingBox.height
使用这些,您可以创建所需的比例变换
let scaleTransform = CATransform3DMakeMakeScale(xScaleFactor, yScaleFactor, 1.0)
缩放此形状图层
使用这两个比例因子,将缩放形状图层以填充容器大小。 如果容器大小与路径具有相同的宽高比,则所有内容都将按预期显示。 如果不是,则缩放图层将显示为拉伸。
适合而不是填充
这个问题(除非你想要它)可以通过计算均匀比例因子来解决,这是两者中较小的一个,因此缩放的路径适合容器而不是填充容器。
我们通过找出哪个比例因子是最受约束的因子,然后将其应用于X和Y来实现
let boundingBoxAspectRatio = boundingBox.width/boundingBox.height let viewAspectRatio = containingSize.width/containingSize.height let scaleFactor: CGFloat if (boundingBoxAspectRatio > viewAspectRatio) { // Width is limiting factor scaleFactor = containingSize.width/boundingBox.width } else { // Height is limiting factor scaleFactor = containingSize.height/boundingBox.height } let scaleTransform = CATransform3DMakeMakeScale(scaleFactor, scaleFactor, 1.0)
这将在不改变其纵横比的情况下缩放路径
缩放图层或缩放路径?
您可能还注意到,在缩放形状图层时,线宽也会缩放,就像它是图像一样。 缩放图层和缩放路径之间存在差异。
如果您只希望它在缩放形状图层的路径时显示,那么您应该缩放路径而不是图层。 您可以通过创建转换的新路径并将该路径与形状图层一起使用来完成此操作 。 请注意,仍然使用未缩放路径的边界框计算比例因子。
var affineTransform = CGAffineTransformMakeScale(scaleFactor, scaleFactor) let transformedPath = CGPathCreateCopyByTransformingPath(path, &affineTransform) yourShapeLayer.path = transformedPath
这将扩大路径,而不会影响形状图层的线宽等。