常見JS動畫效果
阿新 • • 發佈:2018-12-31
作為一名前端開發人員,想要的大多都是,在開發過程中,看著自己製作的動畫的炫酷以及困難的解決;開發結束後,自己的專案、成果可以被他人認可接受。人們瀏覽網頁時,若一個網頁動畫效果豐富炫酷,效能良好,體驗度良好,自然會受到吸引去打來瀏覽。吸引使用者,自然少不了網頁的佈局優美、色彩搭配的恰當,更重要的是其中吸引人的炫酷動畫效果。
在這裡,我為大家提供幾種常用的動畫效果,雖然沒有什麼特別,不是很炫酷,但很常見也很便捷。
一、輪播圖:
輪播圖在網頁中運用較廣,經常使用於頭部banner,使用於電商網站中,例如;淘寶、京東、天貓等購物平臺都少不了。而輪播圖有多種型別,這次就和大家說說其中的兩款。輪播圖的原理:點選上一張或下一張時,圖片移動的距離為圖片本身的寬度;點選圖片下的原點導航時跳轉到相應的圖片位置。
1、一般的輪播圖。這一型別的輪播圖,在切換圖片的過程中,圖片會緩慢的滑動到達相應的位置,即可以看到圖片到達相應位置的全過程。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
img{
width: 520px;
}
div.box{
width: 520px;
height: 280px;
overflow: hidden;
margin: 100px auto;
position: relative;
}
ul.img{
top: 0px;
left: 0px;
width: 1000%;
position : absolute;
}
ul.img li{
float: left;
list-style: none;
}
ul.circle{
left: 50%;
bottom: 10px;
margin-left: -75px;
position: absolute;
}
ul.circle li{
width: 20px;
height: 20px;
float: left;
color: #666;
cursor: pointer;
margin: 0px 5px;
list-style: none;
text-align: center;
border-radius: 10px;
background: #e4e4e4;
font: normal 12px/20px "conslas";
}
ul.arrow{
top: 50%;
width: 100%;
position: absolute;
margin-bottom: -25px;
}
ul.arrow li{
width: 35px;
height: 50px;
color: #666;
cursor: pointer;
list-style: none;
text-align: center;
background: #ccc;
font: 800 30px/50px "conslas";
}
ul.arrow li.left{
float:left;
}
ul.arrow li.right{
float: right;
}
ul.circle li.current{
color:#fff;
background: red;
}
</style>
</head>
<body>
<div class="box">
<ul class="img">
<li><img src="img/p1.jpg" alt="" /></li>
<li><img src="img/p2.jpg" alt="" /></li>
<li><img src="img/p3.jpg" alt="" /></li>
<li><img src="img/p4.jpg" alt="" /></li>
<li><img src="img/p5.jpg" alt="" /></li>
</ul>
<ul class="circle">
</ul>
<ul class="arrow">
<li class="left"><</li>
<li class="right">></li>
</ul>
</div>
<script>
var box=document.getElementsByTagName("div")[0];//輪播圖容器
var img=box.children[0];//圖片容器
var circle=box.children[1];//小圓點容器
var arrow=box.children[2];//箭頭容器
var left=arrow.children[0];//左箭頭
var right=arrow.children[1];//右箭頭
var index=0;//當前顯示的圖片的索引
//需求分析:
//1、在最後一幅圖後面新增第一幅圖
var addImg=img.children[0].cloneNode(true);
img.appendChild(addImg);
//2、動態新增小圓點,同時點亮第一個
var circles=img.children;//小圓點的個數即所有圖片的個數集合
for(var i=1;i<circles.length;i++){
var circleLi=document.createElement("li");
circleLi.innerHTML=i;
circle.appendChild(circleLi);
}
var points=circle.children;
light();
function light(){
for(var i=0;i<points.length;i++){
points[i].className="";
if(index>4){
points[0].className="current";
}else{
points[index].className="current";
}
}
}
//3、點選小圓點,ul移動到相應的圖片,同時點亮小圓點
for(var j=0;j<points.length;j++){
points[j].index=j;
points[j].onclick=function(){
index=this.index;
animate(img,-index*box.offsetWidth);
light();
}
}
//4、左右箭頭切換圖片
right.onclick=autoplay;
function autoplay(){
index++;
if(index>circles.length-1){
img.style.left=0;
index=1;
}
animate(img,-index*box.offsetWidth);
light();
}
left.onclick=function(){
index--;
if(index<0){
img.style.left=-(circles.length-1)*box.offsetWidth+"px";
index=circles.length-2;
}
animate(img,-index*box.offsetWidth);
light();
}
//5、新增自動輪播功能
box.timer=setInterval(autoplay,2000);
box.onmouseover=function(){
clearInterval(box.timer);
}
box.onmouseout=function(){
clearInterval(box.timer);
box.timer=setInterval(autoplay,2000);
}
function animate(obj,target){
clearInterval(obj.timer);
obj.timer=setInterval(function(){
var speed=(obj.offsetLeft>target?-20:20);
if(Math.abs(obj.offsetLeft-target)>20){
obj.style.left=obj.offsetLeft+speed+"px";
}else{
obj.style.left=target+"px";
}
},20)
}
</script>
</body>
</html>
2、無縫輪播圖。此類輪播圖不會顯示圖片移動的全過程。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
* {
margin: 0;
padding: 0;
border: none;
list-style: none;
}
img {
width: 310px;
height: 220px;
}
.slider {
width: 310px;
height: 265px;
margin: 100px auto;
position: relative;
overflow: hidden;
cursor: pointer;
}
.slider-img {
width: 310px;
height: 220px;
}
ul {
list-style: none;
}
li {
position: absolute;
top: 0;
left: 0;
}
.slider-ctrl {
text-align: center;
padding-top: 10px;
}
.slider-ctrl-con {
display: inline-block;
width: 24px;
height: 24px;
background: url("img/icon.png") no-repeat -24px -780px;
text-indent: -99999px;
margin: 0 5px;
cursor: pointer;
}
.slider-ctrl-con.current {
background-position: -24px -760px;
}
.prev,
.next {
position: absolute;
top: 40%;
width: 30px;
height: 35px;
background: url("img/icon.png") no-repeat;
}
.prev {
left: 10px;
}
.next {
right: 10px;
background-position: 0 -44px;
}
</style>
</head>
<body>
<div class="slider" id="slider" style="overflow: hidden;">
<div class="slider-img">
<ul>
<li>
<a href="#"><img src="img/p1.jpg" alt="" /></a>
</li>
<li>
<a href="#"><img src="img/p2.jpg" alt="" /></a>
</li>
<li>
<a href="#"><img src="img/p3.jpg" alt="" /></a>
</li>
<li>
<a href="#"><img src="img/p4.jpg" alt="" /></a>
</li>
<li>
<a href="#"><img src="img/p5.jpg" alt="" /></a>
</li>
<li>
<a href="#"><img src="img/p6.jpg" alt="" /></a>
</li>
</ul>
</div>
<div class="slider-ctrl">
<span class="prev" id="prev"></span>
<span class="next" id="next"></span>
</div>
</div>
<script type="text/javascript">
window.onload = function() {
var slider = document.getElementById("slider"); //獲取元素
var ul = document.getElementsByTagName('ul')[0];
var lis = ul.children;
var per = document.getElementById('prev');
var next = document.getElementById('next');
var imgWidth = slider.offsetWidth; //獲取圖片的寬度作為緩動的距離
for (var i = 0; i < lis.length; i++) { //新增span,用於點選跳轉到指定圖片
var span = document.createElement('span');
span.innerHTML = i;
span.className = "slider-ctrl-con "; //新增未選中狀態
per.parentNode.insertBefore(span, per);
lis[i].style.left = imgWidth + "px";
}
var num = 0; //標記索引值
var span = document.getElementsByTagName('span'); //獲取span元素
span[0].className += " current"; //為第一個span標籤狀態設定為選中狀態
lis[0].style.left = 0 + "px"; //為第一張圖片設定顯示位置
for (var k = 0; k < span.length; k++) {
span[k].onclick = function() { //為所有span標籤新增點選事件(包括左右按鈕)
if (this.className == "prev") { //當點選的是向前播放按鈕時
//要看上一張
animation(lis[num], imgWidth); //當前圖片緩動到右邊位置
num = --num < 0 ? lis.length - 1 : num; //索引值設定為前一張圖片的索引,當索引值小於0時則等於最後一張的索引
lis[num].style.left = -imgWidth + "px"; //將前一張圖片瞬間移動到左側
animation(lis[num], 0); //將移動到左側的圖片,緩動到顯示位置
light(); //點亮底部相應的span標籤
} else if (this.className == 'next') { //當點選的是向後播放按鈕時
//要看下一張
autoplay(); //按自動播放順序播放
} else {
//獲取當前被點選的盒子的索引值
var index = this.innerHTML;
//中間:left = 0;左邊:left = -imgWidth+“px";右邊:left = +imgWidth+”px“
//判斷點選的span和當前的圖片的索引,誰大誰小
if (index > num) { //當點選索引值大於當前播放圖片的索引值時
lis[index].style.left = imgWidth + "px"; //該索引值對應的圖片瞬間移動到右側
animation(lis[num], -imgWidth); //當前播放圖片緩動到左側
animation(lis[index], 0); //再緩動至當前播放位置
num = index; //改變索引值
light(); //點亮底部相應的span標籤
}
if (index < num) {
lis[index].style.left = -imgWidth + "px";
animation(lis[num], imgWidth);
animation(lis[index], 0);
num = index;
light();
}
}
}
}
function animation(obj, target) { //緩動
clearInterval(obj.timer); //為避免多個定時器同時執行帶來的bug,在用定時器之前先清理定時器
obj.timer = setInterval(function() {
var speed = (target - obj.offsetLeft) / 10;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); //為確保能搞達到最終目標值,給speed取整
obj.style.left = obj.offsetLeft + speed + "px"; //賦值給當前元素
if (target == obj.offsetLeft) { //屬性達到目標值時,清理定時器
clearInterval(obj.timer);
}
}, 20);
}
slider.timer = setInterval(function() { //當前無操作時自動播放
autoplay();
}, 2000);
slider.onmouseover = function() { //滑鼠進入圖片區域停止自動播放
clearInterval(slider.timer);
}
slider.onmouseout = function() { //滑鼠離開圖片區域恢復自動播放
clearInterval(slider.timer);
slider.timer = setInterval(function() {
autoplay();
}, 2000);
}
function light() {
for (var j = 0; j < span.length - 2; j++) {
span[j].className = "slider-ctrl-con ";
}
span[num].className += " current";
}
function autoplay() { //封裝自動播放函式
animation(lis[num], -imgWidth);
num = ++num > lis.length - 1 ? 0 : num;
lis[num].style.left = imgWidth + "px";
animation(lis[num], 0);
light();
}
}
</script>
</body>
</html>
二、旋轉木馬。顧名思義,旋轉木馬的動畫效果和遊樂園中旋轉木馬類似,因此而得名。旋轉木馬的原理和輪播圖其實差不多,只是旋轉木馬需要設定每一張圖片的z-index屬性,且每一張的z-index的設定精準、滿意需要一定的經驗。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
* {
margin: 0;
padding: 0;
}
.wrap {
width: 1200px;
margin: 10px auto;
}
.slider {
height: 500px;
position: relative;
}
.slider li {
list-style: none;
position: absolute;
left: 200px;
top: 0;
}
.slider li img {
width: 100%;
display: block;
}
.arrow {
opacity: 1;
}
.prev,
.next {
width: 76px;
height: 112px;
position: absolute;
top: 50%;
margin-top: -56px;
background: url(img/prev.png) no-repeat;
z-index: 99;
}
.next {
right: 0;
background: url("img/next.png") no-repeat;
}
.prev {
left: 0;
}
</style>
</head>
<body>
<div class="wrap">
<div class="slider">
<ul>
<li><img src="img/1.jpg" /></li>
<li><img src="img/2.png" /></li>
<li><img src="img/3.jpg" /></li>
<li><img src="img/4.jpg" /></li>
<li><img src="img/5.jpg" /></li>
</ul>
<div class="arrow">
<div class="prev" id="prev"></div>
<div class="next" id='next'></div>
</div>
</div>
</div>
<script>
var json = [{ // 0
width: 400,
top: 70,
left: 50,
opacity: 0.2,
zIndex: 2
}, { // 1
width: 600,
top: 120,
left: 0,
opacity: 0.8,
zIndex: 3
}, { // 2
width: 800,
top: 100,
left: 200,
opacity: 1,
zIndex: 4
}, { // 3
width: 600,
top: 120,
left: 600,
opacity: 0.8,
zIndex: 3
}, { //4
width: 400,
top: 70,
left: 750,
opacity: 0.2,
zIndex: 2
}];
//根據json的內容把圖片緩動到相應位置,同時緩動
var liArr = document.getElementsByTagName('li');
var next = document.getElementById('next');
var prev = document.getElementById('prev');
function move() {
for (var i = 0; i < liArr.length; i++) {
animation(liArr[i], json[i]);
}
}
move()
next.onclick = function() {
var last = json.pop();
json.unshift(last);
move()
}
prev.onclick = function() {
var first = json.shift();
json.push(first);
move();
}
function animation(obj, json, fn) {
clearInterval(obj.timer);
obj.timer = setInterval(function() {
var flag = true;
//json裡面有幾個屬性就要執行幾次
var target = 0; //記錄目標位置
var leader = 0; //記錄當前位置
var speed = 0; //記錄速度
for (var key in json) {
if (key == 'opacity') {
target = Math.round(json['opacity'] * 100) //0-100
leader = getStyle(obj, 'opacity') * 100 //0-100
} else {
target = parseInt(json[key]);
leader = parseInt(getStyle(obj, key));
}
speed = (target - leader) / 10;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
leader = leader + speed; //0-100
if (key == 'opacity') {
obj.style.opacity = leader / 100;
obj.style.filter = "alpha(opacity=" + leader + ")";
} else if (key == "zIndex") {
obj.style.zIndex = json['zIndex'];
} else {
obj.style[key] = leader + "px";
}
if (leader != target) {
flag = false
}
}
if (flag) {
clearInterval(obj.timer);
if (fn) {
fn();
}
}
}, 20)
}
function getStyle(obj, attr) {
if (window.getComputedStyle) {
return window.getComputedStyle(obj, null)[attr]
} else {
return obj.currentStyle[attr];
}
}
</script>
</body>
</html>
三、樓層跳躍。該動畫效果也大多使用在電商網站,當點選到相應的標籤時就會跳到該位置的內容。例如:當點選淘寶旁的樓層跳躍中的美妝/女裝時就會跳到美妝/女裝模組。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>