Skip to content

Instantly share code, notes, and snippets.

@mayoff
Created July 17, 2017 04:10
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mayoff/0a50fb7e7bf1ae2469b8cc83df4fcc60 to your computer and use it in GitHub Desktop.
Save mayoff/0a50fb7e7bf1ae2469b8cc83df4fcc60 to your computer and use it in GitHub Desktop.
stroked path playground
import UIKit
import ImageIO
import MobileCoreServices
import PlaygroundSupport
let documentFolderUrl = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
print(documentFolderUrl)
class ShapeView: UIView {
override class var layerClass: AnyClass { return CAShapeLayer.self }
private(set) lazy var shapeLayer: CAShapeLayer = { self.layer as! CAShapeLayer }()
init(frame: CGRect, path: CGPath) {
super.init(frame: frame)
shapeLayer.path = path
shapeLayer.lineCap = kCALineCapButt
shapeLayer.lineJoin = kCALineJoinRound
shapeLayer.lineWidth = 1
shapeLayer.fillColor = nil
shapeLayer.strokeColor = nil
}
required init?(coder decoder: NSCoder) { fatalError() }
}
extension UIView {
var snapshotImage: UIImage {
let format = UIGraphicsImageRendererFormat.default()
format.scale = 1
return UIGraphicsImageRenderer(bounds: bounds, format: format).image { rc in
drawHierarchy(in: bounds, afterScreenUpdates: true)
}
}
func savePng(to filename: String) {
try! UIImagePNGRepresentation(snapshotImage)!.write(to: documentFolderUrl.appendingPathComponent(filename), options: .atomic)
}
}
func saveAnimatedGif(to filename: String, frameCount: Int, frameFunction: (_ frameNumber: Int, _ frameCount: Int) -> UIImage) {
let fileGifProperties: [CFString: Any] = [kCGImagePropertyGIFLoopCount: NSNumber(value: UInt16(0))]
let fileProperties: [CFString: Any] = [kCGImagePropertyGIFDictionary: fileGifProperties]
let frameGifProperties: [CFString: Any] = [kCGImagePropertyGIFDelayTime: NSNumber(value: Float(1) / 30)]
let frameProperties: [CFString: Any] = [kCGImagePropertyGIFDictionary: frameGifProperties]
let destination = CGImageDestinationCreateWithURL(documentFolderUrl.appendingPathComponent(filename) as CFURL, kUTTypeGIF, frameCount, fileProperties as CFDictionary)!
for i in 0 ..< frameCount {
CGImageDestinationAddImage(destination, frameFunction(i, frameCount).cgImage!, frameProperties as CFDictionary)
}
// CGImageDestinationSetProperties(destination, fileProperties as CFDictionary)
CGImageDestinationFinalize(destination)
}
let rootView = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: 150))
rootView.backgroundColor = .white
let corePath = CGMutablePath()
let rect = rootView.bounds.insetBy(dx: 20, dy: 20)
corePath.addLines(between: [
CGPoint(x: rect.minX, y: rect.minY),
CGPoint(x: rect.midX - 2, y: rect.maxY),
CGPoint(x: rect.midX + 2, y: rect.maxY),
CGPoint(x: rect.maxX, y: rect.minY)])
let corePathView = ShapeView(frame: rootView.bounds, path: corePath)
corePathView.shapeLayer.strokeColor = UIColor(hue: 0, saturation: 0.9, brightness: 0.9, alpha: 1).cgColor
corePathView.savePng(to: "corePathView.png")
rootView.addSubview(corePathView)
let strokeView = ShapeView(frame: rootView.bounds, path: corePath)
strokeView.shapeLayer.strokeColor = UIColor(hue: 0, saturation: 0.4, brightness: 1.0, alpha: 1).cgColor
strokeView.shapeLayer.lineWidth = 40
strokeView.shapeLayer.lineJoin = kCALineJoinBevel
strokeView.savePng(to: "strokeView.png")
rootView.insertSubview(strokeView, belowSubview: corePathView)
let strokedCopyPath = corePath.copy(strokingWithWidth: strokeView.shapeLayer.lineWidth, lineCap: .butt, lineJoin: .bevel, miterLimit: 0)
let strokedCopyView = ShapeView(frame: rootView.bounds, path: strokedCopyPath)
strokedCopyView.shapeLayer.strokeColor = UIColor(hue: 0, saturation: 0.6, brightness: 0.6, alpha: 1).cgColor
strokedCopyView.shapeLayer.lineJoin = kCALineJoinRound
strokedCopyView.shapeLayer.lineWidth = 1
strokedCopyView.shapeLayer.miterLimit = 20
strokedCopyView.savePng(to: "strokedCopyView.png")
rootView.addSubview(strokedCopyView)
let thinStrokedCopyPath = corePath.copy(strokingWithWidth: 8, lineCap: .butt, lineJoin: .bevel, miterLimit: 0)
let thinStrokedCopyView = ShapeView(frame: rootView.bounds, path: thinStrokedCopyPath)
thinStrokedCopyView.shapeLayer.strokeColor = UIColor(hue: 0, saturation: 0.6, brightness: 0.6, alpha: 1).cgColor
thinStrokedCopyView.shapeLayer.lineJoin = kCALineJoinBevel
thinStrokedCopyView.shapeLayer.lineWidth = 2
thinStrokedCopyView.shapeLayer.miterLimit = 20
thinStrokedCopyView.savePng(to: "thinStrokedCopyView.png")
if false {
strokedCopyView.backgroundColor = .white
saveAnimatedGif(to: "animatedStrokeCopy.gif", frameCount: 201) { (frameNumber: Int, frameCount: Int) in
strokedCopyView.shapeLayer.strokeStart = CGFloat(frameCount - frameNumber) / CGFloat(frameCount - 1)
return strokedCopyView.snapshotImage
}
strokedCopyView.backgroundColor = nil
strokedCopyView.shapeLayer.strokeStart = 0
}
PlaygroundPage.current.liveView = rootView
@mayoff
Copy link
Author

mayoff commented Jul 17, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment