Check to make sure targetZoom is within minZoom and maxZoom whether the zoom is animated or not
Showing
1 changed file
with
57 additions
and
36 deletions
@@ -450,54 +450,75 @@ | @@ -450,54 +450,75 @@ | ||
450 | [self zoomByFactor:zoomFactor near:pivot animated:animated withCallback:nil]; | 450 | [self zoomByFactor:zoomFactor near:pivot animated:animated withCallback:nil]; |
451 | } | 451 | } |
452 | 452 | ||
453 | +- (BOOL)shouldZoomToTargetZoom:(float)targetZoom withZoomFactor:(float)zoomFactor { | ||
454 | + //bools for syntactical sugar to understand the logic in the if statement below | ||
455 | + BOOL zoomAtMax = ([self zoom] == [self maxZoom]); | ||
456 | + BOOL zoomAtMin = ([self zoom] == [self minZoom]); | ||
457 | + BOOL zoomGreaterMin = ([self zoom] > [self minZoom]); | ||
458 | + BOOL zoomLessMax = ([self zoom] < [self maxZoom]); | ||
459 | + | ||
460 | + //zooming in zoomFactor > 1 | ||
461 | + //zooming out zoomFactor < 1 | ||
462 | + | ||
463 | + if ((zoomGreaterMin && zoomLessMax) || (zoomAtMax && zoomFactor<1) || (zoomAtMin && zoomFactor>1)) | ||
464 | + { | ||
465 | + return YES; | ||
466 | + } | ||
467 | + else | ||
468 | + { | ||
469 | + return NO; | ||
470 | + } | ||
471 | +} | ||
472 | + | ||
453 | - (void)zoomByFactor: (float) zoomFactor near:(CGPoint) pivot animated:(BOOL) animated withCallback:(id<RMMapContentsAnimationCallback>)callback | 473 | - (void)zoomByFactor: (float) zoomFactor near:(CGPoint) pivot animated:(BOOL) animated withCallback:(id<RMMapContentsAnimationCallback>)callback |
454 | { | 474 | { |
455 | zoomFactor = [self adjustZoomForBoundingMask:zoomFactor]; | 475 | zoomFactor = [self adjustZoomForBoundingMask:zoomFactor]; |
456 | float zoomDelta = log2f(zoomFactor); | 476 | float zoomDelta = log2f(zoomFactor); |
457 | float targetZoom = zoomDelta + [self zoom]; | 477 | float targetZoom = zoomDelta + [self zoom]; |
458 | 478 | ||
479 | + if (targetZoom == [self zoom]){ | ||
480 | + return; | ||
481 | + } | ||
482 | + // clamp zoom to remain below or equal to maxZoom after zoomAfter will be applied | ||
483 | + if(targetZoom > [self maxZoom]){ | ||
484 | + zoomFactor = exp2f([self maxZoom] - [self zoom]); | ||
485 | + } | ||
486 | + | ||
459 | if (animated) | 487 | if (animated) |
460 | { | 488 | { |
461 | - // goal is to complete the animation in animTime seconds | ||
462 | - static const float stepTime = kZoomAnimationStepTime; | ||
463 | - static const float animTime = kZoomAnimationAnimationTime; | ||
464 | - float nSteps = animTime / stepTime; | ||
465 | - float zoomIncr = zoomDelta / nSteps; | 489 | + if ([self shouldZoomToTargetZoom:targetZoom withZoomFactor:zoomFactor]) |
490 | + { | ||
491 | + // goal is to complete the animation in animTime seconds | ||
492 | + static const float stepTime = kZoomAnimationStepTime; | ||
493 | + static const float animTime = kZoomAnimationAnimationTime; | ||
494 | + float nSteps = animTime / stepTime; | ||
495 | + float zoomIncr = zoomDelta / nSteps; | ||
496 | + | ||
497 | + CFDictionaryRef pivotDictionary = CGPointCreateDictionaryRepresentation(pivot); | ||
498 | + /// \bug magic string literals | ||
499 | + NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys: | ||
500 | + [NSNumber numberWithFloat:zoomIncr], @"zoomIncr", | ||
501 | + [NSNumber numberWithFloat:targetZoom], @"targetZoom", | ||
502 | + pivotDictionary, @"pivot", | ||
503 | + callback, @"callback", nil]; | ||
504 | + CFRelease(pivotDictionary); | ||
505 | + [NSTimer scheduledTimerWithTimeInterval:stepTime | ||
506 | + target:self | ||
507 | + selector:@selector(animatedZoomStep:) | ||
508 | + userInfo:userInfo | ||
509 | + repeats:YES]; | ||
510 | + } else | ||
511 | + { | ||
512 | + if([self zoom] > [self maxZoom]) | ||
513 | + [self setZoom:[self maxZoom]]; | ||
514 | + if([self zoom] < [self minZoom]) | ||
515 | + [self setZoom:[self minZoom]]; | ||
516 | + } | ||
466 | 517 | ||
467 | - CFDictionaryRef pivotDictionary = CGPointCreateDictionaryRepresentation(pivot); | ||
468 | - /// \bug magic string literals | ||
469 | - NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys: | ||
470 | - [NSNumber numberWithFloat:zoomIncr], @"zoomIncr", | ||
471 | - [NSNumber numberWithFloat:targetZoom], @"targetZoom", | ||
472 | - pivotDictionary, @"pivot", | ||
473 | - callback, @"callback", nil]; | ||
474 | - CFRelease(pivotDictionary); | ||
475 | - [NSTimer scheduledTimerWithTimeInterval:stepTime | ||
476 | - target:self | ||
477 | - selector:@selector(animatedZoomStep:) | ||
478 | - userInfo:userInfo | ||
479 | - repeats:YES]; | ||
480 | } | 518 | } |
481 | else | 519 | else |
482 | { | 520 | { |
483 | - if (targetZoom == [self zoom]){ | ||
484 | - return; | ||
485 | - } | ||
486 | - // clamp zoom to remain below or equal to maxZoom after zoomAfter will be applied | ||
487 | - if(targetZoom > [self maxZoom]){ | ||
488 | - zoomFactor = exp2f([self maxZoom] - [self zoom]); | ||
489 | - } | ||
490 | - | ||
491 | - //bools for syntactical sugar to understand the logic in the if statement below | ||
492 | - BOOL zoomAtMax = ([self zoom] == [self maxZoom]); | ||
493 | - BOOL zoomAtMin = ([self zoom] == [self minZoom]); | ||
494 | - BOOL zoomGreaterMin = ([self zoom] > [self minZoom]); | ||
495 | - BOOL zoomLessMax = ([self zoom] < [self maxZoom]); | ||
496 | - | ||
497 | - //zooming in zoomFactor > 1 | ||
498 | - //zooming out zoomFactor < 1 | ||
499 | - | ||
500 | - if ((zoomGreaterMin && zoomLessMax) || (zoomAtMax && zoomFactor<1) || (zoomAtMin && zoomFactor>1)) | 521 | + if ([self shouldZoomToTargetZoom:targetZoom withZoomFactor:zoomFactor]) |
501 | { | 522 | { |
502 | [mercatorToScreenProjection zoomScreenByFactor:zoomFactor near:pivot]; | 523 | [mercatorToScreenProjection zoomScreenByFactor:zoomFactor near:pivot]; |
503 | [imagesOnScreen zoomByFactor:zoomFactor near:pivot]; | 524 | [imagesOnScreen zoomByFactor:zoomFactor near:pivot]; |
-
Please register or login to post a comment