zoukankan      html  css  js  c++  java
  • transform3D实现翻页效果

    ---恢复内容开始---

    闲篇 最近升级了下百度音乐,唯一的感觉就是动画效果很炫丽。我不是个对产品很敏感的人,但是这段时间观察一些大厂的产品发现现在的APP越来越重视动画效果了。大家可能没有注意过,连支付宝的一个很边缘很边缘的小角落(“财富 ->芝麻信用分 ->信用猜猜”)动画也是很炫的。随着手机硬件的增强以及广大苦逼程序员的不懈努力与钻研,APP的会越来越强调交互性,物理效果(UIDynamic)和动画效果(CoreAnimation)会越来越受欢迎。

    准备 好吧,闲话不说了,首先跟大家坦白一下,今天的内容会涉及到图形学知识,但是我的图形学知识都完全还给老师了,所以!你懂得~ 关于矩阵的知识我可能说的不清楚。大家可以到网上找一下相关的博客,很多人写的还是很好的。  

    开始 首先为了能让大家更好的了解整个项目,先给大家先简单介绍一下各个类。具体的代码会在下文介绍。我图简便用的是故事板(storyboard)拖的一个collectionView控制器,并将整个控制器的类指定为CollectionViewController。又建立一个自定义布局类继承自UICollectionViewFlowLayout类。

    #import "CollectionViewController.h"
    
    @implementation CollectionViewController
    
    static NSString * const reuseIdentifier = @"Cell";
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        //补充一下:与tableView 不同,collectionView和view不适同一个对象。tableView 和view是同一个对象
        self.collectionView.backgroundColor=[UIColor whiteColor];
        
        [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier];
    }
    
    #pragma mark <UICollectionViewDataSource>
    
    - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
    {
        return 1;
    }
    
    - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
    {
        return 100;
    }
    
    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
        
        UICollectionViewCell  *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
    
        //把cell 设置为稍微有点圆角,能好看一点
        cell.layer.cornerRadius=4;
        cell.layer.masksToBounds=YES;
        
        //随机颜色
        cell.backgroundColor=[UIColor colorWithRed:(arc4random()%255)/(1.0*255) green:(arc4random()%255)/(1.0*255) blue:(arc4random()%255)/(1.0*255) alpha:1];
        return cell;
    }

    下面主要来看一下布局类,以及布局类的打印信息。通过打印信息我们可以知道各个方法的调用顺序,了解调用顺序对开发至关重要。我们先来看一下打印信息:

    2015-05-19 00:32:07.460 翻页效果[13957:392865] prepareLayout

    2015-05-19 00:32:07.461 翻页效果[13957:392865] layoutAttributesForElementsInRect

    2015-05-19 00:32:08.530 翻页效果[13957:392865] shouldInvalidateLayoutForBoundsChange

    2015-05-19 00:32:08.531 翻页效果[13957:392865] prepareLayout

    2015-05-19 00:32:08.531 翻页效果[13957:392865] layoutAttributesForElementsInRect

    2015-05-19 00:32:08.553 翻页效果[13957:392865] shouldInvalidateLayoutForBoundsChange

    然后我们再来看一下layout 方法,layout方法我加了详细的注释,方便大家阅读。

    //并不是一下子全部都返回出来 而是逐渐的提供
    - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
    {
        NSLog(@"layoutAttributesForElementsInRect");
        
        //首先将系统的特征数组取出
        NSArray *attrs=[super layoutAttributesForElementsInRect:rect];
        
        //这两个数据下面会用到,用到再解释
        CGFloat halfW=self.collectionView.bounds.size.width/2;
        CGFloat orx=self.collectionView.contentOffset.x;
        
        //将这次提供的特征数组 一个一个的将特征取出来进行社会主义大改造
        for  (UICollectionViewLayoutAttributes *attr in attrs)
        {
            
            //计算attr中心的距离可视中心的距离
            CGFloat distance=(orx+halfW)-CGRectGetMidX(attr.frame);
            
            //这里就是用到了上面定义个数据,计算出一个比例,好供我们再下面进行计算,离屏幕中心越远越大
            CGFloat scale=distance/halfW;
            
            //也就是说这个 item 的身体至少一半在屏幕内时我们才去改变它的布局特征
            if (scale<=1)
            {
                //计算各个attr 的M34 什么事m34? 它是transform3D的一个属性
                // m11 (X 缩放)   m12 (Y 切变)   m13 (     )   m14 (     )
                // m21 (X 切变)   m22(Y 缩放)    m23 (     )   m24 (     )
                // m33 (      )  m32 (      )   m33 (     )   m34 (最重要的M34 具有一种倾斜效果,有正负之分方向不同)
                // m41 (X 平移)   m42 (Y 平移)   m43 (Z 平移)   m44 (     )
                
                
                //创建一个单位矩阵
                CATransform3D rotationTrans=CATransform3DIdentity;
                
                //单位矩阵的M34 改为-0.004 数字大家觉得合适即可
                rotationTrans.m34=-0.004;
                
                //计算各个attr 的y轴旋转角度 根据比例来计算,离屏幕中心越远旋转角度越大 这里表示绕Y轴旋转
                rotationTrans=CATransform3DRotate(rotationTrans, M_PI_4*(scale), 0.0, 1, 0.0);
                
                // 计算各个attr的缩放
                CGFloat factor =0.3;
                CGFloat zoom=1+factor-ABS(scale)*factor;//控制再1~1.2倍
                CATransform3D zoomTrans=CATransform3DMakeScale(zoom, zoom, 1.0);
                
                //拟合各个trans
                attr.transform3D=CATransform3DConcat(rotationTrans, zoomTrans);
                
                //计算各个attr 的透明度
                CGFloat alp=1+0.1-ABS(scale);
             
                alp>1?(attr.alpha=1):(attr.alpha=alp);
            }
            else
            {
                attr.alpha=0;
            }
        }
    
        return attrs;
    }
  • 相关阅读:
    Mac php使用gd库出错 Call to undefined function imagettftext()
    centos 使用 locate
    Mac HomeBrew 安装 mysql
    zsh 命令提示符 PROMPT
    新的开始
    Java 面试题分析
    Java NIO Show All Files
    正确使用 Volatile 变量
    面试题整理 2017
    有10阶梯, 每次走1,2 or 3 阶,有多少种方式???
  • 原文地址:https://www.cnblogs.com/dengzhuli/p/4513459.html
Copyright © 2011-2022 走看看