当前位置:首页 > 前端技术 > 【CSS进阶】试试酷炫的 3D 视角

【CSS进阶】试试酷炫的 3D 视角

2022年11月07日 15:06:27前端技术17

写这篇文章的缘由是因为看到了这个页面:

戳我看看(移动端页面,使用模拟器观看)

运用 CSS3 完成的 3D 视角,虽然有一些晕3D,但是使人置身于其中的交互体验感觉非常棒,运用在移动端制作一些 H5 页面可谓十分博人眼球。

并且掌握原理之后制作起来也并不算废力,好好的研究了一番后将一些学习过程共享给大家。

下面进入正文:(一些 Gif 图片较大,需要等待一会)

 

3D 效果示意

百闻不如一见,先直观感受一下上述我所说的效果:

最好能点进去看看,这里我使用了带背景色的 div 作为示例,我们的视角处于一个正方体中,正方体的旋转动画让我们有了 3D 的感觉。

那么原本的图长什么样呢?我们把距离拉远,一探究竟:

是长这样的:

【CSS进阶】试试酷炫的 3D 视角 _ JavaClub全栈架构师技术笔记

相较于第一种效果,其实所做的只是将我们的视角推进到了正方体当中,有了一种身临其景的感觉。

而合理的运用 CSS3 所提供的一些 3D 属性,很容易就能达到上述的效果。

制作这样一个 3D 图形,我在之前的文章已经很详细的讲述了过程,感兴趣的可以戳进去看看:

【CSS3进阶】酷炫的3D旋转透视

 

transform-style 与 perspective

再简单复述一下,主要是运用到了两个 CSS 属性:

transform-style

要利用 CSS3 实现 3D 的效果,最主要的就是借助 transform-style 属性。

transform-style 只有两个值可以选择:

// 语法:
transform-style: flat|preserve-3d;
 
transform-style: flat; // 默认,子元素将不保留其 3D 位置
transform-style: preserve-3d; // 子元素将保留其 3D 位置。

当父元素设置了 transform-style:preserve-3d 后,就可以对子元素进行 3D 变形操作了,3D 变形和 2D 变形一样可以,使用 transform 属性来设置,或者可以通过制定的函数或者通过三维矩阵来对元素变型操作:当我们指定一个容器的 transform-style 的属性值为 preserve-3d 时,容器的后代元素便会具有 3D 效果,这样说有点抽象,也就是当前父容器设置了 preserve-3d 值后,它的子元素就可以相对于父元素所在的平面,进行 3D 变形操作。

  • 使用 translateX(length) 、translateY(length) 、 translateZ(length) 来进行 3D 位移操作,与 2D 操作一样,对元素进行位移操作,也可以合并为 translate3d(x,y,z) 这种写法;

  • 使用 scaleX() 、scaleY() 、scaleY() 来进行3D 缩放操作,也可以合并为 scale3d(number,number,number) 这种写法;

  • 使用 rotateX(angle) 、rotateY(angle) 、rotateZ(angle) 来进行 3D 旋转操作,也可以合并为 rotate3d(Xangle,Yangle,Zangle) 这种写法。

perspective

// 语法
perspective: number|none;

简单来说,当元素没有设置 perspective 时,也就是当 perspective:none/0 时所有后代元素被压缩在同一个二维平面上,不存在景深的效果。perspective 为一个元素设置三维透视的距离,仅作用于元素的后代,而不是其元素本身。

而如果设置 perspective 后,将会看到三维的效果。

我们上面之所以能够在正方体外围看到正方体,以及深入正方体内,都是因为 perspective 这个属性。它让我们能够选择推进视角,还是远离视角,因此便有了 3D 的感觉。

 

3D View页面的布局结构

为了完成这样一个效果,需要一个灵活的布局,去控制整个 3D 效果的展示。

下面是我觉得比较好的一种方式:

