当前位置: 首页 > Web前端 > JavaScript

《你的性格主导色》Reveal

时间:2023-03-27 01:22:56 JavaScript

简介《你的性格主导色》是网易云音乐前端团队今年开发的一款H5应用,测试用户的主打色。该项目的主要开发者imyzf发表了一篇文章《官方揭秘!你的颜色是这样算出来的》解释了一些动画和最终主色的计算。但由于涉及到具体业务,笔者并未将源码开源,不过热心作者给出了很多提示。根据这些提示,我揭示了我比较感兴趣的部分。由于在线演示没有在生产环境中使用Vue3.0和vite,所以我使用Vue3.0+vite来实现源码部分。页面预加载回答页面与一般H5页面的区别在于用户的操作路径是确定的,即每个页面的下一页路由是固定的,所以在路由器层面进行了优化,提前预加载。下一页在活动页面上使用了很多视频和动态效果,所以我想在用户阅读和选择主题时渲染下一页,这样切换到下一页会很流畅,体验很好.一开始我想的是如何使用vue-router来完成页面的预加载。但是做了很多研究,发现都是基于webpack或者vite的懒加载。有些资源是提前加载的,页面不会提前渲染。后来通过看vue-router的文档,找到了灵感。我使用命名视图同时显示两个视图,并使用css隐藏下一页。虽然这时候还没有显示出来,但是页面已经渲染出来了。通过修改router-view的name属性完成页面切换。也就是说,其实我的路由没有变。//App.vue//注意,这里使用两个viewName完成页面跳转,预加载下一页//路由器的定义部分constroutes=[{path:'/',components:{default:Index1,index2:Index2,session1:Session1,session2:Session2,session5:Session5}}];看上面的代码,Index1、Index2和Session1其实就是每个页面的组件。通过修改currentViewName和nextViewName,可以达到页面切换的目的。最终效果如下图,已经提前渲染好下一页:翻页动画作者提醒,画布是用来实现切换页面时的滑幕效果,核心画布API是bezierCurveTo。根据查询,bezierCurveTo需要3个点绘制三次贝塞尔曲线。线上体验见下图。要实现拉动动画,需要不断改变P1、P2、P3的X轴坐标,然后绘制曲线来实现拉动。影响。这里我使用一个比较轻量级的JavaScript动画库animejs来控制以上点的连续运动。三种动画效果分别移动P1、P2、P3的X轴坐标,再配合曲线的绘制,实现拉幕的基本效果。constheights=[0,0.5*pageHeight,pageHeight];points={p1:{x:pageWidth,y:heights[0]},p2:{x:pageWidth,y:heights[1]},p3:{x:pageWidth,y:heights[2]},p4:{x:pageWidth,y:heights[2]},p5:{x:pageWidth,y:heights[0]}};//点P1anime({targets:points.p1,x:0,easing:'easeInQuart',delay:50,duration:500});//点P2anime({targets:points.p2,x:0,easing:'easeInSine',duration:500});anime({targets:points.p2,y:0.6*pageHeight,easing:'easeInSine',duration:500});//点P3anime({targets:points.p3,x:0,easing:'easeInQuart',delay:50,duration:500});//绘制曲线anime({duration:550,update:function(){//清空上次绘制ctx.clearRect(0,0,pageWidth,pageHeight);ctx.beginPath();ctx.moveTo(points.p1.x,points.p1.y);//窗帘的上半部分ctx.bezierCurveTo(points.p1.x,points.p1.y,points.p2.x,points.p2.y-0.2*pageHeight,points.p2.x,points.p2.y);//窗帘的下半部分ctx.bezierCurveTo(points.p2.x,points.p2.y+0.2*pageHeight,points.p3.x,points.p3.y,points.p3.x,points.p3.是);//拉出部分的矩形区域ctx.lineTo(points.p4.x,points.p4.y);ctx.lineTo(points.p5.x,points.p5.y);ctx.closePath();ctx.填充();ctx.strokeStyle='#f1f1f1';ctx.stroke();}});最终效果是这样的:每个页面都需要用到这个动画,所以考虑完成一个通用的全局组件考虑到一般的组件在使用的时候都需要写在vue模板上,很不方便,所以最好直接通过一个全局函数来显示这个动画,类似showAnimation();首先,你需要完成一个独立的组件,因为你要覆盖页面上的所有信息,所以使用了Vue3.0提供的最新teleport组件:然后需要通过vue插件将组件注册到全局属性,因为我要使用CompositionAPI,所以最后决定使用provide+inject来注册和使用全局属性。一般情况下用app.config.globalProperties就够了,但是用CompositionAPI写起来会比较麻烦,所以不推荐。(Maskasany).install=(app:App):void=>{//Vue3的CompositionAPI推荐使用provide+inject注册使用全局属性app.provide('mask',Mask);};//当使用constMask=inject('mask');最后,由于翻页动画和路由一起使用,所以继续封装了一个useNext函数,这样在一般视图组件中使用起来非常简单。同时完成翻页动画和翻页操作:nextPage();这里要夸一下CompositionAPI,非常简单方便。通过对这个全局通用组件的封装,我非常喜欢这种方式。云层动画的部分是我最感兴趣的。之前用three.js实现了一个3D照片墙,但是这个云层动画真的牛逼,也是最难破解的。幸运的是,我完成了。下一篇文章将详细讲解破解过程。源码终于放上源码了。有兴趣的同学可以看看。欢迎Star和建议。