css 灰度_如何在滚动上建立灰度到色彩效果(CSS和JavaScript)

本文教授如何使用CSS Grid、clip-path属性和IntersectionObserver API在滚动时实现从灰度图像到彩色图像的平滑过渡。介绍了HTML结构、CSS样式及JavaScript代码实现。

css 灰度

在这个新教程中,我们将从一些灰度图像开始,并学习如何在滚动条上平滑地显示其彩色变体。 为了达到理想的效果,我们将利用CSS Grid, clip-path属性和Intersection Observer API等现代的前端功能。

我们的灰度到彩色效果

在不做进一步介绍的情况下,让我们检查一下要构建的内容:

浏览器支持

尽管此效果具有不错的浏览器支持,但请注意,它在某些浏览器(如早期版本的Microsoft Edge)中将无法使用。 对于此示例,我将集中精力于效果背后的技术,而不会为其他浏览器提供后备。

1.从HTML标记开始

我们将从四个部分开始:

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

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

<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-top ,或to-bottom

2.定义样式

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

实用程序类

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

.cover {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.vh-100 {
  height: 100vh;
}

堆叠元素

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

以下是必需的样式:

/*CUSTOM VARIABLES HERE*/

.img-wrapper {
  display: grid;
}

.img-wrapper div {
  grid-column: 1;
  grid-row: 1;
}

灰度图像

要创建灰度图像,我们将使用grayscale() CSS函数并将1100%的值作为参数传递。 另外,我们将为所有灰度图像提供背景色作为后备,直到加载这些图像中的每一个:

/*CUSTOM VARIABLES HERE*/

.grayscale {
  filter: grayscale(1);
  background-color: var(--gray);
}

彩色图像

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

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

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

快速clip-path属性说明

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

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

以最简单的形式,它可以沿顺时针方向接收多达四个值,这些值指定生成所选区域的侧面偏移量(顶部,右侧,底部,左侧)。 为简单起见,我们可以使用margin速记,它使我们能够将所有四个inset设置为一个,两个,三个或四个值。 (可选)我们可以向此函数传递一些额外的值,以指定矩形的圆度。

因此,为了练习,让我们假设下面的Pixel图片为200px x 300px。

如果我们给它clip-path: inset(10px 20px 30px 40px) ,则结果图像将为140px x 260px:

更进一步,具有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:最初,我尝试了isIntersecting一个而不是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属性,则可以默认显示彩色图像。

不过,希望该练习可以帮助您学习新知识并给您一些创意。 这提醒我们建立了什么:

与往常一样,非常感谢您的阅读!

翻译自: https://webdesign.tutsplus.com/tutorials/grayscale-to-color-effect-on-scroll--cms-35094

css 灰度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值