Skip to content

Instantly share code, notes, and snippets.

@jaredrada
Created October 3, 2019 00:58
Show Gist options
  • Save jaredrada/5baded65e97c0cf44392747631052c71 to your computer and use it in GitHub Desktop.
Save jaredrada/5baded65e97c0cf44392747631052c71 to your computer and use it in GitHub Desktop.
import UIKit
class ViewController: UIViewController {
let baseLayer = CAShapeLayer()
var pinchX: CGFloat = 0
var pinchY: CGFloat = 0
var panStart = CGPoint()
var viewPosition: CGPoint = CGPoint(x:0, y:0) {
didSet {
moveToCurrentViewPoint()
}
}
private var chartScaleState: CGFloat = 1
private var chartScale: CGFloat {
get {
return chartScaleState
}
set(val) {
let previousScale = chartScaleState
chartScaleState = (val) + chartScaleState
handleScaleAction(scaleAdjust: previousScale / chartScaleState)
}
}
override func viewDidLoad() {
super.viewDidLoad()
drawBaseMap()
viewPosition = CGPoint(x: 0, y: 0)
}
@IBAction func handlePinch(_ sender: UIPinchGestureRecognizer) {
if (sender.state == .changed) {
let pinchCenter = CGPoint(x: sender.location(in: view).x - view.bounds.midX,
y: sender.location(in: view).y - view.bounds.midY)
pinchX = pinchCenter.x + (baseLayer.anchorPoint.x * view.bounds.width)
pinchY = pinchCenter.y + (baseLayer.anchorPoint.y * view.bounds.height)
chartScale = -((sender.scale - 1) * chartScale)
sender.scale = 1.0
}
}
@IBAction func panHandle(_ sender: UIPanGestureRecognizer) {
let location = sender.location(in: self.view)
if (sender.state == .began) {
panStart = CGPoint(x: location.x, y: location.y)
}
if (sender.state == .changed) {
let deltaX = panStart.x - location.x
let deltaY = panStart.y - location.y
moveItems(deltaX: deltaX, deltaY: deltaY)
panStart = CGPoint(x: location.x, y: location.y)
}
}
func moveToCurrentViewPoint() {
baseLayer.anchorPoint = CGPoint(
x: CGFloat(Double(viewPosition.x) / Double(chartScale)) / baseLayer.bounds.width,
y: (CGFloat(Double(viewPosition.y) / Double(chartScale)) / baseLayer.bounds.height) * -1
)
}
func drawBaseMap() {
baseLayer.bounds = CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height)
baseLayer.position = CGPoint(x: view.bounds.midX, y: view.bounds.midY)
baseLayer.anchorPoint = CGPoint(
x: 0,
y: 0
)
baseLayer.actions = [
"transform": NSNull(),
"anchorPoint": NSNull() ]
baseLayer.backgroundColor = UIColor.green.cgColor
baseLayer.strokeColor = UIColor.black.cgColor
baseLayer.fillColor = UIColor(red: 184/255.0, green: 174/255.0, blue: 87/255.0, alpha: 1.0).cgColor
baseLayer.lineWidth = 1
baseLayer.zPosition = -10
let coolRect = CGRect(x: 0, y: 0, width: 100, height: 100)
let path = CGMutablePath()
path.addRect(coolRect)
self.view.layer.addSublayer(baseLayer)
baseLayer.path = path
}
func handleScaleAction(scaleAdjust: CGFloat) {
var pathTransform = CGAffineTransform.identity
pathTransform = pathTransform.translatedBy(x: pinchX, y: pinchY)
pathTransform = pathTransform.scaledBy(x: scaleAdjust, y: scaleAdjust)
pathTransform = pathTransform.translatedBy(x: -(pinchX), y: -(pinchY))
baseLayer.path = baseLayer.path?.copy(using: &pathTransform)
}
public func moveItems(deltaX: CGFloat, deltaY: CGFloat) {
viewPosition = CGPoint(
x: Double(viewPosition.y) - (Double(deltaY) * Double(chartScale)),
y: Double(viewPosition.x) + (Double(deltaX) * Double(chartScale))
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment