[swift]读取svg图片为UIBezierPath,开心做动画
更新给对本文感兴趣的朋友们推荐个好东西:paintcode 动画预览
先扯淡最近手痒又想整点动画玩玩,但是想了几个主意发现稍微复杂一点的手写都一定会累爆。这篇文章记录一下今天折腾的一个方案。说来简单,就是用矢量设计工具舒舒服服的做好设计,然后输出成 svg 格式,再用 清晰起见,这里不使用各种库,由上面的二维码动画为例,只转换最简单的矩形。需要更多高能操作的,出门右转 SVGKit。 开工筹备材料先,首先找个能提供 svg 格式下载的二维码生成网站,比如 这个 。拿到 svg 文件后用文本编辑器打开可以看到其实是一个描述矢量图形的 xml ,而且里面几百个矩形。。。如果你用的生成网站跟我一样,还会有一个白色的背景矩形,待会儿我们会把它排除掉。 准备工作就到这了,接下来我们会用 新建一个 class ViewController: UIViewController { let qrView = UIView() override func viewDidLoad() { super.viewDidLoad() qrView.center = view.center view.addSubview(qrView) } ... } 初始化一个 class ViewController: UIViewController,NSXMLParserDelegate { ... override func viewDidLoad() { ... let qrPath = NSBundle.mainBundle().pathForResource("zcfan_qrcode",ofType: "svg")! let qrData = NSData(contentsOfFile: qrPath) let xmlParser = NSXMLParser(data: qrData) xmlParser.delegate = self xmlParser.parse() } func parser(parser: NSXMLParser!,didStartElement elementName: String!,namespaceURI: String!,qualifiedName qName: String!,attributes attributeDict: [NSObject : AnyObject]!) { // 每当解析到一个新标签,这里就会被调用 } func parserDidEndDocument(parser: NSXMLParser!) { // 整个 svg 文件解析完毕后,这里就会被调用 } ... } 接下来我们会在 <rect ... x="0" y="0" width="12" height="12" fill="black"/> 的标签转换成 先来看看 ... var rects = [CGRect]() // 用于存储二维码 func parser(parser: NSXMLParser!,attributes attributeDict: [NSObject : AnyObject]!) { // 只转换 “黑色” 的二维码 “方块” if elementName == "rect" && (attributeDict["fill"] as String) == "black" { let x = (attributeDict["x"] as NSString).doubleValue let y = (attributeDict["y"] as NSString).doubleValue let w = (attributeDict["width"] as NSString).doubleValue let h = (attributeDict["height"] as NSString).doubleValue let rect = CGRect(x: x,y: y,width: w,height: h) rects.append(rect) // 设置 qrView 的尺寸为 svg 图像的大小 } else if elementName == "svg" { let w = (attributeDict["width"] as NSString).doubleValue let h = (attributeDict["height"] as NSString).doubleValue qrView.bounds = CGRect(x: 0,y: 0,height: h) } } ... 接下来是 ... func parserDidEndDocument(parser: NSXMLParser!) { for r in rects { let rectLayer = CAShapeLayer() rectLayer.fillColor = UIColor.darkGrayColor().CGColor rectLayer.strokeColor = nil rectLayer.path = UIBezierPath(rect: CGRect(origin: CGPointZero,size: r.size)).CGPath // #1 rectLayer.frame = r // #2 qrView.layer.addSublayer(rectLayer) } } ...
至此,运行项目应该就能在屏幕上看到一个大二维码了! 加特技! Duang~回到上面的 func parserDidEndDocument(parser: NSXMLParser!) { qrView.layer.shadowColor = UIColor.grayColor().CGColor qrView.layer.shadowRadius = 4 qrView.layer.shadowOpacity = 1 qrView.layer.shadowOffset = CGSizeZero for r in rects { let rectLayer = CAShapeLayer() rectLayer.fillColor = UIColor.darkGrayColor().CGColor rectLayer.strokeColor = nil rectLayer.path = UIBezierPath(rect: CGRect(origin: CGPointZero,size: r.size)).CGPath rectLayer.frame = r var startTransform = CATransform3DIdentity startTransform.m34 = 1.0 / -20 // 透视 startTransform = CATransform3DRotate(startTransform,CGFloat(M_PI)*0.5,1,0) // 沿 y 轴旋转 π/2 圈,待会再动画转回来 // transform 动画 let transAnim = CABasicAnimation(keyPath: "transform") transAnim.duration = drand48() * 4 // 随机一个持续时间 transAnim.fromValue = NSValue(CATransform3D: startTransform) transAnim.toValue = NSValue(CATransform3D: CATransform3DIdentity) rectLayer.addAnimation(transAnim,forKey: "transAnim") // 透明度动画 let alphaAnim = CABasicAnimation(keyPath: "opacity") alphaAnim.duration = transAnim.duration alphaAnim.fromValue = 0 alphaAnim.toValue = 1 rectLayer.addAnimation(alphaAnim,forKey: "alphaAnim") qrView.layer.addSublayer(rectLayer) } } 完工
没眼看,不录gif了。。。心塞。。。 继续加特技手贱没忍住。。。二维码真是玩不坏。。。
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |