之前做项目的时候,有个需求是要求实现一个翻折纸条的动画效果,经过一番头脑风暴,终于实现了动画,分享出来,给大家一些动画的实现思路,抛砖引玉,下面来看一下效果
首先此动画是一个复合动画,需要多个div组合才能实现如下效果,需要4个div容器进行布局和动画。
<div class="paper_wrap">
<div class="paper_container">
<div class="paper">
<note :item="noteData"></note>
</div>
<div class="paper_triangle"></div>
</div>
</div>
- paper_wrap是一个旋转的矩形, 主要作用是,赋予它overflow:hidden属性,来实现折痕处的斜线,达到一半是上面的纸条,一半是下面的纸条,他的宽高设置足够大,达到遮盖的效果,我们将其宽高设置为5000,5000,
- paper 是绘制纸条的内容
- paper_triangle是纸条翻过去背面部分,他必须和pager同等大小,并且翻转45度,才会在动画运行时候,达到是翻折一张纸条的效果
- paper_container 是一个容器,里面包含pager 和 paper_triangle,主要用户布局定位这两个元素
因为此页面为一屏页面,为了适配不同型号的手机,纸条的位置和大小是不同的,为了绘制以上几个容器,我们会动态计算纸条的宽和高,以及距离屏幕的边缘的距离, 得到width,height,top,left,根据以上参数,我们进行计算布局绘制出如上的效果
this.paperWrap.style.left = `${this.left + this.width - 5000}px`;
this.paperWrap.style.top = `${this.top + this.height - 2500}px`;
this.paperContainer.style.left = `${5000 - this.width}px`;
this.paperContainer.style.top = `${2500 - this.height}px`;
this.paperContainer.style.height = `${this.width + this.height}px`;
this.paperContainer.style.width = `${this.width + this.height}px`;
this.paperContainer.style.transformOrigin = `${this.width}px ${this.height}px`;
this.paper.style.left = `0px`;
this.paper.style.top = `0px`;
this.paper.style.height = `${this.height}px`;
this.paper.style.width = `${this.width}px`;
this.paperTriangle.style.left = `${this.width}px`;
this.paperTriangle.style.top = `${this.height}px`;
this.paperTriangle.style.height = `${this.width}px`;
this.paperTriangle.style.width = `${this.height}px`;
看一下纸条是如何进行翻折动画的
首先将paperWrap,斜向移动,x轴移动 xMove,y轴移动yMove
this.paperWrap.style.left = `${this.left + this.width - 5000 - xMove}px`;
this.paperWrap.style.top = `${this.top + this.height - 2500 - yMove}px`;
可以看到纸条跟着移动了,我们想要的效果是纸条不移动,所以纸条添加一个反向的动画
this.paper.style.left = `${xMove}px`;
this.paper.style.top = `${yMove}px`;
然后我们再将纸条的背面部分也斜向移动
this.paperTriangle.style.left = `${this.width - yMove}px`;
this.paperTriangle.style.top = `${this.height - xMove}px`;
这三个动画组合起来,就达到了翻折纸条的效果。
此文章分享动画的实现思路,大家在遇见比较难实现的动画时候,可以考虑多个div动画混合起来,已达到预期效果,抛砖引玉。