Guest User

Untitled

a guest
Jan 22nd, 2019
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.43 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. class LazyImg extends Component {
  23.  
  24. constructor(props) {
  25. super(props);
  26.  
  27. this.state = {
  28. isLoaded: false,
  29. src: null,
  30. ratio: 0
  31. };
  32. }
  33.  
  34.  
  35. componentDidMount() {
  36. this.img = new Image();
  37. this.img.src = this.props.src;
  38. const src = this.img.src;
  39.  
  40. this.poll = setInterval(() => {
  41. if (this.img.naturalWidth) {
  42. clearInterval(this.poll);
  43. const ratio = (this.img.naturalHeight/this.img.naturalWidth) * 100;
  44. this.setState({ ratio });
  45. }
  46. }, 10);
  47.  
  48. this.img.onload = () => {
  49. setTimeout(() => {
  50. this.setState({ src });
  51. this.setState({ isLoaded: true });
  52. }, 300);
  53. };
  54. }
  55.  
  56. componentWillUnmount() {
  57.  
  58. if (!this.img) {
  59. return;
  60. }
  61.  
  62. clearInterval(this.poll);
  63. this.img.onload = null;
  64. delete this.img;
  65. }
  66.  
  67. render() {
  68. return(
  69. <Figure ratio={this.state.ratio}>
  70. <Img isLoaded={this.state.isLoaded} src={this.state.src}/>
  71. </Figure>
  72. );
  73. }
  74.  
  75. }
  76.  
  77. export default LazyImg;
Add Comment
Please, Sign In to add comment