Skip to content

Instantly share code, notes, and snippets.

@mntone
Last active March 10, 2019 12:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mntone/ee69a06ae7b265776e82879f6f8a0569 to your computer and use it in GitHub Desktop.
Save mntone/ee69a06ae7b265776e82879f6f8a0569 to your computer and use it in GitHub Desktop.
[under MIT License] Show image with using focus point.
import SIMDKit
import UIKit
public final class FocusableImageView: UIImageView {
public var isFocusEnabled: Bool = true {
didSet { layer.setNeedsLayout() }
}
public var focus: CGPoint = .zero {
didSet { layer.setNeedsLayout() }
}
public override var image: UIImage? {
didSet { layer.setNeedsLayout() }
}
public override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
private func setup() { }
public override func layoutSublayers(of layer: CALayer) {
guard isFocusEnabled else {
layer.contentsRect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
return
}
guard let image = image else { return }
let imageSize = image.size
let containerSize = bounds.size
let ratio = imageSize / containerSize
if ratio.width > ratio.height {
let factorX = FocusableImageView.calcShift(containerRatioOtherAxis: ratio.height,
container: containerSize.width,
image: imageSize.width,
focus: focus.x)
layer.contentsRect = CGRect(x: factorX.point, y: 0.0, width: factorX.length, height: 1.0)
} else {
let factorY = FocusableImageView.calcShift(containerRatioOtherAxis: ratio.width,
container: containerSize.height,
image: imageSize.height,
focus: -focus.y)
layer.contentsRect = CGRect(x: 0.0, y: factorY.point, width: 1.0, height: factorY.length)
}
}
private static func calcShift(containerRatioOtherAxis: CGFloat, container: CGFloat, image: CGFloat, focus: CGFloat) -> (point: CGFloat, length: CGFloat) {
let focusFactor = 0.5 * (focus + 1.0)
let lengthFactor = (container * containerRatioOtherAxis) / image
let beginFocusFactor = min(max(0.0, focusFactor - 0.5 * (1.0 - abs(focus)) * lengthFactor), 1.0 - lengthFactor)
return (beginFocusFactor, lengthFactor)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment