最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Make SVG Circle stroke-dashoffset animate - Stack Overflow

programmeradmin1浏览0评论

I would like to animate the SVG Circle's strokeDashoffset,

I make a circle, I get data from an array (will be a database later on) which changes the strokeDashoffset at the moment it doesn't animate smoothly, I'd like a ease-in-out 1s if I wanted it to go from 0 to a 100% I'd use keyframes with "from{}" and "to{}" in css, but I would like to animate any changes happening, cause there will be some color changing as well.

<svg>
      <circle
        cx="50%"
        cy="50%"
        r={radiusHR}
        fill="none"
        stroke={strokedefaultcolor}
        strokeWidth={strokewidth}
      />
      <circle
        id="HRprogress"
        cx="50%"
        cy="50%"
        r={radiusHR}
        fill="none"
        stroke="#E1E5FA"
        strokeWidth={strokewidth}
        strokeDasharray={circumferenceHR}
        strokeDashoffset={circumferenceHR * (1 - this.props.value1 / 101)}
      />

</svg>

I would like to animate the SVG Circle's strokeDashoffset,

I make a circle, I get data from an array (will be a database later on) which changes the strokeDashoffset at the moment it doesn't animate smoothly, I'd like a ease-in-out 1s if I wanted it to go from 0 to a 100% I'd use keyframes with "from{}" and "to{}" in css, but I would like to animate any changes happening, cause there will be some color changing as well.

<svg>
      <circle
        cx="50%"
        cy="50%"
        r={radiusHR}
        fill="none"
        stroke={strokedefaultcolor}
        strokeWidth={strokewidth}
      />
      <circle
        id="HRprogress"
        cx="50%"
        cy="50%"
        r={radiusHR}
        fill="none"
        stroke="#E1E5FA"
        strokeWidth={strokewidth}
        strokeDasharray={circumferenceHR}
        strokeDashoffset={circumferenceHR * (1 - this.props.value1 / 101)}
      />

</svg>
Share Improve this question edited Nov 30, 2017 at 14:53 MrKale asked Nov 30, 2017 at 12:56 MrKaleMrKale 531 silver badge11 bronze badges 1
  • could you create a runnable example using stack snippets? – Robert Longson Commented Nov 30, 2017 at 13:08
Add a ment  | 

2 Answers 2

Reset to default 3

Just use the props in style attribute, and set a transition. For example:

const Circle = (props) => (
  <circle
    cx="50%"
    cy="50%"
    r={radius}
    fill="none"
    style={{
      stroke: props.color,
      transition: 'all 0.3s',
      strokeWidth: props.width,
      strokeDasharray: props.dashArray,
      strokeDashoffset: props.dashOffset
    }}
  />
);

Full example with random values every 800 ms:

const Circle = ({ // default values used if not given in props
  radius,
  color = 'lightslategray',
  width = 1,
  dashArray = '0',
  dashOffset = 0
}) => (
  <circle
    cx="50%"
    cy="50%"
    r={radius}
    fill="none"
    style={{
      stroke: color,
      transition: 'all 0.3s ease-in-out', // animation duration and easing function
      strokeWidth: width,
      strokeDasharray: dashArray,
      strokeDashoffset: dashOffset
    }}
  />
);

class Circles extends React.Component {
  constructor() {
    super();
    this.state = { // initial values
      dashOffset: 0,
      dashArray: '10, 10',
      width: 1
    };
  }

  ponentDidMount() {
    setInterval( // change to some random crap every 800 ms
      () =>
        this.setState({
          dashOffset: this.state.dashOffset + 10,
          dashArray: `${Math.random() * 10}, 10`,
          width: 1 + Math.random() * 4
        }),
      800
    );
  }

  render() {
    return (
      <svg>
        <Circle
          radius={50}
          color="#eb26a8"
          width={this.state.width}
          dashArray={this.state.dashArray}
          dashOffset={this.state.dashOffset * 1}
        />
        <Circle
          radius={60}
          color="#2645eb"
          width={this.state.width * 2}
          dashArray={this.state.dashArray}
          dashOffset={this.state.dashOffset * 4}
        />
        <Circle
          radius={70}
          width={2}
          dashArray="1, 5"
        />
        <Circle
          radius={25}
          width={2}
          dashArray="1, 5"
        />
      </svg>
    );
  }
}

ReactDOM.render(
  <Circles />,
  document.getElementById("mount")
);
<div id="mount"></div>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>

List of timing functions: https://developer.mozilla/en-US/docs/Web/CSS/transition-timing-function

You can even create a custom one: https://developer.mozilla/en-US/docs/Web/CSS/single-transition-timing-function

Personally, I use Greensock Animation Platform for this sort of thing. Here's how I did it in Firmament Wars, a browser RTS game that I made:

TweenMax.to([DOM.targetLine, DOM.targetLineShadow], .2, {
    startAt: {
        strokeDashoffset: 0
    },
    strokeDashoffset: -12,
    repeat: -1,
    ease: Linear.easeNone
}); 

It es with any ease you can think of, so they take care of that, too.

发布评论

评论列表(0)

  1. 暂无评论