我需要缩放路径,但不是使用路径的边界,而是应该使用更大的,封闭的,任意的矩形来执行变换。 (即“画布”。)
我的问题是如何在不绘制画布的情况下做到这一点。
例如,在下图中:
蓝色方块表示路径的原生矩形(在这种情况下为火箭)。
紫色矩形表示“画布”或父坐标系的界限。
紫色矩形仅用于定位;不被画出来。同样忽略了空格。
我需要缩放画布,并保留变换后的火箭路径(用于剪切操作,缓存等)。即转换后我需要失去紫色矩形。
理想情况下,我会使用以下小说:
var canvasPath = UIBezierPath(rect: canvasRect)
canvasPath.append(rocketPath, withName: "rocket")
canvasPath.doSomeTransformOrOther()
let transformedRocketPath = canvasPath.path(forName: "rocket")
可悲的是,即使UIBezierPath
或CGPath
处理了这样的子路径,神奇的追加(:withName :)和path(forName :)方法也不存在。唉!
另一种方法可以是临时为路径添加点,每个画布角一个。然后,转换路径。然后,使用CGPath的(可见的)apply(info:function:)
方法遍历路径,重建没有画布点的路径,然后绘制结果。 (是的,通过伏特加。)
有人能提供更理智的解决方案吗?谢谢你的帮助
(对于那些感兴趣的人:这与如何将不规则形状的路径居中的问题有关。紫色矩形代表最小封闭圆的边界。用MEC的坐标系绘制火箭将使火箭看起来更具视觉效果与使用boundingBox相比,居中。)
答案 0 :(得分:0)
这是我对问题的最终解决方法:使用“canvas”矩形,它将与路径一起缩放。然后在翻译(缩放)路径时使用画布rect。这样可以保持相对于画布的路径
这样做的一个例子是从SVG获取路径,然后缩放,相对于路径边界相对于SVG的原生维度(“viewbox
”)定位路径。这反过来允许在SVG画布中相对定位路径。
extension UIBezierPath
{
func scaled(usingCanvasSize canvasSize: CGSize,
scale: CGFloat) -> CGRect
{
let canvasRect = CGRect(origin: .zero, size: canvasSize)
let canvasPath = UIBezierPath(rect: canvasRect)
let scaleTransform = CGAffineTransform(scaleX: scale, y: scale)
canvasPath.apply(scaleTransform)
self.apply(scaleTransform)
return canvas.bounds
}
}
// Usage:
let nativeSVGSize: CGSize = ... // 'viewBox' size of SVG
let path = UIBezierPath(...) // From SVG, wherever.
let scale: CGFloat = 0.5
// Scale the path, get a "canvas" rect.
let canvasRect = path.scaled(usingCanvasSize: nativeSVGSize,
scale: scale)
// Use the (scaled) canvas for info about the path from now on.
// e.g. move the path using the center of the canvasRect.
let pathCenter = canvasRect.center
let destCenter = ...
let movement = CGPoint(x: destCenter.x - pathCenter.x,
y: destCenter.y - pathCenter.y)
path.apply(CGAffineTransform(translationX: movement.x,
y: movement.y))