1
//! v.2.0 http://ilyabirman.net/projects/emerge/
2
(function(){"use strict";const emerge="emerge";const emergeSpin="emerge-spin-element";const waitingForView=new WeakMap;const spinner=new WeakMap;const defaultDuration=500;const spinner_defaults=Object.freeze({spinSize:24,spinColor:"#404040",spinDirection:"clockwise",spinPeriod:1333,duration:defaultDuration}
3
);const cssImageProps=["backgroundImage","borderImage","borderCornerImage","listStyleImage","cursor"];const cssUrlRegex=/url\(\s*(['"]?)(.*?)\1\s*\)/g;function ready(callback){if(document.readyState!=="loading"){callback()}
4
else{document.addEventListener("readystatechange",function(){if(document.readyState==="interactive"){callback()}
5
}
6
,{passive:true}
7
)}
8
}
9
function spinnerCode(diameter,color,direction,period,fadeDuration){const element=document.createElement("div");Object.assign(element.style,{position:"absolute",display:"flex",justifyContent:"center",alignItems:"center",transition:`opacity ${fadeDuration}
10
ms ease-out`}
11
);element.innerHTML="<svg viewBox='0 0 100 100' display='block'>"+"<defs><mask id='cut'>"+"<rect width='100' height='100' fill='white' stroke='none' />"+"<circle r='40' cx='50' cy='50' fill='black' stroke='none' />"+"<polygon points='50,50 100,25 150,50 100,75' fill='black'"+"stroke='none' transform-origin='center center' />"+"</mask></defs>"+"<circle r='50' cx='50' cy='50' mask='url(#cut)' stroke='none' />"+"</svg>";const svg=element.firstElementChild;svg.setAttribute("width",diameter);svg.setAttribute("hight",diameter);svg.lastElementChild.setAttribute("fill",color);element.firstElementChild.animate([{transform:"rotate(0turn)"}
12
,{transform:"rotate(1turn)"}
13
],{duration:Number(period),iterations:Infinity,direction:direction==="counter-clockwise"?"reverse":"normal"}
14
);return element}
15
function withinView(el){const bodyHeight=Math.min(document.body.clientHeight,document.documentElement.clientHeight);const position=el.getBoundingClientRect().top;const scrollTop=window.pageYOffset||document.documentElement.scrollTop;return position-scrollTop<bodyHeight}
16
function getEmergeElements(){return Array.from(document.querySelectorAll(`.${emerge}
17
`))}
18
const imgLoaded=function(){const cache=Object.create(null);return function imgLoaded(url){if(cache[url]!==undefined){return cache[url]}
19
cache[url]=new Promise(function(resolve){const img=document.createElement("img");img.src=url;if(img.complete){resolve()}
20
else{img.addEventListener("load",()=>resolve());img.addEventListener("error",()=>resolve())}
21
}
22
);return cache[url]}
23
}
24
();function eventDispatched(element,event){return new Promise(function(resolve){if(element.readyState>=4){resolve()}
25
else{element.addEventListener(event,()=>resolve())}
26
}
27
)}
28
function get_element_to_wait_for(element,previous){return element.dataset.await!==undefined?document.getElementById(element.dataset.await):element.dataset.continue!==undefined?previous:undefined}
29
function is_cyclic(element){let next=element;while(next.dataset.await!==undefined){next=document.getElementById(next.dataset.await);if(next===null){return false}
30
if(next===element){return true}
31
}
32
return false}
33
function fire(element){const spinElement=spinner.get(element);if(spinElement){spinElement.style.opacity=0;setTimeout(function(){if(element.parentNode.style.position==="relative"){element.parentNode.style.position=null}
34
spinElement.remove()}
35
,defaultDuration)}
36
element.style.transition=`opacity ${defaultDuration}
37
ms ease-out`;element.style.opacity=1;const style2=element.dataset["style-2"];if(style2){element.setAttribute("style",element.getAttribute("style")+"; "+style2)}
38
console.log(" FIRED!",element.id)}
39
const viewWatcher=new IntersectionObserver(function(entries,watcher){entries.forEach(function(entry){if(entry.isIntersecting||withinView(entry.target)){if(waitingForView.has(entry.target)){waitingForView.get(entry.target)()}
40
waitingForView.delete(entry.target);watcher.unobserve(entry.target);fire(entry.target)}
...
</html>