Last active
March 12, 2020 15:17
-
-
Save taejs/3044b644ce01ceef803b4ddd6b0e6814 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ImageLoader { | |
static DELAY_TIME = 200; //ms 단위 | |
constructor(rowNum, imgElementList) { | |
this.imageElementList = imgElementList; | |
this.rowNum = rowNum; | |
} | |
calculateNextIndex(cnt) { //대각선으로 증가하는 수식 | |
const rowNum = this.rowNum; | |
const lastNumber = this.rowNum * cnt; | |
return new Array(rowNum).fill(0).map((_, i) => lastNumber - ((rowNum - 1) * i)).filter(v => v >= 0); | |
} | |
start() { // 지연실행 가능하도록 생성자와 분리 | |
let rendered = 0; | |
let imageElementList = this.imageElementList; | |
let lastDrawTime = performance.now(); | |
let cnt = 0; | |
const f = (time) => { | |
if(rendered >= imageElementList.length) return; | |
if(time - lastDrawTime >= ImageLoader.DELAY_TIME) { | |
const renderingElementList = this.calculateNextIndex(cnt); | |
renderingElementList.forEach(idx => { | |
if(imageElementList[idx]) { | |
imageElementList[idx].src = imageElementList[idx].dataset.src; | |
imageElementList[idx].classList.add('visible'); | |
} | |
}); | |
rendered += renderingElementList.length; | |
lastDrawTime = time; | |
cnt++; | |
} | |
requestAnimationFrame(f); | |
} | |
requestAnimationFrame(f); | |
} | |
} | |
export default ImageLoader; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function PhotoList ({ | |
photos | |
}) { | |
const imageRefs = []; | |
const setRef = (ref) => { | |
imageRefs.push(ref); | |
if(imageRefs.length === photos.length) { //전체가 로딩되었으면 | |
lazyLoad(imageRefs[0]); | |
} | |
}; | |
const imageLoader = new ImageLoader(3, imageRefs); | |
const lazyLoad = target => { | |
if(!target) return; | |
const io = new IntersectionObserver(([{isIntersecting}], observer) => { | |
if (isIntersecting) { | |
imageLoader.start(); | |
observer.disconnect(); | |
} | |
}); | |
io.observe(target) | |
}; | |
return ( | |
<> | |
{ | |
photos.map(photo => <img ref={setRef} className={"unloaded"} data-src={photo} />) | |
} | |
</> | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment