詳解vue+css3做交互特效的方法
1.前言
做項(xiàng)目就難免會(huì)開發(fā)交互效果或者特效,而我最近開發(fā)的項(xiàng)目一直在使用vue,開發(fā)技術(shù)棧方面,理所當(dāng)然就使用了vue+css3開發(fā),過程中發(fā)現(xiàn)使用vue+css3開發(fā)特效,和javascript/jquery+css3的思維方式不一樣,但是比javascript/jquery+css3簡單一點(diǎn)點(diǎn)。今天就分享三個(gè)簡單的小實(shí)例,希望能起到拓展思維的作用,讓大家明白vue+css3應(yīng)該怎樣開發(fā)交互效果!如果大家有什么好的建議,或者覺得我哪里寫錯(cuò)了,歡迎指出!
1.文章上面的代碼,雖然代碼很簡單,不難理解,但是也是建議大家邊寫邊看,這樣不會(huì)混亂。
2.文章所提及的小實(shí)例,都是很基礎(chǔ)的,大家可以參照自己的想法進(jìn)行擴(kuò)展,或者修改,可能會(huì)有意想不到的效果。我寫這類型的文章也是想授人以漁,不是授人以魚!
3.這幾個(gè)實(shí)例,摘自我自己的平常練習(xí)的項(xiàng)目,代碼已經(jīng)提到github上面了(vue-demos)。歡迎大家star。
2.開場小動(dòng)畫運(yùn)行效果
gif圖模糊效果看著跟實(shí)際效果不太一樣!大家注意!

原理分析
說到原理分析,其實(shí)也沒什么可以分析的,就是在頁面是下面這個(gè)狀態(tài)的時(shí)候,把文字替換掉。至于看到字體縮成一團(tuán),就是letter-spacing這個(gè)css屬性的控制效果。字體模糊就是filter: blur()這個(gè)css屬性的控制效果!看到有逐漸的變化,就是css3動(dòng)畫(animation)的效果

下面簡單分析下,這個(gè)動(dòng)畫的幾個(gè)步驟,從下面看到,這個(gè)動(dòng)畫一共8個(gè)步驟。

這下就清晰明了了,我們要在下圖這個(gè)瞬間開始改變文字,也就是頁面加載了兩秒后,動(dòng)畫執(zhí)行了兩次后就開始改變文字。然后每隔兩秒改變一次文字,直到最后!

下面給出vue和javascript兩種方式的代碼,看下哪種方式更加的簡單!
vue方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<style>
body{
background: #ccc;
}
h1 {
color: white;
text-transform: uppercase;
margin-top: 100px;
text-align: center;
font-size: 6rem;
line-height: 1;
animation: letterspacing 1s 7 alternate ease-in-out;
display: block;
letter-spacing: .5rem;
}
@keyframes letterspacing {
0% {
letter-spacing: -72px;
filter: blur(20px);
}
40% {
filter: blur(6px);
}
80% {
letter-spacing: 8px;
filter: blur(0);
}
}
</style>
<body>
<div id="text">
<h1>{{testText}}</h1>
</div>
</body>
<script src="vue.min.js"></script>
<script type="text/javascript">
new Vue({
el:'#text',
data:{
nowIndex:0,
testText:'歡迎瀏覽'
},
mounted(){
let _this=this;
let timer = setInterval(function(){
_this.nowIndex++;
switch (_this.nowIndex) {
case 1:
_this.testText = '守候的文章';
break;
case 2:
_this.testText = '愿您瀏覽愉快';
break;
case 3:
_this.testText = '學(xué)到知識';
break;
}
if (_this.nowIndex > 3) {
setTimeout(() => {
clearInterval(timer);
}, 2000)
}
}, 2000)
}
})
</script>
</html>
javascript方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<style>
body{
background: #ccc;
}
h1 {
color: white;
text-transform: uppercase;
margin-top: 100px;
text-align: center;
font-size: 6rem;
line-height: 1;
animation: letterspacing 1s 7 alternate ease-in-out;
display: block;
letter-spacing: .5rem;
}
@keyframes letterspacing {
0% {
letter-spacing: -6rem;
filter: blur(1rem);
}
40% {
filter: blur(.3rem);
}
80% {
letter-spacing: .5rem;
filter: blur(0rem);
}
}
</style>
<body>
<div id="text">
<h1>歡迎瀏覽</h1>
</div>
</body>
<script>
var oH1=document.querySelector('h1'),nowIndex=0;
console.log(oH1)
var timer = setInterval(function () {
nowIndex++;
switch (nowIndex) {
case 1:
oH1.innerHTML = '守候的文章';
break;
case 2:
oH1.innerHTML = '愿您瀏覽愉快';
break;
case 3:
oH1.innerHTML = '學(xué)到知識';
break;
}
if (nowIndex > 3) {
setTimeout(() => {
clearInterval(timer);
}, 2000)
}
}, 2000)
</script>
</html>
3.導(dǎo)航滑塊運(yùn)行效果

原理分析
首先,下面是頁面初始化的時(shí)候,橙色滑塊的位置

鼠標(biāo)放到第二個(gè)tab上面,大家可以看到,橙色滑塊就是向右偏移了一個(gè)tab的距離

鼠標(biāo)放到第三個(gè)tab上面,大家可以看到,橙色滑塊就是向右偏移了兩個(gè)tab的距離

如果從第一個(gè)tab到第六個(gè)tab的索引是0,1,2,3,4,5。
那么滑塊的公式就是(索引*tab的寬度)。大家看到有逐漸過去的效果,其實(shí)是css3過渡(transition)的效果。大家看下面的代碼就行了,一看就懂!代碼如下:
vue方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<link rel="stylesheet" href="reset.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >
<style>
.nav{
margin: 40px;
position: relative;
}
.nav li{
float: left;
width: 100px;
height: 40px;
line-height: 40px;
color: #fff;
text-align: center;
background: #09f;
cursor: pointer;
}
.nav span{
position: relative;
z-index: 2;
}
.nav .slider{
position: absolute;
transition: all .5s cubic-bezier(0.4, -0.3, 0.57, 1.38);
width: 100px;
height: 40px;
background: #f90;
top: 0;
left: 0;
z-index: 1;
}
</style>
<body>
<div class="nav clear" id="nav" @mouseleave="nowIndex=0">
<ul>
<li @mouseenter.stop="nowIndex=0"><span>Tab One</span></li>
<li @mouseenter.stop="nowIndex=1"><span>Tab Two</span></li>
<li @mouseenter.stop="nowIndex=2"><span>Tab Three</span></li>
<li @mouseenter.stop="nowIndex=3"><span>Tab four</span></li>
<li @mouseenter.stop="nowIndex=4"><span>Tab five</span></li>
<li @mouseenter.stop="nowIndex=5"><span>Tab six</span></li>
</ul>
<div class="slider" :style="{'transform':'translate3d('+nowIndex*100+'px,0,0)'}"></div>
</div>
</body>
<script src="vue.min.js"></script>
<script type="text/javascript">
new Vue({
el:'#nav',
data:{
nowIndex:0
}
})
</script>
</html>
javascript方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<link rel="stylesheet" href="reset.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >
<style>
.nav{
position: relative;
}
.nav li{
float: left;
width: 100px;
height: 40px;
line-height: 40px;
color: #fff;
text-align: center;
background: #09f;
cursor: pointer;
}
.nav span{
position: relative;
z-index: 2;
}
.nav .slider{
position: absolute;
transition: all .5s cubic-bezier(0.4, -0.3, 0.57, 1.38);
width: 100px;
height: 40px;
background: #f90;
top: 0;
left: 0;
z-index: 1;
}
</style>
<body>
<div class="nav clear" id="nav">
<ul>
<li><span>Tab One</span></li>
<li><span>Tab Two</span></li>
<li><span>Tab Three</span></li>
<li><span>Tab four</span></li>
<li><span>Tab five</span></li>
<li><span>Tab six</span></li>
</ul>
<div class="slider"></div>
</div>
</body>
<script type="text/javascript">
var oDiv=document.querySelector("#nav"),oLi=oDiv.querySelectorAll("li"),oSlider=document.querySelector(".slider");
oDiv.addEventListener("mouseleave",function () {
oSlider.style.transform='translate3d(0,0,0)';
})
for(var i=0;i<oLi.length;i++){
oLi[i].index=i;
oLi[i].addEventListener("mouseenter",function (e) {
oSlider.style.transform='translate3d('+this.index*100+'px,0,0)';
})
}
</script>
</html>
4.輪播圖運(yùn)行效果

原理分析
藍(lán)框的是li,黑框的是div
初始化狀態(tài)

處于顯示第二張圖片的時(shí)候

