炫酷渐变文本加载效果(附源代码)

[复制链接]
七夏(UID:1) 发表于 2024-10-8 10:19:47 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×

图片

这是一个很炫酷的渐变文字价值效果,这个效果的独特之处在于它结合了多层文本、渐变色和遮罩动画,创造出一种复杂而吸引人的视觉效果。通过 CSS 变量的使用,代码也具有很好的可定制性,允许轻松更改颜色、动画时间等参数。

主要特点和核心实现逻辑如下:

效果描述:

  1. 每个单词都有一个从右到左的渐变色擦除动画效果。
  2. 动画包括三层:原始文本、彩色渐变文本和模糊的彩色渐变文本。
  3. 每个单词使用不同的颜色渐变。

核心实现逻辑:

  1. HTML结构:每个单词被包裹在三个 <span> 标签中,分别对应普通文本、渐变文本和模糊渐变文本。
  2. CSS变量:使用 CSS 变量定义动画持续时间、缓动函数和颜色渐变。
  3. 渐变色背景:使用 linear-gradient 创建彩色渐变背景。通过 --colors CSS 变量自定义每个单词的渐变色。
  4. 文本裁剪:使用 -webkit-background-clip: text-webkit-text-fill-color: transparent 将渐变背景裁剪成文字形状。
  5. 遮罩动画:使用 CSS mask 属性创建一个从右到左移动的遮罩。遮罩使用 linear-gradient 定义,创建一个渐变的透明度效果。mask-size: 300% 100% 使遮罩宽度为元素的三倍,允许完整的动画循环。
  6. 模糊效果:.blur-in 类使用 filter: blur(10px) 创建模糊效果。
  7. 动画同步:所有三层使用相同的动画持续时间和缓动函数,确保同步移动。

源代码

<!DOCTYPE html>
<html lang="en">

<head>
   <meta name="viewport" content="width=device-width, initial-scale=1">

<style>
  * {
  transition: all 0.5s;
}

body {
  background-color: #252525;
  font-family: "Lato", sans-serif;
  font-weight: 300;
}

.text {
  position: absolute;
  left: 10px;
  bottom: 10px;
}

.text, a {
  color: #f4f4f4;
  font-weight: 100;
}

