如何使SVG形状在滚动中生成动画

467 阅读4分钟

滚动是非常 有趣的!让我们来看看如何让SVG形状和剪贴路径在滚动时产生动画,为设计增加一点戏剧性和波浪感。我们可以将一个路径变形为另一个路径,一旦一个形状进入视口,我们就会这样做。

让我们开始吧!

分离器上的路径动画

对于全屏图像的分隔符和边框来说,滚动时的路径动画特别有趣。所以,让我们看看这个第一个例子,我们简单地对一个SVG的路径进行动画处理,这个SVG的填充颜色与页面的背景相同。

当我们滚动时,我们将把一个SVG路径从一个矩形变成一个波浪形。

要做到这一点,我们需要两个路径:一个是矩形的初始路径,一个是波浪形的最终路径。当我们创建将被动画化的路径时,我们必须记住,所有出现在最终路径中的点,也需要出现在初始形状中。因此,确保我们的路径动画不会变得怪异的最好方法是开始制作最复杂的形状,在我们的例子中就是带有曲线的最终路径。

创建SVG路径

不幸的是,图形设计软件可能不是制作正确、优化的路径的最佳选择。我通常在Sketch中开始制作形状,然后用SVGOMG来优化它们。然后,我复制路径并将其粘贴到SvgPathEditor中。优化步骤并不总是需要的,因为路径编辑器提供了四舍五入的功能,这很好。我用它来处理那些被Sketch应用了变换的路径或组。SVGOMG可以去除这些。

SVGOMG清理SVG并删除变换值

一旦我们有了优化的SVG和 "干净 "的路径,我们就可以用编辑器从更复杂的形状中创建初始形状。

虽然这个形状并不是真正可见的,但我们需要最终路径的所有点都存在于初始路径中。

在这样做的时候,这也是一个很好的方法,可以大致想象出动画的外观和感觉(当然,是反向的)。一旦我们有了这两条路径,我们就可以在我们的HTML中使用它们。

标记和样式

<svg class="separator separator--up" width="100%" height="100%" viewBox="0 0 100 10" preserveAspectRatio="none">
	<path 
		class="separator__path path-anim" 
		d="M 0 0 C 40 0 60 0 100 0 L 0 0 Z" 
		data-path-to="M 0 0 C 40 10 60 10 100 0 L 0 0 Z" 
		vector-effect="non-scaling-stroke" 
	/>
</svg>

使用一个数据属性,我们定义了我们希望最初的动画所对应的最终路径。一点CSS将确保我们的SVG被放置在全宽的位置,在大背景图片的顶部。

.separator {
	display: block;
	position: absolute;
	z-index: 1000;
	pointer-events: none;
	width: 100%;
	height: 150px;
	fill: var(--color-bg);
}

注意,你可以将你的SVG拉伸到你想要的高度,这取决于你希望滚动时的波浪看起来有多大。

JavaScript

为了实现平滑滚动,我们将使用Studio Freight的新Lenis库。GSAP的ScrollTrigger插件将允许我们在一个元素进入或离开视口时对其进行动画处理。

让我们导入我们需要的脚本。

import Lenis from '@studio-freight/lenis'
import { gsap } from 'gsap';
import { preloader } from './preloader';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);

让我们预先加载图片。

preloader();

现在我们需要所有我们想要动画化的路径元素(它们的类是 "path-anim")。

const paths = [...document.querySelectorAll('path.path-anim')];

接下来,我们初始化平滑滚动。

const lenis = new Lenis({
    lerp: 0.1,
    smooth: true,
});
const scrollFn = () => {
    lenis.raf();
    requestAnimationFrame(scrollFn);
};
requestAnimationFrame(scrollFn);

最后,当我们的路径进入视口时,我们将其做成动画。最终的路径是在路径元素的数据属性 "data-path-to "中定义的,正如我们之前看到的。

起点终点是由SVG元素的顶部到达视口的底部,以及底部到达视口的顶部来定义的。

paths.forEach(el => {
    const svgEl = el.closest('svg');
    const pathTo = el.dataset.pathTo;

    gsap.timeline({
        scrollTrigger: {
            trigger: svgEl,
            start: "top bottom",
            end: "bottom top",
            scrub: true
        }
    })
    .to(el, {
        ease: 'none',
        attr: { d: pathTo }
    });
});

现在,我们有了在滚动页面时变形的SVG路径!

虽然我们可以在路径和 "分隔符 "上使用这种动画技术,但我们也可以在图像上制作剪辑路径的动画,就像这个例子中一样。

<svg class="image-clip" width="500px" height="750px" viewBox="0 0 500 750">
	<defs>
		<clipPath id="shape1">
			<path 
				class="path-anim" 
				d="M 0 0 L 500 0 C 500 599.6 500 677.1 500 750 L 0 750 C 0 205 0 105 0 0 Z"
				data-path-to="M 0 0 L 500 0 C 331 608 485 551 500 750 L 0 750 C 120 281 7 296 0 0 Z" 
			/>
		</clipPath>
	</defs>
	<image 
		clip-path="url(#shape1)" 
		xlink:href="img/2.jpg" 
		x="0" y="0" 
		width="500" 
		height="750"
	/>
</svg>

我们可以在SVG图像上制作剪辑路径的动画

最终结果

将平滑滚动与SVG路径动画结合起来,可以为设计增加一个额外的变形酷感。它并不复杂,但效果看起来非常戏剧化。这种技术为滚动体验提供了一种有机的触感,并且可以在某些简单的变形效果中不需要使用WebGL。

我真的希望你喜欢这个小教程,并发现它对创建你自己的动画很有帮助!

The postHow to Animate SVG Shapes on Scrollappeared first onCodrops.