Transfrom3D旋转

本文详细介绍使用Core Animation实现3D旋转效果,并结合手势识别实现缩放与点击事件。通过CATransform3D方法设置旋转、缩放及偏移量,实现一个六面体的3D展示,并添加了拖动、缩放和点击的手势识别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果如下,一个3D旋转支持缩放点击事件的效果


先简单介绍 Transfrom3D的一些方法

1.针对偏移量设置      CATransform3DMakeTranslation(x,y,z)

         x :x轴偏移位置  向下正数

         y :y轴偏移位置  向右正数

         z :z轴偏移位置  向外正数

2.针对缩放设置       CATransform3DMakeScale(x,y,z)

         x y z 分别对应方向的缩放

3.针对旋转设置      

         CATransfrom3DMakeRotation(angle,x,y,z)

         angle  旋转弧度  iOS 中所有的都是指弧度(注意)

         x,y,z 分别沿各轴方向旋转 取值  -1 ------ 1

4.针对叠加设置

        CATransfrom3DMakeRotate(transfrom3D,angle,x,y,z)

       一个类似于叠加 

      transfrom3D  经过变换之后的 上述几个返回的都是transfrom3D类型的

      angle 旋转弧度

      x,y,z 旋转

5.具体实现思路

     1)构建正方体 调整旋转偏移的位置

     2)设置每个面显示的内容

     //正
    [self addCubeLayer:@[@0, @0, @(_side/2), @0, @0, @0, @0,@"hinata.jpg"]];
    //背
    [self addCubeLayer:@[@0, @0, @(-_side/2), @(M_PI), @0, @0, @0,@"konan.jpg"]];
    //左
    [self addCubeLayer:@[@(-_side/2), @0, @0, @(-M_PI_2), @0, @1, @0,@"sakula.jpg"]];
    //右
    [self addCubeLayer:@[@(_side/2), @0, @0, @(M_PI_2), @0, @1, @0,@"tenten.jpg"]];
    //上
    [self addCubeLayer:@[@0, @(-_side/2), @0, @(-M_PI_2), @1, @0, @0,@"konan.jpg"]];
    //下
    [self addCubeLayer:@[@0, @(_side/2), @0, @(M_PI_2), @1, @0, @0,@"konan.jpg"]];
   
    CATransform3D transform3D = CATransform3DIdentity;
    transform3D.m34 = -1.0/2000;
    _cubeLayer.sublayerTransform = transform3D;
   
    [self.layer addSublayer:_cubeLayer];


   //添加sublayers
- (void)addCubeLayer:(NSArray *)params
{
    CALayer *gradient = [CALayer layer];
    gradient.contentsScale = [UIScreen mainScreen].scale;
    gradient.bounds = CGRectMake(0, 0, _side, _side);
    gradient.position = self.center;
    gradient.contents = (id)[UIImage imageNamed:params[7]].CGImage;

    //抗锯齿
    gradient.shouldRasterize = YES;
   
    CATransform3D trans3D = CATransform3DMakeTranslation([params[0] floatValue], [params[1] floatValue], [params[2] floatValue]);
    CATransform3D rotate3D = CATransform3DRotate(trans3D , [params[3] floatValue], [params[4] floatValue], [params[5] floatValue], [params[6] floatValue]);
    CATransform3D transform3D = rotate3D;
    
    gradient.transform = transform3D;
   
    [_cubeLayer addSublayer:gradient];
}

     3)添加手势

      [self addGestureRecognizer:[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panRotate:)]];
       
        UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(scale:)];
        [pinchRecognizer setDelegate:self];
        [self addGestureRecognizer: pinchRecognizer];
       
        UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapRecogn:)];
        [tapRecognizer setDelegate:self];
        [self addGestureRecognizer: tapRecognizer];

       #pragma mark - PanGesture