svg {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.textTime {
  fill: #f4f4f4;
  text-anchor: middle;
  alignment-baseline: middle;
  font-size: 1.5rem;
  font-weight: 100;
}

.outerRing {
  fill: none;
  stroke: #f4f4f4;
  stroke-width: 2px;
  stroke-dasharray: 4px;
  opacity: 0.5;
}

.primCircle {
  fill: #252525;
  stroke: #f4f4f4;
  stroke-width: 10px;
}

.secCircle {
  fill: #45d9fd;
  stroke: #252525;
  stroke-width: 3px;
}

.spike {
  stroke: #f4f4f4;
  stroke-width: 2px;
}

.triangle {
  fill: #ee2560;
}
</style>
</head>

<body>
<div class="clock"></div>
</body>

<script>
const r1 = 5;
const r2 = 10;
const r3 = 15;
const width = window.innerWidth;
const height = window.innerHeight;

const minWH = Math.min(width, height);

let maxSize;
if (minWH < 430) {
    maxSize = minWH - 30;
} else {
    maxSize = 400;
}

const rad = (a) => (Math.PI * (a - 90)) / 180;
const rx = (r, a, c) => c + r * Math.cos(rad(a, c));
const ry = (r, a, c) => c + r * Math.sin(rad(a));
const HMS = (t) => ({
    h: t.getHours(),
    m: t.getMinutes(),
    s: t.getSeconds()
});

const pathStringVars = (c, r, time) => {
    const { h, m, s } = HMS(time);
    const hAngFact = 30;
    const mAngFact = 6;
    const sAngFact = 6;
    const hx = rx(r - 30, hAngFact * h, c);
    const hy = ry(r - 30, hAngFact * h, c);
    const mx = rx(r - 30, mAngFact * m, c);
    const my = ry(r - 30, mAngFact * m, c);
    const sx = rx(r - 30, sAngFact * s, c);
    const sy = ry(r - 30, sAngFact * s, c);
    return { hx, hy, mx, my, sx, sy };
};

// 辅助函数:创建SVG元素
function createSVGElement(type) {
    return document.createElementNS("http://www.w3.org/2000/svg", type);
}

// 创建时钟
function createClock() {
    const size = maxSize;
    const viewBox = `0 0 ${size} ${size}`;
    const mid = size / 2;
    const paddedRadius = (size - 30) / 2;

    const svg = createSVGElement("svg");
    svg.setAttribute("viewBox", viewBox);
    svg.setAttribute("width", size);
    svg.setAttribute("height", size);

    // 外圈
    const outerRing = createSVGElement("circle");
    outerRing.setAttribute("cx", mid);
    outerRing.setAttribute("cy", mid);
    outerRing.setAttribute("r", mid - 5);
    outerRing.setAttribute("class", "outerRing");
    svg.appendChild(outerRing);

    // 内圈
    const primCircle = createSVGElement("circle");
    primCircle.setAttribute("cx", mid);
    primCircle.setAttribute("cy", mid);
    primCircle.setAttribute("r", mid - 15);
    primCircle.setAttribute("class", "primCircle");
    svg.appendChild(primCircle);

    // 刻度
    const spikesGroup = createSVGElement("g");
    for (let i = 1; i < 13; i++) {
        let ang = i * 30;
        let spike = createSVGElement("line");
        spike.setAttribute("x1", rx(paddedRadius - 5, ang, mid));
        spike.setAttribute("x2", rx(paddedRadius - 10, ang, mid));
        spike.setAttribute("y1", ry(paddedRadius - 5, ang, mid));
        spike.setAttribute("y2", ry(paddedRadius - 10, ang, mid));
        spike.setAttribute("class", "spike");
        spikesGroup.appendChild(spike);
    }
    svg.appendChild(spikesGroup);

    // 三角形路径
    const triangle = createSVGElement("path");
    triangle.setAttribute("class", "triangle");
    svg.appendChild(triangle);

    // 二级圆圈
    const secCircleGroup = createSVGElement("g");
    for (let i = 0; i < 3; i++) {
        const circle = createSVGElement("circle");
        circle.setAttribute("class", "secCircle");
        circle.setAttribute("r", [r1, r2, r3][i]);
        secCircleGroup.appendChild(circle);
    }
    svg.appendChild(secCircleGroup);

    // 文本时间
    const textTime = createSVGElement("text");
    textTime.setAttribute("x", mid);
    textTime.setAttribute("y", mid);
    textTime.setAttribute("class", "textTime");
    svg.appendChild(textTime);

    document.querySelector(".clock").appendChild(svg);

    // 更新时钟
    function updateClock() {
        const time = new Date();
        const { hx, hy, mx, my, sx, sy } = pathStringVars(mid, paddedRadius, time);

        // 更新三角形
        triangle.setAttribute("d", `M${hx},${hy} L${mx},${my} L${sx},${sy} L${hx},${hy}`);

        // 更新二级圆圈
        const circles = secCircleGroup.children;
        circles[0].setAttribute("cx", hx);
        circles[0].setAttribute("cy", hy);
        circles[1].setAttribute("cx", mx);
        circles[1].setAttribute("cy", my);
        circles[2].setAttribute("cx", sx);
        circles[2].setAttribute("cy", sy);

        // 更新文本时间
        const timeString = time.toTimeString().slice(0, 8).replace(/:/g, " : ");
        textTime.textContent = timeString;
    }

    // 每秒更新时钟
    setInterval(updateClock, 1000);
    updateClock(); // 初始更新
}

// 当DOM加载完成后创建时钟
document.addEventListener("DOMContentLoaded", createClock);
</script>
</html>
小时候,看腻了农村的牛和马,长大后,来到了城里,才知道原来到处都是牛马!
全部回复0 显示全部楼层
暂无回复,精彩从你开始!

快速回帖

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于楼主

管理员
  • 主题

    710
  • 回答

    248
  • 积分

    1903
虚位以待,此位置招租

商务推广

    网盘拉新-短剧推广 此位置招租 此位置招租 此位置招租 此位置招租 此位置招租 此位置招租 此位置招租 此位置招租 此位置招租