[swift]读取svg图片为UIBezierPath,开心做动画

[swift]读取svg图片为UIBezierPath,开心做动画,第1张

概述更新 给对本文感兴趣的朋友们推荐个好东西:paintcode 动画预览 先扯淡 最近手痒又想整点动画玩玩,但是想了几个主意发现稍微复杂一点的手写都一定会累爆。这篇文章记录一下今天折腾的一个方案。说来简单,就是用矢量设计工具舒舒服服的做好设计,然后输出成 svg 格式,再用 NSXMLParser 去读出来,转换成 UIBezierPath ,然后就天高任鸟飞~ 清晰起见,这里不使用各种库,由上面的 更新

给对本文感兴趣的朋友们推荐个好东西:paintcode

动画预览

先扯淡

最近手痒又想整点动画玩玩,但是想了几个主意发现稍微复杂一点的手写都一定会累爆。这篇文章记录一下今天折腾的一个方案。说来简单,就是用矢量设计工具舒舒服服的做好设计,然后输出成 svg 格式,再用 NSXMLParser 去读出来,转换成 UIBezIErPath ,然后就天高任鸟飞~

清晰起见,这里不使用各种库,由上面的二维码动画为例,只转换最简单的矩形。需要更多高能 *** 作的,出门右转 SVGKit。

开工

筹备材料先,首先找个能提供 svg 格式下载的二维码生成网站,比如 这个 。拿到 svg 文件后用文本编辑器打开可以看到其实是一个描述矢量图形的 xml ,而且里面几百个矩形。。。如果你用的生成网站跟我一样,还会有一个白色的背景矩形,待会儿我们会把它排除掉。

准备工作就到这了,接下来我们会用 NSXMLParser 来解析这个二维码。

新建一个 Single VIEw Application ,把二维码拖进项目里去,在 VIEwController 里添加一个 UIVIEw 作为二维码的容器:

class VIEwController: UIVIEwController {    let qrVIEw = UIVIEw()    overrIDe func vIEwDIDLoad() {        super.vIEwDIDLoad()                qrVIEw.center = vIEw.center        vIEw.addSubvIEw(qrVIEw)    }        ...}

初始化一个 NSXMLParser 去解析 svg ,同时让 VIEwController 实现 NSXMLParserDelegate`
parser(_:dIDStartElement:namespaceURI:qualifIEdname:attributes:)
parserDIDEnddocument(_:)` 两个方法用于处理解析结果:

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 文件解析完毕后,这里就会被调用    }        ...}

接下来我们会在 parser(_:dIDStartElement:namespaceURI:qualifIEdname:attributes:) 中把遇到的每一个形如:

<rect ... x="0" y="0" wIDth="12" height="12" fill="black"/>

的标签转换成 CGRect 保存在数组中,并在 parserDIDEnddocument(_:) 中把他们转换为 CAShapeLayer 并添加动画。

先来看看 parser(_:dIDStartElement:namespaceURI:qualifIEdname:attributes:) 的内容:

...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)    }}...

接下来是 parserDIDEnddocument(_:) ,在这里我们要把二维码显示出来:

...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)    }}...

#1、#2 :看着有点晕?代码不直观的话不妨稍微把玩一下,原因很简单,但要用语言解释我的舌头可能会打结。。。

至此,运行项目应该就能在屏幕上看到一个大二维码了!

加特技! Duang~

回到上面的 parserDIDEnddocument(_:) 方法,然后把它改到面目全非!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了。。。心塞。。。

继续加特技

手贱没忍住。。。二维码真是玩不坏。。。

总结

以上是内存溢出为你收集整理的[swift]读取svg图片为UIBezierPath,开心做动画全部内容,希望文章能够帮你解决[swift]读取svg图片为UIBezierPath,开心做动画所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1091728.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)

保存