只是看过一些比如视觉差的类似这样的根据鼠标动而动的动画,

举例解释:

1、先前的github404动画图片层第轴动殊效页面(最近改版了,没有动画效果了,以前我写有一篇文章便是关于github星球大战为主题的404缺点页面,对鼠标哦活动作出回应的干系代码,3d元素点睛);

htmlbanner图片滚动代码? ???前端开辟实现B站首页动态banner jQuery

github 404:

2、视差引擎 parallax : [例子] (matthew.wagerfield.com/parallax/) 对光标的位置做出相应的反应。

parallax :

3、滚动动画(视差、动画、交互) ScrollMagic

多伦多24小时环保干洗店、修鞋、洗衣叠服做事网站Alfred

苹果vision产品页面

太多这种类似视觉差效果的产品图了,就不一一举例了,有兴趣的伙伴自行搜索...

前面讲到B站的首页的最上面一栏的根据鼠标的相应鼠标位置的视差效果。
有的伙伴可能不怎么常去B站看(可能偶尔或者更多的是用手机端看),这边我贴一下效果,如下:

确实是想看一下是怎么做的。
然后我就去搜,结果你可以去看看,印象很深的是一个人讲过(这里我就不讲了,可以搜搜看),反正便是提出了问题,问了不雅观众是怎么做的,然后末了的结论是便是根据鼠标移动而移动。

"Talk is cheap, show me the code. —— Linus Torvalds" (直接翻译便是说话随意马虎,给我展示代码),这个人的一句名言,也代表了他对实际代码和行动的重视,而不是勾留口头的吹吹说说假大空。
真正的生产力和进步是基于编写(或者集成他人的)代码的质量和效率,而不是单单评论辩论功能、空想事情的所有办法等等)。

有时候设计的时候观点很大略脱口而出,但是实际实现中须要做的事情是要多得多的(相信很多开拓者在开拓时候对这句话深有体会,说说说、说出花来、吹得天花乱坠,但是做,又是做不出个以是然来。
以是说到一定程度,但彷佛没什么进展的时候,就得“多说无用,给我看你的行动”了,我笃信,无论是事情上还是人际关系上都是如此)。

以是,类似常常说的写作便是思考,那么我相信编程便是思考这句话也是同样富含逻辑和道理的。

接下来我们看一下是如何实现的

准备事情——素材

一共15张素材,15张素材构成一幅图。
叫UI设计组小姐姐做。
如若PS技能强,可以自己搞(先画出整体图,构想整体须要什么场景的、人和物和景,对了,然后一层一层关闭图层保存矢量图给前端),根据鼠标有规律(这里规律是指有范围、有移动偏移曲线、有透明度变革、有缩放变革等等地动)这个不知道是不是有产品经理给效果图给到UI小姐姐、给到前端去看终极效果,从而做出来的。

编程第一步:建一个html文件

不想着后面有多难,但至少这一步建文件我是会的,我正规点,建个文件夹,文件夹里建一个banner.html文件,再建一个static文件夹用来放素材。
第一步就基本也错不到哪里去,大不了错了我再删,删了我再建。

该文用原生先写一遍,下一篇我再用vue或者react搞一遍,不喜好看或者目前用不上原生的js来搞这个动画效果的可以到这里结束了,可以去B站首页自行体验体验。

建完文件的第一步:! + Tab

vscode !+Tab,完事,又进了一步。

画底色

子内容重复循环的。
那么,外框先画好。
子内容接下来再想。

编写代码不雅观察,定义好数据构造

不雅观察别人是怎么做的。
实在这一步,该当从一开始就该当一贯贯彻到末端。
只不过,做完上一步不知道下一步怎么做了,为了只管即便可能靠近结果,就先不雅观察,把会做的,先做了。
这里值得一提的是:掌握台(掌握台是一个很好的高分精良答题者,有时候从掌握台找答案会比我自己空想来得要完全和有用)。

<div class="layer"> <img src="素材" style="高度; 宽度; transform: translate(x, y) rotate(角度) scale(缩小或放大); opacity: 透明度;" ></div>// .// .// .// 以此类推,15个素材元素,恰好15个这样差不多的dom构造,(也可推测这是个数组,用来循环,开拓如果所有东西都类似的东西手动一个个写人会疯掉且,纵然乐意不怕累那也使不得,由于量大效率不高。
以是这里用循环来搞)// 而且如果下次要换不同的元素或者版块,改数据就好,不须要改其他。
// 那么数据构造是什么样子的呢?...

layers 数组数据构造:

const layers = [ { resources: [ { src: './static/4e7edb416c34eccc40f34d2b297524652685a9bb.png', id: 0 } ], scale: { initial: 0.6, }, rotate: {}, translate: {}, blur: {}, opacity: { wrap: "clamp", }, name: '01 bg' }, // 以此类推(有多少素材就有多少个工具,定义好素材地址、scale缩放、rotate旋转、translate偏移量、blur模糊度、opacity透明度、文件名备注): {}]

切以中央原点为定值:

01 bg

13 远鸟

02 灯塔丛林

03 底部海水

04 鳄鱼a

04 鳄鱼b

05 左边鱼影

06 左边鱼群

07 右边鱼

08 右边鸟

09 中间

11 33

10 水面

12 近鸟

14 两侧

给每个素材定宽高

这一步便是根据上面的数据结果,给每个素材设置一下宽高。
个中要看scale的值和相对它们来说最大的外框.animated-banner的高度来相应式地对每个素材的宽高进行处理。

给每个元素加个div

这一步就直接给每个img加个div。
class为layer。

css 须要加上这个layer的样式:

.layer { position: absolute; left: 0; top: 0; height: 100%; width: 100%; display: flex; align-items: center; justify-content: center;}

js 须要加上:

const divElementArr = layers.map(() => { const divElement = document.createElement('div') divElement.classList.add('layer') banner.appendChild(divElement) return divElement})

末了得到的是一个数组,每一个(这里有15个)元素class为layer的div。
然后append到.animated-banner最大boss上。

append素材到layer的div上

append素材元素,追加上去,代码如下:

layers.map((layer, layerKey) => { const layerElement = layer.resources[0].el divElementArr[layerKey].appendChild(layerElement)})

这个时候就得到效果图如下:

可以看到,所有的元素都以正中央排布(缘故原由便是上面的css中相对定位所有都center水平居中垂直居中)。

那这个时候就说了,下一步是不是根据数据构造,给每个元素间隔正中央偏移多少设置了。
没错的。

初始样式设置 以及 每个元素间隔正中央偏移排布

初始样式设置

// 鼠标指针相对窗口边缘水平坐标 左还是右,左进则是正数比率,右进则是负数比率let relativeX = 0;

每个元素间隔正中央偏移排布

一开始加载元素的偏移排布

鼠标监听事宜

效果图

总结

这次文章研究B站的动图如何实现(实现transform中的translate如何如何一比一还原,篇幅太大缩放大小、透明度,以及moveleave还没仔细讲解),但基本上同一事理,这里难点重点是贝塞尔曲线,元素按曲线运动以及旁边移动换鳄鱼图,以及透明度的问题。

原文链接:https://juejin.cn/post/7275576084128350248