<!-- 最外层容器,控制图形的位置及在整个页面上的布局-->
<div class="container">
	<!-- 舞台层,设置 preserve-3d 与 perspective 视距  -->
	<div class="stage">
		<!-- 控制层,动画的控制层,通过这一层可以添加旋转动画或者触摸动画 -->
		<div class="control">
			<!-- 图片层,装入我们要拼接的图片 -->
			<div class="imgWrap">
				<div class="img img1"></div>
				<div class="img img2"></div>
				<div class="img img3"></div>
				<div class="img img4"></div>
			</div>
		</div>
	</div>
</div>
  • 最外层 container ,控制图形的位置及在整个页面上的布局;
  • stage 层,舞台层,从这里开始设置 3D 景深效果,添加 perspective 视距;
  • control 层,动画的控制层,通过这一层可以添加旋转动画或者在移动端的触摸动画,通过更改translateZ 属性也可以拉近拉远视角;
  • imgWrap 层,图片层,装入我们要拼接的图片,下文会提及。

 

图片拼接

图片拼接其实才是个技术活,需要许多的计算。

以上述 Demo 中的正方体为例子,class 为 img 的 div 块的高宽为 400px*400px。那么要利用 4 个 这样的 div 拼接成一个正方体,需要分别将 4 个 div 绕 Y 轴旋转 [90°, 180°, 270°, 360°],再 translateY(200px) 。

值得注意的是,一定是先旋转角度,再偏移距离,这个顺序很重要。

看看俯视图,也就是这个意思:

【CSS进阶】试试酷炫的 3D 视角 _ JavaClub全栈架构师技术笔记

 

这是最简单的情况了,都是直角。

如果是一张图需要分割成八份,假设每张图分割出来的高宽为 400 400 , 8 张图需要做的操作是依次绕 Y 轴旋转 [45°, 90°, 135°, 180°, 225°, 270°, 315°, 360°] ,偏移的距离为 translateY(482.84px) ,也就是 (200 + 200√2)。

看看俯视图:

【CSS进阶】试试酷炫的 3D 视角 _ JavaClub全栈架构师技术笔记

效果图:

 

图片分割

上面的示例都是使用的带背景色的 div 块,现在我们选取一张真正的图片,将其拼接成一个柱体。

下面这张图,大小为 3480px * 2000px :

【CSS进阶】试试酷炫的 3D 视角 _ JavaClub全栈架构师技术笔记

我们把它分割为 20 份,拼成一个正 20 边形,当然不用一块一块切图下来,利用 background-position 就可以完成了。而且分割的份数越多,最终做出来的效果越像一个圆柱,效果也更加真实。

正 20 边形,需要 20 个 div ,假设容器是 .img-bg1 ~ .img-bg20 ,那么每块图片的宽度为 174px,依次需要递增的角度为 18° ,并且我们需要计算出需要偏移的距离为 translateZ(543px)

可以利用一些 CSS 预处理器处理这段代码,下面是 Sass 的写法:

// Sass 的写法
$imgCount : 20 !default;
@for $i from 1 through $imgCount {
	.img-bg#{$i}{
		background-position:($i * -174px + 174px) 0;
		transform: rotateY($i * 18deg) translateZ(543px);
	}
}

看看效果: Demo可以戳这里

【CSS进阶】试试酷炫的 3D 视角 _ JavaClub全栈架构师技术笔记

可以看到,图中近视为一个圆柱形,不过有一些小问题:

  • 选取的图片必须是左右首尾相连的的,不然圆柱结合处会有明显的不协调,这就要求要使用这种方式制作 H5 页面的时候,美术出的设计图必须左右相连无违和感。
  • 另外一点就是分割的块术,图片分割越多块,越近视为为一个圆柱,效果更佳。

 

控制 control 层,进入到圆柱画面内

做到这一步,只剩下最后一步,就是推进我们的视角,进入到圆柱内部,产生 3D 视图的感觉。

