diff options
author | Minh Nguyễn <mxn@1ec5.org> | 2016-06-05 23:52:21 -0700 |
---|---|---|
committer | Minh Nguyễn <mxn@1ec5.org> | 2017-07-05 18:32:59 -0700 |
commit | f35b8703268cb09d5a48fa56a94b87564e8064db (patch) | |
tree | bfa649f0933fcae170e561904f072b72a80282e2 /platform/ios/src/MGLAnnotationView.mm | |
parent | cc1f1a1e0bd4801fa3e079c723955f5a800c8bd6 (diff) | |
download | qtlocation-mapboxgl-f35b8703268cb09d5a48fa56a94b87564e8064db.tar.gz |
[ios] Apply perspective to x-free annotation views
Working towards #5090.
Diffstat (limited to 'platform/ios/src/MGLAnnotationView.mm')
-rw-r--r-- | platform/ios/src/MGLAnnotationView.mm | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/platform/ios/src/MGLAnnotationView.mm b/platform/ios/src/MGLAnnotationView.mm index 6d38dc41c0..13edc444c6 100644 --- a/platform/ios/src/MGLAnnotationView.mm +++ b/platform/ios/src/MGLAnnotationView.mm @@ -10,8 +10,7 @@ @interface MGLAnnotationView () <UIGestureRecognizerDelegate> @property (nonatomic, readwrite, nullable) NSString *reuseIdentifier; -@property (nonatomic, readwrite) CATransform3D lastAppliedScaleTransform; -@property (nonatomic, readwrite) CATransform3D lastAppliedRotateTransform; +@property (nonatomic, readwrite) CATransform3D lastAppliedTransform; @property (nonatomic, weak) UIPanGestureRecognizer *panGestureRecognizer; @property (nonatomic, weak) UILongPressGestureRecognizer *longPressRecognizer; @property (nonatomic, weak) MGLMapView *mapView; @@ -41,7 +40,7 @@ } - (void)commonInitWithAnnotation:(nullable id<MGLAnnotation>)annotation reuseIdentifier:(nullable NSString *)reuseIdentifier { - _lastAppliedScaleTransform = CATransform3DIdentity; + _lastAppliedTransform = CATransform3DIdentity; _annotation = annotation; _reuseIdentifier = [reuseIdentifier copy]; _scalesWithViewingDistance = YES; @@ -139,20 +138,31 @@ - (void)updateTransform { if (self.dragState == MGLAnnotationViewDragStateDragging) return; - - CATransform3D t = CATransform3DIdentity; + + // We keep track of each viewing distance scale transform that we apply. Each iteration, + // we can account for it so that we don't get cumulative scaling every time we move. + // We also avoid clobbering any existing transform passed in by the client, too. + CATransform3D undoOfLastScaleTransform = CATransform3DInvert(_lastAppliedTransform); + + CATransform3D freeTransform = CATransform3DIdentity; MGLMapCamera *camera = self.mapView.camera; if (camera.pitch >= 0 && (self.freeAxes & MGLAnnotationViewBillboardAxisX)) { - t = CATransform3DRotate(t, MGLRadiansFromDegrees(camera.pitch), 1.0, 0, 0); + // https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreAnimation_guide/AdvancedAnimationTricks/AdvancedAnimationTricks.html#//apple_ref/doc/uid/TP40004514-CH8-SW13 + // FIXME: This is a rough, eyeballed value. Replace this transform with one derived from mbgl::TransformState::coordinatePointMatrix(). + CGRect superBounds = self.superview.bounds; + freeTransform.m34 = -1.0 / (1000 - CGRectGetWidth(superBounds)); + + freeTransform = CATransform3DRotate(freeTransform, MGLRadiansFromDegrees(camera.pitch), 1.0, 0, 0); } if (camera.heading >= 0 && (self.freeAxes & MGLAnnotationViewBillboardAxisY)) { - t = CATransform3DRotate(t, MGLRadiansFromDegrees(-camera.heading), 0.0, 0.0, 1.0); + freeTransform = CATransform3DRotate(freeTransform, MGLRadiansFromDegrees(-camera.heading), 0.0, 0.0, 1.0); } + CATransform3D scaleTransform = CATransform3DIdentity; CGFloat superviewHeight = CGRectGetHeight(self.superview.frame); - if ( ! self.scalesWithViewingDistance && superviewHeight > 0.0) { + if (self.scalesWithViewingDistance && superviewHeight > 0.0) { // Find the maximum amount of scale reduction to apply as the view's center moves from the top // of the superview to the bottom. For example, if this view's center has moved 25% of the way // from the top of the superview towards the bottom then the maximum scale reduction is 1 - .25 @@ -172,16 +182,12 @@ // map view is 50% pitched then the annotation view should be reduced by 37.5% (.75 * .5). The // reduction is then normalized for a scale of 1.0. CGFloat pitchAdjustedScale = 1.0 - maxScaleReduction * pitchIntensity; - - // We keep track of each viewing distance scale transform that we apply. Each iteration, - // we can account for it so that we don't get cumulative scaling every time we move. - // We also avoid clobbering any existing transform passed in by the client, too. - CATransform3D undoOfLastScaleTransform = CATransform3DInvert(_lastAppliedScaleTransform); - CATransform3D newScaleTransform = CATransform3DMakeScale(pitchAdjustedScale, pitchAdjustedScale, 1); - CATransform3D effectiveTransform = CATransform3DConcat(undoOfLastScaleTransform, newScaleTransform); - self.layer.transform = CATransform3DConcat(self.layer.transform, effectiveTransform); - _lastAppliedScaleTransform = newScaleTransform; + scaleTransform = CATransform3DMakeScale(pitchAdjustedScale, pitchAdjustedScale, 1); } + + CATransform3D effectiveTransform = CATransform3DConcat(freeTransform, scaleTransform); + self.layer.transform = CATransform3DConcat(self.layer.transform, CATransform3DConcat(undoOfLastScaleTransform, effectiveTransform)); + _lastAppliedTransform = effectiveTransform; } #pragma mark - Draggable |