我无法将使用 UIBezierPath 绘制的图标添加到 CAEmitterCell。我想知道是不是图标没有画出来?当我运行应用程序时,ShapeView 不起作用。但是,您可能会发现 ShapeView 在您正常使用时可以正常工作。
那么我有机会将 UIBezierPath 转换为图像吗?
它实际上可以在不转换为图像的情况下完成吗?
使用
struct GameView: View {
....
let playerBounds = UIBezierPath.calculateBounds(paths: [.none, .playerX, .playerO])
var body: some View {
ZStack {
ParticleEffectView(particleImages: [ShapeView(bezier: .playerX, pathBounds: playerBounds), ShapeView(bezier: .playerO, pathBounds: playerBounds)])
....
}
}
}
形状视图
struct ShapeView: Shape {
let bezier: UIBezierPath
let pathBounds: CGRect
func path(in rect: CGRect) -> Path {
let pointScale = (rect.width >= rect.height) ? max(pathBounds.height, pathBounds.width) : min(pathBounds.height, pathBounds.width)
let pointTransform = CGAffineTransform(scaleX: 1/pointScale, y: 1/pointScale)
let path = Path(bezier.cgPath).applying(pointTransform)
let multiplier = min(rect.width, rect.height)
let transform = CGAffineTransform(scaleX: multiplier, y: multiplier)
return path.applying(transform)
}
}
UIBezier 路径
extension UIBezierPath {
static func calculateBounds(paths: [UIBezierPath]) -> CGRect {
let myPaths = UIBezierPath()
for path in paths {
myPaths.append(path)
}
return (myPaths.bounds)
}
static var playerX: UIBezierPath {
let shape = UIBezierPath()
shape.move(to: CGPoint(x: 48.04, y: 33.28))
shape.addLine(to: CGPoint(x: 62.04, y: 19.28))
shape.addCurve(to: CGPoint(x: 62.04, y: 3.96), controlPoint1: CGPoint(x: 66.28, y: 15.05), controlPoint2: CGPoint(x: 66.28, y: 8.19))
shape.addCurve(to: CGPoint(x: 46.72, y: 3.96), controlPoint1: CGPoint(x: 57.81, y: -0.27), controlPoint2: CGPoint(x: 50.96, y: -0.27))
shape.addLine(to: CGPoint(x: 32.72, y: 17.96))
shape.addLine(to: CGPoint(x: 18.71, y: 3.96))
shape.addCurve(to: CGPoint(x: 3.39, y: 3.96), controlPoint1: CGPoint(x: 14.48, y: -0.27), controlPoint2: CGPoint(x: 7.62, y: -0.27))
shape.addCurve(to: CGPoint(x: 3.39, y: 19.28), controlPoint1: CGPoint(x: -0.84, y: 8.18), controlPoint2: CGPoint(x: -0.84, y: 15.05))
shape.addLine(to: CGPoint(x: 17.4, y: 33.28))
shape.addLine(to: CGPoint(x: 3.39, y: 47.29))
shape.addCurve(to: CGPoint(x: 3.39, y: 62.61), controlPoint1: CGPoint(x: -0.84, y: 51.52), controlPoint2: CGPoint(x: -0.84, y: 58.38))
shape.addCurve(to: CGPoint(x: 18.71, y: 62.61), controlPoint1: CGPoint(x: 7.62, y: 66.84), controlPoint2: CGPoint(x: 14.48, y: 66.84))
shape.addLine(to: CGPoint(x: 32.72, y: 48.6))
shape.addLine(to: CGPoint(x: 46.72, y: 62.61))
shape.addCurve(to: CGPoint(x: 62.04, y: 62.61), controlPoint1: CGPoint(x: 50.96, y: 66.84), controlPoint2: CGPoint(x: 57.81, y: 66.84))
shape.addCurve(to: CGPoint(x: 62.04, y: 47.29), controlPoint1: CGPoint(x: 66.28, y: 58.38), controlPoint2: CGPoint(x: 66.28, y: 51.52))
shape.addLine(to: CGPoint(x: 48.04, y: 33.28))
shape.close()
return shape
}
static var playerO: UIBezierPath {
let shape = UIBezierPath()
shape.move(to: CGPoint(x: 32.5, y: 0))
shape.addCurve(to: CGPoint(x: 0, y: 32.5), controlPoint1: CGPoint(x: 14.55, y: 0), controlPoint2: CGPoint(x: 0, y: 14.55))
shape.addCurve(to: CGPoint(x: 32.5, y: 65), controlPoint1: CGPoint(x: 0, y: 50.45), controlPoint2: CGPoint(x: 14.55, y: 65))
shape.addCurve(to: CGPoint(x: 65, y: 32.5), controlPoint1: CGPoint(x: 50.45, y: 65), controlPoint2: CGPoint(x: 65, y: 50.45))
shape.addCurve(to: CGPoint(x: 32.5, y: 0), controlPoint1: CGPoint(x: 65, y: 14.55), controlPoint2: CGPoint(x: 50.45, y: 0))
shape.close()
shape.move(to: CGPoint(x: 32.01, y: 49.24))
shape.addCurve(to: CGPoint(x: 15.76, y: 32.99), controlPoint1: CGPoint(x: 23.03, y: 49.24), controlPoint2: CGPoint(x: 15.76, y: 41.97))
shape.addCurve(to: CGPoint(x: 32.01, y: 16.74), controlPoint1: CGPoint(x: 15.76, y: 24.02), controlPoint2: CGPoint(x: 23.03, y: 16.74))
shape.addCurve(to: CGPoint(x: 48.26, y: 32.99), controlPoint1: CGPoint(x: 40.98, y: 16.74), controlPoint2: CGPoint(x: 48.26, y: 24.02))
shape.addCurve(to: CGPoint(x: 32.01, y: 49.24), controlPoint1: CGPoint(x: 48.26, y: 41.97), controlPoint2: CGPoint(x: 40.98, y: 49.24))
shape.close()
return shape
}
static var none: UIBezierPath {
let shape = UIBezierPath()
return shape
}
}
粒子效果视图
struct ParticleEffectView: UIViewRepresentable {
var particleImages: [ShapeView]
func makeUIView(context: Context) -> UIView {
let host = UIView(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
let particlesLayer = CAEmitterLayer()
particlesLayer.frame = CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
host.layer.insertSublayer(particlesLayer, at: 0)
host.layer.masksToBounds = true
host.insetsLayoutMarginsFromSafeArea = false
particlesLayer.backgroundColor = .none
particlesLayer.emitterShape = .circle
particlesLayer.emitterPosition = CGPoint(x: 509.4, y: 707.7)
particlesLayer.emitterSize = CGSize(width: 1648.0, height: 1112.0)
particlesLayer.emitterMode = .outline
particlesLayer.renderMode = .backToFront
particlesLayer.emitterCells = prepareParticeCell(particles: particleImages)
return host
}
func prepareParticeCell(particles: [ShapeView]) -> [CAEmitterCell] {
var arrayParticleCell: [CAEmitterCell] = [CAEmitterCell]()
for particleItem in particles {
let particleCell: CAEmitterCell = CAEmitterCell()
particleCell.contents = particleItem
particleCell.name = "XO"
particleCell.birthRate = 1
particleCell.lifetime = 74.5
particleCell.velocityRange = 0.0
particleCell.velocity = 79.0
particleCell.xAcceleration = 0.0
particleCell.yAcceleration = 0.0
particleCell.emissionLatitude = 1*6.0 * (.pi / 180)
particleCell.emissionLongitude = -105.0 * (.pi / 180)
particleCell.emissionRange = 360.0 * (.pi / 180.0)
particleCell.spin = -65.6 * (.pi / 180.0)
particleCell.spinRange = 314.2 * (.pi / 180.0)
particleCell.scale = 0.010
particleCell.scaleRange = 0.01
particleCell.scaleSpeed = 0.02
particleCell.alphaRange = 0.0
particleCell.alphaSpeed = 0.47
particleCell.color = UIColor(red: 255.0/255.0, green: 255.0/255.0, blue: 255.0/255.0, alpha: 1.0).cgColor
arrayParticleCell.append(particleCell)
}
return arrayParticleCell
}
func updateUIView(_ uiView: UIView, context: Context) {
uiView.insetsLayoutMarginsFromSafeArea = false
}
}