css3的3d旋转为啥会导致元素变大?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了css3的3d旋转为啥会导致元素变大?相关的知识,希望对你有一定的参考价值。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
bodymargin: 0;
.box
position: relative;
margin: 0 auto;
width: 1000px;
-webkit-perspective:1000;

ul,limargin: 0;padding: 0;
lilist-style: none;
imgborder:0; vertical-align: bottom;
.box ul
transition:all .5s linear;
transform-style: preserve-3d;
position: relative;

.box ul li
height: 300px;
overflow: hidden;
transition:all .5s linear;
position: absolute;
width: 1000px;
backface-visibility:hidden;

.box ul li:nth-child(1)
transform:rotate3d(0,0,0,0deg);
background-color: green;
z-index: 2;

.box ul li:nth-child(2)
transform-origin:top;
transform:rotate3d(1,0,0,-90deg);
background-color: pink;
top: 300px;

.box:hover ul
transform:rotate3d(1,0,0,90deg);

</style>
</head>
<body>
<div class="box">
<ul>
<li></li>
<li></li>
</ul>
</div>
</body>
</html>

这是demo的完整代码,复制到chrome浏览器中就可以运行,哪位大神帮忙看看是什么原因。
鼠标移上去后粉色的长方形会变得很大,这是为什么?

3d旋转,顾名思义就是立体旋转,涉及到三个轴向,x,y, z,2D旋转只有两个轴向,x,y关键就在z轴呢,我来解释下z轴

z轴就是物体远近,近大远小,所以会使元素看上去会变大,这个是正常的,css3 3D还有个属性就是-webkit-perspective:这个的含义就是景深,就是这个元素离你的眼睛多远,这两个属性有一定的联系,
参考技术A 2个li标签的位置对于XYZ的3轴交汇点有问题,加上3D视角的作用 所以会变大,你写的时候就改在处理2个li的位置的时候以交互点 也就是正中心的轴点为基础追问

能帮我指出具体应该修改哪里吗?我想让元素翻转后还处在原来的位置,轴点应该在重心处,但是我不知道哪个地方导致了轴点不对。

参考技术B 不是元素变大了 而是元素离你更近了, 你可以试着拉远Z轴
顺便推荐你看下3D里面 摄像机的概念
参考技术C 翻转子元素的top值有问题,你的转轴一定要用你用的那么考虑清楚反正后变大问题追问

为什么top值会影响到大小呢?

为啥此裁剪代码会导致图像旋转?

【中文标题】为啥此裁剪代码会导致图像旋转?【英文标题】:Why Does this Cropping Code Result in a Rotated Image?为什么此裁剪代码会导致图像旋转? 【发布时间】:2012-10-08 14:48:28 【问题描述】:

这个问题的标题应该很清楚。下面的代码执行裁剪操作,然后在图像视图中显示新裁剪的照片。问题是图像一旦被裁剪,就会以与原始源图像不同的方向显示。这是为什么?我该怎么办?

-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info

[self.popoverController dismissPopoverAnimated:true];

NSString *mediaType = [info
                       objectForKey:UIImagePickerControllerMediaType];
