简体   繁体   中英

Animated SVG Mask Wipe

Here's a storyboard of the CSS/JS/SVG animation I'm trying to accomplish. Two triangle masks enter from either side, then intersect resulting in a negative mask:

在此处输入图片说明

The point where the triangles intersect is where it gets tricky. When I export the mask for panel 4 to SVG, it looks like this:

<svg width="416px" height="289px" viewBox="0 0 416 289" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <defs>
        <path d="M211.503681,65.6626347 L507.009604,-138.787586 L507.009604,425.787586 L211.507182,221.339788 L-84,425.792431 L-84,-138.787586 L211.503681,65.6626347 Z M211.503681,65.6626347 L99,143.5 L211.507182,221.339788 L324.01001,143.502422 L211.503681,65.6626347 Z" id="path-1"></path>
    </defs>
    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <rect id="Rectangle-1-Copy-3" fill="#F6A623" x="0" y="0" width="416" height="289"></rect>
        <mask id="mask-2" fill="white">
            <use xlink:href="#path-1"></use>
        </mask>
        <use id="Combined-Shape" fill="#000000" xlink:href="#path-1"></use>
        <rect id="Rectangle-1-Copy-2" fill="#4990E2" mask="url(#mask-2)" x="0" y="0" width="416" height="289"></rect>
    </g>
</svg>

It looks like it's basically drawing two shapes, the negative-space diamond mask in the center and the remainder of the outer triangles.

So the static mask itself appears to be possible with SVG, but I don't know how to animate it. Is there a library that can simplify this kind of SVG transition/tweening, or a fancy math equation that can calculate the paths dynamically?

Or am I looking at this the wrong way entirely and there's a much easier way to do it altogether?

So the solution was to make it both more simple AND more complicated.

Instead of two layers on top of each other with one mask, I needed three layers. One on the bottom to show behind the first mask, the second to be masked by the incoming triangles, and a third layer above that, duplicate to the first, where a diamond-shaped mask is applied.

<svg width="500" height="300" viewbox="0 0 500 300">
    <defs>
        <clipPath id="triangles">
            <path id="left" d="M-250,-150 L250,150 L-250,450 Z" fill="black" />
            <path id="right" d="M250,150 L750,-150 L750,450 Z" fill="black" />
        </clipPath>

        <clipPath id="diamond">
            <path id="diamond-path" d="M250,0 L500,150 L250,300 L0,150 Z" fill="black" />
        </clipPath>
    </defs>

    <!-- bottom -->
    <g id="bottom">
        <rect fill="darkorange" x="0" y="0" width="500" height="300" />
        <text x="50%" y="65%" text-anchor="middle" class="text">Text</text>
    </g>

    <!-- middle/triangles -->
    <g id="middle" clip-path="url(#triangles)">
        <rect fill="dodgerblue" x="0" y="0" width="500" height="300"  />
        <text x="50%" y="65%" text-anchor="middle" class="text">Text</text>
    </g>

    <!-- top/diamond -->
    <g id="top" clip-path="url(#diamond)">
        <rect fill="darkorange" x="0" y="0" width="500" height="300"  />
        <text x="50%" y="65%" text-anchor="middle" class="text">Text</text>
    </g>

</svg>

The top layer with the diamond path starts out scaled to 0, making it invisible. The two triangle clip paths are animated in towards each other, showing the bottom layer underneath. When the two triangle points meet, the diamond clip path on the top layer is scaled up, revealing the top layer which is a duplicate of the bottom.

I also switched to clip paths instead of masks because they're a) better supported and b) allow for multiple paths.

Here's a Codepen using CSS for the animations (only works in WebKit for the moment).

UPDATE: Here's a Codepen using GSAP that works in all browsers: http://s.codepen.io/kgrote/debug/mPxzZY

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM