[swift]讀取svg圖片為UIBezierPath,開心做動畫
https://segmentfault.com/a/1190000002580541
更新
給對本文感興趣的朋友們推薦個好東西:paintcode
動畫預覽
先扯淡
最近手癢又想整點動畫玩玩,但是想了幾個主意發現稍微複雜一點的手寫都一定會累爆。這篇文章記錄一下今天折騰的一個方案。說來簡單,就是用向量設計工具舒舒服服的做好設計,然後輸出成 svg 格式,再用 NSXMLParser
去讀出來,轉換成 UIBezierPath
,然後就天高任鳥飛~
清晰起見,這裡不使用各種庫,由上面的二維碼動畫為例,只轉換最簡單的矩形。需要更多高能操作的,出門右轉 SVGKit。
開工
籌備材料先,首先找個能提供 svg
準備工作就到這了,接下來我們會用 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!, didStartElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!, 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, width: w, 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, 0, 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,開心做動畫
https://segmentfault.com/a/1190000002580541 更新 給對本文感興趣的朋友們推薦個好東西:paintcode 動畫預覽 先扯淡 最近手癢又想整點動畫玩玩,但是想了幾個主意發現稍微複雜一點的手寫都一定會累爆。這篇文章
SVG2PNG(前臺個後臺將SVG轉換為PNG,完美支持IE8下載)--amcharts導出png
doc 項目 commons cep finall 保存 格式 lose 矢量圖形 在項目中用到了amcharts,amcharts圖標統計插件是利用SVG實現的,其自帶下載png功能,但是不支持IE以下瀏覽器。因此研究了SVG轉換為png,最終實現的效果是將a
C語言讀取二進位制檔案,讀取結果全部為零,編譯執行都沒有報錯
利用fread讀取二進位制檔案,讀出來的結果全部為零,編譯執行都沒有報錯,程式碼如下, 有人說是大小端的問題,怎麼理解啊?判斷出來的本機器的為little endian,怎麼判斷需不需要轉換啊?要是需要轉換,怎麼轉換啊?在網上找了利用巨集處理進行大小端轉換的程式碼,但是在我這種情況下,怎
C++使用tinyxml來操作DOM物件(以svg格式為例,其他格式都類似操作)
1.首先去下載tinyxml庫,在這裡下載http://sourceforge.net/projects/tinyxml/ 。我使用tinyxml作為例子,不用tinyxml2。下載完畢後將兩個標頭檔案tinystr.h和tinyxml.h放到工程的標頭檔案下,幷包含進
mysql日期儲存為int,mybatis做ORM對映與java.util.Date的轉換問題
在mysql做資料庫的應用中,日期型別經常回儲存為int(10)型別。方便排序和計算。但是在java中用Date.getTime返回的是13位的Long。並且在實體中我們如果用long來儲存會有諸多不便。所以涉及到了轉換問題。在我的專案中,用的是mybatis做
viewer 視窗控制,圖片懶載入,出入場動畫前端框架
1.開發中有這樣的需求,即希望新增在可視區域內觸發的動畫效果2.或者根據視窗位置動態改變樣式3.亦或是懶載入等,使用viewer都能輕鬆實現,一般來說使用viewer能輕鬆實現監控元素距離視窗位置執行任何你想要的回撥github地址:
iOS9中,swift判斷相機,相冊權限,選取圖片為頭像
返回 而已 頭像 iss 模式 會有 vid str 編輯模式 在iOS7以後要打開手機攝像頭或者相冊的話都需要權限,在iOS9中更是更新了相冊相關api的調用 首先新建一個swift工程,在SB中放上一個按鈕,並在viewController中拖出點擊事件 ok!按鈕和事
iOS9中,Swift判斷相機,相簿許可權,選取圖片為頭像
在iOS7以後要開啟手機攝像頭或者相簿的話都需要許可權,在iOS9中更是更新了相簿相關api的呼叫 首先新建一個swift工程,在SB中放上一個按鈕,並在viewController中拖出點選事件 ok!按鈕和事件設定好以後,我們來引入要用到的庫,判斷攝像頭許可權,需要引入AVFoundat
已知文件 a.txt 文件中的內容為“bcdeadferwplkou”, * 請編寫程序讀取該文件內容,並按照自然順序排序後輸出到 b.txt 文件中。 * 即 b.txt 中的文件內容應為“abcd…………..”這樣的順序。
urn exception abc public catch put cep 返回 輸入 import java.io.*;class SortChar{ private String str; private char arrayList[]; priv
python3 學習 3:python爬蟲之爬取動態載入的圖片,以百度圖片為例
轉: https://blog.csdn.net/qq_32166627/article/details/60882964 前言: 前面我們爬取圖片的網站都是靜態的,在頁面中右鍵檢視原始碼就能看到網頁中圖片的位置。這樣我們用requests庫得到頁面原始碼後,再用bs4庫解析標籤即可儲存圖片
nrrd格式用Python讀取並儲存為png圖片
安裝pynrrd pip install pynrrd pip install git+https://github.com/mhe/pynrrd.git cd pynrrd pip install . 如果報錯了,則輸入 python setup.py install 注意:
Opencv讀取USB網路攝像頭無法顯示,影象為空,顯示黑色?
利用Opencv讀取電腦的攝像頭,程式碼如下,一直無法正常執行,搜尋網上的解決方案,均未解決。程式碼語法沒有錯誤,攝像頭也可以開啟,但是就是無法讀取當前幀影象 #include <opencv.hpp> using namespace cv; int main() { Vid
python 將圖片存入mongodb,讀取圖片,gridfs模組
匯入圖片 引入模組,其中gridfs模組不需要單獨安裝,引入了pymongo即可直接引入 from pymongo import MongoClient from gridfs import * import os #連結mongodb client=MongoClient('localhost',
關於瀏覽器快取問題(圖片更換後,頁面仍優先讀取快取)
因為部分需求(跟換頭像,切換輪播圖等等)改變圖片或者本地上傳新圖片,會導致圖片快取問題,從而達不到預期效果,還是載入原圖片查找了一些資料,總結出2個步驟: 1.在圖片的路徑的後面拼接 ‘?內容’ 解決,具體如下 (1)在圖片src路徑後面加上時間戳,使瀏覽
圖片或檔案上傳到伺服器或從伺服器上讀取(圖片可根據路徑src回顯展示,從伺服器上讀出來)
不需要配置虛擬路徑,存的時候資料庫裡只存了圖片的名稱(隨機重新命名的形式),存在指定伺服器上,取的時候也是根據圖片名稱從伺服器上找到,並用OutputStream 讀出來 前臺頁面(用的bootstrap): html程式碼(可回顯,回顯的時候也是去後臺根據路徑查詢到圖片):
MFC中當儲存點陣圖時,圖片為全黑的解決辦法
需要建立相容點陣圖,建立相容DC,然後需要將點陣圖選入DC中,再將螢幕DC的影象拷貝到建立的相容記憶體DC中。 ······ CRect rect1; GetClientRect(&rect1);
網路圖片轉換為base64,解決跨域問題
function convertImgToBase64(url, callback, outputFormat) { var canvas = document.createElement('CANVAS'), ctx = canvas.getContext(
tensorflw資料寫入為tfrecord,使用DataSet讀取
#寫入tfrecord def create_tf_record(inputs, labels, tfrecords_filename): writer = tf.python_io.TFRecordWriter(tfrecords_filename)
將PDF轉換為word,HTML,SVG,XPS並將其儲存為流
本文我們將演示如何通過呼叫Spire.PDF提供的方法PdfDocument.SaveToStream()將PDF頁面轉換為HTML,Word,SVG,XPS,PDF並將它們儲存為流。從Spire.PDF版本4.3開始,它新支援轉換定義範圍的PDF頁面並將其儲存為流。 將PDF儲存為流 步驟
利用HTML5上傳檔案並顯示在前端預覽,以圖片為例
由於專案中有上傳檔案的功能,所以這次單獨拿出來研究研究,我上網查了查,以前都是用iframe,但是自從HTML5出世之後,就可以利用H5的一些特性來上傳檔案了,啥也不說了,我上程式碼了 <!DOCTYPE html> <html lang