Search code examples
ioscocos2d-iphonescalinguipinchgesturerecognizer

Issue scaling layer at the center of a pinch gesture


I am currently having a map(tilemap) within a layer that i would like to pan/zoom using the following code:

- (void) pinchGestureUpdated: (UIPinchGestureRecognizer *) recognizer {

    if([recognizer state] == UIGestureRecognizerStateBegan) {

            _lastScale = [recognizer scale];

            CGPoint touchLocation1 = [recognizer locationOfTouch:0 inView:recognizer.view];
            CGPoint touchLocation2 = [recognizer locationOfTouch:1 inView:recognizer.view];

            CGPoint centerGL = [[CCDirector sharedDirector] convertToGL: ccpMidpoint(touchLocation1, touchLocation2)];
            _pinchCenter = [self convertToNodeSpace:centerGL];
    }

    else if ([recognizer state] == UIGestureRecognizerStateChanged) {

//        NSLog(@"%d", recognizer.scale);

        CGFloat newDeltaScale = 1 -  (_lastScale - [recognizer scale]);
        newDeltaScale = MIN(newDeltaScale, kMaxScale / self.scale);
        newDeltaScale = MAX(newDeltaScale, kMinScale / self.scale);

        CGFloat newScale = self.scale * newDeltaScale;

        //self.scale = newScale;
        [self scale: newScale atCenter:_pinchCenter];

        _lastScale = [recognizer scale];
    }
}

- (void) scale: (CGFloat) newScale atCenter: (CGPoint) center {

    CGPoint oldCenterPoint = ccp(center.x * self.scale, center.y * self.scale);

    // Set the scale.
    self.scale = newScale;

    // Get the new center point.
    CGPoint newCenterPoint = ccp(center.x * self.scale, center.y * self.scale);

    // Then calculate the delta.
    CGPoint centerPointDelta  = ccpSub(oldCenterPoint, newCenterPoint);

    // Now adjust your layer by the delta.
    self.position = ccpAdd(self.position, centerPointDelta);
}

my issue is that the zoom is not taking in effect at the center of the pinch even though i am trying to change it at the same time i am zooming in through this method: (void) scale: (CGFloat) newScale atCenter: (CGPoint) center. Is there any reason this might not happening properly? Also how do i convert to the center location of the pinch into the coordinates system for my scene/layer?


Solution

  • Everything was actually fine in my approach. The problem i was having though is that the layer anchor point was different from the map one i defined, which was introducing an offset during scaling. I had to set both anchor to ccp(0,0).

    The concersion from the screen coordinates of the pinch gesture's center to the layer is correct and can be achived by the following instructions when using UIKIt gesture recognizers:

    CGPoint centerGL = [[CCDirector sharedDirector] convertToGL: ccpMidpoint(touchLocation1, touchLocation2)];
    _pinchCenter = [self convertToNodeSpace:centerGL];