Skip to content

Commit 0a51cfa

Browse files
committed
Optimize point control
1 parent 85e7809 commit 0a51cfa

File tree

1 file changed

+61
-30
lines changed

1 file changed

+61
-30
lines changed

CubicBezier/ViewController.m

Lines changed: 61 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@ @interface ViewController()
1717
// 标识两个圆点的松开状态
1818
@property (assign) BOOL roundButton1Up;
1919
@property (assign) BOOL roundButton2Up;
20+
@property (assign) BOOL blankTouchUp;
2021

21-
@property (assign) CGPoint bezierPoint1;
22-
@property (assign) CGPoint bezierPoint2;
22+
@property (assign) CGPoint bezierDataPoint1;
23+
@property (assign) CGPoint bezierDataPoint2;
2324

2425
@property (strong) CALayer *previewLayer1;
2526
@property (strong) CALayer *previewLayer2;
@@ -32,8 +33,14 @@ @interface ViewController()
3233

3334
@implementation ViewController
3435

35-
// 坐标转换
36+
#pragma mark -
37+
38+
/// 比较两点间距离
39+
- (float)distanceBetween:(CGPoint)p1 and:(CGPoint)p2{
40+
return sqrt(pow(p2.x-p1.x,2)+pow(p2.y-p1.y,2));
41+
}
3642

