SVG笔画动画增加长度

时间:2017-09-27 08:31:36

标签: html animation svg path stroke

我一直在互联网上搜索(未成功)如何实现某个SVG路径动画。 我从他的CSS Tricks文章中重新使用了Chris Coyier的编码器。 在我编辑的版本中,我已经达到了预期的效果,但非常粗略,而且它是一种非常“破解”的方法,它绝对没有效率。

笔:https://codepen.io/anon/pen/zEZpPK(在Chrome中可视化)

想法:为SVG笔划设置动画,使其以长度0(dashOffset等于路径总长度)开始,因此没有任何渲染。然后,逐渐减小dashOffset,直到显示整个SVG笔划。 到目前为止,没有任何问题,这实际上是一个相当普遍的影响。但是我想添加一些额外的东西:笔划的“起始点”也必须逐渐偏移,以达到类似笔中的效果。

具体要求是,笔划可以通过起点两次,并且当第二次经过起点时,行程长度达到100%,就像它在笔中一样(不是预定)。

我实现它的方式:将其写下来相当复杂。你可以探索笔,亲眼看看我做了什么。也许为了更好地理解,您可以将ID为Layer_3的SVG的笔触颜色编辑为与白色和黑色不同的内容,以可视化动画的触发方式。但是,我会试着解释一下:

我复制了原始SVG并将其粘贴在HTML文件中两次,因此文档中有3个SVG,每个SVG在另一个上面。中间的那个,有一个白色的笔划,另外2个有黑色的笔触。第二个SVG,即中间的SVG,其动画持续时间是第一个SVG动画的两倍。然后,第3个SVG动画与第1个相同,但它的动画延迟与第1个动画完成时间相同。

这是一个非常无效的解决方案,但它可以很好地说明我想要实现的目标。

问题:有没有办法达到这样的效果? 当笔划大小增加直到达到完整路径长度时,笔划在路径上移动?

我有可能沿着dashOffset动画使用TweenMax(GSAP)来尝试从单个锚点到完全构造的路径逐渐变形SVG路径,并让dashOffset动画从minus .getTotalLength()开始,直到,零。但是变形效果并不是真正需要的,更像是一个切片函数,它采用单个锚点并添加更多锚点(跟踪路径数据),直到路径变为闭合形状。但同样,我没有找到关于这种影响的信息。

也许我面临着SVG的限制。但是,如果有人有想法或知道描述此效果的网站,请告诉我。

1 个答案:

答案 0 :(得分:3)

只需一个SVG即可完成。 IMO最简单的方法是忘记破折号偏移,只需为破折号数组设置动画。

由于动画的一部分,你需要一个

的数组
import React, { Component } from 'react';

import common from '../../jsons/common.json';

import catalogSpecs from '../../jsons/infiniti.json';


class Papertype extends Component {

    constructor(props) {

        super(props);

        this.state = {

            paperType: "Regular",

            regularPaper : true,

            heavyPaper : false
        }
    }
    changePaperTypeLayoutParams(event){

        let nameSelection = event.target.value;

        let lalala = catalogSpecs.commonProps.paperType.paperTypeDefinitionDTOs

        let paperTypebinding = lalala[nameSelection].absolutelayflat;

        let paperLaminationVisibility = lalala[nameSelection].paperLamination;

        this.setState({

            paperType: nameSelection

        });

        if(nameSelection.indexOf("Regular")>-1 || 

nameSelection.indexOf("Metallic")>-1){

            this.setState({

                regularPaper : true,

                heavyPaper : false
            });
            this.props.setRegularOrHeavy(true,false,paperTypebinding,paperLaminationVisibility);

        }else{

            this.setState({

                heavyPaper : true,

                regularPaper : false

            });
            this.props.setRegularOrHeavy(false,true,paperTypebinding,paperLaminationVisibility);
        }



    }
    render() {

        let validLayoutPaperType=this.props.validLayoutPaperType;

        let paperTypeOptions = [];
        let paperTypeOpts = common.paperTypeOpts;
        for(let i=0;i<validLayoutPaperType.length;i++){
            let paper = paperTypeOpts[validLayoutPaperType[i]]
            paperTypeOptions.push(<option label={paper} value={paper} key={i}>{paper}</option>)
        }
        return(
            <div className="layout-item">
                <label>Paper Type</label>
                <div className="custom-select">
                    <select className="form-control" onChange={this.changePaperTypeLayoutParams.bind(this)}>
                        {paperTypeOptions}
                    </select>
                    <i className="icon icon-angle-down"></i>
                </div>
            </div>
        )
    }
}
export default Papertype;

你需要使用一个有四个值的dasharray(笔画间隙笔画间隙)。

请注意,在dash数组中使用与路径长度匹配的值也很重要。在您的情况下,您的路径长度是821.6。所以我使用822的值来表示简单 - 这已足够接近了。

gap - stroke - gap
.path1 {
  stroke-dasharray: 0;
  animation: dash 5s linear;
}
/* 821.6 */

@keyframes dash {
  0% {
    stroke-dasharray: 0 0 0 822;
  }
  25% {
    stroke-dasharray: 0 205.5 205.5 822;
  }
  50% {
    stroke-dasharray: 0 411 411 822;
  }
  75% {
    stroke-dasharray: 411 205.5 822 822;
  }
  100% {
    stroke-dasharray: 822 0 822 822;
  }
}