我们通过 class 为 control 这个 div 控制这个效果,不过这里控制我们进入圆柱内部的属性不是调整修改 perspective 属性,而是调整 translateZ 属性。通过控制 translateZ 得到的画面更加真实,可以自己尝试一下分别控制 perspective 与 translateZ 得到的效果,便会有深刻的感受。

最后的效果: Demo可以戳这里,由于是移动端效果,打开模拟器观看更佳

整个效果图太大,只截取了部分制作成 GIF:

【CSS进阶】试试酷炫的 3D 视角 _ JavaClub全栈架构师技术笔记

还有一个小问题,那就是进入到圆柱内部之后,整个图片都反了过来,所以我们可能需要利用PS将原图进行一次左右翻转,这样进入内部之后,看到的就是原图效果。

至此,整个页面就算完工了,接下来的就是添加一些 touch 事件,增添一些细节。可能写的过程中遗漏了一些细节,有什么很难一下理解过来的地方可以在评论留言。

本文示例 Demo 已上传在我的 Github 上:

Css33DView

 

到此本文结束,如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

作者:ChokCoco
来源链接:https://www.cnblogs.com/coco1s/p/5847080.html

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。


本文链接:https://www.javaclub.cn/front/68370.html

标签: css
分享给朋友:

“【CSS进阶】试试酷炫的 3D 视角” 的相关文章

CSS a标签样式

a标签悬停时鼠标样式、下划线、颜色等 a { color: blue; cursor: pointer; /* 鼠标样式*/ } a:link { color: #06F; text-decoration: none; }...

Html/Css

原文地址:http://blog.csdn.net/annip/article/details/53455226 一.什么是role属性 role属性作用是告诉Accessibility类应用(比如屏幕朗读程序,为盲人提供的访问网络的便利程...

HTML标签属性与CSS样式

HTML标签属性与CSS样式

HTML基础 定义:超文本标记语言 Hypetext Markup Language 特点: • 不需要编译,直接由浏览器执行 • 是一个文本文件 • 必须用htm或html作文件后缀 • 对大小写不敏感,HTML或html都可以 HT...

HTML标签自带属性 和 CSS 常用属性区分

**前言:**相信很多人在开发时都遇到过这样一个问题,当我们需要用一个属性去修饰某个标签时,常常会分不清楚其到底是标签自带的属性(HTML属性)还是 CSS 里的属性,因此这篇博文记录的就是一些常用的 HTML 和 CSS 属性,方便查阅的同时,也希望和...

HTML&CSS实验(5)---学习颜色、字体、文本格式化和盒模型的样式定义

HTML&CSS实验(5)---学习颜色、字体、文本格式化和盒模型的样式定义

  【实验题目】HTML&CSS实验(5) 【实验目的】学习颜色、字体、文本格式化和盒模型的样式定义。                  ----------------------个人作业,如果有后辈的作业习题一致,可以参考学习,一起交流...

css中*的用法

*是代表所有html中的标签 例.写了一个 *{box-sizing:border-box} .span-class{ width:80px; padding:20px; } 结果,span标签的内容宽度是80px,并不是40px...

js修改css样式的方法,js如何设置css样式?js修改css样式的方法

js如何设置css样式?本篇文章就给大家介绍js设置(修改)css样式的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所帮助。 下面我们就给大家介绍使用javascript是如果设置css样式的。 1、直接设置样式(内联样式) 使...

css实现页面底部固定在屏幕最下方,内容占满屏后紧跟其后的两种方法

1.只针对底部高度固定的情况,不能解决底部高度不固定的情况, 原理:主要内容放在page-main里面,page-container最小高度100%(注意这里html,body高度也要设为100%),position为relative。footer的position为abs...

内联式css样式,直接写在现有的HTML标签中

<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> &l...

CSS中的global

在我使用antd等组件时,常常需要更改组件的默认样式,这时候,我们就需要用:global{}将需要修改的样式包裹起来。这种情况,我遇到过很多次,但是从来没有探究过原因,今天就浅浅的说一下我的理解。 在说这个问题之前,我们需要先知道CSS Modules。...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。