Anime.js - pause between loop iterations - javascript
I have this animation:
const brushKeyframes = {
translateX: [
{ value: -150, duration: 200, delay: 100 },
{ value: -180, duration: 200, delay: 200 },
{ value: 0, duration: 200, delay: 300 }
],
translateY: [
{ value: -160, duration: 200, delay: 100 },
{ value: 0, duration: 200, delay: 300 }
]
};
const paintingIconAnimation = anime({
targets: `.painting-icon__brush`,
...brushKeyframes,
delay: 400,
easing: "linear",
loop: true
});
.icon {
width: 150px;
height: 150px;
}
svg {
width: 100%;
height: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.1.0/anime.min.js"></script>
<div class="icon painting-icon">
<svg enable-background="new 0 0 512 512" height="512" viewBox="0 0 512 512" width="512" xmlns="http://www.w3.org/2000/svg">
<g class="painting-icon__egg">
<path d="m174.233 41.593c82.515-.993 178.916 120.817 180.664 266.089 1.179 97.995-77.403 170.322-175.398 171.501-97.996 1.18-178.296-69.235-179.475-167.23-1.748-145.273 91.693-269.367 174.209-270.36z" fill="#f1cd88"></path>
<path d="m174.233 41.593c-7.254.087-14.592 1.145-21.942 3.066 76.061 19.681 154.906 131.769 156.485 263.023 1.095 90.996-66.589 159.847-154.724 170.164 8.318.978 16.811 1.441 25.446 1.337 97.995-1.179 176.577-73.506 175.398-171.501-1.747-145.272-98.148-267.082-180.663-266.089z" fill="#ebb34c"></path>
<g class="painting-icon__egg-top egg-top">
<path class="egg-top__main" d="m174.233 41.593c-51.847.624-108 49.855-142.151 122.395h21.135c23.712 0 42.934 19.222 42.934 42.934v112.7c0 16.066 13.024 29.091 29.091 29.091s29.091-13.024 29.091-29.091v-111.88c0-13.136 10.649-23.785 23.785-23.785s23.785 10.649 23.785 23.785v19.501c0 10.004 8.11 18.114 18.114 18.114s18.114-8.11 18.114-18.114v-24.116c0-31.227 25.315-56.542 56.542-56.542h17.192c-36.051-63.885-89.226-105.574-137.632-104.992z" fill="#80b6fc"></path>
<path class="egg-top__shadow" d="m269.115 152.695c7.678-3.899 16.357-6.111 25.557-6.111h17.192c-9.042-16.022-19.656-31.524-31.786-45.649-.141-.164-.283-.328-.424-.491-21.474-24.876-49.943-47.782-81.52-55.86-.21-.054-.42-.11-.63-.163-15.88-3.956-30.328-3.651-45.214.238 42.821 11.08 86.523 51.449 116.825 108.036z" fill="#62a4fb"></path>
</g>
</g>
<g class="painting-icon__basket">
<path d="m416.187 479.198h-137.091c-11.242 0-20.355-9.113-20.355-20.355v-111.1h177.801v111.1c0 11.242-9.113 20.355-20.355 20.355z" fill="#766d78"></path>
<path d="m405.767 347.743v111.1c0 11.242-9.113 20.355-20.355 20.355h30.775c11.242 0 20.355-9.113 20.355-20.355v-111.1z" fill="#655e67"></path>
<path d="m238.131 314.955v40.948c0 5.394 4.373 9.767 9.767 9.767h199.488c5.394 0 9.767-4.373 9.767-9.767v-40.948c0-5.394-4.373-9.767-9.767-9.767h-199.488c-5.394 0-9.767 4.373-9.767 9.767z" fill="#f7f3f1"></path>
<path d="m447.386 305.188h-30.776c5.394 0 9.767 4.373 9.767 9.767v40.948c0 5.394-4.373 9.767-9.767 9.767h30.775c5.394 0 9.767-4.373 9.767-9.767v-40.948c.001-5.394-4.372-9.767-9.766-9.767z" fill="#ebe1dc"></path>
<ellipse cx="347.642" cy="419.499" fill="#80b6fc" rx="39.651" ry="24.365"></ellipse>
</g>
<g class="painting-icon__brush">
<path d="m378.767 166.038c-20.7-20.702-54.483-20.672-75.149.065-8.107 8.135-13.015 18.246-14.755 28.778 0 0-5.274 29.198-20.47 44.545-4.268 4.31-3.721 11.409 1.321 14.781 32.361 21.645 81.521 14.441 109.052-13.09 20.732-20.733 20.733-54.346.001-75.079z" fill="#766d78"></path>
<path d="m378.767 166.038c-1.585-1.585-3.255-3.034-4.981-4.376 5.761 18.278 1.412 39.054-13.077 53.543-22.6 22.6-59.767 31.486-90.26 21.977-.666.772-1.347 1.527-2.056 2.243-4.268 4.31-3.721 11.409 1.321 14.781 32.361 21.645 81.521 14.441 109.052-13.09 20.732-20.731 20.733-54.345.001-75.078z" fill="#655e67"></path>
<path d="m351.356 193.446c-14.285-14.285-13.235-37.749 2.269-50.701l126.132-105.374c7.805-6.521 19.297-6.007 26.489 1.185s7.706 18.683 1.185 26.489l-105.374 126.132c-12.952 15.504-36.415 16.554-50.701 2.269z" fill="#94d4a2"></path>
<path d="m506.245 38.557c-2.857-2.857-6.394-4.641-10.107-5.369.247 4.778-1.705 10.224-5.734 14.831l-108.011 123.493c-10.756 12.298-26.327 17.188-37.517 12.938 1.613 3.239 3.769 6.283 6.481 8.995 14.285 14.285 37.749 13.235 50.701-2.269l105.373-126.131c6.52-7.805 6.006-19.297-1.186-26.488z" fill="#6dc17d"></path>
</g>
</svg>
</div>
I want to make a pause between animation loops: so when brush returns to the final point, it will stay here a bit before new movement starting. But I have no idea how to fix animation (timings, maybe?) properly to achieve it.
Thank you in advance!
Ok, finally I got it.
In arrayed keyframes in anime.js delays are not absolute, but kind of relative to each other. So I can fix delays in the array like that:
const brushKeyframes = {
translateX: [
{ value: -150, duration: 130, delay: 1300 },
{ value: -180, duration: 130, delay: 100 },
{ value: 0, duration: 130, delay: 100 }
],
translateY: [
{ value: -160, duration: 130, delay: 1300 },
{ value: 0, duration: 130, delay: 100 }
]
};
and it will work properly
I was able to add a pause between a timeline loop by adding an empty key frame with duration for the last item of my timeline.
In the following example, the animation will loop after 3000ms (3s).
var timeline = anime.timeline({ duration: 15000, loop: true, easing: 'linear' })
timeline
.add({
targets: '#a',
keyframes: [
{ translateX: '-300%', duration: 6000 },
{ zIndex: 0, duration: 0 },
{ translateX: '-150%', duration: 3000 },
{ opacity: 0, duration: 3000 },
],
})
.add({
targets: '#b',
keyframes: [
{ scale: 1.5, duration: 4000 },
{ duration: 3000 }
],
},
'-=2500'
);
Related
Why is my Framer Motion animation happening twice?
I have an animation on a logo that I want to happen when the logo is being hovered over. Here's the CodeSandbox Demo. Current behavior: When you hover over the logo, the correct animation occurs. When you move off the logo, the middle path spins again. Expected behavior: Animation occurs on hover, reverts back to contracted logo when mouse is no longer hovering Any ideas? Logo code: import { motion, Variants } from "framer-motion"; interface LogoProps { hover?: boolean; width?: string; height?: string; } interface CustomVariants { [key: string]: Variants; } const Logo: React.FC<LogoProps> = (props: LogoProps) => { const customVariants: CustomVariants = { left: { rest: { x: 0 }, hover: { x: -20, transition: { repeat: 1, repeatType: "reverse", repeatDelay: 1 } } }, right: { rest: { x: 0 }, hover: { x: 20, transition: { repeat: 1, repeatType: "reverse", repeatDelay: 1 } } }, bottom: { rest: { y: 0 }, hover: { y: 20, transition: { repeat: 1, repeatType: "reverse", repeatDelay: 1 } } }, middle: { rest: {}, hover: { rotate: -360 * 10, transition: { delay: 0.5 } } } }; return ( <motion.svg width={props.width ?? 60} height={props.height ?? 60} viewBox="0 0 158 146" fill="none" xmlns="http://www.w3.org/2000/svg" className="verifax-logo" > <motion.path id="side" d="M14.5017 66.3155C14.5327 75.092 14.8561 82.8129 15.1938 83.3718C15.4639 83.819 22.2984 87.9471 30.187 92.5369L44.6399 100.808L44.6607 85.4447C44.6485 76.9559 44.8577 69.0902 45.0151 67.811C45.3187 66.004 48.3905 64.16 60.19 58.5434C69.5292 53.9863 74.6938 50.9875 74.2886 50.3168C73.8834 49.6461 67.2327 45.5656 59.3629 41.2634L45.1125 33.3279L29.765 41.7966L14.4174 50.2652L14.5017 66.3155Z" fill="#6200EA" initial="hover" animate={props.hover ? "hover" : "rest"} variants={customVariants.left} /> <motion.path className="side" d="M61.1382 25.1267C61.3405 25.4616 67.2779 28.8833 74.2679 32.7662C81.4415 36.6965 87.9483 40.5483 88.8361 41.2492C89.724 41.95 90.5114 49.4043 90.4749 58.0574C90.371 66.5989 90.6078 73.9104 90.8101 74.2453C91.0124 74.5802 97.8331 71.2631 106.077 66.7141L120.823 58.5772L120.855 42.4844C120.757 33.6081 120.501 26.0092 120.164 25.451C119.894 25.0045 113.136 20.9935 105.142 16.4739L90.593 8.27822L75.7307 16.4792C67.6029 20.9641 61.0033 24.9034 61.1382 25.1267Z" fill="#6200EA" animate={props.hover ? "hover" : "rest"} variants={customVariants.right} /> <motion.path className="side" d="M59.6443 33.9735L59.5773 38.4802L70.0055 44.1985L80.5013 50.0285L63.9667 59.5989L47.4321 69.1693L47.5159 80.5954C47.6605 100.331 47.1504 98.974 52.497 96.0239C56.9137 93.5868 57.0599 93.0592 56.9503 84.9252C56.7873 69.52 55.3063 69.8902 74.0554 80.4036L90.9782 89.6898L104.926 81.9938L118.873 74.2978L114.437 71.8288L110.069 69.4716L99.1732 75.0366C93.178 78.1957 88.1425 80.3782 88.0075 80.1547C87.805 79.8194 87.6091 71.2861 87.503 61.3622L87.2685 43.0167L74.2791 35.8808C67.0983 31.9465 60.8736 28.8255 60.4087 29.082C59.9438 29.3386 59.5428 31.4967 59.6443 33.9735Z" fill="#6200EA" animate={props.hover ? "hover" : "rest"} variants={customVariants.middle} /> <motion.path className="side" d="M59.2076 92.5587L59.4758 108.66L74.4152 116.963L89.4708 125.202L104.821 116.732L120.171 108.262L120.087 92.2088L120.07 76.2673L104.982 84.1454L89.8948 92.0235L75.2068 83.8795C67.0168 79.3053 60.1024 75.8161 59.6372 76.0728C59.2884 76.2653 59.0604 83.8447 59.2076 92.5587Z" fill="#6200EA" animate={props.hover ? "hover" : "rest"} variants={customVariants.bottom} /> </motion.svg> ); }; export default Logo;
Assuming that the goal is to remove the hover out effect for middle, since there is already a variant value rest for this element when not hovering, it seems that a transition of duration: 0 can be set with it so that the hover out effect is finished immediately. Forked example with modification: codesandbox middle: { rest: { rotate: 0, transition: { duration: 0, }, }, hover: { rotate: -360 * 10, transition: { delay: 0.5, }, }, }
jQuery to monitor links to see if they are hovered over, if they are go up 3 parents and add css/class
I have lots of links on my page with the HTML format of: <div class="heading-column"> <div class="heading-container"> <h2 class="heading-item"> <a href="/find/">Find</h2> </div> </div> </div> Currently we have some animations happening when they hover over the heading-column element, but they should actually only happen when hovering over the a hyperlink. I'm trying to figure out how to create some jQuery to monitor all hyperlinks, if one with the class of .heading-item a is hovered over for it to update its parent 3 higher (.heading-column) by adding the css of pointer-events: auto; but as soon as the mouse stops hovering, this css rule should be deleted so that the pointer-events: none; stops the .heading-column animation/hover from happening I'd greatly appreciate some help
Have you tried: $(".heading-column a").hover(function(){ // In $(this).closest(".heading-column").css("pointer-events", "none"); }, function(){ // Out $(this).closest(".heading-column").css("pointer-events", "auto"); }); Reference: https://api.jquery.com/hover/ Might consider adding and removing a Class too.
See if this helps - https://codepen.io/VweMWoz const tl = gsap.timeline({paused: true}); tl.from( ".gsap-swipe", { y: 20, x: 20, rotate: -40, duration: 3, transformOrigin: '30% 80%', ease: Elastic.easeOut.config(1, 0.5), }, 0 ) .fromTo( ".swipe", { xPercent: -100 }, { duration: 1, xPercent: 100, ease: Sine.easeInOut, stagger: { each: 0.15 } }, 0 ) .from( ".maskSwipe", { xPercent: -100, ease: Sine.easeInOut }, 0.4 ) .from( "#hello", { duration: 1.5, drawSVG: "0%" }, 1 ) .from( ".swoop", { duration: 2, drawSVG: "0%" }, 1 ) .from( ".line", { drawSVG: "0%", duration: 0.5, stagger: { each: 0.2 } }, 1 ) .from( ".shape", { scale: 0, duration: 1.3, transformOrigin: "50% 50%", rotate: '+=random(-60, 60)', ease: Elastic.easeOut.config(1, 0.8), stagger: { each: 0.2 } }, 0.2 ); // ScrubGSAPTimeline(tl); let hover = document.querySelector('.js-hover'); hover.addEventListener('mouseover', playTl); hover.addEventListener('mouseout', resetTl); function playTl(){ tl.timeScale(1.25).restart(); } function resetTl(){ tl.progress(0).pause(); }
How to add a shadow to an SVG element
I have such an element made in SVG: import Svg, { Path, Circle } from "react-native-svg" function CloseIcon(props) { return ( <Svg viewBox="0 0 1000 1000" fillRule="evenodd" clipRule="evenodd" strokeLinejoin="round" strokeMiterlimit={2} style={styles.shadow} > <Path d="M500 420.886L781.42 139.464c19.297-19.28 50.622-19.28 69.919 0l9.179 9.195c19.296 19.28 19.296 50.623 0 69.903L579.097 499.983l281.438 281.455c19.296 19.28 19.296 50.622 0 69.902l-9.179 9.195c-19.296 19.28-50.622 19.28-69.918 0L500 579.081 218.562 860.535c-19.297 19.28-50.623 19.28-69.919 0l-9.179-9.195c-19.296-19.28-19.296-50.622 0-69.902l281.438-281.455-281.421-281.421c-19.297-19.28-19.297-50.623 0-69.903l9.178-9.195c19.297-19.28 50.623-19.28 69.92 0l281.42 281.422z" fill="#fff" /> </Svg> ) }; Is it possible to add a shadow to it? These types of options do not work: (this solution treats the path as a rectangle) shadowColor: "#000", shadowOffset: { width: 0, height: 2, }, shadowOpacity: 0.23, shadowRadius: 2.62, elevation: 4,
Highcharts points and lines are missing
This is the code generated by highcharts for lines and point. I'm using inspect element and points are where they should be but they seem to be transparent or something like behind he chart. but the code looks right. <g class="highcharts-series-group" zIndex="3"> <g class="highcharts-series" clip-path="url(http://localhost:63540/admin/reports.aspx?type=like#highcharts-1)" visibility="visible" transform="translate(40,10)"> <path d="M 244 50.4 L 732 302.6" fill="none" stroke="rgb(0, 0, 0)" stroke-width="5" isShadow="true" stroke-opacity="0.05" transform="translate(1,1)"></path> <path d="M 244 50.4 L 732 302.6" fill="none" stroke="rgb(0, 0, 0)" stroke-width="3" isShadow="true" stroke-opacity="0.1" transform="translate(1,1)"></path> <path d="M 244 50.4 L 732 302.6" fill="none" stroke="rgb(0, 0, 0)" stroke-width="1" isShadow="true" stroke-opacity="0.15000000000000002" transform="translate(1,1)"></path> <path d="M 244 50.4 L 732 302.6" fill="none" stroke="#4D4D4D" stroke-width="2"></path><path d="M 732 298.6 C 737.328 298.6 737.328 306.6 732 306.6 C 726.672 306.6 726.672 298.6 732 298.6 Z" fill="#4D4D4D" stroke="#FFFFFF" stroke-width="0.000001" zIndex="2000"></path> <path d="M 244 46.4 C 249.328 46.4 249.328 54.4 244 54.4 C 238.672 54.4 238.672 46.4 244 46.4 Z" fill="#4D4D4D" stroke="#FFFFFF" stroke-width="0.000001"></path></g></g> What can be wrong with it? It's funny that I have copied the code from my other project (that is working) and only have changed the data. this is the compiled js code: var dates = ['1394/12/06','1394/12/11']; after.push(function () { chart = new Highcharts.Chart({ chart: { height: 500, backgroundColor:'#eee', renderTo: 'chart', defaultSeriesType: 'line', // marginRight: 130, //marginBottom: 150, // marginTop: 20, // events: { click: function () { startWait($('html')); document.location = 'price.aspx' } } }, title: { text: '', x: -20 //center }, subtitle: { text: '', x: -20 }, xAxis: { categories: dates, labels: { rotation: 90, formatter: function () { return this.value; }, y:40 } }, yAxis: { title: { text: '' }, plotLines: [{ value: 0, width: 1, color: '#808080' }], labels: { formatter: function () { // return toFarsi(virgulize(this.value)) ; } } }, tooltip: { formatter: function () { return "<b>" + this.y + "</b>"; } }, legend: { //enabled: false }, series: [ { name:' likes', color:'#4D4D4D', data: [2,1] }, ] }); });
Well after disabling css, javascript, and many other tests nothing worked. Thanks to jlbriggs his fiddle gave me the idea of testing the code with older version of jquery. It worked with older version of jquery. Update: New version of Highcharts works with the latest version of jquery.
Complex SVG animation in ReactJS
I am using React to build an animated intro that comprises three taglines paired with animated SVG icons. I opted for TweenMax to manage the SVG animations, due to the solid cross-browser support it offers. This also would allow me to perform a simple morph of the d attribute on <path> elements. I am combining the aforementioned with ReactTransitionGroup However, I ran into the following problems while trying to make TweenMax and React play nice: While opting for component state, componentWillReceiveProps is somehow called twice in console. This would mean, my animation method would be called twice. What is causing this and might storing the tag index using Redux be a better option in this use case? The way that I am animating currently seems very crude, e.g. repeating this.refs and findDOMNode() repeatedly. Surely there must be a better way? In which ways could the structure of my code be improved? I am completely stumped and would love to be pointed in the right direction. Kind regards, Jason Code html, body { margin: 0; padding: 0; width: 100%; height: 100%; } body { background: rgb(240, 90, 48); font: bold 1em sans-serif; color: rgb(255, 255, 255); text-align: center; } .reveal-wrap { position: absolute; width: 200px; height: 200px; top: 0; right: 0; bottom: 0; left: 0; margin: auto; overflow: hidden; } .reveal-icon { width: 100px; height: 100px; margin: 0 auto 2em auto; } .reveal-icon svg { width: 100%; height: 100%; } .reveal-icon .fill { fill: rgb(251, 163, 10); } .reveal-icon .mask { fill: rgb(240, 90, 48); } .reveal-icon .stroke { stroke: rgb(251, 163, 10); stroke-linecap: round; stroke-width: 5; } .reveal-text { position: absolute; width: 100%; } .switch-locale { position: fixed; top: 1em; left: 1em; } <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.25/browser.min.js"></script> <script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenMax.min.js"></script> <script src="https://fb.me/react-with-addons-0.13.3.min.js"></script> <div id="react-root"></div> <script type="text/babel"> const ReactTransitionGroup = React.addons.TransitionGroup const UI_TEXT = { EN_US: { REVEAL: [ { ID: 0, TEXT: 'Tagline 1' }, { ID: 1, TEXT: 'Tagline 2' }, { ID: 2, TEXT: 'Tagline 3' } ] }, NL_NL: { REVEAL: [ { ID: 0, TEXT: 'Slagzin 1' }, { ID: 1, TEXT: 'Slagzin 2' }, { ID: 2, TEXT: 'Slagzin 3' } ] } } class Reveal extends React.Component { constructor() { super(); this.state = { index: 0, locale: 'EN_US' } } nextTagline() { this.setState({index: this.state.index + 1}) console.log('this.state.index # ' + this.state.index) } switchLocale() { let locale = (this.state.locale === 'EN_US') ? 'NL_NL' : 'EN_US' this.setState({locale}) } render() { return ( <ReactTransitionGroup className='reveal-wrap' component='div'> <RevealIcon tag={this.state.index} nextTag={() => this.nextTagline()} /> <RevealText tag={this.state.index} locale={this.state.locale} key={this.state.index} /> <SwitchLocale switchLocale={() => this.switchLocale()} /> </ReactTransitionGroup> ) } } class RevealText extends React.Component { fadeIn(callback, delay) { TweenLite.fromTo(React.findDOMNode(this), 0.5, { y: '100px', opacity: 0 }, { y: 0, delay: delay, opacity: 1, ease: Quad.easeOut, onComplete: callback, onCompleteScope: this } ) } fadeOut(callback, delay) { TweenLite.fromTo(React.findDOMNode(this), 0.5, { y: 0, opacity: 1 }, { y: '+=100px', delay: delay, opacity: 0, ease: Quad.easeIn, onComplete: callback, onCompleteScope: this } ) } componentWillAppear(callback) { //console.log('RevealText will appear') this.fadeIn(callback, 1) } componentDidAppear() { //console.log("RevealText did appear") } componentWillLeave(callback) { this.fadeOut(callback, 0) } componentDidLeave() { //console.log('RevealText did leave') } componentWillEnter(callback) { this.fadeIn(callback, 1) } componentDidEnter() { //console.log("RevealText did enter") } render() { return ( <div className='reveal-text'> { UI_TEXT[this.props.locale].REVEAL[this.props.tag].TEXT } </div> ) } } class RevealIcon extends React.Component { componentWillAppear(callback) { const HAND_1 = [React.findDOMNode(this.refs.HAND_1), React.findDOMNode(this.refs.HAND_1_MASK), React.findDOMNode(this.refs.HAND_1_THUMB)] const HAND_2 = [React.findDOMNode(this.refs.HAND_2), React.findDOMNode(this.refs.HAND_2_MASK)] const HAND_3 = React.findDOMNode(this.refs.HAND_LINES) const HAND_4 = [React.findDOMNode(this.refs.HAND_LINES_1), React.findDOMNode(this.refs.HAND_LINES_2), React.findDOMNode(this.refs.HAND_LINES_3), React.findDOMNode(this.refs.HAND_LINES_4), React.findDOMNode(this.refs.HAND_LINES_5), React.findDOMNode(this.refs.HAND_LINES_6), React.findDOMNode(this.refs.HAND_LINES_7), React.findDOMNode(this.refs.HAND_LINES_8)] let anim = new TimelineMax({ delay: 2, onComplete: this.props.nextTag, onCompleteScope: this }) anim.fromTo(HAND_1, 0.5, { y: '-=100px', x: '+=100px', opacity: 0 }, { y: 0, x: 0, opacity: 1, ease: Quad.easeOut }) .fromTo(HAND_2, 0.5, { y: '-=100px', x: '-=100px', opacity: 0 }, { y: 0, x: 0, opacity: 1, ease: Quad.easeOut }, '-=0.20') .fromTo(HAND_3, 0.75, { scaleX: 0.5, scaleY: 0.5, transformOrigin: '50% 50%' }, { scaleX: 1, scaleY: 1, ease: Quad.easeOut }) .fromTo(HAND_4, 0.5, { opacity: 0, }, { opacity: 1, ease: Quad.easeOut }, '-=0.75') .fromTo(HAND_4, 1, { 'stroke-dasharray': '25px', 'stroke-dashoffset': '0px' }, { 'stroke-dasharray': '25px', 'stroke-dashoffset': '25px', ease: Power3.easeOut }, '-=0.75') .set({}, {}, '+=1') // .set is used to lengthen the animation by 1 second } componentWillReceiveProps(nextProps) { console.log('RevealIcon will receive props', 'nextProps.tag: ' + nextProps.tag) if(nextProps.tag === 1){ // Animation code / reference to method here } else if (nextProps.tag === 2) { // Animation code / reference to method here } else if (nextProps.tag === 3) { // Animation code / reference to method here } } render() { return ( <div className='reveal-icon' > <svg height="200" width="200" viewBox="0, 0, 200, 200"> <path ref="HAND_1" className="fill" d="M146.8,79.9l-55.2,55.2c-1.8,1.8-4.8,1.8-6.7,0c-1.8-1.8-1.8-4.8,0-6.7h0l18.4-18.4l-3.3-3.3 l-18.4,18.4c-0.9,0.9-2.1,1.4-3.3,1.4s-2.5-0.5-3.3-1.4c-0.9-0.9-1.4-2.1-1.4-3.3c0-1.3,0.5-2.5,1.4-3.3L93.3,100L90,96.7 l-18.4,18.4c-1.8,1.8-4.8,1.8-6.7,0c-1.8-1.8-1.8-4.8,0-6.7l41.8-41.8l-3.3-3.3L61.5,105c-3.7,3.7-3.7,9.7,0,13.4 c1.8,1.8,4.3,2.8,6.7,2.8c0.2,0,0.4,0,0.6,0c0,0.2,0,0.4,0,0.6c0,2.5,1,4.9,2.8,6.7c1.8,1.8,4.2,2.8,6.7,2.8c0.2,0,0.4,0,0.6,0 c-0.2,2.6,0.7,5.3,2.7,7.3c1.8,1.8,4.3,2.8,6.7,2.8c2.4,0,4.8-0.9,6.7-2.8l55.2-55.2L146.8,79.9z"/> <path ref="HAND_2_MASK" className="mask" d="M138.5,105l-22.7-22.7L83.3,49.8L49.8,83.3l32.5,32.5l22.7,22.7 c1.8,1.8,4.3,2.8,6.7,2.8c2.4,0,4.8-0.9,6.7-2.8c2-2,2.9-4.7,2.7-7.3c0.2,0,0.4,0,0.6,0c2.5,0,4.9-1,6.7-2.8 c1.8-1.8,2.8-4.2,2.8-6.7c0-0.2,0-0.4,0-0.6c0.2,0,0.4,0,0.6,0c2.4,0,4.8-0.9,6.7-2.8c1.8-1.8,2.8-4.2,2.8-6.7 C141.2,109.2,140.2,106.8,138.5,105z"/> <path ref="HAND_2" className="fill" d="M138.5,105L83.3,49.8l-3.3,3.3l55.2,55.2c0.9,0.9,1.4,2.1,1.4,3.3c0,1.3-0.5,2.5-1.4,3.3 c-1.8,1.8-4.8,1.8-6.7,0L110,96.7l-3.3,3.3l18.4,18.4c0.9,0.9,1.4,2.1,1.4,3.3c0,1.3-0.5,2.5-1.4,3.3c-0.9,0.9-2.1,1.4-3.3,1.4 s-2.5-0.5-3.3-1.4L100,106.7l-3.3,3.3l18.4,18.4c1.8,1.8,1.8,4.8,0,6.7c-1.8,1.8-4.8,1.8-6.7,0L53.2,79.9l-3.3,3.3l55.2,55.2 c1.8,1.8,4.3,2.8,6.7,2.8c2.4,0,4.8-0.9,6.7-2.8c2-2,2.9-4.7,2.7-7.3c0.2,0,0.4,0,0.6,0c2.5,0,4.9-1,6.7-2.8 c1.8-1.8,2.8-4.2,2.8-6.7c0-0.2,0-0.4,0-0.6c0.2,0,0.4,0,0.6,0c2.4,0,4.8-0.9,6.7-2.8c1.8-1.8,2.8-4.2,2.8-6.7 C141.2,109.2,140.2,106.8,138.5,105z"/> <path ref="HAND_1_MASK" className="mask" d="M116.7,49.8l-5,5l-3.3-3.3c-1.8-1.8-4.2-2.8-6.7-2.8c-2.5,0-4.9,1-6.7,2.8 L73.2,73.2c-3.7,3.7-3.7,9.7,0,13.4c1.8,1.8,4.3,2.8,6.7,2.8c2.4,0,4.8-0.9,6.7-2.8l20.1-20.1l5-5l8.4-8.4L116.7,49.8z"/> <path ref="HAND_1_THUMB" className="fill" d="M116.7,49.8l-5,5l-3.3-3.3l0,0c-1.8-1.8-4.2-2.8-6.7-2.8c-2.5,0-4.9,1-6.7,2.8 L73.2,73.2c-3.7,3.7-3.7,9.7,0,13.4c1.8,1.8,4.3,2.8,6.7,2.8c2.4,0,4.8-0.9,6.7-2.8l20.1-20.1l-3.3-3.3L83.3,83.3 c-1.8,1.8-4.8,1.8-6.7,0s-1.8-4.8,0-6.7l21.7-21.7c0.9-0.9,2.1-1.4,3.3-1.4c1.3,0,2.5,0.5,3.3,1.4l6.7,6.7l8.4-8.4L116.7,49.8z"/> <g ref="HAND_LINES"> <line ref="HAND_LINES_8" className="stroke" x1="32.6" y1="32.6" x2="49.4" y2="49.4"/> <line ref="HAND_LINES_7" className="stroke" x1="4.7" y1="100" x2="28.4" y2="100"/> <line ref="HAND_LINES_6" className="stroke" x1="32.6" y1="167.4" x2="49.4" y2="150.6"/> <line ref="HAND_LINES_5" className="stroke" x1="100" y1="195.3" x2="100" y2="171.6"/> <line ref="HAND_LINES_4" className="stroke" x1="167.4" y1="167.4" x2="150.6" y2="150.6"/> <line ref="HAND_LINES_3" className="stroke" x1="195.3" y1="100" x2="171.6" y2="100"/> <line ref="HAND_LINES_2" className="stroke" x1="167.4" y1="32.6" x2="150.6" y2="49.4"/> <line ref="HAND_LINES_1" className="stroke" x1="100" y1="4.7" x2="100" y2="28.4"/> </g> </svg> </div> ) } } class SwitchLocale extends React.Component { render() { return ( <button className='switch-locale' onClick={this.props.switchLocale}> Switch locale </button> ) } } React.render(<Reveal/>, document.getElementById('react-root')) </script> On the left, the animation I currently have created in React, on the right, the icons I still have to implement in the same manner.