看到上面,其實(shí)也就是控制ul的偏移量(transform:translate3d)。計(jì)算公式和上面的滑塊相似,索引(0|1|2|3)*li的寬度。不同的就是,ul的偏移量是取負(fù)數(shù),因?yàn)閡l是想左偏,上面的滑塊是向右偏!
當(dāng)?shù)谝粡垐D片的時(shí)候,ul偏移量設(shè)置(transform: translate3d(0px, 0px, 0px))。
當(dāng)?shù)诙垐D片的時(shí)候,ul偏移量設(shè)置(transform: translate3d(-1000px, 0px, 0px))。
當(dāng)?shù)诙垐D片的時(shí)候,ul偏移量設(shè)置(transform: translate3d(-2000px, 0px, 0px))。以此類推,偏移量很簡單的就能計(jì)算出來!
可能我說的大家有點(diǎn)懵,但是,看下面的代碼,就不會(huì)懵了,因?yàn)榇a也很簡單!
vue方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="reset.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >
<style>
.slide-img {
width: 1000px;
height: 500px;
overflow: hidden;
position: relative;
margin: 20px auto;
}
ul {
transition: all .5s ease;
}
li {
float: left;
}
.slide-arrow div {
width: 50px;
height: 100px;
position: absolute;
margin: auto;
top: 0;
bottom: 0;
background: url("http://i1.bvimg.com/1949/4d860a3067fab23b.jpg") no-repeat;
}
.arrow-right {
transform: rotate(180deg);
right: 0;
}
.arrow-left {
left: 0;
}
.slide-option{
position: absolute;
bottom: 10px;
width: 100%;
left: 0;
text-align: center;
}
.slide-option span{
display: inline-block;
width: 14px;
height: 14px;
border-radius: 100%;
background: #ccc;
margin: 0 10px;
}
.slide-option .active{
background: #09f;
}
</style>
</head>
<body>
<div class="slide-img clear" id="slide-img">
<!--用tran這個(gè)class控制ul是否含有過渡效果,樣式已經(jīng)寫好-->
<ul :style="{'width':(listWidth*list.length)+'px','transform':'translate3d(-'+(listWidth*nowIndex)+'px,0,0)'}">
<!--遍歷出來的圖片-->
<li v-for="(li,index) in list" :style="{'width':listWidth+'px'}">
<a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >
<img :src="li" class="slider-img"/>
</a>
</li>
</ul>
<div class="slide-option">
<span v-for="(li,index) in list" :class="{'active':index===nowIndex}"></span>
</div>
<div class="slide-arrow">
<div class="arrow-left" @click.stop="switchDo('reduce')"></div>
<div class="arrow-right" @click.stop="switchDo"></div>
</div>
</div>
</body>
<script src="vue.min.js"></script>
<script type="text/javascript">
new Vue({
el: '#slide-img',
data: {
nowIndex: 0,
listWidth: '1000',
list: ['./images/timg1.jpg', './images/timg2.jpg', './images/timg3.jpg', './images/timg4.jpg'],
timer:null
},
methods: {
//滑動(dòng)操作
switchDo(reduce){
clearInterval(this.timer);
//根據(jù)reduce判斷this.nowIndex的增加或者減少!
if(reduce==='reduce'){
//如果是第一張,就返回最后一張
if(this.nowIndex===0){
this.nowIndex=this.list.length-1;
}
else{
this.nowIndex--;
}
}
else{
//如果是最后一張,就返回第一張
if(this.nowIndex===this.list.length-1){
this.nowIndex=0;
}
else{
this.nowIndex++;
}
}
var _this=this;
this.timer=setInterval(function () {
_this.switchDo();
},4000)
},
},
mounted(){
var _this=this;
this.timer=setInterval(function () {
_this.switchDo();
},4000)
}
})
</script>
</html>
javascript方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="reset.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >
<style>
.slide-img {
width: 1000px;
height: 500px;
overflow: hidden;
position: relative;
margin: 20px auto;
}
ul {
transition: all .5s ease;
}
li {
float: left;
}
.slide-arrow div {
width: 50px;
height: 100px;
position: absolute;
margin: auto;
top: 0;
bottom: 0;
background: url("http://i1.bvimg.com/1949/4d860a3067fab23b.jpg") no-repeat;
}
.arrow-right {
transform: rotate(180deg);
right: 0;
}
.arrow-left {
left: 0;
}
.slide-option{
position: absolute;
bottom: 10px;
width: 100%;
left: 0;
text-align: center;
}
.slide-option span{
display: inline-block;
width: 14px;
height: 14px;
border-radius: 100%;
background: #ccc;
margin: 0 10px;
}
.slide-option .active{
background: #09f;
}
</style>
</head>
<body>
<div class="slide-img clear" id="slide-img">
<!--用tran這個(gè)class控制ul是否含有過渡效果,樣式已經(jīng)寫好-->
<ul id="slide-img-ul">
<!--遍歷出來的圖片-->
<li style="width: 1000px;"><a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" ><img src="images/timg1.jpg" class="slider-img"/></a></li>
<li style="width: 1000px;"><a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" ><img src="images/timg2.jpg" class="slider-img"/></a></li>
<li style="width: 1000px;"><a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" ><img src="images/timg3.jpg" class="slider-img"/></a></li>
<li style="width: 1000px;"><a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" ><img src="images/timg4.jpg" class="slider-img"/></a></li>
</ul>
<div class="slide-option">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<div class="slide-arrow">
<div class="arrow-left"></div>
<div class="arrow-right"></div>
</div>
</div>
</body>
<script type="text/javascript">
window.onload=function () {
var oUl=document.querySelector('#slide-img-ul');
var oLi=oUl.querySelectorAll('li');
var oSpan=document.querySelector('.slide-option').querySelectorAll('span');
var oArrowLeft=document.querySelector('.arrow-left');
var oArrowRight=document.querySelector('.arrow-right');
oUl.style.width='4000px';
oArrowLeft.addEventListener('click',function () {
switchDo('reduce');
})
oArrowRight.addEventListener('click',function () {
switchDo();
})
var timer=null,nowIndex=0;
function switchDo(reduce){
clearInterval(timer);
//設(shè)置樣式
oUl.style.transform='translate3d(-'+(1000*nowIndex)+'px,0,0)';
for (var i=0;i<oSpan.length;i++){
if(i===nowIndex){
oSpan[i].className='active';
}
else{
oSpan[i].className='';
}
}
//根據(jù)reduce判斷this.nowIndex的增加或者減少!
if(reduce==='reduce'){
//如果是第一張,就返回最后一張
if(nowIndex===0){
nowIndex=oLi.length-1;
}
else{
nowIndex--;
}
}
else{
//如果是最后一張,就返回第一張
if(nowIndex===oLi.length-1){
nowIndex=0;
}
else{
nowIndex++;
}
}
timer=setInterval(function () {
switchDo();
},4000)
}
switchDo();
}
</script>
</html>
5.小結(jié)
好了,關(guān)于vue+css3開發(fā)的特效,以及和javascript+css3的對比,就說到這里了,希望這三個(gè)小實(shí)例,能幫到大家了解下應(yīng)該怎么使用vue+css3開發(fā)特效的。今天講這三個(gè)小實(shí)例不是說給大家代碼,讓大家復(fù)制粘貼使用,而是希望能起到一個(gè)拋磚引玉的作用,拓展思維的作用!就像我之前寫文章說得那樣,我寫文章是希望能起到一個(gè)授人以漁的作用,而不是授人以魚!最后,如果大家覺得有什么地方我寫錯(cuò)了,寫錯(cuò)不好,或者有其它什么建議,歡迎指出!讓大家相互學(xué)習(xí),共同進(jìn)步!也希望大家多多支持腳本之家?。。?/p>
相關(guān)文章
vue基于兩個(gè)計(jì)算屬性實(shí)現(xiàn)選中和全選功能示例
這篇文章主要介紹了vue基于兩個(gè)計(jì)算屬性實(shí)現(xiàn)選中和全選功能,結(jié)合實(shí)例形式分析了vue計(jì)算屬性get及set操作頁面元素實(shí)現(xiàn)選中與全選功能相關(guān)操作技巧,需要的朋友可以參考下2019-02-02
一文詳解Vue3中使用ref獲取元素節(jié)點(diǎn)
這篇文章主要介紹了一文詳解Vue3中使用ref獲取元素節(jié)點(diǎn),本文介紹在vue3的setup中使用composition?API獲取元素節(jié)點(diǎn)的幾種方法,需要的朋友可以參考一下2022-07-07
vue中實(shí)現(xiàn)拖拽排序功能的詳細(xì)教程
在業(yè)務(wù)中列表拖拽排序是比較常見的需求,下面這篇文章主要給大家介紹了關(guān)于vue中實(shí)現(xiàn)拖拽排序功能的詳細(xì)教程,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08
詳解vue-cli腳手架build目錄中的dev-server.js配置文件
這篇文章主要介紹了詳解vue-cli腳手架build目錄中的dev-server.js配置文件,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-11-11
Vue.js 時(shí)間轉(zhuǎn)換代碼及時(shí)間戳轉(zhuǎn)時(shí)間字符串
這篇文章主要介紹了Vue.js 時(shí)間轉(zhuǎn)換代碼及時(shí)間戳轉(zhuǎn)時(shí)間字符串,需要的朋友可以參考下2018-10-10
Vue如何將當(dāng)前窗口截圖并將數(shù)據(jù)base64轉(zhuǎn)為png格式傳給服務(wù)器
這篇文章主要介紹了Vue如何將當(dāng)前窗口截圖并將數(shù)據(jù)base64轉(zhuǎn)為png格式傳給服務(wù)器,通過實(shí)例代碼介紹了將當(dāng)前窗口截圖,并將數(shù)據(jù)存儲(chǔ)下來,需要的朋友可以參考下2023-10-10

