Created
October 3, 2019 00:58
-
-
Save jaredrada/5baded65e97c0cf44392747631052c71 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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