<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="colorblock1" id="b"></div>
<button onclick="a()">变色</button>
<style>
.colorblock1 {
width: 300px;
height: 100px;
margin: 20px auto;
background-image: -webkit-linear-gradient(left, rgb(255, 0, 0), blue);
/* Safari 5.1 - 6.0 */
background-image: -o-linear-gradient(right, red, blue);
/* Opera 11.1 - 12.0 */
background-image: -moz-linear-gradient(right, red, blue);
/* Firefox 3.6 - 15 */
background-image: linear-gradient(to right, red, blue);
/* 标准的语法(必须放在最后) */
opacity: 1;
}
.colorblock2 {
width: 300px;
height: 100px;
margin: 20px auto;
background-image: -webkit-linear-gradient(left, rgba(228, 248, 50, 0.479), rgba(52, 235, 77, 0.932));
/* Safari 5.1 - 6.0 */
background-image: -o-linear-gradient(right, rgba(228, 248, 50, 0.473), rgba(52, 235, 77, 0.932));
/* Opera 11.1 - 12.0 */
background-image: -moz-linear-gradient(right, rgba(228, 248, 50, 0.473), rgba(52, 235, 77, 0.932));
/* Firefox 3.6 - 15 */
background-image: linear-gradient(to right, rgba(228, 248, 50, 0.438), rgba(52, 235, 77, 0.932));
/* 标准的语法(必须放在最后) */
opacity: 0;
}
</style>
<script>
//实现颜色渐弱然后渐强
function a() {
let d = document.getElementById('b')
let j = 1
let z = 0
for (let i = 1; i >= 0; i = i - 0.001) {
setTimeout(function () {
d.style.cssText = `opacity: ${j}; `
j = j - 0.001
}, i * 300)
}
setTimeout(function () {
d.setAttribute("class", "colorblock2")
}, 400)
for (let i = 2; i >= 1; i = i - 0.001) {
setTimeout(function () {
d.style.cssText = `opacity: ${z}; `
z = z + 0.001
}, i * 500)
}
}
</script>
</body>
</html>
原理:通过 JS 函数修改颜色的透明度属性,从1到0逐渐减少透明度就会让颜色消失,再从0到1逐渐增加透明度就可以让颜色重新出现,如果在消失和出现之间在变换样式颜色,就可以实现颜色从一个颜色逐渐变为另一个颜色。
方法L:利用for循环,和三个 setTimeout安排渐变和颜色改变的顺序,三个setTimeout的延迟经过测试,可以是 400,500,600或者他们的倍数。并且要做出渐进的动画效果,每个setTimeout的延迟还不能相同,必须是成一个函数递增的关系,所以就可以在延迟上乘上一个步长 ,让时间延迟成 y = x * 步长 的一次函数关系,这样每个渐变之间相差相同的时间,就可以实现顺滑的渐变效果了。
不能用循环体的变量 i 作为透明度的参数
并且注意,for循环在执行时遇到setTimeout会直接把它放到宏任务队列,并不会执行setTimeout中的回调函数,只有当宏任务开始执行时才回调,所以函数中设置透明度的选项只会等for循环执行完后才会执行,此时 for上的 i 早就已经变成最大/最小值了,所以千万不能用循环体的变量 i 来作为透明度的参数,有些人图省事直接用 i 作为变量,最后发现根本没有渐变的效果。
所以需要在循环体外单独创建两个变量,来指定透明度的变化。
透明度的递增递减的步长最好在0.001的数量级最好。
函数部分:
function a() {
let d = document.getElementById('b')
let j = 1 //用于控制颜色消失时的透明度值
let z = 0 //用于控制颜色出现时的透明度值
for (let i = 1; i >= 0; i = i - 0.001) { //千万不要用循环体的i作为透明度变化的参数
setTimeout(function () { //setTimeout直接加入宏任务队列
d.style.cssText = `opacity: ${j}; `
j = j - 0.001
}, i * 300)
}
setTimeout(function () {
d.setAttribute("class", "colorblock2")
}, 400)
//第二个for循环最好是第一个for循环的2倍,使得setTimeout的时间足够的长。
for (let i = 2; i >= 1; i = i - 0.001) {
setTimeout(function () {
d.style.cssText = `opacity: ${z}; `
z = z + 0.001
}, i * 500)
}
}
注意一点,setTimeout的时间延迟都是从长到短的。
更多js动画效果:https://www.jb51.net/article/74686.htm
https://www.imooc.com/learn/167