zoukankan      html  css  js  c++  java
  • 计算Pan手势到指定点的角度

    计算Pan手势到指定点的角度

    效果图:

    源码:

    //
    //  RootViewController.m
    //  Circle
    //
    //  Copyright (c) 2014年 Y.X. All rights reserved.
    //
    
    #import "RootViewController.h"
    #import "Radian.h"
    #import "FrameAccessor.h"
    
    @interface RootViewController ()
    
    @property (nonatomic, strong) CALayer *layer;
    
    @end
    
    @implementation RootViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        // 显示参考用的view
        UIView *showView = [[UIView alloc] initWithFrame:CGRectMake(0, 20, 300, 300)];
        showView.layer.borderWidth = 1.f;
        showView.layer.cornerRadius = 150.f;
        showView.layer.borderColor = [UIColor redColor].CGColor;
        showView.center = self.view.center;
        [self.view addSubview:showView];
        
        // 新建layer
        _layer = [CALayer layer];
        _layer.backgroundColor = [UIColor blackColor].CGColor;
        
        // 重置锚点
        _layer.anchorPoint = CGPointMake(0.f, 0.f);
        
        // 设置layer的frame值(在showView正中间摆放)
        _layer.frame = CGRectMake(showView.middleX, showView.middleY, 150, 1);
        
        // 添加进showView中
        [showView.layer addSublayer:_layer];
        
        // 给showView添加手势
        UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
        [panGesture setMaximumNumberOfTouches:1];
        [showView addGestureRecognizer:panGesture];
    }
    
    - (void)handlePan:(UIPanGestureRecognizer *)recognizer
    {
        // 获取触摸点点
        CGPoint translation = [recognizer locationInView:self.view];
        
        // 计算触摸点到中心点的弧度
        CGFloat angleInRadians = [Radian tanA:translation.y - self.view.center.y
                                            B:translation.x - self.view.center.x];
        
        // layer的动画
        [CATransaction setDisableActions:YES];
        _layer.transform = CATransform3DMakeRotation(angleInRadians, 0.0, 0.0, 1.0);
    }
    
    @end

    以下3步非常关键:

    引入POP库设计阻尼动画

    效果如下:

    //
    //  RootViewController.m
    //  Circle
    //
    //  Copyright (c) 2014年 Y.X. All rights reserved.
    //
    
    #import "RootViewController.h"
    #import "Radian.h"
    #import "FrameAccessor.h"
    #import "POP.h"
    
    @interface RootViewController ()
    
    @property (nonatomic, strong) CALayer *layer;
    
    @end
    
    @implementation RootViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        // 显示参考用的view
        UIView *showView = [[UIView alloc] initWithFrame:CGRectMake(0, 20, 300, 300)];
        showView.layer.borderWidth = 1.f;
        showView.layer.cornerRadius = 150.f;
        showView.layer.borderColor = [UIColor redColor].CGColor;
        showView.center = self.view.center;
        [self.view addSubview:showView];
        
        // 新建layer
        _layer = [CALayer layer];
        _layer.backgroundColor = [UIColor blackColor].CGColor;
        
        // 重置锚点
        _layer.anchorPoint = CGPointMake(0.f, 0.f);
        
        // 设置layer的frame值(在showView正中间摆放)
        _layer.frame = CGRectMake(showView.middleX, showView.middleY, 150, 1);
        
        // 添加进showView中
        [showView.layer addSublayer:_layer];
        
        // 给showView添加手势
        UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
        [panGesture setMaximumNumberOfTouches:1];
        [showView addGestureRecognizer:panGesture];
    }
    
    - (void)handlePan:(UIPanGestureRecognizer *)recognizer
    {
        // 获取触摸点点
        CGPoint translation = [recognizer locationInView:self.view];
    
        // 将度数转换为弧度
    #define   RADIAN(degrees)  ((M_PI * (degrees))/ 180.f)
        
        // 将弧度转换为度数
    #define   DEGREES(radian)  ((radian) * 180.f / M_PI)
    
        
        if(recognizer.state == UIGestureRecognizerStateChanged)
        {
            // 计算触摸点到中心点的弧度
            CGFloat angleInRadians = [Radian tanA:translation.y - self.view.center.y
                                                B:translation.x - self.view.center.x];
            
            POPBasicAnimation *positionAnimation = 
            [POPBasicAnimation animationWithPropertyNamed:kPOPLayerRotation];
            // 设置速度动画
            positionAnimation.toValue = @(angleInRadians);
            positionAnimation.duration = 0.01f;
            
            // 添加动画
            [_layer pop_removeAnimationForKey:@"kPOPLayerRotation"];
            [_layer pop_addAnimation:positionAnimation
                              forKey:@"kPOPLayerRotation"];
        }
        
        // 拖拽动作结束
        if(recognizer.state == UIGestureRecognizerStateEnded)
        {
            // 计算触摸点到中心点的弧度
            CGFloat angleInRadians = [Radian tanA:translation.y - self.view.center.y
                                                B:translation.x - self.view.center.x];
            
            // 计算出移动的速度
            CGPoint velocity = [recognizer velocityInView:self.view];
            CGFloat x = velocity.x;
            CGFloat y = velocity.y;
            
            // 衰退减速动画
            POPDecayAnimation *positionAnimation = 
            [POPDecayAnimation animationWithPropertyNamed:kPOPLayerRotation];
            positionAnimation.velocity = @(+(x*ABS(cosf(angleInRadians)/100.f) +
                                             y*ABS(sinf(angleInRadians)/100.f)));
            
            // 添加动画
            [_layer pop_removeAnimationForKey:@"kPOPLayerRotation"];
            [_layer pop_addAnimation:positionAnimation
                              forKey:@"layerPositionAnimation"];
        }
    }
    
    @end

    重点地方:

    其实,实现这个效果真心挺难的......

  • 相关阅读:
    css的网页布局案例
    position定位及实际应用
    float浮动以及案例演示
    第二十三节 margin合并实例
    第二十二节 margin合并
    第二十一节 margin技巧
    第二十节 盒子练习
    第十九节 盒子真实尺寸
    第十八节 盒子案例
    第十七节 盒子模型
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/3782207.html
Copyright © 2011-2022 走看看