前言
本期给大家带来是结合 CSS3 画出来的一个立体 3d 魔方, 结合了 JS 让你随心所欲想怎么转, 就怎么转, 我们先来看看效果, 然后再分解它的实现过程吧
绘制过程:
好吧, gif 图看着好像有点不是很清晰, 想在线预览的同学, 可点击在线预览 , 废话不多扯了, 先来分析一下, 看如何实现这个功能吧.
∙ API 预热 :
本次示例是一个立体的正方形, 既然有立体效果, 肯定少不了 CSS3 中的 -webkit-perspective - 透视, preserve-3d - 三维空间, 这个两个是重点哦, 当然还有 transform-origin,transition,transform 等, 先来回故一下 API 怎么是讲的吧:
perspective 取值 :
none : 不指定透视 ;
length : 指定观察者与「z=0」平面的距离, 使具有三维位置变换的元素产生透视效果.「z>0」的三维元素比正常大, 而「z<0」时则比正常小, 大小程度由该属性的值决定, 不允许负值.
transform-style 取值 :
flat : 指定子元素位于此元素所在平面内;
preserve-3d : 指定子元素定位在三维空间内, 当该属性值为 preserve-3d 时, 元素将会创建局部堆叠上下文;
小结 : 决定一个变换元素看起来是处在三维空间还是平面内, 需要该元素的父元素上定义 <'transform-style'> 属性, 也就是说想某元素有三维效果, 需要设定它的父级有 preserve-3d.
transform-origin 取值 :
percentage: 用百分比指定坐标值. 可以为负值;
length: 用长度值指定坐标值. 可以为负值;
left: 指定原点的横坐标为 left;
center1: 指定原点的横坐标为 center;
right: 指定原点的横坐标为 right;
top: 指定原点的纵坐标为 top;
center2: 指定原点的纵坐标为 center;
bottom: 指定原点的纵坐标为 bottom;
transform,transition 等, 就不介绍了
- /* perspective 使用示例:*/
- div{
- -webkit-perspective:600px;
- perspective:600px;
- }
- /*transform-style 使用示例:*/
- .preserve{
- transform-style:preserve-3d;
- -webkit-transform-style:preserve-3d;
- }
- /*transform-origin 使用示例:*/
- .preserve{
- -webkit-transform-origin:50% 50% -100px; or
- -webkit-transform-origin:bottom; or
- -webkit-transform-origin:top;
- ............
- }
- <div class="cube">
- <div class="cube-inner running">
- <p class="single-side s1"><span > 最 </span></p>
- <p class="single-side s2"><span > 懂 </span></p>
- <p class="single-side s3"><span > 你 </span></p>
- <p class="single-side s4"><span > 的 </span></p>
- <p class="single-side s5"><span > 魔 </span></p>
- <p class="single-side s6"><span > 方 </span></p>
- </div>
- </div>
- // 欢迎加入全栈开发交流群一起学习交流: 864305860
- .cube{
- width:200px;
- height:200px;
- margin:10px auto;
- padding:260px;
- position:relative;
- -webkit-perspective:600px;
- perspective:600px;
- transition: .5s ;
- }
- .cube-inner{
- width:200px;
- height:200px;
- position:relative;
- -webkit-transform-style:preserve-3d;
- transition:.3s;
- -webkit-transform-origin:50% 50% -100px;
- transform: rotateX(45deg);
- }
- .cube:hover{
- /* 鼠标经过时, 把 perspective 过渡到 100 */
- -webkit-perspective:100px;
- perspective:100px;
- }
- // 欢迎加入全栈开发交流群一起学习交流: 864305860
- .cube-inner .single-side.s1{
- /*s1 顶部 */
- left:0;top:-200px;
- background: radial-gradient(circle, rgba(255,255,255,.88), #00adff);
- background: -webkit-radial-gradient(circle, rgba(255,255,255,.88), #00adff);
- transform-origin:bottom;
- -webkit-transform-origin:bottom;
- transform:rotateX(90deg);
- -webkit-transform:rotateX(90deg);
- }
- .cube-inner .single-side.s3{
- /*s3 底部 */
- left:0;top:200px;
- background: radial-gradient(circle, rgba(255,255,255,.88), #100067);
- background: -webkit-radial-gradient(circle, rgba(255,255,255,.88), #100067);
- transform-origin:top;
- -webkit-transform-origin:top;
- transform:rotateX(-90deg);
- -webkit-transform:rotateX(-90deg);
- }
- //// 欢迎加入全栈开发交流群一起学习交流: 864305860
- .cube-inner .single-side.s4{
- /*s4 背部, 公众号: honeyBadger8*/
- z-index:2;
- left:0;top:0;
- background: radial-gradient(circle, rgba(255,255,255,.88), #F0C);
- background: -webkit-radial-gradient(circle, rgba(255,255,255,.88), #F0C);
- transform:translateZ(-200px) rotateX(180deg) ;
- -webkit-transform:translateZ(-200px) rotateX(180deg) ; /*rotateZ(-180deg) 左右旋转的时候, Z 轴旋转 180°, 因为字是倒着的 */
- }
- .cube-inner .single-side.s5{
- /*s5 左侧 */
- left:-200px;top:0;
- background: radial-gradient(circle, rgba(255,255,255,.88),rgba(33,33,33,1));
- background: -webkit-radial-gradient(circle, rgba(255,255,255,.88),rgba(33,33,33,1));
- transform-origin:right;
- -webkit-transform-origin:right;
- transform:rotateY(-90deg)
- -webkit-transform:rotateY(-90deg)
- }
- .cube-inner .single-side.s6{
- /*s6 右侧 */
- right:-200px;top:0;
- transform-origin:left;
- -webkit-transform-origin:left;
- background: radial-gradient(circle, rgba(255,255,255,.88), #f00);
- background: -webkit-radial-gradient(circle, rgba(255,255,255,.88), #f00);
- transform:rotateY(90deg);
- -webkit-transform:rotateY(90deg);
- }
- .cube .cube-inner{
- /*-webkit-transform:rotateX(180deg) rotateY(0deg) ;*/
- animation: elfCube 10s infinite ease-in-out;
- -webkit-animation: elfCube 10s infinite ease alternate;
- }
- @keyframes elfCube {
- 0% {
- transform: rotateX(0deg) rotateY(0deg);
- }
- 50% {
- transform: rotateX(360deg) rotateY(360deg);
- }
- 100% {
- transform: rotateX(0deg) rotateY(0deg);
- }
- }
- @-webkit-keyframes elfCube {
- 0% {
- -webkit-transform: rotateX(0deg) rotateY(0deg);
- }
- 50% {
- -webkit-transform: rotateX(360deg) rotateY(360deg);
- }
- 100% {
- transform: rotateX(0deg) rotateY(0deg);
- }
- }
- ......
- getAxisX(e){
- let left = this.cubeEle.offsetLeft;
- return e.pageX - left - (this.cubeW/2) * (this.cubeW>this.cubeH ? this.cubeH/this.cubeW : 1);
- }
- getAxisY(e){
- let top = this.cubeEle.offsetTop;
- return e.pageY - top - (this.cubeH/2) * (this.cubeH>this.cubeW ? this.cubeW/this.cubeH : 1);
- }
- ............
- ............
- run(){
- this.cubeEle.addEventListener('mouseover',(e)=>this.hoverOut(e),false);
- this.cubeEle.addEventListener('mousemove',(e)=>this.move(e),false);
- this.cubeEle.addEventListener('mouseout',(e)=>this.hoverOut(e),false);
- }
- hoverOut(e){
- // 进入 / 离开
- e.preventDefault();
- this.axisX = this.getAxisX(e),
- this.axisY = this.getAxisY(e);
- if(e.type == 'mouseout'){ // 离开
- this.axisX=0;
- this.axisY = 0;
- console.log("离开")
- this.cubeInner.className="cube-inner running";
- }else{
- this.cubeInner.className="cube-inner";
- console.log("进入")
- };
- let rotate = `rotateX(${-this.axisY}deg) rotateY(${-this.axisX}deg)`;
- this.cubeInner.style.WebkitTransform = this.cubeInner.style.transform = rotate;
- }
- ......
- -webkit-perspective,
- -webkit-transform-style,
- -webkit-transform-origin,
- radial-gradient,linear-gradient,
- transform:rotate,translate,scale,
- transition,
- animation;
来源: http://www.qdfuns.com/article/51117/ee91ca4c44651840ce3820839169b4bd.html