Intro to CSS 3D transforms
原文地址:Intro to CSS 3D transforms,本文只是翻译了其中的一部分,省去了作者写文章的原因浏览器兼容部分(已经过时)
Perspective
元素需要设置需要设置perspective
来激活3D效果,可以通过两种方式实现
在transform属性中使用perspective方法
transform: perspective( 600px );
直接使用perspective属性
perspective: 600px;
NOTE:出于代码简介的目的,demo中的CSS样式没有使用浏览器前缀,在实际使用中需要使用-webkit-perspective, -moz-perspective, 等
<style>
.container {
width: 200px;
height: 200px;
border: 1px solid #CCC;
margin: 0 auto 40px;
}
.box {
width: 100%;
height: 100%;
}
#red1 .box {
background-color: red;
transform: perspective( 600px ) rotateY( 45deg );
}
</style>
<section id="red1" class="container">
<div class="box red"></div>
</section>
.container {
width: 200px;
height: 200px;
border: 1px solid #CCC;
margin: 0 auto 40px;
}
.box {
width: 100%;
height: 100%;
}
#red1 .box {
background-color: red;
transform: perspective( 600px ) rotateY( 45deg );
}
<style>
#blue1{
perspective: 600px;
}
#blue1 .box {
background-color: blue;
transform: rotateY( 45deg );
}
</style>
<section id="blue1" class="container">
<div class="box blue1"></div>
</section>
#blue1{
perspective: 600px;
}
#blue1 .box {
background-color: blue;
transform: rotateY( 45deg );
}
这两种方式都会触发3D效果,但是有一点不同:第一种方式直接在一个元素上触发3D变形,但是当多个元素的时候变形效果和预期会有所不同,如果使用同样的方法作用于不同位置的元素的时候,每个元素会有自己的轴心,为了解决这个问题,需要在父元素使用perspective属性,这样每个子元素都共享相同的3D空间
<style>
#red2 figure {
background: red;
transform: perspective( 400px ) rotateY(45deg);
}
.container figure {
display: block;
width: 55px;
height: 55px;
float: left;
margin: 5px;
}
#red2 figure {
background: #F00;
-webkit-transform: perspective( 400px ) rotateY( 45deg );
-moz-transform: perspective( 400px ) rotateY( 45deg );
-o-transform: perspective( 400px ) rotateY( 45deg );
transform: perspective( 400px ) rotateY( 45deg );
}
</style>
<section id="red2" class="container">
<figure></figure>
<figure></figure>
<figure></figure>
<figure></figure>
<figure></figure>
<figure></figure>
<figure></figure>
<figure></figure>
<figure></figure>
</section>
#red2 figure {
background: red;
transform: perspective( 400px ) rotateY(45deg);
}
.container figure {
display: block;
width: 55px;
height: 55px;
float: left;
margin: 5px;
}
#red2 figure {
background: #F00;
-webkit-transform: perspective( 400px ) rotateY( 45deg );
-moz-transform: perspective( 400px ) rotateY( 45deg );
-o-transform: perspective( 400px ) rotateY( 45deg );
transform: perspective( 400px ) rotateY( 45deg );
}
<style>
#blue2 {
perspective: 400px;
}
#blue2 figure {
background: blue;
transform: rotateY( 45deg );
}
</style>
<section id="blue2" class="container">
<figure></figure>
<figure></figure>
<figure></figure>
<figure></figure>
<figure></figure>
<figure></figure>
<figure></figure>
<figure></figure>
<figure></figure>
</section>
#blue2 {
perspective: 400px;
}
#blue2 figure {
background: blue;
transform: rotateY( 45deg );
}
perspective属性的值决定了3D效果的强烈程度,可以认为是观察者到页面的距离。值越大距离越远,视觉上的3D效果就会相应的减弱。perspective: 2000px; 会产生一个好像我们使用望远镜看远方物体的3D效果,perspective: 100px;会产生一个小昆虫看大象的效果。
3D效果默认轴心是元素中央,可以通过perspective-origin
来修改轴心
perspective-origin: 25% 75%;
点击这里看一下作者写的一个有意思的立方体旋转页面
3D变形方法
作为一个web者,可能很熟悉两个方向:X & Y,表示元素的水平方向和垂直方向,在perspective激活的3D空间中我们可以在X、Y、Z三个坐标轴上对元素进行变形处理。3D变形使用的变形方法和2D变形一样,如果熟悉2D变形方法很容易掌握3D变形
- rotateX( angle )
- rotateY( angle )
- rotateZ( angle )
- translateZ( tz )
- scaleZ( sz )
translateX()方法使元素延X轴移动,translateZ()使元素延Z轴(在3D空间中方向从前到后)移动。正值使元素离观察者更近,负值使元素变远。
.container2 {
width: 200px;
height: 200px;
border: 1px solid #CCC;
margin: 0 auto 60px;
position: relative;
-webkit-perspective: 600px;
-moz-perspective: 600px;
-o-perspective: 600px;
perspective: 600px;
}
.panel {
width: 100%;
height: 100%;
position: absolute;
opacity: 0.7;
color: white;
background: red;
}
#translate-z-negative .panel {
-webkit-transform: translateZ( -200px );
-moz-transform: translateZ( -200px );
-o-transform: translateZ( -200px );
transform: translateZ( -200px );
}
#translate-z-positive .panel {
-webkit-transform: translateZ( 200px );
-moz-transform: translateZ( 200px );
-o-transform: translateZ( 200px );
transform: translateZ( 200px );
}
#rotate-x .panel {
-webkit-transform: rotateX( 45deg );
-moz-transform: rotateX( 45deg );
-o-transform: rotateX( 45deg );
transform: rotateX( 45deg );
}
#rotate-y .panel {
-webkit-transform: rotateY( 45deg );
-moz-transform: rotateY( 45deg );
-o-transform: rotateY( 45deg );
transform: rotateY( 45deg );
}
#rotate-z .panel {
-webkit-transform: rotateZ( 45deg );
-moz-transform: rotateZ( 45deg );
-o-transform: rotateZ( 45deg );
transform: rotateZ( 45deg );
}
有几个变形方法的缩写,这些方法需要把三个参数写全
- translate3d( tx, ty, tz )
- scale3d( sx, sy, sz )
- rotate3d( rx, ry, rz, angle )
Pro-tip: fn3d()变形方法可以触发硬件加速HTML5 buzzwords in action
任意3D操作会触发硬件加速,甚至可能变形只用到了2D的,或者没有做任何事情(比如translate3d(0,0,0))。需要注意的是这只是当前的表现,未来可能变化(这也是为什么我们没有写文档或者鼓励这么做),但是这在很多场景下非常有用,可以显著的提高渲染性能
立方体
创建六个面
<section class="container">
<div id="cube">
<figure class="front">1</figure>
<figure class="back">2</figure>
<figure class="right">3</figure>
<figure class="left">4</figure>
<figure class="top">5</figure>
<figure class="bottom">6</figure>
</div>
</section>
为6个面设置基本的位置和尺寸样式
.container {
width: 200px;
height: 200px;
position: relative;
perspective: 1000px;
}
#cube {
width: 100%;
height: 100%;
position: absolute;
transform-style: preserve-3d;
}
#cube figure {
width: 196px;
height: 196px;
display: block;
position: absolute;
border: 2px solid black;
}
1、2是前后面,3、4是左右,5、6是上下
#cube .front { transform: rotateY( 0deg ); }
#cube .back { transform: rotateX( 180deg ); }
#cube .right { transform: rotateY( 90deg ); }
#cube .left { transform: rotateY( -90deg ); }
#cube .top { transform: rotateX( 90deg ); }
#cube .bottom { transform: rotateX( -90deg ); }
我们可以移除#cube .front样式声明,只用前面是可见的,上、下、左、右面与视角平行,所以看不到。需要从中心位置移动它们才可以看得到,每个面都是200px宽,每个面都需要从立方体中心移动100px;
#cube .front { transform: rotateY( 0deg ) translateZ( 100px ); }
#cube .back { transform: rotateX( 180deg ) translateZ( 100px ); }
#cube .right { transform: rotateY( 90deg ) translateZ( 100px ); }
#cube .left { transform: rotateY( -90deg ) translateZ( 100px ); }
#cube .top { transform: rotateX( 90deg ) translateZ( 100px ); }
#cube .bottom { transform: rotateX( -90deg ) translateZ( 100px ); }
需要注意的是translateZ方法在rotate方法之后,变形方法的顺序很重要,吸收一会儿屌丝们,每面都先按自己的方向旋转,然后向外移动一个向量。
为了用户看清楚,我们的3D变形不应该在扭曲不是active的面,但是我们延Z轴移动的时候,这种情况就难以避免。为了保持3D变形的瞬间,Safari先组合元素,然后再应用变形,因此文本会保持变形之前的样式,在3D变形中经常会出现显著的像素变化
.ex {
text-align: center;
line-height: 60px;
margin: 0;
white-space: pre;
}
.font-size {
font-size: 2.5em;
}
.scale {
-webkit-transform: scale(2.5);
-moz-transform: scale(2.5);
-o-transform: scale(2.5);
transform: scale(2.5);
}
.perspective {
-webkit-transform: perspective(1200px) translateZ(700px);
-moz-transform: perspective(1200px) translateZ(700px);
-o-transform: perspective(1200px) translateZ(700px);
transform: perspective(1200px) translateZ(700px);
}
font-size: 2.5em
transform: scale(2.5);
transform: perspective(1200) translateZ(700px);
通过之前例子可以发现无论perspective的值多小,或者变形的轴心在哪里,面1永远回到初始位置,好像3D变形对它没影响
为了解决变形和像素保留问题,我们可以向后推一下3D对象,这样前面就会Z轴后移
#cube { transform: translateZ( -100px ); }
为了显示每个面,我们需要一个旋转立方体的样式,变形和当前面的方向相反,我们在#box 上切换必要的类来应用变形
#cube.show-front { transform: translateZ( -100px ) rotateY( 0deg ); }
#cube.show-back { transform: translateZ( -100px ) rotateX( -180deg ); }
#cube.show-right { transform: translateZ( -100px ) rotateY( -90deg ); }
#cube.show-left { transform: translateZ( -100px ) rotateY( 90deg ); }
#cube.show-top { transform: translateZ( -100px ) rotateX( -90deg ); }
#cube.show-bottom { transform: translateZ( -100px ) rotateX( 90deg ); }
需要注意变形方法的顺序变了,我们先向后推元素,然后再旋转,再添加transition属性就完成了
#cube { transition: transform 1s; }
旋转木马
和创建立方体类似,我们创建一个9个面的旋转木马
<section class="container">
<div id="carousel">
<figure>1</figure>
<figure>2</figure>
<figure>3</figure>
<figure>4</figure>
<figure>5</figure>
<figure>6</figure>
<figure>7</figure>
<figure>8</figure>
<figure>9</figure>
</div>
</section>
现在应用一下基本的布局样式,给每个#carousel子元素面板20px的间距,这样每个面板的空间为210px
.container {
width: 210px;
height: 140px;
position: relative;
perspective: 1000px;
}
#carousel {
width: 100%;
height: 100%;
position: absolute;
transform-style: preserve-3d;
}
#carousel figure {
display: block;
position: absolute;
width: 186px;
height: 116px;
left: 10px;
top: 10px;
border: 2px solid black;
}
下一步需要旋转每个面,9个面板,如果等分的话每个面板需要旋转40deg相对下一个
#carousel figure:nth-child(1) { transform: rotateY( 0deg ); }
#carousel figure:nth-child(2) { transform: rotateY( 40deg ); }
#carousel figure:nth-child(3) { transform: rotateY( 80deg ); }
#carousel figure:nth-child(4) { transform: rotateY( 120deg ); }
#carousel figure:nth-child(5) { transform: rotateY( 160deg ); }
#carousel figure:nth-child(6) { transform: rotateY( 200deg ); }
#carousel figure:nth-child(7) { transform: rotateY( 240deg ); }
#carousel figure:nth-child(8) { transform: rotateY( 280deg ); }
#carousel figure:nth-child(9) { transform: rotateY( 320deg ); }
现在外移元素,我们需要计算外移的距离,画一个草图,我们发现只有两个已知数:每个面板的宽度是210px,每个面板相对下一个旋转了40deg。拿出任意一个三角形都是右边的样子
我们可以通过正切函数算出r
这样我们就知道知道需要移动288px
#carousel figure:nth-child(1) { transform: rotateY( 0deg ) translateZ( 288px ); }
#carousel figure:nth-child(2) { transform: rotateY( 40deg ) translateZ( 288px ); }
#carousel figure:nth-child(3) { transform: rotateY( 80deg ) translateZ( 288px ); }
#carousel figure:nth-child(4) { transform: rotateY( 120deg ) translateZ( 288px ); }
#carousel figure:nth-child(5) { transform: rotateY( 160deg ) translateZ( 288px ); }
#carousel figure:nth-child(6) { transform: rotateY( 200deg ) translateZ( 288px ); }
#carousel figure:nth-child(7) { transform: rotateY( 240deg ) translateZ( 288px ); }
#carousel figure:nth-child(8) { transform: rotateY( 280deg ) translateZ( 288px ); }
#carousel figure:nth-child(9) { transform: rotateY( 320deg ) translateZ( 288px ); }
如果需要改变面板的宽度或者数量,我们只需要应用一下公式就可以了,在JavaScript中
var tz = Math.round( ( panelSize / 2 ) /
Math.tan( ( ( Math.PI * 2 ) / numberOfPanels ) / 2 ) );
// or simplified to
var tz = Math.round( ( panelSize / 2 ) /
Math.tan( Math.PI / numberOfPanels ) );
最后我们需要再旋转木马上应用些变形
transform: translateZ( -288px ) rotateY( -160deg );
Intro to CSS 3D transforms的更多相关文章
- Codrops 优秀教程:CSS 3D Transforms 实现书本效果
这个使用 CSS 3D Transforms 实现创意书本效果的来自 Codrops 网站.你可以看到两种类型的书设计:精装书和平装书.这两个效果都可以很容易地使用 CSS 修改.赶紧体验一下吧. ...
- CSS 3D transforms
https://www.creativebloq.com/css3/20-stunning-examples-css-3d-transforms-11112759 https://github.com ...
- EF Core使用SQL调用返回其他类型的查询 ASP.NET Core 2.0 使用NLog实现日志记录 CSS 3D transforms cSharp:use Activator.CreateInstance with an Interface? SqlHelper DBHelper C# Thread.Abort方法真的让线程停止了吗? 注意!你的Thread.Abort方法真
EF Core使用SQL调用返回其他类型的查询 假设你想要 SQL 本身编写,而不使用 LINQ. 需要运行 SQL 查询中返回实体对象之外的内容. 在 EF Core 中,执行该操作的另一种方法 ...
- 探究 CSS 混合模式\滤镜导致 CSS 3D 失效问题
今天在写一个小的 CSS Demo,一个关于 3d 球的旋转动画,关于 CSS 3D,少不了会使用下面这几个属性: { transform-style: preserve-3d; perspectiv ...
- 从css 3d说到空间坐标轴
有一次我们说到掷骰子那个游戏,当时是用了一个steps属性+雪碧图来制作帧动画,这当然颇为不错,但其实一开始我想的不是这样的,我想的是用真的3d和动画去做,这个方案涉及到不少空间的知识,今天来给大伙好 ...
- 10个超漂亮的CSS 3D特效
10个超漂亮的CSS 3D特效 一.总结 一句话总结: 后面有空得好好练一练,也可以作为录课素材 二.10个超漂亮的CSS 3D特效 转自或参考:10个超漂亮的CSS 3D特效https://blog ...
- css 3D动画
一.今天让我们来学习一下css 3D吧! 1.首先我们要学习好css3 3d一定要有一定的立体感! 2.再来那就聊聊原理吧! 3.css3 3d 顾名思义是由两个2d名片组成的 但不是让你建立连个2d ...
- CSS 3D 的魅力
作者 | 子慕大诗人 来源 | www.cnblogs.com/1wen/p/9064011.html 前言: 最近玩了玩用css来构建3D效果,写了几个demo,所以博客总结一下. 在阅读 ...
- WebVR & CSS 3D & WebGL
WebVR & CSS 3D & WebGL VR https://developer.mozilla.org/en-US/docs/Web/API/WebVR_API https:/ ...
随机推荐
- SSH框架整合(全注解)
全部jar包 目录结构 配置案例 package cn.yzu.Tbook.action; import javax.annotation.Resource; import org.apach ...
- shell获取文件最后100行,开头100行,指定开始行和结束行的内容
文件最后100行:tail -n100 filePath: 文件开头100行:head -n100 filePath: 文件指定开始行和结束行的内容:sed '1,100p' filePath: 文件 ...
- 11大Java开源中文分词器的使用方法和分词效果对比
本文的目标有两个: 1.学会使用11大Java开源中文分词器 2.对比分析11大Java开源中文分词器的分词效果 本文给出了11大Java开源中文分词的使用方法以及分词结果对比代码,至于效果哪个好,那 ...
- 自动滑动的banner图
实例: HTML页面: <div style="position: absolute; left: 0; top: 0; width: 100%; height: 100%; min- ...
- 现场打印智能无线PDA安卓POS 条码识别、打印、数据采集销售开单收银管理软件
现场打印安卓POS 条码识别.打印.数据采集管理软件 案例: 经营日化品牌,从事小型超市和日用品商店的批发配送业务. 公司以前的销售模式:三个业务员负责跑市场,每个人负责一个区域,平均每天每个人要去到 ...
- Gridview中几个Button的应用
gridview中有三种方式添加button的应用,CommandField.ButtonField.TemplateField中加Button这三种方式.三种方式都可以实现同样的功能,但在实现某些功 ...
- linux內核輸出soft lockup
創建的內核線程長期佔用cpu,一直內核認為線程soft lockup,如無法獲取自旋鎖等:因此線程可適度調用schdule(),以進行進程的調度:因為kwatchdog的執行級別低,一直得不到執行 [ ...
- xcode8 升级后注释快键键不能使用的解决方法
1.这个是因为苹果解决xcode ghost.把插件屏蔽了.解决方法 命令运行: sudo /usr/libexec/xpccachectl 然后必须重启电脑后生效 2.option+command ...
- Ant环境变量配置
Ant环境变量配置 1.新建系统变量ANT_HOME 变量名: ANT_HOME 变量值: D:\biancheng\apache-ant-1.7.1 2.修改PATH 变量值最后面 ...
- linux opensuse 程序中上传文件大小限制
上传文件大小限制 修改nginx主配置文件 /etc/nginx/nginx.conf增加配置 client_max_body_size 40m; (说明:这里40m是最大支持上传40兆)