@@ -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