我想实现这种类型的动画。请检查这个 URL
https://www.dropbox.com/s/gz9vfy5refsh7a5/Screen.mov?dl=0
我正在添加我在项目中使用的代码,在该项目中我使用 Core Graphics 来渲染带有动画的文本,但我无法为上述链接中显示的文本设置动画
这是我用来在屏幕上呈现文本的代码
let context = UIGraphicsGetCurrentContext()!
context.saveGState()
context.setAlpha(noLightText)
let nOLIGHTRect = CGRect(x: 145.66, y: 590, width: 449.38, height: 125)
let nOLIGHTStyle = NSMutableParagraphStyle()
nOLIGHTStyle.alignment = .center
let nOLIGHTFontAttributes = [
.font: UIFont(name: "Futura-CondensedExtraBold", size: 96)!,
.foregroundColor: nOLIGHTColor,
.paragraphStyle: nOLIGHTStyle,
] as [NSAttributedStringKey: Any]
"NO LIGHT".draw(in: nOLIGHTRect, withAttributes: nOLIGHTFontAttributes)
context.restoreGState()
//// LOW LIGHT Drawing
context.saveGState()
context.setAlpha(_0)
let lOWLIGHTRect = CGRect(x: 145.94, y: 590, width: 449.38, height: 125)
let lOWLIGHTStyle = NSMutableParagraphStyle()
lOWLIGHTStyle.alignment = .left
let lOWLIGHTFontAttributes = [
.font: UIFont(name: "Futura-CondensedExtraBold", size: 96)!,
.foregroundColor: lOWLIGHTColor,
.paragraphStyle: lOWLIGHTStyle,
] as [NSAttributedStringKey: Any]
"LOW LIGHT".draw(in: lOWLIGHTRect, withAttributes: lOWLIGHTFontAttributes)
context.restoreGState()
//// MID LIGHT Drawing
context.saveGState()
context.setAlpha(mediumLightText)
let mIDLIGHTRect = CGRect(x: 145.77, y: 590, width: 449.38, height: 125)
let mIDLIGHTStyle = NSMutableParagraphStyle()
mIDLIGHTStyle.alignment = .left
let mIDLIGHTFontAttributes = [
.font: UIFont(name: "Futura-CondensedExtraBold", size: 96)!,
.foregroundColor: mIDLIGHTColor,
.paragraphStyle: mIDLIGHTStyle,
] as [NSAttributedStringKey: Any]
"MID LIGHT".draw(in: mIDLIGHTRect, withAttributes: mIDLIGHTFontAttributes)
context.restoreGState()
最佳答案
如果您想一次为多个字符的轮廓笔画设置动画,您可以:
- 确定每个字符的 CGPaths
- 将 CGPaths 映射到 CAShapeLayers
- 为
strokeEnd
属性设置动画
请注意: iOS 使用的字体是使用 TrueType 或 OpenType 格式的轮廓字体。这意味着每个字形都使用直线和曲线来定义其边界。我们通常在渲染字形时看到的是填充区域。因此,如果“strokeEnd”属性是动画的,则绘制字形的轮廓。以下代码显示了如何实现这一目标。
以人类编写文本的方式对文本进行动画处理会更加费力(例如,使用笔划字体而不是轮廓字体加上关联的引擎或使用用户定义的矢量路径来表示每个字符)
var charLayers = [CAShapeLayer]()
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
for layer in self.charLayers {
layer.removeFromSuperlayer()
}
let stringAttributes = [ NSAttributedStringKey.font: UIFont(name: "Futura-CondensedExtraBold", size: 64.0)! ]
let attributedString = NSMutableAttributedString(string: "hello world", attributes: stringAttributes )
let charPaths = self.characterPaths(attributedString: attributedString, position: CGPoint(x: 24, y: 192))
self.charLayers = charPaths.map { path -> CAShapeLayer in
let shapeLayer = CAShapeLayer()
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.strokeColor = UIColor.red.cgColor
shapeLayer.lineWidth = 2
shapeLayer.path = path
return shapeLayer
}
for layer in self.charLayers {
view.layer.addSublayer(layer)
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.fromValue = 0
animation.duration = 2.2
layer.add(animation, forKey: "charAnimation")
}
}
func characterPaths(attributedString: NSAttributedString, position: CGPoint) -> [CGPath] {
let line = CTLineCreateWithAttributedString(attributedString)
guard let glyphRuns = CTLineGetGlyphRuns(line) as? [CTRun] else { return []}
var characterPaths = [CGPath]()
for glyphRun in glyphRuns {
guard let attributes = CTRunGetAttributes(glyphRun) as? [String:AnyObject] else { continue }
let font = attributes[kCTFontAttributeName as String] as! CTFont
for index in 0..<CTRunGetGlyphCount(glyphRun) {
let glyphRange = CFRangeMake(index, 1)
var glyph = CGGlyph()
CTRunGetGlyphs(glyphRun, glyphRange, &glyph)
var characterPosition = CGPoint()
CTRunGetPositions(glyphRun, glyphRange, &characterPosition)
characterPosition.x += position.x
characterPosition.y += position.y
if let glyphPath = CTFontCreatePathForGlyph(font, glyph, nil) {
var transform = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: characterPosition.x, ty: characterPosition.y)
if let charPath = glyphPath.copy(using: &transform) {
characterPaths.append(charPath)
}
}
}
}
return characterPaths
}
关于ios - 如何使用 CoreGrahpics 和 Core 动画绘制文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49087257/