基于CSS3的3D旋转效果
自从有了html5和css3,好多以前只能想想的华丽效果都可以上手实现了。3D 转换(个人认为3D变换更贴切^)就是其中之一。关于3D转换,可以阅读CSS3 3D transform变换,不过如此,文中对3D转换进行了形象、生动、详细的阐述。在这里,只和大家讨论怎么利用3D转换来实现立体及其旋转效果,例如:
好吧,废话不多说,上代码!
1.页面代码
- <div class="translate3D_test">
- <ul class="cube">
- <li class="translate3D_li">1</li>
- <li class="translate3D_li">2</li>
- <li class="translate3D_li">3</li>
- <li class="translate3D_li">4</li>
- <li class="translate3D_li">5</li>
- <li class="translate3D_li">6</li>
- </ul>
- <br/>
- <a href="#" onclick="return clicka(11)">左</a>
- <a href="#" onclick="return clicka(12)">右</a>
- <a href="#" onclick="return clicka(13)">上</a>
- <a href="#" onclick="return clicka(14)">下</a>
- <a href="#" onclick="return clicka(1)">1</a>
- <a href="#" onclick="return clicka(2)">2</a>
- <a href="#" onclick="return clicka(3)">3</a>
- <a href="#" onclick="return clicka(4)">4</a>
- <a href="#" onclick="return clicka(5)">5</a>
- <a href="#" onclick="return clicka(6)">6</a>
- <a href="#" onclick="return clicka(0)">复原</a>
- </div>
2.CSS代码
- ul
- {
- list-style-type:none;
- margin:;
- padding:;
- }
- li
- {
- border:;
- }
- .translate3D_test{
- position: relative;
- width:500px;
- height: 500px;
- margin:auto;
- background:#ddd;
- }
- .translate3D_li{
- background:#999;
- font-size:50px;
- border:1px solid #F15000;
- }
3.JS代码
- $(document).ready(function(){
- $(".cube").translate3D(400,0,0.5);
- $("#notcube").translate3D(400,500,0.5);
- });
- function clicka(who){
- switch(who)
- {
- case 0:
- $(".cube").transform3D(0);
- break;
- case 1:
- $(".cube").transform3D(1);
- break;
- case 2:
- $(".cube").transform3D(2);
- break;
- case 3:
- $(".cube").transform3D(3);
- break;
- case 4:
- $(".cube").transform3D(4);
- break;
- case 5:
- $(".cube").transform3D(5);
- break;
- case 6:
- $(".cube").transform3D(6);
- break;
- case 11: // left
- $(".cube").transform3D("left");
- break;
- case 12: // right
- $(".cube").transform3D("right");
- break;
- case 13: // up
- $(".cube").transform3D("up");
- break;
- case 14: // down
- $(".cube").transform3D("down");
- break;
- default:break;
- };
- return false;
- }
- function clickb(who){
- switch(who)
- {
- case 0:
- $("#notcube").transform3D(0);
- break;
- case 1:
- $("#notcube").transform3D(1);
- break;
- case 2:
- $("#notcube").transform3D(2);
- break;
- case 3:
- $("#notcube").transform3D(3);
- break;
- case 4:
- $("#notcube").transform3D(4);
- break;
- case 11: // left
- $("#notcube").transform3D("left");
- break;
- case 12: // right
- $("#notcube").transform3D("right");
- break;
- case 13: // up
- $("#notcube").transform3D("up");
- break;
- default:break;
- };
- return false;
- }
- /*
- * translate3D 1.0
- * Copyright (c) 2014 BowenLuo http://www.luobo.com/
- * Date: 2014-06-04
- * 基于Html5和CSS3的立体旋转效果实现,支持循环旋转,支持指定面的显示
- * Example: $(".cube").translate3D(400,0,0.5);//设置类为cube的元素立方体效果,400为长宽高,当第一个参数为0时为正方体效果,0.5为旋转时间,单位为s
- * $("#notcube").translate3D(400,500,0.5);//设置ID为notcube的元素立方体效果,400为长宽,500为高,0.5为旋转时间,单位为s
- * $(".cube").transform3D("left");//设置类为cube的立体元素向左旋转90°
- * $("#notcube").transform3D(5);//设置ID为notcube的立体元素旋转后显示第5个面,即顶部界面
- * 注意:1.插件需jquery支持,暂时只支持Chrome ,Safari ,Firefox 浏览器;
- * 2.面元素和元素容器推荐使用div标签,并请确保至少有4个面元素(正方体效果支持6个面,柱体效果支持4个面);
- * 3.当不为正方体效果或面元素少于6个时,请不要使用上下旋转和显示第5、6个面,以确保良好的用户体验;
- * 4.同一个页面可以设置多个标签的立体效果,但暂时只完美支持对一个立方体进行旋转操作;
- * 5.在进行旋转动作之前,请设置元素的立体效果(在文档加载完成之后设置)。
- */
- (function($){
- $.fn.translate3D = function(width,height,time){
- isCube = false;
- if(height==0){
- isCube = true;
- }
- var thisEle=$(this);
- if(isCube){
- $(thisEle).css({"width":width,"height":width,"overflow":"visible"});
- $(thisEle).children().css({"position": "absolute","width":width,"height":width});
- }else{
- $(thisEle).css({"width":width,"height":height,"overflow":"visible"});
- $(thisEle).children().css({"position": "absolute","width":width,"height":height});
- }
- $(thisEle).css({"-webkit-transition":"-webkit-transform "+time+"s linear","-webkit-transform-style":"preserve-3d"});
- $(thisEle).css({"-moz-transition":"-moz-transform "+time+"s linear","-moz-transform-style":"preserve-3d"});
- $(thisEle).children().css({"-webkit-backface-visibility":"hidden","-moz-backface-visibility":"hidden"});
- var mcpara = width/2;
- var translateZ1 = "translateZ("+mcpara+"px)";
- var translateZ2 = "rotateY(90deg) translateZ("+mcpara+"px)";
- var translateZ3 = "rotateY(180deg) translateZ("+mcpara+"px)";
- var translateZ4 = "rotateY(-90deg) translateZ("+mcpara+"px)";
- var translateZ5,translateZ6;
- $(thisEle).children("*:eq(0)").css({"-webkit-transform":translateZ1});
- $(thisEle).children("*:eq(1)").css({"-webkit-transform":translateZ2});
- $(thisEle).children("*:eq(2)").css({"-webkit-transform":translateZ3});
- $(thisEle).children("*:eq(3)").css({"-webkit-transform":translateZ4});
- $(thisEle).children("*:eq(0)").css({"-moz-transform":translateZ1});
- $(thisEle).children("*:eq(1)").css({"-moz-transform":translateZ2});
- $(thisEle).children("*:eq(2)").css({"-moz-transform":translateZ3});
- $(thisEle).children("*:eq(3)").css({"-moz-transform":translateZ4});
- if(isCube){
- translateZ5 = "rotateX(90deg) translateZ("+mcpara+"px) " ;
- translateZ6 = "rotateX(-90deg) translateZ("+mcpara+"px) ";
- $(thisEle).children("*:gt(5)").css({"display":"none"});
- $(thisEle).children("*:eq(4)").css({"-webkit-transform":translateZ5});
- $(thisEle).children("*:eq(5)").css({"-webkit-transform":translateZ6});
- $(thisEle).children("*:eq(4)").css({"-moz-transform":translateZ5});
- $(thisEle).children("*:eq(5)").css({"-moz-transform":translateZ6});
- }else{
- $(thisEle).children("*:gt(3)").css({"display":"none"});
- }
- };
- $.fn.transform3D = function(direction){
- if(typeof(yAngle)!=='number'){
- yAngle = 0;
- }
- if(typeof(xAngle)!=='number'){
- xAngle = 0;
- }
- var thisEle=$(this);
- var basexAngle = Math.round((xAngle%360)/360)*360+(xAngle-xAngle%360);
- /*
- if(Math.abs(xAngle%360)>180){
- if(xAngle>0){
- basexAngle=xAngle-xAngle%360+360;
- }
- if(xAngle<0){
- basexAngle=xAngle-xAngle%360-360;
- }
- }else{
- basexAngle=xAngle-xAngle%360;
- }*/
- if(typeof(direction)=='number'){
- switch(direction)
- {
- case 0:
- xAngle = 0;
- yAngle = 0;
- break;
- case 1:
- xAngle = basexAngle;
- if(Math.abs(yAngle%360)>180){
- if(yAngle>0){
- yAngle = yAngle-yAngle%360+360;
- }
- if(yAngle<0){
- yAngle = yAngle-yAngle%360-360;
- }
- }else{
- yAngle=yAngle-yAngle%360;
- }
- break;
- case 2:
- xAngle = basexAngle;
- if(Math.abs(-yAngle%360-90)>180){
- if(yAngle>0){
- yAngle = yAngle-yAngle%360-90+360;
- }
- if(yAngle<0){
- yAngle = yAngle-yAngle%360-90-360;
- }
- }else{
- yAngle=yAngle-yAngle%360-90;
- }
- break;
- case 3:
- xAngle = basexAngle;
- if(Math.abs(-yAngle%360-180)>180){
- if(yAngle>0){
- yAngle = yAngle-yAngle%360-180+360;
- }
- if(yAngle<0){
- yAngle = yAngle-yAngle%360-180-360;
- }
- }else{
- yAngle=yAngle-yAngle%360-180;
- }
- break;
- case 4:
- xAngle = basexAngle;
- Math.abs(xAngle%360)/360
- if(Math.abs(-yAngle%360+90)>180){
- if(yAngle>0){
- yAngle = yAngle-yAngle%360+90+360;
- }
- if(yAngle<0){
- yAngle = yAngle-yAngle%360+90-360;
- }
- }else{
- yAngle=yAngle-yAngle%360+90;
- }
- break;
- case 5:
- xAngle = basexAngle-90;
- if(Math.abs(yAngle%360)>180){
- if(yAngle>0){
- yAngle = yAngle-yAngle%360+360;
- }
- if(yAngle<0){
- yAngle = yAngle-yAngle%360-360;
- }
- }else{
- yAngle=yAngle-yAngle%360;
- }
- break;
- case 6:
- xAngle = basexAngle+90;
- if(Math.abs(yAngle%360)>180){
- if(yAngle>0){
- yAngle = yAngle-yAngle%360+360;
- }
- if(yAngle<0){
- yAngle = yAngle-yAngle%360-360;
- }
- }else{
- yAngle=yAngle-yAngle%360;
- }
- break;
- default:break;
- };
- }
- if(direction=='left'){
- xAngle = basexAngle;
- yAngle -= 90;
- }
- if(direction=='right'){
- xAngle = basexAngle;
- yAngle += 90;
- }
- if(direction=='up'){
- if(xAngle%360==0){
- xAngle += 90;
- }else{
- xAngle += 180;
- }
- if(Math.abs(yAngle%360)>180){
- if(yAngle>0){
- yAngle = yAngle-yAngle%360+360;
- }
- if(yAngle<0){
- yAngle = yAngle-yAngle%360-360;
- }
- }else{
- yAngle=yAngle-yAngle%360;
- }
- }
- if(direction=='down'){
- if(xAngle%360==0){
- xAngle -= 90;
- }else{
- xAngle -= 180;
- }
- if(Math.abs(yAngle%360)>180){
- if(yAngle>0){
- yAngle = yAngle-yAngle%360+360;
- }
- if(yAngle<0){
- yAngle = yAngle-yAngle%360-360;
- }
- }else{
- yAngle=yAngle-yAngle%360;
- }
- }
- $(thisEle).css("transform","rotateX("+xAngle+"deg) rotateY("+yAngle+"deg)");
- $(thisEle).css("webkitTransform","rotateX("+xAngle+"deg) rotateY("+yAngle+"deg)");
- $(thisEle).css("-moz-Transform","rotateX("+xAngle+"deg) rotateY("+yAngle+"deg)");
- };
- })(jQuery);
整个过程可以分为2步,第一步:通过对面元素<li class="translate3D_li"></li>进行3D变换来搭建立方体;第二步:通过对面元素容器<ul class="cube"></ul>的3D变换来实现3D立体旋转效果。在搭建立方体时需要注意translateZ的使用,translateZ大小即为立方体中心到该面的垂直距离:
一般为面元素宽的一半。rotateX和roteteY可以理解为位置偏移量,例如右转90°,需要在原roteteY的基础上加90,即roteteY+=90,而不是roteteY=90。要想实现立体旋转效果,还必须设置动作效果transition:transform 2s linear(各浏览器之间不同),一个是偏转量,一个是动作时间,类似于left:'250px'和animate({left:'250px'})的关系。而要实现平滑的旋转效果,例如从当前面转到右侧面,可以左转90°,也可以右转270°,当然左转90°更优美。在这里,平滑就是转换的角度总是相对最小的。为了实现平滑的旋转,死了我大量脑细胞,结果差强人意,效果上没什么问题,感觉代码和算法有点复杂,如果大家有什么好的办法,不吝指教。我简单说下我的思路:
1.确定目标偏移量,并确保目标便宜量与当前偏移量之间的差值小于360;
2.计算当前偏移量和目标偏移量之间的差值,如果绝对值大于180(即270),想办法变为90;
3.综合水平和垂直偏移量进行变换。
其中,水平和垂直方向的偏移量是分别处理,互不干扰的,处理完后再结合变换,保证在水平和垂直方向上转换的角度都达到最小。
PS:1.上面的js部分,从多行注释开始,是我自己写的jquery插件,为了节省时间我全粘贴出来了,哈哈。
2.为了优雅性,除正方体外都只能显示水平方向的四个面而不要进行垂直方向上的转换;垂直方向上的变换只有三个状态:正常显示(0°),显示顶部(-90°),显示底部(90°),因为转换为180°时,会发现显示的东西都是倒立的(可以在z轴上变换180°来正常显示,但比较麻烦^)。所以在垂直方向上的平滑处理相对更简单点,可以先找到最近的正常显示的偏移量,再进行三个态的变换处理。当然,不管是垂直还是水平变换,都要先确保另一个方向上正常显示,才能保证变换后的显示是正常的。
3.为了保存便宜量,所以在插件中定义了全局变量。这样一来,为了确保友好性,一个页面上就只能对一个立方体进行旋转操作。怎样对不同的立方体保存对应的偏移量,请大家多多指教。
基于CSS3的3D旋转效果的更多相关文章
- 一款基于css3的3D图片翻页切换特效
今天给大家分享一款基于css3的3D图片翻页切换特效.单击图片下方的滑块会切换上方的图片.动起你的鼠标试试吧,效果图如下: 在线预览 源码下载 实现的代码. html代码: <div id= ...
- 基于css3的3D立方体旋转特效
今天给大家分享一款基于css3的3D立方体旋转特效.这款特效适用浏览器:360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗. 不支持IE8及以下浏览器.效果图如下 : ...
- css3 3D旋转效果
css3 record2 css3 3D旋转效果 需理解transform css3知识: keyframes transform perspective jsfiddle demo keyframe ...
- 基于css3的文字3D翻转特效
一款基于css3的文字3D翻转特效.这款特效当鼠标经过文字的时候3D翻转显示阴影.效果图如下: 在线预览 源码下载 实现的代码. html代码: <div class="compo ...
- 基于css3新属性transform及原生js实现鼠标拖动3d立方体旋转
基于css3新属性transform,实现3d立方体的旋转 通过原生JS,点击事件,鼠标按下.鼠标抬起和鼠标移动事件,实现3d立方体的拖动旋转,并将旋转角度实时的反应至界面上显示 实现原理:通过获取鼠 ...
- Css3动画(一) 如何画3D旋转效果或者卫星围绕旋转效果
如何画3D旋转效果或者卫星围绕旋转效果,当然这个也是工作中的一个任务,我在网上翻了一下,并没有找到类似的东西,所以写下来还是费了一番功夫,因此我把它拿出来记录一下,当然替换了一部分内容.好了,话不多说 ...
- css3图书3D动画
css3图书3D动画,css3,立体特效,旋转效果,3D动画,css3图书3D动画是一款基于css3实现的立体旋转3D图书动画特效. 代码下载页:http://www.huiyi8.com/sc/71 ...
- Arctext.js - 基于 CSS3 & jQuery 的文本弯曲效果
Arctext.js 是基于 Lettering.js 的文本旋转插件,根据设置的旋转半径准确计算每个字母的旋转弧度并均匀分布.虽然 CSS3 也能够实现字符旋转效果,但是要让安排每个字母都沿着弯曲路 ...
- 纯css3 transforms 3D文字翻开翻转3D开放式效果
详细内容请点击 在线预览立即下载 在本教程中,将基于CSS3创建的一个实现一个有趣的3D开放式效果.教程的目的是展示我们如何能带来一些生活上使用CSS3 . html: <ul class=&q ...
随机推荐
- TX2 默认root用户启动
Jetpack3.1 修改方式 修改1 gedit /usr/share/lightdm/lightdm.conf.d/50-ubuntu.conf 修改后: 修改2 gedit /root/.pro ...
- SQL函数:返回传入的字符中的数字或者字符
/******返回传入的字符串的所有字符 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOALTER function [dbo].[F_Get ...
- 使用IDEA完成maven整合SSH框架时抛出Hibernate : Mapping (RESOURCE) not found
切入主题,看看今天的错误是如何发生的: 首先这是我的项目路径,java 是 Sources Root , resources 是 Resources Root ,放了所需要的配置文件,其中 Hiber ...
- C++_基础5-内存模型
C++为在内存中存储数据提供了多种选择: 可以选择数据保留在内存中的时间长度(存储持续性): 程序的哪一部分可以访问数据(作用域和链接): 可以使用new来动态地分配内存:定位new运算符提供了这种技 ...
- React笔记:ref注意事项
[一]使用ref必须用在[类型式的组件]才起作用,用在[函数式的组件]是无效的. 下面这个例子用在了[函数式的组件]上,所以是无效的: function MyFunctionalComponent() ...
- Marlin (思维)
The city of Fishtopia can be imagined as a grid of 44 rows and an odd number of columns. It has two ...
- 2018acm-icpc青岛站心得
今年总共两场区域赛,一场南京,一场青岛.南京场队伍真正开始磨合,虽然最后还是铜牌,但是和银牌队伍其实只差一个计算几何的板子的问题.而鉴于南京的教训,所以在准备青岛站的时候,我准备了非常多的模板,还和派 ...
- 112th LeetCode Weekly Contest Minimum Increment to Make Array Unique
Given an array of integers A, a move consists of choosing any A[i], and incrementing it by 1. Return ...
- drf(djangorestframework)
一.django restful_framework 核心思想: 缩减编写api接口的代码 Django REST framework是一个建立在Django基础之上的Web 应用开发框架,可以快速的 ...
- Java8如何用
2014年发布的Java8,现在应该是业界使用最普遍的Java版本,可很多Java开发人员并没有充分发挥这4年前发布的版本的优点, 本文就是带着“学以致用”的目的去了解Java8,挖掘编码中可提高效率 ...