目标:
点击立方体的上半部分立方体向上翻转一次,点击立方体下半部分,立方体向下翻转。
思路:
先建立一个静态的立方体,立方体的面上分出两div并分别设置onclick事件。
代码的实现
建立立方体
一个立方体有六个面,因此设立六个平行div,再在外面包裹一个div命名为box以便六个面(box的子元素)有3d效果(transform-style: preserve-3d;),又因为立方体涉及3d(想要有近大远小的效果),因此要用一个div作舞台,命名为container,其主要是为了使用perspective这个属性,以及调整立方体在页面的位置。
html部分:
<div id="container">
<div class="box" >
//因为每个面有相同的地方所以设立的一个box-page的类
<div class=".box-page top"></div>
<div class=".box-page bottom"></div>
<div class="box-page left"></div>
<div class="box-page right"></div>
<div class="box-page before"></div>
<div class="box-page after"></div>
</div>
</div>
css部分:
*{
padding: 0;
margin: 0;
}
#container{
height: 400px;
width: 400px;
margin: 100px auto;
perspective: 1000px;
}
.box{
height: 400px;
width: 400px;
/* 控制子元素保持3d */
transform-style: preserve-3d;
}
.box-page{
height: 400px;
width: 400px;
/* 固定各面的位置 */
position: absolute;
}
.top{
width: 400px;
height: 400px;
position: absolute;
/* top和bottom的上面三个值不知道为什么没传过来,按理来说是不用写上面三行的 */
/* translateZ不知道为什么用不了 */
background: red;
transform:translate3d(0,0,-200px);
}
.bottom{
width: 400px;
height: 400px;
position: absolute;
background: black;
/*注意这个bottom 因为bottom和其他几个面是相反的,为了保持统一所以将其顺序倒过来 */
transform:translate3d(0,0,200px) rotateX(180deg);
}
.left{
background: orange;
transform: translateX(-200px) rotateY(-90deg);
}
.right{
background: green;
transform: translateX(200px) rotateY(90deg);
}
.after{
background: yellow;
transform: translateY(-200px) rotateX(-90deg);
}
.before{
background: blue;
transform: translateY(200px) rotateX(90deg);
}
有以下几点要注意的
1.translate和rotate的顺序不能反
2.transform只能写一行
//错误示范:
div {
transform:translateX(200px);
transform:rotateX(90deg);
}
3.计算机y轴和x轴相反,x轴指向右,y轴指向下,z轴插眼
4.以眼睛为原点,远处为正方向,顺时针为负的deg,逆时针为正(在csdn上看到一个更有意思的记法,即每个轴的旋转正方向都符合左手螺旋定则,详细看原文)
添加js函数
在添加js函数之前先在每个面里面加入两个div
<div class=".box-page top">
<div class="foot_space" οnclick="downturn()"></div>
<div class="top_space" οnclick="upturn()"></div>
</div>
upturn和downturn为js函数如下:
function upturn(){
var css = document.querySelector('.box')
x_rotate = css.style.transform.substring(7).match(/-?[0-9]+/)[0]
x_rotate =String(Number(x_rotate) +90)
css.style.transform = "rotateX( " + x_rotate +"deg)" //注意引号
}
function downturn(){
var css = document.querySelector('.box')
x_rotate = css.style.transform.substring(7).match(/-?[0-9]+/)[0]
x_rotate =String(Number(x_rotate) -90)
css.style.transform="rotateX( " + x_rotate +"deg)"
再在css文件的.box里加个动画样式
transition: transform 0.4s;
在html文件的box行里加style="transform:rotateX(0deg)"属性至于为什么要在行间加style而不直接写在css里我在下面说。
这样一个点击翻转的正方向就做好了!
以下为完整代码(纯享版,复制即所得)
html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>魔方-点击翻转</title>
<link rel="stylesheet" type="text/css" href="魔方-点击翻转css.css"/>
<script type="text/javascript">
function upturn(){
var css = document.querySelector('.box')
x_rotate = css.style.transform.substring(7).match(/-?[0-9]+/)[0]
x_rotate =String(Number(x_rotate) +90)
css.style.transform = "rotateX( " + x_rotate +"deg)"
}
function downturn(){
var css = document.querySelector('.box')
x_rotate = css.style.transform.substring(7).match(/-?[0-9]+/)[0]
x_rotate =String(Number(x_rotate) -90)
css.style.transform="rotateX( " + x_rotate +"deg)"
}
</script>
</head>
<body>
<div id="container">
<div class="box" style="transform: rotateX(0deg);">
<div class=".box-page top">
<div class="foot_space" onclick="downturn()"></div>
<div class="top_space" onclick="upturn()"></div>
</div>
<div class=".box-page bottom">
<div class="foot_space" onclick="downturn()"></div>
<div class="top_space" onclick="upturn()"></div>
</div>
<div class="box-page left">
<div class="foot_space" onclick="downturn()"></div>
<div class="top_space" onclick="upturn()"></div>
</div>
<div class="box-page right">
<div class="foot_space" onclick="downturn()"></div>
<div class="top_space" onclick="upturn()"></div>
</div>
<div class="box-page before">
<div class="foot_space" onclick="downturn()"></div>
<div class="top_space" onclick="upturn()"></div>
</div>
<div class="box-page after">
<div class="foot_space" onclick="downturn()"></div>
<div class="top_space" onclick="upturn()"></div>
</div>
</div>
</div>
</body>
</html>
css:
*{
padding: 0;
margin: 0;
}
#container{
height: 400px;
width: 400px;
margin: 100px auto;
perspective: 1000px;
}
.box{
height: 400px;
width: 400px;
transform-style: preserve-3d;
transition: transform 0.4s;
}
.box-page{
height: 400px;
width: 400px;
position: absolute;
}
.top{
width: 400px;
height: 400px;
position: absolute;
background: red;
transform:translate3d(0,0,-200px);
}
.bottom{
width: 400px;
height: 400px;
position: absolute;
background: black;
transform:translate3d(0,0,200px) rotateX(180deg);
}
.left{
background: orange;
transform: translateX(-200px) rotateY(-90deg);
}
.right{
background: green;
transform: translateX(200px) rotateY(90deg);
}
.after{
background: yellow;
transform: translateY(-200px) rotateX(-90deg);
}
.before{
background: blue;
transform: translateY(200px) rotateX(90deg);
}
.foot_space,.top_space{
height: 200px;
width:400px;
}
写js的时候遇到的一些**坑
看上面的js好像就那么简单的几行,实际上我在做的时候大部分时间浪费在这几行上面了。在此我想分享一下我写这几行的历程,希望大家能通过我的经历对这几行代码有更深的理解,同时解释一下为什么我要在box行内加入style属性而不在css文件里面加。
问题1:如何获取css样式:
c初学js的话,大家一定对document.getElementById()
,document.getElementsByClassName()等语句非常熟悉,但是对于获取css样式的方法却全然不知,然鹅,通过面向csdn编程不难的到答案。
var 元素=document.querySelector('选择器')
var 获取属性值=window.getComputedStyle(元素[,伪类元素]).css属性;
问题2:为什么我对transform的修改是无效的?
先声明一下,一开始我是把transform放在css文件里的。在我操作网页的时候发现transform的值并没有改变!
z在仔细翻阅大量csdn文章后发现,原来获取css样式的方法有两种,分别对应的是内嵌样式和外联样式。
var css = document.querySelector('.box')
var 外联样式值=window.getComputedStyle(css).transform
//这里注意一下,这里我当时写的是 document.defaultView.getComputedStyle(element[,pseudo-element]);
//貌似这是只读的方法?绝大部分时间网上一致认为写window.get....就行了
var 内嵌样式值=css.style.transform
我当时脑子没转过来,执意要改外联的样式,于是在这我又遇到了两个问题。
问题3:window.getComputedStyle(css,null)方法返回的是matrix3d(n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n),要怎么改?
这是一个4*4矩阵,对于一个大一学生来说(没学线代),这是没办法改的,还好,关键时刻被动技能(面向csdn编程)很好的解决了我的问题。原文在这里 . 下面是我当时写的
var x_rotate = window.getComputedStyle(css, null).transform
//x_rotate += 90; //错误注意类型转化
x_rotate =String(Number(x_rotate) +90)
var window.getComputedStyle(css,null).transform="rotateX( " + x_rotate +"deg);"//注意这个的分号!后面有他的戏份
问题4:NoModificationAllowedError: Modifications are not allowed for this document
然而他提示我 NoModificationAllowedError: Modifications are not allowed for this document
几经折腾,我都无法得知我的代码出了什么问题(有大佬看到希望可以解答一下)。迫于期末复习的压力,我放下了我最后的倔强决定改内嵌样式(其实是我脑子终于转过来了)。这也是为什么我把transform写在了box的行内了。
在我以为我终于完成这个小功能的时候,我却傻眼了。(问题就像想买的东西,总是一个接一个的出现)
问题5:为什么我的立方体还tm没有动呐?
其实写到这里,我的代码已经无限接近成功了
var css = document.querySelector('.box')
x_rotate = css.style.transform.substring(7).match(/-?[0-9]+/)[0]
x_rotate =String(Number(x_rotate) -90)
cs.style.transform="rotateX( " + x_rotate +"deg);"//就是这个分号错了!
原来我这了写多了一个分号(css里要加,html中不用),这是个蠢问题,可能大部分人并不会犯这样的错,写在这里仅仅为了警醒我自己,以及纪念我那为此而逝去的三个小时!(如果不是因为我手滑我说不定还改不出来)
以上就是我壮烈的编码全过程。
写在最后
导致这次悲惨的历程有几个我自己的原因,总结一下:
1.看文章、菜谱不要急,要看清楚使用说明!
2.debug不要想当然,要逐项排查,正如 夏洛克·福尔摩斯 爱新觉罗·邓尔摩斯所说,“除去不可能的、剩下的即使再不可能,那也是 真相 bug