效果图
原理
前端,所见即所得
就是人所能得到的就是所能看到的
那么,如果把变色的文字遮住一部分,另一部分保留,那是不是可以达到文字变色效果
再动态控制遮住多少,那是不是可以达到背景经过,文字变色的原理
代码实现
单行文字变色
- 文字不能分行
- 文字只能在同一行
没有背景颜色
<div class="text">Hello,world</div>
// 把.text的文字写入属性data-text,CSS要用
let text = document.querySelector(".text");
text.setAttribute("data-text", text.innerHTML);
.text {
margin: 0;
padding: 0;
position: absolute;
top: 20%;
left: 30%;
font-size: 5em;
color: #ccc;
/* 文字只在一行 */
white-space: nowrap;
}
.text::before {
content: attr(data-text);
position: absolute;
top: 0;
left: 0;
color: red;
overflow: hidden;
width: 0%;
transition: 1s;
}
.text:hover::before {
width: 100%;
}
有背景颜色
- 一般用做按钮
简单写法
<div class="button3">
<div class="text">中间文字</div>
<div class="bg" dataText="中间文字"></div>
</div>
div {
box-sizing: border-box;
}
.button3 {
position: relative;
width: 150px;
height: 30px;
line-height: 30px;
margin: 30px auto;
text-align: center;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
}
.button3 .bg {
position: absolute;
left: 0;
top: 0;
width: 0%;
height: 100%;
background: linear-gradient(to right, #e66465, #9198e5);
}
.button3 .bg::before {
content: attr(dataText);
position: absolute;
top: 0;
left: 0;
color: #fff;
overflow: hidden;
width: 150px;
height: 30px;
transition: 1s;
}
.button3:hover .bg {
width: 100%;
}
复杂写法
<div class="button">
<div class="text">中间文字</div>
<div class="bg">
<div class="bgw"></div>
<span>中间文字</span>
</div>
</div>
div {
box-sizing: border-box;
}
.button {
position: relative;
width: 150px;
height: 30px;
line-height: 30px;
margin: 30px auto;
text-align: center;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
}
.text {
width: 100%;
height: 100%;
height: 100%;
position: absolute;
}
.bg {
position: absolute;
left: 0;
top: 0;
width: 0%;
height: 100%;
overflow: hidden;
transition: all 0.5s ease-out;
}
.button:hover .bg {
width: 100%;
}
.bgw {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: linear-gradient(to right, #e66465, #9198e5);
}
.bg span {
position: absolute;
left: 0;
top: 0;
display: block;
z-index: 10;
color: #fff;
width: 150px;
height: 100%;
}
多行文字
<div class="box">
<div class="bg">
<div class="bgText"></div>
</div>
<div class="text">
前端,所见即所得,就是人所能得到的就是所能看见的,那么,如果把变色的文字遮住一部分,另一部分保留,那是不是可以达到文字变色效果,再动态控制遮住多少,那是不是可以达到背景经过,文字变白的原理
</div>
</div>
* {
box-sizing: border-box;
}
.box {
/* 超出部分隐藏 */
overflow: hidden;
position: relative;
width: 300px;
height: 400px;
background-color: #34495e;
border-radius: 10px;
box-shadow: 10px 10px 20px rgba(33, 44, 55, 0.3);
margin: 100px auto;
}
.text {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 230px;
}
.bg {
position: absolute;
top: 0;
left: 0;
width: 0;
height: 0;
border-radius: 50%;
/* 鼠标居中 */
transform: translate(-50%, -50%);
background-color: #916968;
z-index: 9;
overflow: hidden;
display: none;
}
@keyframes in {
0% {
width: 0;
height: 0;
}
100% {
/* 1000px这个值是box对角线500的两倍*/
width: 1000px;
height: 1000px;
}
}
@keyframes out {
0% {
/* 1000px这个值是box对角线500的两倍*/
width: 1000px;
height: 1000px;
}
100% {
width: 0;
height: 0;
}
}
.bgText {
position: absolute;
color: #fff;
z-index: 8;
width: 0;
display: none;
}
@keyframes bgTextIn {
0% {
left: 0;
top: 0;
}
100% {
/* 500px这个值是box对角线500px的两倍*/
left: 500px;
top: 500px;
}
}
@keyframes bgTextOut {
0% {
/* 500px这个值是box对角线500px的大小*/
left: 500px;
top: 500px;
}
100% {
left: 0;
top: 0;
}
}
let box = document.querySelector(".box");
let text = document.querySelector(".text");
let textRect = text.getBoundingClientRect();
let bg = document.querySelector(".bg");
let bgRect = bg.getBoundingClientRect();
let bgText = document.querySelector(".bgText");
let bgextRect = bgText.getBoundingClientRect();
// 写入文字
bgText.innerHTML = text.innerHTML;
let inTime, outTime;
let isIn = true; //默认开关 打开
let isOut;
//鼠标进入事件
box.addEventListener("mouseenter", function (e) {
isOut = false; //预先关闭,若不进入if语句,则不能进入鼠标离开事件里的 if
if (isIn) {
bgText.style.width = textRect.width + "px";
bgText.style.height = textRect.height + "px";
inTime = new Date().getTime();
//bg 去使用 in动画
bg.style.animation = "in .5s ease-out forwards";
bgText.style.animation = "bgTextIn .5s ease-out forwards";
bg.style.display = "block";
bgText.style.display = "block";
console.log(e);
//计算 top 和 left 值,跟踪鼠标位置
let top = e.clientY - e.target.offsetTop;
let left = e.clientX - e.target.offsetLeft;
bg.style.top = top + "px";
bg.style.left = left + "px";
// 对齐文字
// 对齐文字
// 对齐文字
bgText.style.transform = `translate(${
bgRect.width / 2 - left
}px,${bgRect.height / 2 - top}px)`;
isIn = false; //当我们执行完程序后,关闭
isOut = true; //当我们执行完里面的程序,再打开
}
});
//鼠标离开事件
box.addEventListener("mouseleave", function (e) {
if (isOut) {
outTime = new Date().getTime();
let passTime = outTime - inTime;
if (passTime < 500) {
setTimeout(mouseleave, 500 - passTime); //已经经过的时间就不要了
} else {
mouseleave();
}
}
function mouseleave() {
bg.style.animation = "out .5s ease-out forwards";
bgText.style.animation = "bgTextOut .5s ease-out forwards";
//计算 top 和 left 值,跟踪鼠标位置
let top = e.clientY - e.target.offsetTop;
let left = e.clientX - e.target.offsetLeft;
bg.style.top = top + "px";
bg.style.left = left + "px";
// 对齐文字
// 对齐文字
// 对齐文字
bgText.style.transform = `translate(${
bgRect.width / 2 - left
}px,${bgRect.height / 2 - top}px)`;
//注意:因为要等到动画结束,所以要给个定时器
setTimeout(function () {
isIn = true; //当我们执行完鼠标离开事件里的程序,才再次打开
}, 500);
}
});