You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

75 lines
1.5 KiB

  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. export default class GIFV extends React.PureComponent {
  4. static propTypes = {
  5. src: PropTypes.string.isRequired,
  6. alt: PropTypes.string,
  7. width: PropTypes.number,
  8. height: PropTypes.number,
  9. onClick: PropTypes.func,
  10. };
  11. state = {
  12. loading: true,
  13. };
  14. handleLoadedData = () => {
  15. this.setState({ loading: false });
  16. }
  17. componentWillReceiveProps (nextProps) {
  18. if (nextProps.src !== this.props.src) {
  19. this.setState({ loading: true });
  20. }
  21. }
  22. handleClick = e => {
  23. const { onClick } = this.props;
  24. if (onClick) {
  25. e.stopPropagation();
  26. onClick();
  27. }
  28. }
  29. render () {
  30. const { src, width, height, alt } = this.props;
  31. const { loading } = this.state;
  32. return (
  33. <div className='gifv' style={{ position: 'relative' }}>
  34. {loading && (
  35. <canvas
  36. width={width}
  37. height={height}
  38. role='button'
  39. tabIndex='0'
  40. aria-label={alt}
  41. title={alt}
  42. onClick={this.handleClick}
  43. />
  44. )}
  45. <video
  46. src={src}
  47. width={width}
  48. height={height}
  49. role='button'
  50. tabIndex='0'
  51. aria-label={alt}
  52. title={alt}
  53. muted
  54. loop
  55. autoPlay
  56. playsInline
  57. onClick={this.handleClick}
  58. onLoadedData={this.handleLoadedData}
  59. style={{ position: loading ? 'absolute' : 'static', top: 0, left: 0 }}
  60. />
  61. </div>
  62. );
  63. }
  64. }