本文为作者行舟客投稿,点击阅读原文可到达github位置~
github位置:https://github.com/1314mxc/yunUI ,欢迎star!
咱们大概都晓得css能够用来作平面旋转、扭曲、放大缩小、平移。。。并且用起来几乎都得心应手。但日前来讲,3D效果的“高级”动画似乎更受欢迎有些,况且咱们亦确实必须。
这不,前两天笔者就在项目中给“翻转动画”增多了一个3D效果,看起来贼爽:
这个动画实现所用到的3D盒子模型是此刻3D模型中最常用的一个 —— 不外咱们先拿其中两个面分析: 首要,要实现这个功能,咱们从外往里看:把文字所在部分看作一个盒子的话,前后两个横线并不属于这个盒子才对,那样,很自然就想到了—— ::after 和 ::before 伪元素;其次,两个文字分别在两个div上,那样就必须有一个能够附带 overflow: hidden 的盒子 —— 不可加到上面的盒子中,由于after和before不属于div!最后是两个元素的翻转效果:咱们必须晓得的是,为了性能思虑,咱们最好是对全部盒子进行翻转,而不是对两个文字div附加动画★
事实上,transform动画中的属性暗示的含义更加多的是“过渡多少”而不是“过渡到哪里”! ”
那样,这个层级关系就很明了了: <!--伪元素装饰盒子--><div class="pic_border"> <!--overflow-hidden盒子--> <div class="pic_box"> <!--transition过渡盒子--> <div class="pic_item"> <div class="pic_text">music</div> <div class="pic_back">此时此刻,非我莫属</div> </div> </div></div>
按照上面所说,咱们很容易为它添加对应的CSS: .pic_border
{ position
: relative;
} .pic_border::before
{ content
: ; position
: absolute; top: 50%
; left: 0
; width: 43vw
; height: 1px
; bac公斤round-color
: red;
} .pic_border::after
{ content
: ; position
: absolute; top: 50%
; right: 0
; width: 43vw
; height: 1px
; bac公斤round-color
: red;
} @mediascreen and (max-width:1100px
) { .pic_border::before,.pic_border::after
{ width: 20vw
;
}
} .pic_box
{ display
: inline-block; height: 70px
; margin-left: calc
(50% - 70px); overflow
: hidden; perspective: 2000px
; cursor
: pointer; user-select
: none;
} .pic_item
{ width: 100%
; height: 100%
; transform-style: preserve-3
d; transition: all .7s
ease;
} .pic_text,.pic_back
{ width: 100%
; height: 100%
; display
: flex; justify-content
: center; align-items
: center;
} .pic_text
{ transform: rotateX(0deg) translateZ
(-21.9px);
} .pic_back
{ transform: rotateX(90deg) translateZ
(-15px);
} .pic_box:hover .pic_item
{ transform: rotateX
(-90deg);
} .pic_box:active .pic_item
{ transform: rotateX
(-90deg);
}
必须重视的是:3D效果是必定要有Z轴参与的! 否则会显出很“尴尬”
有了简单的上下翻滚,咱们还能够实现“跟随鼠标上下上下翻滚”动画,便是所说的“鼠标从哪里进入盒子,盒子就往哪个方向翻转” —— 有两种实现方式: 在最外层盒子中加四个方向的i或span标签,用来判断鼠标从哪里进入,JS掌控盒子做对应的rotateX/Y;借助数学库与“matrix”:<div class="block" id="block"> <div class="face front"></div> <div class="face back"></div> <div class="face up"></div> <div class="face down"></div> <div class="face left"></div> <div class="face right"></div></div>.block
{ position
: absolute; transform-style: preserve-3
d; width: 100px
; height: 100px
; transform-origin: 50px 50px
;
} .front
{ bac公斤round
: fuchsia;
} .back
{ transform: translate3d(0, 0, 100px) rotateY
(180deg); bac公斤round
: red;
} .left
{ transform-origin: 100% 50% 0px
; transform: rotateY
(90deg); bac公斤round
: aqua;
} .right
{ transform-origin: 0% 50% 0px
; transform: rotateY
(-90deg); bac公斤round
: blueviolet;
} .up
{ transform-origin: 50% 0% 0px
; transform: rotateX
(90deg); bac公斤round
: darkorange;
} .down
{ transform-origin: 50% 100% 0px
; transform: rotateX
(-90deg); bac公斤round
: darkviolet;
}
为了便于观察,咱们为让魔方格子旋转起来:鼠标滑动分为左、右、上、下滑动,每种滑动对应一种方向的格子旋转。 从右往左:绕 Y 轴旋转 θ 角从左往右:绕 Y 轴旋转 -θ 角从上往下:绕 X 轴旋转 θ 角从下往上:绕 X 轴旋转 -θ 度当然旋转必须有一个参照点,默认盒子中心。咱们能够借助库函数将生成的矩阵转化为 CSS 中 transform 的 matrix3d 属性值。 var currentQ = {x:0, y:0, z:0, w:1
}; var lastQ = {x:0, y:0, z:0, w:1
}; var
currentMatrix = matrix.identity(); varl =Math
.sqrt(dx * dx + dy * dy); if(l <= 0) return
; var
x = dx / l, y = dy / l; var axis = {x: x, y: y, z: 0
}; var
q = matrix.fromAxisAndAngle(axis, l);
currentQ = matrix.multiplyQuaternions(q, lastQ);
currentMatrix = matrix.makeRotationFromQuaternion(currentQ);
经过以上方式咱们计算出了当前旋转矩阵 currentMatrix,接下来,咱们运用上面介绍的矩阵转化成对应 css 的函数,生成对应的 transform 属性: // 将矩阵转化为transform matrix 属性值。function matrix2css(m)
{ var style = matrix(
; if(m.length == 16
){ style = matrix3d(
} for(let i =0
; i< m.length; i++){
style += m[i]; if(i !== m.length - 1
){ style += , }else
{ style +=)
}
} return
style;
} var
style = matrix2css(currentMatrix);
最后将生成的样式应用到魔方格子上: document.querySelector(#block
).style.transform = style;
这般就实现了一个美妙的动画盒子!
帧动画在canvas中的应用
除去CSS-transform和animation在项目中的大放异彩,canvas+CSS的动画方式亦得到了非常多人的支持!而canvas中实现动画的最好方式不是离屏技术、不是canvas动画库,而是帧动画!
咱们一般经过requestAnimFrame掌控一张照片上的表示区域的位置从而达到“伪动画”!
例如: //调用方js部分内容var starPic=new
Image() starPic.src="上面照片位置"var
lastTime,deltaTime; var stardog=new
starObj()
stardog.init() lastTime=Date
.now()
gameloop() function gameloop()
{ window
.requestAnimFrame(gameloop) var now=Date
.now()
deltaTime=now-lastTime
lastTime=now
drawStars()
} //真正掌控动画的js文件var satrObj=function()
{ this
.x; this
.y; this
.picNo; this
.timer;
} starObj.prototype.init=function()
{ this.x=Math.random()*630+100; //630:照片宽度 this.y=Math.random()*70+150; //70:照片高度 this.picNo=0
; this.timer=0
;
} starObj.prototype.update=function()
{ this
.timer+=deltaTime; if(this.timer>50
){ this.picNo+=1
; this.picNo%=7
; this.timer=0
;
}
} starObj.prototype.draw=function()
{ ctx.drawImage(starPic,0,0,this.picNo*70,70,this.x,this.y,70,70
)
} function drawStars()
{
stardog.update();
stardog.draw();
}
毫没疑问的是:这种方式对UI和前端的结合起始有了需求。(笔者前段时间科研支付宝春节活动发掘:里面采用的亦是“前端引入动画文件”的方式!) 最后欢迎加我微X(winty230),拉你进技术群,长时间交流学习...
欢迎关注「前端Q」,认真学前端,做个专业的技术人...
点个在看支持我吧
|