Guest User

Untitled

a guest
Jan 22nd, 2019
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.17 KB | None | 0 0
  1. import React, { Component } from 'react';
  2. import styled from 'styled-components';
  3.  
  4. const Figure = styled.figure`
  5. height: 0;
  6. margin: 0;
  7. background-color: #efefef;
  8. position: relative;
  9. padding-bottom: ${props => props.ratio}%;
  10. `;
  11.  
  12. const Img = styled.img`
  13. width: 100%;
  14. height: 100%;
  15. top: 0;
  16. position: absolute;
  17. object-fit: contain;
  18. opacity: ${props => props.isLoaded ? '1' : '0'};
  19. transition: opacity .50s ease-in;
  20. `;
  21.  
  22.  
  23. // good-enough shim for this...
  24. const idle = {
  25. request: window.requestIdleCallback || ((fn) => setTimeout(fn, 10)),
  26. cancel: window.cancelIdleCallback || clearTimeout,
  27. };
  28.  
  29. class LazyImg extends Component {
  30.  
  31. constructor(props) {
  32. super(props);
  33.  
  34. this.state = {
  35. src: null,
  36. value: null,
  37. error: null,
  38. };
  39. }
  40.  
  41. static getDerivedStateFromProps(props, state) {
  42. if (props.src !== state.src) {
  43. return { src: props.src, value: null, error: null }
  44. }
  45. }
  46.  
  47. loadImage() {
  48. if (this.cleanup) {
  49. this.cleanup();
  50. }
  51.  
  52. let idleHandle = null;
  53. this.img = new Image();
  54. this.img.src = this.props.src;
  55. const src = this.img.src;
  56.  
  57. const handleLoad = () => {
  58. idleHandle = idle.request(() => {
  59. idleHandle = null;
  60.  
  61. this.setState({ error: null, value: { src, ratio: something } });
  62. }, { timeout: 50 });
  63. };
  64.  
  65.  
  66. const handleError = () => {
  67. // TODO: implement
  68. };
  69.  
  70.  
  71.  
  72. img.addEventListener('load', handleLoad);
  73. img.addEventListener('error', handleError);
  74.  
  75. // set this.cleanup to remove load/error listeners, and cancel idleHandle if needed
  76. }
  77.  
  78. componentDidMount() {
  79. this.loadImage();
  80. }
  81.  
  82. componentDidUpdate(_, prevState) {
  83. if (this.state.src !== prevState.src) {
  84. this.loadImage();
  85. }
  86. }
  87.  
  88. componentWillUnmount() {
  89. if (this.cleanup) {
  90. this.cleanup();
  91. }
  92. }
  93.  
  94. render() {
  95. if (this.state.error) {
  96. return something // TODO
  97. }
  98.  
  99. if (!this.state.value) {
  100. // we're loading
  101. }
  102.  
  103. const { src, ratio } = this.state.value;
  104.  
  105. return(
  106. <Figure ratio={ratio}>
  107. <Img key={src} isLoaded={true} src={src} />
  108. </Figure>
  109. );
  110. }
  111.  
  112. }
  113.  
  114. export default LazyImg;
Add Comment
Please, Sign In to add comment