Last active
March 10, 2019 12:51
-
-
Save mntone/ee69a06ae7b265776e82879f6f8a0569 to your computer and use it in GitHub Desktop.
[under MIT License] Show image with using focus point.
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 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