43+
/// 坐标转换:转换成相对画板的坐标
3744
- (CGPoint)boardPoint:(CGPoint)p{
3845
return CGPointMake(self.bezierBoardView.frame.origin.x + p.x * 200.0,
3946
self.bezierBoardView.frame.origin.y + p.y * 200.0);
@@ -57,8 +64,8 @@ - (void)viewDidLoad {
5764
self.bezierBoardLeftTextField.frameRotation = 90;
5865

5966
// 初始点
60-
self.bezierPoint1 = CGPointMake(0.2, 0.7);
61-
self.bezierPoint2 = CGPointMake(0.7, 0.2);
67+
self.bezierDataPoint1 = CGPointMake(0.2, 0.7);
68+
self.bezierDataPoint2 = CGPointMake(0.7, 0.2);
6269

6370
// 控制点颜色
6471
NSColor *color1 = [NSColor colorWithRed:244 / 255.0 green:0 blue:221 / 255.0 alpha:1];
@@ -73,12 +80,12 @@ - (void)viewDidLoad {
7380
[self.view addSubview:rightZero];
7481

7582
// 动态点
76-
CGPoint point1 = [self boardPoint:self.bezierPoint1];
83+
CGPoint point1 = [self boardPoint:self.bezierDataPoint1];
7784
self.roundButton1 = [[RoundButton alloc] initWithFrame:NSMakeRect(point1.x + self.bezierBoardView.frame.origin.x - RoundButtonDiameter / 2.0, point1.y + self.bezierBoardView.frame.origin.y - RoundButtonDiameter / 2.0, RoundButtonDiameter, RoundButtonDiameter)];
7885
self.roundButton1.backgroundColor = color1;
7986
[self.view addSubview:self.roundButton1];
8087

81-
CGPoint point2 = [self boardPoint:self.bezierPoint2];
88+
CGPoint point2 = [self boardPoint:self.bezierDataPoint2];
8289
self.roundButton2 = [[RoundButton alloc] initWithFrame:NSMakeRect(point2.x + self.bezierBoardView.frame.origin.x - RoundButtonDiameter / 2.0, point2.y + self.bezierBoardView.frame.origin.y - RoundButtonDiameter / 2.0, RoundButtonDiameter, RoundButtonDiameter)];
8390
self.roundButton2.backgroundColor = color2;
8491
[self.view addSubview:self.roundButton2];
@@ -122,22 +129,48 @@ - (void)setRepresentedObject:(id)representedObject {
122129

123130
-(void)mouseDown:(NSEvent *)theEvent{
124131
if (NSPointInRect(theEvent.locationInWindow, self.roundButton1.frame)) {
132+
// 如果点中第一个点
125133
self.roundButton1Up = YES;
126134
}else if(NSPointInRect(theEvent.locationInWindow, self.roundButton2.frame)){
135+
// 如果点中的第二个点
127136
self.roundButton2Up = YES;
137+
}else if(NSPointInRect(theEvent.locationInWindow, self.bezierBoardView.frame)){
138+
// 如果点的空白地方(画板内)
139+
self.blankTouchUp = YES;
128140
}
129141
NSLog(@"mouseDown:%@",NSStringFromPoint(theEvent.locationInWindow));
130142
}
131143

132144
-(void)mouseDragged:(NSEvent *)theEvent{
145+
[self updateBezierBoard:theEvent];
146+
NSLog(@"mouseDragged");
147+
}
148+
149+
-(void)mouseUp:(NSEvent *)theEvent{
150+
[self updateBezierBoard:theEvent];
151+
152+
// 清除状态
153+
self.roundButton1Up = NO;
154+
self.roundButton2Up = NO;
155+
self.blankTouchUp = NO;
133156

157+
NSLog(@"mouseUp");
158+
}
159+
160+
-(void)mouseMoved:(NSEvent *)event {
161+
CGPoint bezierPoint = [self bezierPoint:event.locationInWindow];
162+
[self updateBezierBoardLabels:bezierPoint];
163+
}
164+
165+
- (void)updateBezierBoard:(NSEvent *)theEvent {
134166
// 贝塞尔曲线点
135167
CGPoint bezierPoint = [self bezierPoint:theEvent.locationInWindow];
136-
168+
137169
// 计算出 圆点 Center
138170
CGPoint roundButtonCenter = CGPointMake(theEvent.locationInWindow.x - RoundButtonDiameter / 2.0, theEvent.locationInWindow.y - RoundButtonDiameter / 2.0);
139171
CGPoint roundButtonCenterForBoard = [self.view convertPoint:theEvent.locationInWindow toView:self.bezierBoardView];
140172

173+
// 边界判断
141174
if (bezierPoint.x < 0) {
142175
bezierPoint.x = 0;
143176
roundButtonCenter.x = self.bezierBoardView.frame.origin.x - RoundButtonDiameter / 2.0;
@@ -150,39 +183,37 @@ -(void)mouseDragged:(NSEvent *)theEvent{
150183
}
151184

152185
// 给予新的位置和重绘点,记录贝塞尔曲线点
153-
CGRect newFrame = CGRectMake(roundButtonCenter.x,
154-
roundButtonCenter.y,
155-
RoundButtonDiameter,
156-
RoundButtonDiameter);
186+
CGRect newFrame = CGRectMake(roundButtonCenter.x, roundButtonCenter.y, RoundButtonDiameter, RoundButtonDiameter);
157187
if (self.roundButton1Up) {
188+
// 按住到第一个点的
158189
self.roundButton1.frame = newFrame;
159190
self.bezierBoardView.point1 = roundButtonCenterForBoard;
160-
self.bezierPoint1 = bezierPoint;
191+
self.bezierDataPoint1 = bezierPoint;
161192
}else if (self.roundButton2Up){
193+
// 按住到第二个点的
162194
self.roundButton2.frame = newFrame;
163195
self.bezierBoardView.point2 = roundButtonCenterForBoard;
164-
self.bezierPoint2 = bezierPoint;
196+
self.bezierDataPoint2 = bezierPoint;
197+
}else if(self.blankTouchUp) {
198+
// 没点到点上,查找最近的点
199+
double dist1 = [self distanceBetween:roundButtonCenter and:self.bezierDataPoint1];
200+
double dist2 = [self distanceBetween:roundButtonCenter and:self.bezierDataPoint2];
201+
if (dist1 < dist2) {
202+
self.roundButton1.frame = newFrame;
203+
self.bezierDataPoint1 = roundButtonCenter;
204+
self.bezierBoardView.point1 = roundButtonCenterForBoard;
205+
}else{
206+
self.roundButton2.frame = newFrame;
207+
self.bezierDataPoint2 = roundButtonCenter;
208+
self.bezierBoardView.point2 = roundButtonCenterForBoard;
209+
}
165210
}
166211

167-
self.bezierTextField.stringValue = [NSString stringWithFormat:@"%.2f,%.2f,%.2f,%.2f",self.bezierPoint1.x,self.bezierPoint1.y,self.bezierPoint2.x,self.bezierPoint2.y];
212+
self.bezierTextField.stringValue = [NSString stringWithFormat:@"%.2f,%.2f,%.2f,%.2f",self.bezierDataPoint1.x,self.bezierDataPoint1.y,self.bezierDataPoint2.x,self.bezierDataPoint2.y];
168213

169214
[self.view setNeedsDisplay:YES];
170-
171-
NSLog(@"mouseDragged:%@",NSStringFromPoint(bezierPoint));
172-
}
173-
174-
-(void)mouseUp:(NSEvent *)theEvent{
175-
self.roundButton1Up = NO;
176-
self.roundButton2Up = NO;
177-
NSLog(@"mouseUp");
178-
}
179-
180-
-(void)mouseMoved:(NSEvent *)event {
181-
CGPoint bezierPoint = [self bezierPoint:event.locationInWindow];
182-
[self updateBezierBoardLabels:bezierPoint];
183215
}
184216

185-
186217
- (IBAction)goAnimation:(id)sender{
187218

188219
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position.x"];
@@ -195,7 +226,7 @@ - (IBAction)goAnimation:(id)sender{
195226
CABasicAnimation *animation2 = [CABasicAnimation animationWithKeyPath:@"position.x"];
196227
animation2.toValue = @(self.previewLayerXPosition);
197228
animation2.duration = self.speedSlider.doubleValue;
198-
animation2.timingFunction = [CAMediaTimingFunction functionWithControlPoints:self.bezierPoint2.x :self.bezierPoint2.y :self.bezierPoint2.x :self.bezierPoint2.y];
229+
animation2.timingFunction = [CAMediaTimingFunction functionWithControlPoints:self.bezierDataPoint2.x :self.bezierDataPoint2.y :self.bezierDataPoint2.x :self.bezierDataPoint2.y];
199230
animation2.fillMode = kCAFillModeForwards;
200231
animation2.removedOnCompletion = NO;
201232
[self.previewLayer2 addAnimation:animation2 forKey:nil];

0 commit comments

Comments
 (0)