H5+C3:高级动画的应用实践

简介: H5+C3:高级动画的应用实践

我们大概都知道css可以用来作平面旋转、扭曲、放大缩小、平移。。。并且用起来几乎都得心应手。

但目前来说,3D效果的“高级”动画似乎更受欢迎一些,而且我们也确实需要

image.png

这不,前两天笔者就在项目中给“翻转动画”增加了一个3D效果,看起来贼爽:

2345_image_file_copy_1.jpg

这个动画实现所用到的3D盒子模型是现在3D模型中最常用的一个 —— 不过我们先拿其中两个面分析:


       1.首先,要实现这个功能,我们从外往里看:把文字所在部分看作一个盒子的话,前后两个横线并不属于这个盒子才对,那么,很自然就想到了—— ::after 和 ::before 伪元素;

       2.其次,两个文字分别在两个div上,那么就需要有一个可以附带 overflow: hidden 的盒子 —— 不能加到上面的盒子中,因为after和before不属于div!

       3.最后是两个元素的翻转效果:我们需要知道的是,为了性能考虑,我们最好是对整个盒子进行翻转,而不是对两个文字div附加动画

image.png

那么,这个层级关系就很明了了:

<!--伪元素装饰盒子-->
<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;
    background-color: red;
}
.pic_border::after{
    content: '';
    position: absolute;
    top: 50%;
    right: 0;
    width: 43vw;
    height: 1px;
    background-color: red;
}
@media screen 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-3d;
    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轴参与的! 不然会显得很“尴尬”

image.png

image.png

有了简单的上下翻滚,我们还可以实现跟随鼠标上下左右翻滚”动画,就是所谓的“鼠标从哪里进入盒子,盒子就往哪个方向翻转” —— 有两种实现方式:

1.在最外层盒子中加四个方向的i或span标签,用来判断鼠标从哪里进入,JS控制盒子做对应的rotateX/Y;

2.借助数学库与“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-3d;
    width: 100px;
    height: 100px;
    transform-origin: 50px 50px;
}
.front {
    background: fuchsia;
}
.back {
    transform: translate3d(0, 0, 100px) rotateY(180deg);
    background: red;
}
.left {
    transform-origin: 100% 50% 0px;
    transform: rotateY(90deg);
    background: aqua;
}
.right {
    transform-origin: 0% 50% 0px;
    transform: rotateY(-90deg);
    background: blueviolet;
}
.up {
    transform-origin: 50% 0% 0px;
    transform: rotateX(90deg);
    background: darkorange;
}
.down {
    transform-origin: 50% 100% 0px;
    transform: rotateX(-90deg);
    background: 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();
var l = 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;

这样就实现了一个美妙的动画盒子!

image.png

帧动画在canvas中的应用

除去CSS-transform和animation在项目中的大放异彩,canvas+CSS的动画方式也得到了很多人的支持!而canvas中实现动画的最好方式不是离屏技术、不是canvas动画库,而是帧动画!

我们通常通过requestAnimFrame控制一张图片上的显示区域的位置从而达到“伪动画”!

比如:

image.png

//调用方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();
}

2345_image_file_copy_2.jpg

毫无疑问的是:这种方式对UI和前端的结合开始有了要求。

(笔者前段时间研究支付宝春节活动发现:里面采用的也是“前端引入动画文件”的方式!)

目录
相关文章
|
5月前
|
移动开发 前端开发 JavaScript
技术经验分享:Canvas入门到高级详解(上)
技术经验分享:Canvas入门到高级详解(上)
47 0
|
数据安全/隐私保护 iOS开发 MacOS
CocosCreator3.8研究笔记(二十四)CocosCreator 动画系统-动画编辑器实操-关键帧实现动态水印动画效果(2)
CocosCreator3.8研究笔记(二十四)CocosCreator 动画系统-动画编辑器实操-关键帧实现动态水印动画效果
137 0
|
数据安全/隐私保护
CocosCreator3.8研究笔记(二十四)CocosCreator 动画系统-动画编辑器实操-关键帧实现动态水印动画效果(1)
CocosCreator3.8研究笔记(二十四)CocosCreator 动画系统-动画编辑器实操-关键帧实现动态水印动画效果
133 0
Threejs入门进阶实战案例(2):正常静态渲染和渲染动画的解决方案
Threejs入门进阶实战案例(2):正常静态渲染和渲染动画的解决方案
105 0
[BlocklyNukkit入门]#8高级窗口
给窗口添加更多控件
83 0
Threejs入门进阶实战案例(4):addEventListener() 方法自适应窗口显示的方案
Threejs入门进阶实战案例(4):addEventListener() 方法自适应窗口显示的方案
121 0
|
图形学
unity-初级动画系统
unity-初级动画系统
100 0
An动画基础之按钮动画与基础代码相结合
An动画基础之按钮动画与基础代码相结合
751 0
An动画基础之按钮动画与基础代码相结合
|
存储 JavaScript 算法
系统带你学习 WebAPIs —— 动画篇(第六讲)
系统带你学习 WebAPIs —— 动画篇(第六讲)
系统带你学习 WebAPIs —— 动画篇(第六讲)
3D 动画解决方案
本文研究全球及中国市场3D 动画解决方案现状及未来发展趋势,侧重分析全球及中国市场的主要企业,同时对比北美、欧洲、中国、日本、东南亚和印度等地区的现状及未来发展趋势