2

I am working on a React AMP project where I need to do some tweaky animation with AMP to show and hide a button when the window is scrolled.

As AMP Animation tag expects an object in the children on <amp-animation> but React does not allows object as it's children.

Here is the code I am trying with:

import React from 'react';
const showAnim = {
  "duration": "200ms",
  "fill": "both",
  "iterations": "1",
  "direction": "alternate",
  "animations": [
    {
      "selector": "#download-button",
      "keyframes": [
        { "opacity": "1", "visibility": "visible" }
      ]
    }
  ]
}
const hideAnim = {
  "duration": "200ms",
  "fill": "both",
  "iterations": "1",
  "direction": "alternate",
  "animations": [
    {
      "selector": "#download-button",
      "keyframes": [
        { "opacity": "0", "visibility": "hidden" }
      ]
    }
  ]
};
export default class Animate extends React.Component {

  componentDidMount() {
    window.addEventListener('scroll', this.onScroll)
  }

  onScroll = () => {
    console.log('scrolling')
  }

  renderShowAnimation = () => <amp-animation id="showAnim" layout="nodisplay" src="">
    <script type="application/json">
      {showAnim}
    </script>
  </amp-animation >;

  renderHideAnimation = () => <amp-animation id="showAnim" layout="nodisplay">
    <script type="application/json">
    {hideAnim}
    </script>
  </amp-animation >;


  render() {
    return (
      <main onScroll={this.onScroll} >
        <div>
         {this.renderShowAnimation()}
          {this.renderHideAnimation()}
              <div className="download-button" id="download-button" role="button">
                Download
                <amp-position-observer
                  on="enter:hideAnim.start; exit:showAnim.start"
                  layout="nodisplay">
                </amp-position-observer>
              </div>
        </div>
      </main>
    )
  }
}

Now when I am trying to run the app I am getting the following error:

Objects are not valid as a React child (found: object with keys {duration, fill, iterations, direction, animations}).

I tried to put an onScroll event also but it is also not working in AMP. If someone has an aleternative or if something is wrong in my code please suggest.

Harish Soni
  • 1,796
  • 12
  • 27

2 Answers2

0

amp-animation expects a JSON as a child, not a Javascript object. (They are similar in syntax, but different.) Even though you wrote the object in JSON syntax, showAnim and hideAnim end up interpreted as objects by javascript. You can convert them to JSON with JSON.stringify().

Simplifying your issue for a second, if you look at one of their examples.

<amp-animation layout="nodisplay">
  <script type="application/json">
    {
      "selector": "#target-id",
      "duration": "1s",
      "keyframes": {"opacity": 1}
    }
  </script>
</amp-animation>

The problem is if you paste this into the render method of React, you'll get errors because the { escapes the jsx and it now expects javascript. One way to fix this is to use React's dangerouslySetInnerHTML.

<amp-animation layout="nodisplay">
  <script type="application/json" dangerouslySetInnerHTML={{__html: 
    JSON.stringify(
      {
        "selector": "#target-id",
        "duration": "1s",
        "keyframes": {"opacity": 1}
      }
    )
  }}>
  </script>
</amp-animation>

In your case, you can change your two functions to

renderShowAnimation = () => <amp-animation id="showAnim" layout="nodisplay" src="">
    <script type="application/json" dangerouslySetInnerHTML={{__html: JSON.stringify(showAnim)}}>
    </script>
  </amp-animation >;

  renderHideAnimation = () => <amp-animation id="showAnim" layout="nodisplay">
    <script type="application/json" dangerouslySetInnerHTML={{__html: JSON.stringify(showAnim)}}>
    </script>
  </amp-animation >
jimbotron
  • 864
  • 10
  • 11
-1

AMP not allow define custom javascript (unlimited js) and custom event listener except on attribute). You can implement some dynamic functionality in AMP with amp-bind component and amp-script component

Masih Jahangiri
  • 9,489
  • 3
  • 45
  • 51
  • You can add custom javascript, under heavy restrictions, with the new tag: https://amp.dev/documentation/guides-and-tutorials/develop/custom-javascript/?format=websites – jimbotron May 10 '20 at 20:23