发布时间:2022-08-11 文章分类:编程知识 投稿人:赵颖 字号: 默认 | | 超大 打印

?前言

?分析

[前端小项目] 模糊加载 blurry loading (50projects50days)

  1. 数字从0不断增长到100;
  2. 中间的百分比数字逐渐消失,即透明度opacity到1到0;
  3. 背景图片从模糊变为清晰,滤镜filter:blur()的参数设置为从30px0px.

?布局

?图片大小

⏱进度模拟

?不同数值范围之间的映射

变量名 意义
$in\_min$ 输入范围的起始值
$in\_max$ 输入范围的终止值
$input$ 输入的值
$out\_min$ 输出范围的起始值
$out\_max$ 输出范围的终止值
$output$ 输出的值,即映射得到的值

输入值在输入范围内占比:

\[scale_0 = \frac{input-in\_min}{in\_max - in\_min}
\]

输出值在输出范围内的占比:

\[scale_1 = \frac{output-out\_min}{out\_max - out\_min}
\]

又因为输入值在输入范围内的占比输出值在输出范围中的占比应保持一致:

\[\frac{input-in\_min}{in\_max - in\_min} = \frac{output-out\_min}{out\_max - out\_min}
\]

化简后,可得输出值output:

\[output = \frac{input-in\_min}{in\_max - in\_min} \times (out\_max - out\_min) + out\_min
\]
function scale(num, inMin, inMax, outMin, outMax) {
        return ((num - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin;
    }

该函数代码参考自StackOverflow?map a range of numbers to another range of numbers

?代码实现

<!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>blurry-loading</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            min-height: 100vh;
            /* 使用flex布局,将文字设置在屏幕中间 */
            display: flex;
            align-items: center;
            justify-content: center;
            overflow: hidden;
        }
        .bg {
            position: absolute;
            background: url(https://images.unsplash.com/photo-1576161787924-01bb08dad4a4?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2104&q=80) no-repeat center center/cover;
            filter: blur(0px);
            z-index: -1;
            /* blur滤镜会导致图片边界出现白色区域,将图片扩大可以改善 */
            top:-30px;
            left:-30px;
            width: calc(100vw + 60px);
            height: calc(100vh + 60px);
        }
        .load {
            /* 文字样式 */
            font-size: 2rem;
            color: #fff;
            font-weight: bold;
            /* 设置为不可选中 */
            user-select: none;
        }
    </style>
</head>
<body>
    <section class="bg"></section>
    <p class="load">0%</p>
</body>
<script>
    // 获取文字和背景图片
    const loadText = document.querySelector('.load');
    const bg = document.querySelector('.bg');
    //load表示当前进度的百分比数字
    let load = 0;
    // setInterval:进度不断增加,并渲染进度数字和背景模糊程度
    const int = setInterval(loading, 20);
    function loading() {
        //进度增加
        load++;
        //如果进度到达100,表示进度完成,不用增加了。
        if (load > 99) {
            clearInterval(int);
        }
        //修改进度百分数
        loadText.innerText = `${load}%`;
        //修改数字的透明度:具体表现为文字逐渐隐形
        loadText.style.opacity = scale(load, 0, 100, 1, 0);
        //修改背景图片的模糊程度
        bg.style.filter = `blur(${scale(load,0,100,30,0)}px)`;
    }
    //https://stackoverflow.com/questions/10756313/javascript-jquery-map-a-range-of-numbers-to-another-range-of-numbers
    //这个函数的作用是:获取 一个在某范围内的值 映射到 另一个范围时 对应的值。
    function scale(num, inMin, inMax, outMin, outMax) {
        return ((num - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin;
    }
</script>
</html>