[self dismissModalViewControllerAnimated:YES];
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) 
    UIImage *image = [info
                      objectForKey:UIImagePickerControllerOriginalImage];


    CGRect rect = CGRectMake(0, ((image.size.height - image.size.width) / 2), image.size.width, image.size.width);


    CGImageRef subImageRef = CGImageCreateWithImageInRect(image.CGImage, rect);
    CGRect smallBounds = CGRectMake(rect.origin.x, rect.origin.y, CGImageGetWidth(subImageRef), CGImageGetHeight(subImageRef));

    UIGraphicsBeginImageContext(smallBounds.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextDrawImage(context, smallBounds, subImageRef);
    croppedImage = [UIImage imageWithCGImage:subImageRef];
    UIGraphicsEndImageContext();

    imageView.image = croppedImage;

*编辑

根据 cmets 表明问题的根本原因是删除了 EXIF 标记,我尝试使用以下代码更正方向。这仍然不能解决问题,但我认为这是朝着正确方向迈出的一步。也许它会帮助某人为这个问题提出一个新的答案。

if (image.imageOrientation == UIImageOrientationLeft) 
        NSLog(@"left");
        CGContextRotateCTM (context, radians(90));

     else if (image.imageOrientation == UIImageOrientationRight) 
        NSLog(@"right");
        CGContextRotateCTM (context, radians(-90));

     else if (image.imageOrientation == UIImageOrientationUp) 
        NSLog(@"up");
        // NOTHING
     else if (image.imageOrientation == UIImageOrientationDown) 
        NSLog(@"down");
        CGContextRotateCTM (context, radians(-180.));
    

见https://***.com/a/5184134/549273

【问题讨论】:

我相信Apple使用EXIF标签来实现照片的旋转。您的新图像可能缺少该方向信息,因此显示不正确。 图片来自 iPhone 摄像头,所以它应该有一个 EXIF 标签。 在将 exif 数据绘制到上下文中时,您没有将其考虑在内。图像将始终处于其“原始”方向。 UIImage 根据 exif 旋转它。除了您将其原始绘制到没有 exif 数据的新 UIImage 中,因此“未旋转”。 有没有办法通过上下文保存EXIF数据? 【参考方案1】:

我认为您最好的选择是从传入的图像中获取方向,然后使用适当的旋转创建新图像。

从传入的信息字典中获取元数据:

NSDictionary *metadata = [info objectForKey:UIImagePickerControllerMediaMetadata];
NSNumber *orientation = [metadata objectForKey:@"Orientation"];

然后当你创建你的UIImage:

croppedImage = [UIImage imageWithCGImage:subImageRef 
                                   scale:1.0 
                             orientation:[orientation intValue]];

希望这是你的起点,至少。

【讨论】:

【参考方案2】:

你应该做的是在处理之前修复图像方向,我遇到了同样的问题,我正在使用 swift 所以我不得不改变这个答案:

iOS UIImagePickerController result image orientation after upload

但代码运行良好。请记住,它返回一个图像并且它没有编辑图像,我只是因为那个简单的错误而努力让它正确。顺便说一句,你不应该使用 UIImageOrientation 而是 UIImageOrientation.rawValue,至少在 swift 中是这样。

我将在此处留下 swift 的代码,希望它有所帮助

extension UIImage 
public func fixOrientation() -> UIImage?

    if self.imageOrientation.rawValue == UIImageOrientation.Up.rawValue 
        return self
    

    var transform : CGAffineTransform = CGAffineTransformIdentity

    switch self.imageOrientation.rawValue 

    case UIImageOrientation.Down.rawValue:
            transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)
            transform = CGAffineTransformRotate(transform, CGFloat(M_PI))
    case UIImageOrientation.DownMirrored.rawValue:
            transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height)
            transform = CGAffineTransformRotate(transform, CGFloat(M_PI))

    case UIImageOrientation.Left.rawValue:
            transform = CGAffineTransformTranslate(transform, self.size.width, 0)
            transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
    case UIImageOrientation.LeftMirrored.rawValue:
            transform = CGAffineTransformTranslate(transform, self.size.width, 0)
            transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))

    case UIImageOrientation.Right.rawValue:
            print("working on right orientation")
            transform = CGAffineTransformTranslate(transform, 0, self.size.height)
            transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2))
    case UIImageOrientation.RightMirrored.rawValue:
            transform = CGAffineTransformTranslate(transform, 0, self.size.height)
            transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2))

    case UIImageOrientation.Up.rawValue: break
    case UIImageOrientation.UpMirrored.rawValue: break

    default: break
    

    switch self.imageOrientation.rawValue 

    case UIImageOrientation.UpMirrored.rawValue:
            transform = CGAffineTransformTranslate(transform, self.size.width, 0)
            transform = CGAffineTransformScale(transform, -1, 1)
    case UIImageOrientation.DownMirrored.rawValue:
            transform = CGAffineTransformTranslate(transform, self.size.width, 0)
            transform = CGAffineTransformScale(transform, -1, 1)

    case UIImageOrientation.LeftMirrored.rawValue:
            transform = CGAffineTransformTranslate(transform, self.size.height, 0)
            transform = CGAffineTransformScale(transform, -1, 1)
    case UIImageOrientation.RightMirrored.rawValue:
            transform = CGAffineTransformTranslate(transform, self.size.height, 0)
            transform = CGAffineTransformScale(transform, -1, 1)

    case UIImageOrientation.Up.rawValue: break
    case UIImageOrientation.Down.rawValue: break
    case UIImageOrientation.Left.rawValue: break
    case UIImageOrientation.Right.rawValue: break

    default: break
    

    let bitmapInfo = CGImageGetBitmapInfo(self.CGImage)

    let ctx = CGBitmapContextCreate(nil, Int(self.size.width), Int(self.size.height), CGImageGetBitsPerComponent(self.CGImage), 0, CGImageGetColorSpace(self.CGImage),
        bitmapInfo.rawValue)

    CGContextConcatCTM(ctx, transform)

    switch self.imageOrientation 

    case UIImageOrientation.Left:
            CGContextDrawImage(ctx, CGRectMake(0, 0, self.size.height, self.size.width), self.CGImage)
    case UIImageOrientation.LeftMirrored:
            CGContextDrawImage(ctx, CGRectMake(0, 0, self.size.height, self.size.width), self.CGImage)
    case UIImageOrientation.Right:
            CGContextDrawImage(ctx, CGRectMake(0, 0, self.size.height, self.size.width), self.CGImage)
    case UIImageOrientation.RightMirrored:
            CGContextDrawImage(ctx, CGRectMake(0, 0, self.size.height, self.size.width), self.CGImage)

    default:
        CGContextDrawImage(ctx, CGRectMake(0, 0, self.size.width, self.size.height), self.CGImage)

    

    let cgimg = CGBitmapContextCreateImage(ctx)
    let image = UIImage(CGImage: cgimg!)

    return image

    

【讨论】:

以上是关于css3的3d旋转为啥会导致元素变大?的主要内容,如果未能解决你的问题,请参考以下文章

CSS3在动画元素上旋转导致点击事件不调用

如何css制作3d旋转立方体效果?

CSS3 3D位移和旋转

css3 由小变大然后一直旋转的动画怎么做

css3怎么让3d旋转的层近大远小

3D旋转菜单