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;
    }
  • 相关阅读:
    IIS使用十大原则,(IIS过期时间,IIS缓存设置) 【转载】
    微软中国的相关研发团队 交流平台
    Excel文件减肥和加速
    二进制与字符串之间的转换
    调度模式·WorkerChannelRequest
    引用Hibernate的Java桌面程序打包方法
    [收藏]Open CASCADE
    需要天天读月月读年年读的书
    geotools的dotnet版本
    FC4 下ns2.28的安装 (zz)
  • 原文地址:https://www.cnblogs.com/dengzhuli/p/4513459.html
Copyright © 2011-2022 走看看