iCSS icon indicating copy to clipboard operation
iCSS copied to clipboard

利用 CSS @property 探寻渐变的极限状态

Open chokcoco opened this issue 4 years ago • 0 comments

本文利用 CSS @property 来实现一些有意思的(但可能毫无卵用)事情。

渐变动画的历史

我们都知道,在之前,我们想实现渐变的动画,其实是非常复杂甚至是做不到的。

例如,从下图 A 状态,到 B 状态:

<div></div>
div {
    width: 300px;
    height: 150px;
    animation: gradientChange 5s infinite linear;
}
@keyframes gradientChange {
    from {
        background: linear-gradient(black, deeppink);
    }
    to {
        background: linear-gradient(green, blue);
    }
}

我们无法得到补间动画,只能得到两帧动画的切换:

而有了 CSS @property 之后,我们可以非常轻松的实现渐变直接的动画效果,只需要这样改造一下代码:

@property --colorA {
    syntax: "<color>";
    inherits: false;
    initial-value: black;
}
@property --colorB {
    syntax: "<color>";
    inherits: false;
    initial-value: deeppink;
}
div {
    width: 300px;
    height: 150px;
    background: linear-gradient(var(--colorA), var(--colorB));
    animation: propertyChange 4s infinite linear;
}
@keyframes propertyChange {
    from {
        --colorA: black;
        --colorB: deeppink;
    }
    to {
        --colorA: green;
        --colorB: blue;
    }
}

可以非常轻松的得到渐变的变化动画效果:

对于 CSS @Property 还不算太了解的,可以猛击这篇文章:CSS @property,让不可能变可能

利用 CSS @property 探寻渐变的极限状态

基于此,我们就可以利用 CSS @property 来搞事了。

我们可以利用它,观察渐变的一些极限状态。看看到渐变粒度非常小的时候,会发生什么,它的变化状态又是如何的。

主要是利用多重线性渐变、多重径向渐变、多重角向渐变。

多重线性渐变

它们的代码其实都大同小异:

@property --per {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 100%;
}

body {
    background: repeating-linear-gradient(45deg, deeppink, #fc0, #000, red, green, gray var(--per));
    animation: perChange 60s infinite linear;
    cursor: pointer;

    &:hover {
        animation-play-state: paused;
    }
}

@keyframes perChange {
    5% {
        --per: 1%;
    }
    10% {
        --per: .1%;
    }
    30% {
        --per: .01%;
    }
    50% {
        --per: .001%;
    }
    70% {
        --per: .0001%;
    }
    78% {
        --per: .00001%;
    }
    90% {
        --per: .000001%;
    }
    95%,
    100% {
        --per: .0000001%;
    }
}

通过控制多重线性渐变的没份的百分比 --per,观察动画的变化:

c

我们还可以通过 hover 伪类,在 hover 元素的时候添加 animation-play-state: paused 以暂停动画。

多重径向渐变

和上述代码一样,只需要把 repeating-linear-gradient() 改为 repeating-radial-gradient() 即可。

最终的动画效果:

d

多重角向渐变

和上述代码一样,只需要把 repeating-linear-gradient() 改为 repeating-conic-gradient() 即可。

最终的动画效果:

e

由于完整的变化图片超出了限制,我只能每秒截取了 3 帧,所以看起来非常卡顿,实际是非常流畅的,补充一个完整的 5 秒的变化:

可以看到,在 --per 逐渐变小的过程中,整个渐变图形呈现出了非常有意思的效果,在小于 0.1% 基本已经处于一种非常抽象看不懂的状态,在小于 0.00001% 后,图形已经无法被渲染出来了。

上述完整的代码,你可以戳这里:CSS 灵感 -- 利用 CSS @property 探寻渐变的极限效果

基于此,其实还可以做很多有意思的事情,譬如实现一个电视的雪花效果:

CSS 灵感 -- 利用渐变及 CSS Property 实现 TV 噪音动画

CSS @property 其实非常强大,本文只是介绍它的冰山一角,旨在让大家浅显的了解有这么个东西,在 CSS 动画的过程中如果发现有一些本身不支持的动画的属性,可以考虑利用 CSS @proerpty,巧妙的实现它~

最后

好了,本文到此结束,希望对你有帮助 :)

想 Get 到最有意思的 CSS 资讯,千万不要错过我的公众号 -- iCSS前端趣闻 😄

更多精彩 CSS 效果可以关注我的 CSS 灵感

更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。

如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

chokcoco avatar Aug 30 '21 12:08 chokcoco