- (void)panRotate:(UIPanGestureRecognizer *)ges
{
    static CGPoint start;
    if (ges.state == UIGestureRecognizerStateBegan) {
        start = [ges locationInView:self];
    } else if (ges.state == UIGestureRecognizerStateChanged) {
        CATransform3D transform = _cubeLayer.sublayerTransform;
        _rotMatrix = GLKMatrix4MakeWithArray((void *)&transform);
       
        CGPoint loc = [ges locationInView:self];
        CGPoint diff = CGPointMake(start.x-loc.x, start.y-loc.y);
       
        float rotX = 1 * GLKMathDegreesToRadians(diff.y/2.0);
        float rotY = -1 * GLKMathDegreesToRadians(diff.x/2.0);
       
        bool isInvertible;
        GLKVector3 xAxis = GLKMatrix4MultiplyVector3(GLKMatrix4Invert(_rotMatrix, &isInvertible),
                                                     GLKVector3Make(1, 0, 0));
        _rotMatrix = GLKMatrix4Rotate(_rotMatrix, rotX, xAxis.x, xAxis.y, xAxis.z);
        GLKVector3 yAxis = GLKMatrix4MultiplyVector3(GLKMatrix4Invert(_rotMatrix, &isInvertible),
                                                     GLKVector3Make(0, 1, 0));
        _rotMatrix = GLKMatrix4Rotate(_rotMatrix, rotY, yAxis.x, yAxis.y, yAxis.z);
       
        _cubeLayer.sublayerTransform = *((CATransform3D *)&_rotMatrix);
       
        start = loc;
    }
}

-(void)scale:(id)sender {
   
    if([(UIPinchGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan) {
       
        _lastScale = 1.0;
       
    }
   
    if ([(UIPinchGestureRecognizer*)sender state] == UIGestureRecognizerStateChanged) {
       
        //Scale的仿射变换,只改变缩放比例,其他仿射变换底下会说
       
//        CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);
       
        CATransform3D newTransform = CATransform3DMakeScale([(UIPinchGestureRecognizer*)sender scale], [(UIPinchGestureRecognizer*)sender scale], [(UIPinchGestureRecognizer*)sender scale]);
       
        _cubeLayer.sublayerTransform = newTransform;
       
        _lastScale = [(UIPinchGestureRecognizer*)sender scale];
       
    }
   
}
-(void)tapRecogn:(id)sender {
   
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"描述" message:@"这是一张图片" preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];
        UIAlertAction *action2 = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
        [alert addAction:action1];
        [alert addAction:action2];
   
    [self.window.rootViewController presentViewController:alert animated:YES completion:nil];
   
}

至此完成











### 使用 CSS Transform 实现 3D 旋转效果 为了创建一个基本的 3D 旋转变换,`transform` 属性提供了多种函数来操作元素的空间位置和方向。对于 3D 变换来说,最常用的属性包括 `rotateX()`、`rotateY()` 和 `rotateZ()` 函数。 #### 创建简单的立方体结构 首先定义 HTML 结构,构建六个面组成的立方体: ```html <div class="scene"> <div class="cube"> <div class="face front">Front</div> <div class="face back">Back</div> <div class="face left">Left</div> <div class="face right">Right</div> <div class="face top">Top</div> <div class="face bottom">Bottom</div> </div> </div> ``` #### 设置基础样式与视角 为了让这个三维物体看起来有立体感,需要给父容器 `.scene` 添加透视效果,并设定其距离屏幕的距离(即 perspective 值),这使得最终呈现出来的图像更接近真实世界中的视觉感受[^1]。 ```css .scene { width: 200px; height: 200px; margin: auto; position: relative; perspective: 800px; /* 设定观察者到投影平面之间的距离 */ } .cube { width: 100%; height: 100%; position: absolute; transform-style: preserve-3d; } ``` #### 配置各个面的位置关系 通过调整每个面的定位以及应用相应的 rotate 和 translate 方法,可以让这些 div 正确排列成一个完整的正方体形状[^2]。 ```css .face { position: absolute; width: 200px; height: 200px; background-color: rgba(255, 69, 0, .7); border: 1px solid black; } .front { transform: translateZ(100px); } .back { transform: rotateY(180deg) translateZ(100px); } .left { transform: rotateY(-90deg) translateZ(100px); } .right { transform: rotateY(90deg) translateZ(100px); } .top { transform: rotateX(90deg) translateZ(100px); } .bottom{ transform: rotateX(-90deg) translateZ(100px);} ``` #### 动态控制旋转角度 最后一步是让这个立方体能够响应用户的交互动作而发生转动。这里可以通过 JavaScript 或者纯 CSS 来完成。下面是一个基于鼠标悬停事件触发自动连续自转的例子。 ```css /* 当鼠标指针位于场景之上时启动无限循环动画 */ .scene:hover .cube { animation-name: spin; animation-duration: 5s; animation-timing-function: linear; animation-iteration-count: infinite; } @keyframes spin { from { transform: rotateX(0deg) rotateY(0deg); } to { transform: rotateX(360deg) rotateY(360deg); } } ``` 上述代码片段展示了如何利用 CSS 的 `transform` 属性配合其他相关特性轻松实现复杂的 3D 图形变换效果。值得注意的是,在实际开发过程中还需要考虑不同浏览器间的兼容性问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值