如何拖动旋转和缩放的 CALayer?
How to drag a CALayer that is rotated and scaled?
我在 CALayer 中有一个图像(使用 CALayers 内容 属性)。 CALayer 有一个变换 属性 可以用来缩放和旋转。当 CALayer 静止时,我可以毫无困难地使用该变换。
但是当我尝试拖动 CALayer(使用 mouseDragged:(NSEvent *)theEvent)时,它就会崩溃(图像在我拖动时变平)。
-(void)mouseDragged:(NSEvent *)theEvent {
CGPoint loc = [self convertPoint:theEvent.locationInWindow fromView:nil];
CGPoint deltaLoc = ccpSub(loc, downLoc); // subtract two points
CGPoint newPos = ccpAdd(startPos, deltaLoc); // adds two points
[layer changePosition:newPos];
...
}
图层中
-(void)changePosition:(CGPoint)newPos {
//prevent unintended animation actions
self.actions = @{@"position": [NSNull null]};
CGSize size = self.frame.size;
CGRect newRect = CGRectMake(newPos.x, newPos.y, size.width, size.height);
self.frame = newRect;
}
问题是我使用CALayer的框架在拖动时动态改变CALayer的位置,但是当旋转角度不为零时,框架不再平行于x和y轴。解决此问题的最佳方法是什么?
一种方法是为每个增量运动重新生成变换。
-(void)mouseDragged:(CGPoint)deltaLoc start:(CGPoint)startPos {
CGPoint newPos = ccpAdd(startPos, deltaLoc);
[self changePosition:newPos];
}
-(void)changePosition:(CGPoint)newPos {
//prevent unintended animation actions
self.actions = @{@"position": [NSNull null]};
double angle = [[self valueForKeyPath: @"transform.rotation"] doubleValue];
double scaleX = [[self valueForKeyPath: @"transform.scale.x"] doubleValue];
double scaleY = [[self valueForKeyPath: @"transform.scale.y"] doubleValue];
self.transform = CATransform3DIdentity;
CGSize size = self.frame.size;
CGRect newRect = CGRectMake(newPos.x, newPos.y, size.width, size.height);
self.frame = newRect;
[self applyTransformRotation:angle scale:ccp(scaleX, scaleY)];
}
-(void)applyTransformRotation:(double)angle scale:(CGPoint)scale {
self.transform = CATransform3DMakeRotation(angle, 0, 0, 1);
self.transform = CATransform3DScale(self.transform, scale.x, scale.y, 1);
}
我不知道这是否是最有效的方法,但它确实有效。
我在 CALayer 中有一个图像(使用 CALayers 内容 属性)。 CALayer 有一个变换 属性 可以用来缩放和旋转。当 CALayer 静止时,我可以毫无困难地使用该变换。
但是当我尝试拖动 CALayer(使用 mouseDragged:(NSEvent *)theEvent)时,它就会崩溃(图像在我拖动时变平)。
-(void)mouseDragged:(NSEvent *)theEvent {
CGPoint loc = [self convertPoint:theEvent.locationInWindow fromView:nil];
CGPoint deltaLoc = ccpSub(loc, downLoc); // subtract two points
CGPoint newPos = ccpAdd(startPos, deltaLoc); // adds two points
[layer changePosition:newPos];
...
}
图层中
-(void)changePosition:(CGPoint)newPos {
//prevent unintended animation actions
self.actions = @{@"position": [NSNull null]};
CGSize size = self.frame.size;
CGRect newRect = CGRectMake(newPos.x, newPos.y, size.width, size.height);
self.frame = newRect;
}
问题是我使用CALayer的框架在拖动时动态改变CALayer的位置,但是当旋转角度不为零时,框架不再平行于x和y轴。解决此问题的最佳方法是什么?
一种方法是为每个增量运动重新生成变换。
-(void)mouseDragged:(CGPoint)deltaLoc start:(CGPoint)startPos {
CGPoint newPos = ccpAdd(startPos, deltaLoc);
[self changePosition:newPos];
}
-(void)changePosition:(CGPoint)newPos {
//prevent unintended animation actions
self.actions = @{@"position": [NSNull null]};
double angle = [[self valueForKeyPath: @"transform.rotation"] doubleValue];
double scaleX = [[self valueForKeyPath: @"transform.scale.x"] doubleValue];
double scaleY = [[self valueForKeyPath: @"transform.scale.y"] doubleValue];
self.transform = CATransform3DIdentity;
CGSize size = self.frame.size;
CGRect newRect = CGRectMake(newPos.x, newPos.y, size.width, size.height);
self.frame = newRect;
[self applyTransformRotation:angle scale:ccp(scaleX, scaleY)];
}
-(void)applyTransformRotation:(double)angle scale:(CGPoint)scale {
self.transform = CATransform3DMakeRotation(angle, 0, 0, 1);
self.transform = CATransform3DScale(self.transform, scale.x, scale.y, 1);
}
我不知道这是否是最有效的方法,但它确实有效。