Vue3+typescript+vite realize the leading color of Netease cloud music year activities

biyezuopinvip 2022-06-23 18:22:17 阅读数:225

vue3+typescript+vitevuetypescriptviterealize

Resource download address :https://download.csdn.net/download/sheziqiong/85749561
Resource download address :https://download.csdn.net/download/sheziqiong/85749561

imitation 《 Your character dominates 》

Vue 3 + Typescript + Vite

On-line Demo

function

// install 
yarn
// Run locally 
yarn dev

Introduce

《 Your character dominates 》 This year, Netease cloud music front-end team developed a software to test the dominant color of users H5 application , After going online, the response was very good , It blew up microblog and circle of friends .

The main developer of the project imyzf Published an article 《 Official secrets ! Your color is calculated like this 》, Some problems in the calculation of dynamic effect and final dominant color are explained . But because it involves specific business , So the author didn't open the source code , But the enthusiastic author gave a lot of tips . I follow these tips , Uncover the part I'm more interested in .

Because it has not been used in production environment Vue3.0 and vite, So I used the source code Vue3.0+vite Realization .

Page preload

The answer page is similar to the general H5 The difference between pages is , The user's operation path is determined , That is, the route of the next page of each page is fixed , So in router The level has been optimized , The next page is preloaded in advance

Because the active page uses a lot of videos and dynamic effects , So I want to render the next page when the user reads and selects the topic , In this way, it will be smooth when switching to the next page , It was a good experience .

At first I thought about how to use vue-router Complete page preloading . But after a circle, I found , It's all based on webpack perhaps vite Lazy loading , Some resources are loaded in advance , The page will not be rendered in advance .

Later, by looking at vue-router file , To find inspiration , Use named views , Show at the same time 2 Individual view , Use css Hide next page , Although it doesn't show , But the page has been rendered .

By modifying the router-view Of name attribute , Complete the page switch . in other words , In fact, my route has not changed .

// App.vue
<template>
<router-view :name="currentViewName"></router-view>
<router-view :name="nextViewName"></router-view>
</template>
// Be careful , Two are used here viewName Completed the page Jump ,next The page is preloaded 
const currentViewName = computed(() => store.getters.currentViewName);
const nextViewName = computed(() => store.getters.nextViewName);
// router The definition part of 
const routes = [
{

path: '/',
components: {

default: Index1,
index2: Index2,
session1: Session1,
session2: Session2,
session5: Session5
}
}
];

See the code above ,Index1Index2 and Session1 Wait is actually the component of each page , By modifying the currentViewName and nextViewName You can achieve the purpose of page switching .

The final effect is as follows , The next page has been rendered in advance :

 Insert picture description here

Page turning dynamic effect

The author suggests using canvas The screen pulling effect during page switching is realized , It mainly uses the core canvas API yes bezierCurveTo.

Through inquiry, we know ,bezierCurveTo need 3 individual Points are used to draw cubic Bezier curves , Online experience

Look at the picture below , Want to achieve pull animation ,P1 P2 P3 Of X Axis coordinates need to change continuously , And then draw the curve , It can achieve the pulling effect .
 Insert picture description here

I use a lighter weight here JavaScript Animation library animejs, Used to control the continuous movement of the above points .3 The two animation effects moved P1 P2 P3 Of X Axis coordinates , Then cooperate with the drawing of curve , The basic curtain pulling effect is achieved .

const heights = [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]
}
};
// P1 Change of point 
anime({

targets: points.p1,
x: 0,
easing: 'easeInQuart',
delay: 50,
duration: 500
});
// P2 Change of point 
anime({

targets: points.p2,
x: 0,
easing: 'easeInSine',
duration: 500
});
anime({

targets: points.p2,
y: 0.6 * pageHeight,
easing: 'easeInSine',
duration: 500
});
// P3 Change of point 
anime({

targets: points.p3,
x: 0,
easing: 'easeInQuart',
delay: 50,
duration: 500
});
// Draw a curve 
anime({

duration: 550,
update: function () {

// Clear the last drawing 
ctx.clearRect(0, 0, pageWidth, pageHeight);
ctx.beginPath();
ctx.moveTo(points.p1.x, points.p1.y);
// The upper half of the screen 
ctx.bezierCurveTo(points.p1.x, points.p1.y, points.p2.x, points.p2.y - 0.2 * pageHeight, points.p2.x, points.p2.y);
// The lower half of the curtain 
ctx.bezierCurveTo(points.p2.x, points.p2.y + 0.2 * pageHeight, points.p3.x, points.p3.y, points.p3.x, points.p3.y);
// Rectangular area of the pulled part 
ctx.lineTo(points.p4.x, points.p4.y);
ctx.lineTo(points.p5.x, points.p5.y);
ctx.closePath();
ctx.fill();
ctx.strokeStyle = '#f1f1f1';
ctx.stroke();
}
});

The final result is :

 Insert picture description here

This dynamic effect is due to the need to use , So consider completing a common global component .

Considering that the general components need to be written to vue On the template , Very inconvenient , So it's best to directly display this dynamic effect through a global function , Be similar to showAnimation();

First, you need to complete a separate component , Because you want to overwrite all the information on the page , So we used Vue3.0 The latest offer teleport Components :

<!-- This canvas Will be rendered as app The children of -->
<teleport to="#app">
<canvas class="mask-canvas" ref="canvas" :class="{ 'mask-canvas-posi': isShow }"></canvas>
</teleport>

Then you need to pass the component through Vue The plug-in is registered to the global attribute , Because I want to use Composition API , So I finally decided to use provide + inject To register and use global property. In general, use app.config.globalProperties That's all right. , But this cooperation Composition API It will be more troublesome to write , Not recommended .

(Mask as any).install = (app: App): void => {

// Vue3 Of Composition API It is recommended to use provide + inject To register and use global property
app.provide('mask', Mask);
};
// When you use it 
const Mask = inject('mask');

Last , Because page flipping and routing are used together , Just continued to encapsulate useNext function , In general view If the component is used , It's very simple , At the same time, the page turning dynamic effect and page turning operation are done :

nextPage();

Here I can boast Composition API 了 , Very simple and convenient , Through the encapsulation of this global common component , I totally like this way .

Cloud dynamics

todo…

Resource download address :https://download.csdn.net/download/sheziqiong/85749561
Resource download address :https://download.csdn.net/download/sheziqiong/85749561

版权声明:本文为[biyezuopinvip]所创,转载请带上原文链接,感谢。 https://qdmana.com/2022/174/202206231727072061.html