• 日常搜索
  • 百度一下
  • Google
  • 在线工具
  • 搜转载

如何在滚动上构建灰度到颜色效果(CSS 和 JavaScript)

在这个新教程中,我们将从一些灰度图像开始,并学习如何在滚动时平滑地显示它们的颜色变体。为了达到预期的效果,我们将利用不同的现代前端特性,如 css Grid、 clip-path属性和 Intersection Observer api

我们的灰度到颜色效果

无需进一步介绍,让我们看看我们将要构建的内容:

See the Pen  How to Build a Grayscale to Color Effect on Scroll by Envato Tuts+ (@tutsplus)  on CodePen.

浏览器支持

尽管此效果具有不错的浏览器支持,但请注意,它不适用于某些浏览器,例如早期版本的 Microsoft Edge。对于这个例子,我将专注于效果背后的技术,而不为其他浏览器提供回退。

注意:一旦你完成了本教程,就可以通过这个后续行动将你的技能提升到一个新的水平!

1. 从 html 标记开始

我们将从四个部分开始:

<section class="section">...</section>

<section class="section">...</section>

<section class="section">...</section>

<section class="section">...</section>

在每个部分中,我们将放置一个标题和一个全屏 div包装器。包装器将包含两个空div的 s。两个元素将共享相同的背景图像。第一个将显示它的灰度版本,而最后一个将显示其原始彩色版本:

<h2>...</h2>

<div class="vh-100 img-wrapper">

  <div class="grayscale cover" style="background-image: url(IMG_SRC);"></div>

  <div class="colored cover" style="background-image: url(IMG_SRC);"></div>

</div>

彩色图像将显示从左到右的幻灯片动画data-animation令人高兴的是,我们可以通过属性自定义这个动画的方向。它所需要的只是将此属性添加到具有值、或的相应.colored元素。to-leftto-topto-bottom

2. 定义样式

准备好标记后,我们将继续使用主要样式。

实用程序类

对于这个演示,我们将首先定义两个实用程序类,我们将附加到目标元素: 

.cover {

  background-size: cover;

  background-position: center;

  background-repeat: no-repeat;

}

 

.vh-100 {

  height: 100vh;

}

堆叠元素

默认情况下,div保存图像的 s 将堆叠在另一个之上。只有div灰度图像可见。

以下是所需的样式:

/*CUSTOM VARIABLES HERE*/

 

.img-wrapper {

  display: grid;

}

 

.img-wrapper div {

  grid-column: 1;

  grid-row: 1;

}

灰度图像

要创建灰度图像,我们将使用grayscale() CSS 函数并将 1 or的值100%作为其参数传递。此外,我们将为所有灰度图像提供背景颜色作为后备,直到每个图像加载:

/*CUSTOM VARIABLES HERE*/

 

.grayscale {

  filter: grayscale(1);

  background-color: var(--gray);

}

彩色图像

如上所述,彩色图像最初将被隐藏。一旦它们的一部分在页面上可见,它们就会通过幻灯片动画变得可见。

在此处查看最终效果的 GIF 版本。

为了在视觉上隐藏它们,我们不会使用任何传统的 CSS 方式,例如display: none、opacity: 0和transform: translateX(-100%). 事实上,我们将尝试clip-path,一个现代的 CSS 属性,可以帮助我们构建有趣的效果。

快速clip-path 属性说明

该clip-path属性使我们能够切掉元素的一部分并仅显示它的特定部分。可见区域可以用不同的形状(圆形、椭圆形、多边形、矩形)表示。

在我们的示例中,我们将使用inset()函数来构建所需的矩形。

在最简单的形式中,它可以接收最多四个顺时针方向的值,这些值指定生成选定区域的侧偏移(上、右、下、左)。为简单起见,我们可以使用边距简写,它使我们能够将所有四个插图设置为一个、两个、三个或四个值。可选地,我们可以传递一些额外的值给这个函数来指定矩形的圆度。

因此,为了练习,我们假设我们有以下200 像素 x 300 像素的Pixabay图像。


如何在滚动上构建灰度到颜色效果(CSS 和 JavaScript)  第1张


如果我们给它clip-path: inset(10px 20px 30px 40px),生成的图像将是 140 像素 x 260 像素:


如何在滚动上构建灰度到颜色效果(CSS 和 JavaScript)  第2张


更进一步,一个元素clip-path: inset(0)意味着整个元素都会出现。 

另一方面,将四个值之一设置为 100% 的元素意味着它将被挤压和隐藏。请记住,该值在函数中的顺序很重要,并且可以产生不同的动画。

回到我们的示例,这是我们最初隐藏彩色图像的方式:

.colored {

  clip-path: inset(0 100% 0 0);

  transition: all 1.5s ease-in-out;

}

 

.colored[data-animation="to-left"] {

  clip-path: inset(0 0 0 100%);

}

 

.colored[data-animation="to-top"] {

  clip-path: inset(0 0 100% 0);

}

 

.colored[data-animation="to-bottom"] {

  clip-path: inset(100% 0 0 0);

}

3. 滚动动画

彩色图像将被动画化并在滚动时切换。 

为了完成这项任务,我们将利用 Intersection Observer API。 

当每个目标元素至少有 50% 进入视口时,它将接收到is-animated类。否则,它将失去这个类并被隐藏。

无需过多介绍,以下是实现此功能的 javascript 代码:

const targets = document.queryselectorAll(".colored");

const isAnimated = "is-animated";

const threshold = 0.5;

 

function callback(entries, observer) {

  entries.forEach((entry) => {

    const elem = entry.target;

    if (entry.intersectionRatio >= threshold) {

      elem.classList.add(isAnimated);

      //observer.unobserve(elem);

    } else {

      elem.classList.remove(isAnimated);

    }

  });

}

 

const observer = new IntersectionObserver(callback, { threshold });

for (const target of targets) {

  observer.observe(target);

}

注意 1:要查看此 API 的工作原理以及滚动时返回的内容,请在浏览器控制台中打印entry.

注意2:intersectionRatio最初,我尝试了一个而不是属性isIntersecting。但是,我注意到它在 Firefox 中存在问题。

提示:如果您希望动画只运行一次,则必须调用该 unobserve() 方法,如下所示:

...

 

if (entry.isIntersecting) {

  elem.classList.add(isAnimated);

  observer.unobserve(elem);

} else {

  elem.classList.remove(isAnimated);

}

 

...

以及相关的 CSS 类:

.colored.is-animated {

  clip-path: inset(0);

}

结论

就是这样,伙计们!今天,我们通过利用令人高兴的新 CSS 和 JavaScript 功能成功地构建了一个有趣的滚动效果。 

显然,与任何现代工具一样,这种效果在浏览器支持方面有一些限制,特别是如果您针对的是较旧的浏览器。例如,作为后备,您可以默认显示彩色图像,以防浏览器不支持该clip-path属性。 

文章目录
  • 我们的灰度到颜色效果
    • 浏览器支持
  • 1. 从 html 标记开始
  • 2. 定义样式
    • 实用程序类
    • 堆叠元素
    • 灰度图像
    • 彩色图像
    • 快速clip-path 属性说明
  • 3. 滚动动画
  • 结论