| @ -21,6 +21,8 @@ | |||||
| <script src="js/lastblock.js" defer></script> | <script src="js/lastblock.js" defer></script> | ||||
| <script src="js/blockexplorer.js" defer></script> | <script src="js/blockexplorer.js" defer></script> | ||||
| <script src="js/simpleParallax.js"></script> | |||||
| <script> | <script> | ||||
| $(document).ready(function(){ | $(document).ready(function(){ | ||||
| @ -28,6 +30,8 @@ | |||||
| getMyAdressInfos(); | getMyAdressInfos(); | ||||
| setParallax(); | |||||
| $('#myNavbar').on('show.bs.collapse', function () { | $('#myNavbar').on('show.bs.collapse', function () { | ||||
| $('#logo_topisto').css({'height' : '30px','width' : '30px'}); | $('#logo_topisto').css({'height' : '30px','width' : '30px'}); | ||||
| $('#titre_topisto').css({'font-size' : '30px'}); | $('#titre_topisto').css({'font-size' : '30px'}); | ||||
| @ -89,7 +93,8 @@ | |||||
| * Calculer et afficher la balance en EUR et USD | * Calculer et afficher la balance en EUR et USD | ||||
| * | * | ||||
| */ | */ | ||||
| function getMyAdressInfos() { | |||||
| function getMyAdressInfos() | |||||
| { | |||||
| var balance_url = 'https://blockchain.info/q/addressbalance/15V7XfBX2Xn5uKpK3VuVngDg44TSKLtTSh?cors=true'; | var balance_url = 'https://blockchain.info/q/addressbalance/15V7XfBX2Xn5uKpK3VuVngDg44TSKLtTSh?cors=true'; | ||||
| $.get( balance_url, function( data ) { | $.get( balance_url, function( data ) { | ||||
| var balance = data/100000000; | var balance = data/100000000; | ||||
| @ -100,7 +105,17 @@ | |||||
| $('#BTC_CHANGE').html(btc_change); | $('#BTC_CHANGE').html(btc_change); | ||||
| }); | }); | ||||
| }); | }); | ||||
| } | |||||
| } | |||||
| function setParallax() | |||||
| { | |||||
| var image = document.getElementsByClassName('simple-parallax'); | |||||
| new simpleParallax(image,{ | |||||
| scale: 1.5, | |||||
| overflow: true, | |||||
| orientation: 'down' | |||||
| }); | |||||
| } | |||||
| </script> | </script> | ||||
| @ -130,7 +145,7 @@ | |||||
| </div> | </div> | ||||
| </nav> | </nav> | ||||
| <div id="explorer" class="container-fluid bg-grey" style="padding-bottom:10px"> | |||||
| <div id="explorer" class="container-fluid" style="padding-bottom:10px"> | |||||
| <div class="row"> | <div class="row"> | ||||
| <div class="col-sm-12 text-left"> | <div class="col-sm-12 text-left"> | ||||
| <br>BTC adress : <a href="https://www.blockchain.com/btc/address/15V7XfBX2Xn5uKpK3VuVngDg44TSKLtTSh">15V7XfBX2Xn5uKpK3VuVngDg44TSKLtTSh</a> | <br>BTC adress : <a href="https://www.blockchain.com/btc/address/15V7XfBX2Xn5uKpK3VuVngDg44TSKLtTSh">15V7XfBX2Xn5uKpK3VuVngDg44TSKLtTSh</a> | ||||
| @ -139,21 +154,25 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div id="about" class="container-fluid"> | |||||
| <div class="row"> | |||||
| <div class="col-sm-8"> | |||||
| <h4>This site is a hobby.<br>It's also a testing place where i can do <a href="blog.php">things</a> that are impossible at work.</h4> | |||||
| <div id="about" class="container-fluid bg-grey" style="padding-top:5px;padding-bottom:5px"> | |||||
| <div class="row" style="margin-top:0px"> | |||||
| <div class="col-sm-8" style="margin-top:0px"> | |||||
| <h4 style="margin-top:0px">This site is a hobby.<br>It's also a testing place where i can do <a href="blog.php">things</a> that are impossible at work.</h4> | |||||
| <p class="text-justify">I like <b>surfing</b> and sailing on the ocean. But during longs winter nights, computing is fun. I'm interested into <b>cryptocurrencies</b>, computationnal art, datavisualisation. I know that <b>42</b> is the answer to <b>the Life, Universe and Everything Else</b>. As <b>Eto Demerzel</b> said to me, the <b>Seldon's Plan</b> will save the Galaxy. My favorites books are the <b>House of leaves</b>, the <b>Necronomicron</b> and the <b>DarkHold</b>. I also know that <b>great power comes with great responsibility</b>. I'm still in <b>the search of Captain Zero</b>, because <b>the Truth is out there</b>.</p> | <p class="text-justify">I like <b>surfing</b> and sailing on the ocean. But during longs winter nights, computing is fun. I'm interested into <b>cryptocurrencies</b>, computationnal art, datavisualisation. I know that <b>42</b> is the answer to <b>the Life, Universe and Everything Else</b>. As <b>Eto Demerzel</b> said to me, the <b>Seldon's Plan</b> will save the Galaxy. My favorites books are the <b>House of leaves</b>, the <b>Necronomicron</b> and the <b>DarkHold</b>. I also know that <b>great power comes with great responsibility</b>. I'm still in <b>the search of Captain Zero</b>, because <b>the Truth is out there</b>.</p> | ||||
| <p class="text-justify">.I'm also really astonished by <b>Universal Numbers</b>, aka Disjunctives Sequences. Thinking that a single number can contain every others, that's a great <b>mystery</b>. So I'm trying to write the chronicles of these numbers (in french)</p> | |||||
| </div> | </div> | ||||
| <div class="col-sm-4"> | <div class="col-sm-4"> | ||||
| <div style="background-image:url(images/topisto_vert_tr.png);background-repeat: no-repeat;background-position:center top;background-size: 100% auto;"> | |||||
| <img id="gargoyle" src="images/logo.php" alt="avatar dragon gargoyle" width="100%; height: auto" style="opacity:0.4"></img> | |||||
| </div> | |||||
| <!-- | |||||
| <div style="background-image:url(images/topisto_vert_tr.png);background-repeat: no-repeat;background-position:center top;background-size: 100% auto;"> | |||||
| <img id="gargoyle" src="images/logo.php" alt="avatar dragon gargoyle" width="100%; height: auto" style="opacity:0.4"></img> | |||||
| </div> | |||||
| --> | |||||
| <img id="gargoyle" class="simple-parallax" src="images/logo.php" alt="avatar dragon gargoyle" width="100%; height: auto" style="margin-top:-20px"></img> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div id="contact" class="container-fluid bg-grey"> | |||||
| <div id="contact" class="container-fluid"> | |||||
| <div class="row slideanim"> | <div class="row slideanim"> | ||||
| <div class="col-sm-4"> | <div class="col-sm-4"> | ||||
| Bookmarks : <br> | Bookmarks : <br> | ||||
| @ -36,7 +36,7 @@ | |||||
| padding: 60px 50px; | padding: 60px 50px; | ||||
| } | } | ||||
| .bg-grey { | .bg-grey { | ||||
| background-color: #f6f6f6; | |||||
| background-color: #e6e6e6; | |||||
| } | } | ||||
| .bg-grey-odd { | .bg-grey-odd { | ||||
| background-color: #fff; | background-color: #fff; | ||||
| @ -0,0 +1,288 @@ | |||||
| { | |||||
| "Height" : "610613", | |||||
| "Hash" : "00000000000000000002e115eeead81ee6977eb7697c267748cb5bf8b4dd761b", | |||||
| "Version" : "541065216", | |||||
| "Timestamp" : "1577789001", | |||||
| "Nonce" : "1978572825", | |||||
| "Previous" : "0000000000000000000e27bcd20a2c05064636b6abd52975d59062a803d86fb9", | |||||
| "Merkle" : "09f4975c0c558d0bdc82244d0811ce648773799ea2d5a7211ad69aa7ed156440", | |||||
| "TX" : [ | |||||
| {"Hash":"430e1560a55ea77c4334389f7e5c57eb76675edbafe46bce72be5238f8768685", "Timelock":"0","Amount":"1252070815"}, | |||||
| {"Hash":"ab88d5013a926d1a0b04384ef63cdeb59e8e015f76698ed64a72f87054854284", "Timelock":"0","Amount":"1408948128"}, | |||||
| {"Hash":"7f7ff846fd1a08bd8ed698711cf69b5d5f84f64a14348284f79f2537c89c7f03", "Timelock":"0","Amount":"52585327"}, | |||||
| {"Hash":"87b24db8855066ffb61156ea5e0ff874a489bc26a079c8de4207a02319f268b7", "Timelock":"610611","Amount":"4370410956"}, | |||||
| {"Hash":"091c632678d4353356d2aa19a0a5022b48e43dc5839b976dfa4db3a27df7cfae", "Timelock":"610612","Amount":"137301334"}, | |||||
| {"Hash":"2ed396ad457cddb176c07099022ba27e2fa8b8714b629f4cd642f2714c3b4007", "Timelock":"0","Amount":"829288"}, | |||||
| {"Hash":"33c2694dd3acedb0b333817dadac4e52fd2254a50a70337bb84bfe473718154b", "Timelock":"610612","Amount":"2573250"}, | |||||
| {"Hash":"d8f67c3a56409ec0574809b5d68ae8418605396815794a31110c2b3472e0ef8e", "Timelock":"610612","Amount":"25997116"}, | |||||
| {"Hash":"4551b5df7a1bea50a625260b1f528d6fa3b8748d6768909791aff3a75dd110c0", "Timelock":"0","Amount":"2307242207"}, | |||||
| {"Hash":"00b65c3b22bf12d9e1609e002c6909cad91a3d76f4855652848670981a9ccd13", "Timelock":"0","Amount":"172453"}, | |||||
| {"Hash":"368128cc945384050a9af4f595334de573b18261ca36d90b6f48e8b51aa04142", "Timelock":"0","Amount":"415333"}, | |||||
| {"Hash":"438e52615dcc7bf45ebdd8487cd1e817ac53ab646e1748ffcdfcabd52ab85352", "Timelock":"0","Amount":"199508"}, | |||||
| {"Hash":"90c7bd4a106935cadf8726c1ece872d69a5223001ab46d8dd67453f71d0a527c", "Timelock":"0","Amount":"442388"}, | |||||
| {"Hash":"f4e947923b060117db520238f8d695b5733d843626a33d8adfbb25768b0ebaa8", "Timelock":"0","Amount":"172517"}, | |||||
| {"Hash":"ff1083f1013239427e1325836bd57e6e5ed6dd56c2a59d868e2e6a1086f065cb", "Timelock":"0","Amount":"172560"}, | |||||
| {"Hash":"464e5f5b4ed996b4fec45a2e78e3b0e7f1419be4e581ff87b2bf42582c81adf7", "Timelock":"0","Amount":"442334"}, | |||||
| {"Hash":"ff8b744bcc7433fc2b729cac2e51f88c86b33ec58aaf2a7800e965b32f40563e", "Timelock":"0","Amount":"442388"}, | |||||
| {"Hash":"d52ab83f47d71c22af57fa10fdbe3d7716d94c8b68c0a07734815b41901d395a", "Timelock":"0","Amount":"172507"}, | |||||
| {"Hash":"d7e172f6826ec1099400c7af6ae76cf9e8221f60bea298552df5a61d2d80be62", "Timelock":"0","Amount":"226453"}, | |||||
| {"Hash":"b8506d4e89af438bd8e3d733a6b81bc7e8f1e19032f90a6202c432d2e2b7fd72", "Timelock":"0","Amount":"172561"}, | |||||
| {"Hash":"59a3ce63eb6ce9ab6421a09f1aea495cc68fdcb0a2772449a5f6e60686dd3a7b", "Timelock":"0","Amount":"172454"}, | |||||
| {"Hash":"d77460002718fef51efea5529061c8ba76285660ce2b8b0070ff9aee2961678c", "Timelock":"0","Amount":"226453"}, | |||||
| {"Hash":"e44847a9fb68ceebe63ee8ea6e12b78a22de10c518f84f029b901b7d9a5ee68d", "Timelock":"0","Amount":"442334"}, | |||||
| {"Hash":"0a7061f1806a4fafb3f8f8c1ab5508268b598f15b775b4c9f1029da6e63b7aa1", "Timelock":"0","Amount":"442334"}, | |||||
| {"Hash":"5059939f8c9e7e2090c9615c87aac3247658ccfabd83eddff7def430e89473ad", "Timelock":"0","Amount":"415441"}, | |||||
| {"Hash":"1892d746c63082d84660d302c2976f52af6489376a3a4bfeac1296d91a47d8ae", "Timelock":"0","Amount":"415388"}, | |||||
| {"Hash":"eb6263a9cc47b37d9e78dfdcd9a81ee7a0a93423ab9809e94dd50402da8ad3b0", "Timelock":"0","Amount":"442388"}, | |||||
| {"Hash":"3a608b91415e0d5e5e958c9aa3adc9308ac6becfd817d49c868e682e9923fabb", "Timelock":"0","Amount":"226507"}, | |||||
| {"Hash":"175e437471fa7a87607b0f69b60124c852b7c3bec604533bfd3e537e67d58cd7", "Timelock":"0","Amount":"415387"}, | |||||
| {"Hash":"764ac68edd0bb5583923b382736a36ac080fc513f157b1eddca1cc6c5d0ab4de", "Timelock":"0","Amount":"226399"}, | |||||
| {"Hash":"aa0773b9f6f156a3739204b59f1399cbab7f8d15d256de3678efccc7ee79a3e8", "Timelock":"0","Amount":"442388"}, | |||||
| {"Hash":"5b34a8c685f8d1ffa92062c5b9a907289e96a26d6ec05144eb79e6f0c5c89cf1", "Timelock":"0","Amount":"172452"}, | |||||
| {"Hash":"0a3a1e763e1b39ce1f412bdf1d1ef5931237a49945012b234082bb2c1f1901f9", "Timelock":"0","Amount":"442334"}, | |||||
| {"Hash":"8929dd3205413caa862c85cca472f0d6354277923ac53a607028389942513afd", "Timelock":"0","Amount":"172614"}, | |||||
| {"Hash":"c4b10b1aa965dd239b52d6fbdc8454a371f064ce1b188f8ff2984e56cf231416", "Timelock":"0","Amount":"172561"}, | |||||
| {"Hash":"834514b9c659c3d337e218c6c4f5e2dadfc29c09424f64aeab34fcf75300681d", "Timelock":"0","Amount":"172400"}, | |||||
| {"Hash":"84809433f9b27b32d44dd928cd790d94de91ad42b1f2dc17304ee56cc8d67d23", "Timelock":"0","Amount":"226453"}, | |||||
| {"Hash":"1cdbc639f27b1d95781bbf708623a54dd3694b33253942741eb6266ca2a32b3f", "Timelock":"0","Amount":"172507"}, | |||||
| {"Hash":"cae61d427b4f3b53665768ed5bd188e91c34c1ff81cc73bd54486c2965062f53", "Timelock":"0","Amount":"415388"}, | |||||
| {"Hash":"4a7e289c57fe0221e39d3a9a7c13bf1004a4d594d7dcd3102b8e7ffea167915a", "Timelock":"0","Amount":"442334"}, | |||||
| {"Hash":"ef1e7dca343e90c8e03285463579d8fbcd886fe7552681ba574206af0b84c772", "Timelock":"0","Amount":"172614"}, | |||||
| {"Hash":"1fdbf1cee2838bb1fa3d2f3dc7aa9cf312a4e5de1ecb390244c2c6eef05cada7", "Timelock":"0","Amount":"172561"}, | |||||
| {"Hash":"5fcda12bd9da552d9cf6921689eb6d2bfd0f5736725b55cecc13c8145c7662ac", "Timelock":"0","Amount":"172398"}, | |||||
| {"Hash":"35ed4fc56ddda175a2a22b07e66bf85ce9128d33214a930cf8a313c66e6f85f8", "Timelock":"0","Amount":"172506"}, | |||||
| {"Hash":"ac504cb9488ec9cfa4df07398a18fc07a1a419d5bd5102bc0ef45c429b27f1e1", "Timelock":"0","Amount":"37910603"}, | |||||
| {"Hash":"e6814a02507e07d18970151512ade5dbc083fe87921475d96d60669d6df03ac9", "Timelock":"0","Amount":"1181500"}, | |||||
| {"Hash":"3b390023200a6a1b205a0f706c04bcd2f52f11a0622e5992dfbd59ac0fcc6ab9", "Timelock":"610611","Amount":"109555200"}, | |||||
| {"Hash":"3bdd3340e02fe7e6163bffcc923e76660a20362187a3e7423f3ef70553cf16fd", "Timelock":"610611","Amount":"1434152"}, | |||||
| {"Hash":"974efc78ddf5fa212ab015d5cab8ef985139522857820d6d2539a2a2e347af26", "Timelock":"610611","Amount":"1420756"}, | |||||
| {"Hash":"a9c0e05edd7be77210e80bf1c55513a0f5a7306ad3a555193af278d68084e09b", "Timelock":"610526","Amount":"1407360"}, | |||||
| {"Hash":"786fb70f2cccb69848abfbc7dbb88f5b8381cfb751a569063e56fc040a36b15c", "Timelock":"610611","Amount":"1394014"}, | |||||
| {"Hash":"950f03c106f5b48de77147505d5aecbc1af2653c849056860fe4d9a7418022fd", "Timelock":"610611","Amount":"1380618"}, | |||||
| {"Hash":"4f0d9dc0858458b15bbef552d6109577821db359cb97056c2c4914c45b4d1940", "Timelock":"0","Amount":"9343098"}, | |||||
| {"Hash":"c23db3a178b0e81fc83c462705518ededf56de524309b1a66279ee12879ba176", "Timelock":"0","Amount":"118208932"}, | |||||
| {"Hash":"199c060f771b52e47dd17af1d9273ac1a1aedec30c9dfc93b4d61db12b341728", "Timelock":"0","Amount":"9341082"}, | |||||
| {"Hash":"77baaa6822444fa968b6b21195b2f26d9543622e508d1afef9f2ce044aed7032", "Timelock":"0","Amount":"9340829"}, | |||||
| {"Hash":"bd3ce87659d9bf61730138b5f79c6bc056b0832896a6d984cf1eae7284058418", "Timelock":"0","Amount":"9328349"}, | |||||
| {"Hash":"fc512cc59bb13ce369542b03cfaf877fc3becc98f1949dcab9037eabd8870564", "Timelock":"0","Amount":"1778747"}, | |||||
| {"Hash":"51181d9de70705d063506caf35f539e0b570816f98c8aa77e3b1530c8d9e29c0", "Timelock":"0","Amount":"1778624"}, | |||||
| {"Hash":"a569f21c36c5a2c9dfe1465e1ad44dbfbe76fa8fb028af0c263e1eab95c807c2", "Timelock":"0","Amount":"9327992"}, | |||||
| {"Hash":"a5bbdc76d94faa4e56eab49c3c8faf1d56c3c972695072a53c9534195b2602d3", "Timelock":"0","Amount":"1780330"}, | |||||
| {"Hash":"93f3b439a44f7fb4c90c410aea40d1a6968bbbb4807d4add7beb2b5d3e715f14", "Timelock":"0","Amount":"1779710"}, | |||||
| {"Hash":"ebb20b84a721f902c7f0349774d4ee8d7f58ad067fae718407a885797097fd77", "Timelock":"0","Amount":"20884786"}, | |||||
| {"Hash":"75eb8805b3014a13bd0e73062a636d1d006d6f13e79fb72645dd4b170684f686", "Timelock":"0","Amount":"2588900"}, | |||||
| {"Hash":"10e74529beaf33ce82148373f9f05561c4c178fdd9cc0ec75197de9e4ac90905", "Timelock":"0","Amount":"4899475"}, | |||||
| {"Hash":"77a14c6afee21c6db185075b173196b71f9cc88137c0c6030a3a45d411def53b", "Timelock":"610611","Amount":"2294190"}, | |||||
| {"Hash":"bca263663f36b5dcc800f0ff103ac884d331d704df27ada5c9970a748a5411eb", "Timelock":"610611","Amount":"2821732"}, | |||||
| {"Hash":"b17688fb601092a4f1826c4589c88b84441f0bffc27120cf0499cb992bc309a0", "Timelock":"0","Amount":"7513163"}, | |||||
| {"Hash":"a1129c0f13794c33f7bbd43acb6510b48d9f6958d4d8369275945db84fb2cf65", "Timelock":"0","Amount":"25945760"}, | |||||
| {"Hash":"7caf265d8c38089d58fae9a07210ea3fa9daa3b906c00845d0fd7fe8aa5cd5d7", "Timelock":"0","Amount":"802895"}, | |||||
| {"Hash":"53639f44f3675c3dd5da703aa3cd12dd931fc4685949cbd55c4654c734a67eda", "Timelock":"610525","Amount":"1930027"}, | |||||
| {"Hash":"9f0a66a02460215f5c9e8f1f9e0bd213f6422bf1e03c50921ab150387707cca6", "Timelock":"610611","Amount":"8879050"}, | |||||
| {"Hash":"c7758975a419c2cd3055cea02118c8f3a86e4a4597c6957d04e7640ebc86b7a0", "Timelock":"0","Amount":"47696224"}, | |||||
| {"Hash":"801e013770a9b8ee232a4c48eb2734ac61276fa27afcf5ecefab4defb231da35", "Timelock":"0","Amount":"3610116"}, | |||||
| {"Hash":"a447c26916b130d4293bdad593716d2a8b28a95309a025354adb0e9dd56e3752", "Timelock":"0","Amount":"1695019"}, | |||||
| {"Hash":"77e3e0b3c955f9327de85ff8852988b4ee8d7995945a908e8adbdd31f7e14d37", "Timelock":"0","Amount":"245120348"}, | |||||
| {"Hash":"978cb28e1e3d1285a59a89560736d14dd7e219cea4985b051d6cdcb7648cfde5", "Timelock":"0","Amount":"109305802"}, | |||||
| {"Hash":"d3aba0f4509139fe1af47112c15814b25123f7dbf436dc1186975e31369c0d0c", "Timelock":"0","Amount":"8672328"}, | |||||
| {"Hash":"f3345d8766bacdece0db04ff3bcbb89ae6916ca752d57d045dee3c324368dd6f", "Timelock":"0","Amount":"697116"}, | |||||
| {"Hash":"90aa1b582b779cbb12ea725ef0931ac497c058f57c95ed46b49d150ca5fa797a", "Timelock":"0","Amount":"46938046"}, | |||||
| {"Hash":"bd266c769b9826dcaf582bfa55e34022dae4c970e0435e29a22a024c2ed48997", "Timelock":"0","Amount":"315857548"}, | |||||
| {"Hash":"c934f2ebb0b6e6e124d5e2bf607c42d6fc815c34482db67be87b9b91afebd6a5", "Timelock":"610611","Amount":"138204874"}, | |||||
| {"Hash":"1b3d99e6afc8ff9fb5f378ee1028b9d6da5c0ac1ab6e05c9629c30da9f022cad", "Timelock":"0","Amount":"17290649927"}, | |||||
| {"Hash":"8a4e6513932c083eb8f29bc82a5c59fca0b3df3c4b01073032a8cece337c8cf8", "Timelock":"0","Amount":"2134590"}, | |||||
| {"Hash":"3b717dde9b891e7d8803b972e42b93fe016e5367be19371ad414e38e9711e687", "Timelock":"610612","Amount":"1189729"}, | |||||
| {"Hash":"0187ef5c6ac4c395deb08dfd178240d5e2440f3694810c665a5dc9715af98917", "Timelock":"0","Amount":"11476313"}, | |||||
| {"Hash":"23b83c1242f24f931226b6a6b753edcc016bf3f3318a1e5d9b9ed7662825801e", "Timelock":"0","Amount":"10772334"}, | |||||
| {"Hash":"35ac2974a3b008e14cf662fcc7ff4fdea0f44b46a317306afbacc81abd3af268", "Timelock":"0","Amount":"11614502"}, | |||||
| {"Hash":"99d5c98fff55040bfb3f631d069f92db86d43a1fe5a5b58305b90fc156008a21", "Timelock":"0","Amount":"4083241"}, | |||||
| {"Hash":"0d4939cec1d06e5d6821db20354085646f3462705b9b6fc5e2479dbfc63e7ad0", "Timelock":"0","Amount":"11573411"}, | |||||
| {"Hash":"4d7d94c6f9340935f9fac63380d71944e274683d8271a7886c5de78dab0db102", "Timelock":"0","Amount":"2370883"}, | |||||
| {"Hash":"49e0bee994a241b6a5cd8c6921d7eeec2198e50035e9bfe92290d1ca55db8b66", "Timelock":"0","Amount":"36245331"}, | |||||
| {"Hash":"05fbe4e855613c1a62f91f58b2ff3f39526030d46b7f00a8a4e486eb0a1c68a1", "Timelock":"0","Amount":"36245311"}, | |||||
| {"Hash":"f341add38baf66a365302997cdcfd4ef78154302ff90f4c01eb7659454211812", "Timelock":"0","Amount":"1830231"}, | |||||
| {"Hash":"08b9c10598ba595aabf808d17965e13f24dc664ad671cccb886372ca510e9b93", "Timelock":"0","Amount":"690565"}, | |||||
| {"Hash":"297cf01c89f9499348d245f81b5d6f48156ae71d22ccd09e0e1a9978df606da4", "Timelock":"0","Amount":"10004692"}, | |||||
| {"Hash":"d26dbe9426bc55d1f428d7f71a332511a4927c61a5387e1cf5bba920c9c46c15", "Timelock":"0","Amount":"62232459"}, | |||||
| {"Hash":"3f9aff8c341bdd6afdd3906c3eaae891e23a31910050defe9c5f18bb17ae07d5", "Timelock":"0","Amount":"59916685"}, | |||||
| {"Hash":"9541401b5af8348b1e9ee58692f0f15af82d9435a66ab31842c220ec88398bee", "Timelock":"0","Amount":"59488224"}, | |||||
| {"Hash":"6fae3b219cba8c62fda41471ad0a92e7f15bc8a65095a9521622b577fd48f37f", "Timelock":"0","Amount":"56648936"}, | |||||
| {"Hash":"6c9a8302eb69c447362cc2a50ffaa01f3bbc48139a974e87951bc345e90b0858", "Timelock":"0","Amount":"48492217"}, | |||||
| {"Hash":"c32a46c407a008b73b0ecca3b0a1d3ab905b15499cca314951894e7296e89494", "Timelock":"0","Amount":"47430066"}, | |||||
| {"Hash":"7ea69120fb99685089da3c9cc35b9575749afc5f67efd47223414036cafb827c", "Timelock":"0","Amount":"28914493"}, | |||||
| {"Hash":"a722bc55d7537f1c8bd8c6f11d58e03e8e26808080486c6ca44e4b8573b7fe6c", "Timelock":"0","Amount":"12204009"}, | |||||
| {"Hash":"4ee5de1cc3eba8252dd6e7bc74c6da2e08b9803ffe21e0539f4da3b1aa9c5521", "Timelock":"0","Amount":"596830"}, | |||||
| {"Hash":"9dadb5b119f67fff4e6d72614cb889c0f81f57f1cbdd18f11b723af2af458802", "Timelock":"0","Amount":"1092617"}, | |||||
| {"Hash":"baa4f5e91b453f85c1838fe3ab9fa6f7e65bc075e62cb48e4beb2308307f00e4", "Timelock":"0","Amount":"613854672"}, | |||||
| {"Hash":"83b1a68a0ede876c9747e103df25e8d334ce08147b10ef2eff3aa094f1855e63", "Timelock":"0","Amount":"76576"}, | |||||
| {"Hash":"f7f7d6800091828a57b255e8b7ace07319f831005829f901de39fe95304a4849", "Timelock":"0","Amount":"516018"}, | |||||
| {"Hash":"7908c475e26c3a148d15282afa31bef739b25183bb7ce5437aa0e84f3dcdcbff", "Timelock":"0","Amount":"976581"}, | |||||
| {"Hash":"44f7a0fc1e2b4f78184e58a943fc72735e8edc65d469ad2a558154c3a894de3a", "Timelock":"0","Amount":"46174460"}, | |||||
| {"Hash":"8774a74f7998a01a5bf0f1c80fc7690ee08addb2146550b2f06e583793aaa8f3", "Timelock":"0","Amount":"3908771"}, | |||||
| {"Hash":"ee3fc85e94640147e2b74bd8b263936e02e7844e3e3865c18d3d4e876d6d5115", "Timelock":"0","Amount":"54029203"}, | |||||
| {"Hash":"110a64b5152ff73956dc46c9cbaf994742b782cba74150af4995237615e63a5e", "Timelock":"0","Amount":"1864060"}, | |||||
| {"Hash":"8ff0fa0f2c0f141549e72723a2fab1fa0093b5b80f5fb12945ff73bef180b192", "Timelock":"0","Amount":"1093080"}, | |||||
| {"Hash":"aa05d3f9239c50094413c4270af895652e0c3acdee41f5441ba2fe24304b40e7", "Timelock":"0","Amount":"17960007"}, | |||||
| {"Hash":"d9956a24133fb231e178aaa20d6762fc70fd201aac6717634abe1572a46839fc", "Timelock":"0","Amount":"4140524"}, | |||||
| {"Hash":"9a630c4c8c5dff30dcea319068d4a9c0c1401860f4cfa6931910b69a275badbd", "Timelock":"0","Amount":"1252648"}, | |||||
| {"Hash":"ff8eeda68b788b83aa6591b3690f87ffa17f85e1f61490cade92e0bc142b0b2b", "Timelock":"0","Amount":"552000"}, | |||||
| {"Hash":"6d3d40c04f66a8200b2b9b508f0e72b80315f6c4ae233d64a0d62aa3fdbceb37", "Timelock":"0","Amount":"7546810"}, | |||||
| {"Hash":"22ac47f4e5eb62f77454df2e8c7ed2d2a234a5016738ca75e1653be43efcd0f1", "Timelock":"0","Amount":"16808660"}, | |||||
| {"Hash":"ef48bdce7be5da3c3d359b2b3f1b8d036143625549f9b9e36e96381966375b2b", "Timelock":"0","Amount":"273426"}, | |||||
| {"Hash":"f8bdc6db5dcfc62a374304d356470658839d595159a752bda2875a2a5947cdf5", "Timelock":"0","Amount":"15014603"}, | |||||
| {"Hash":"f39b3fbbb7814041e8d9308481ff66c28e0f155e035d454391d01e606421c11b", "Timelock":"0","Amount":"32377579"}, | |||||
| {"Hash":"591db08ca2d396de4e0d930b8b81e67d77165f33386f64b540cbbeb5d8c04dac", "Timelock":"0","Amount":"5537223"}, | |||||
| {"Hash":"6fbc22e1852563db0f25e1cc740834c683947ac7ef03c73ccb457d32d56b99ec", "Timelock":"0","Amount":"4099008"}, | |||||
| {"Hash":"24d61de3080367401e7cd3debaa1b05ae54bf205fe40313bfeb8be3751be07be", "Timelock":"0","Amount":"17144935"}, | |||||
| {"Hash":"b88e78277759f488a616855021776d2513dadc7600cb6215c3b78e1abe0cebc8", "Timelock":"0","Amount":"1786188"}, | |||||
| {"Hash":"fcf5cea27e6d0a2593843416f1ad4045c78e4d189d66648948783107971065cf", "Timelock":"0","Amount":"545170"}, | |||||
| {"Hash":"f7108c7615e587163df51b99a408dc3a07a6b25855fd348333400d6c04614231", "Timelock":"0","Amount":"70574654"}, | |||||
| {"Hash":"7a79a71655a0aaa232ab8c9adad799d1a3b0c968a6c8cde528642b1a5e7733d7", "Timelock":"0","Amount":"602315"}, | |||||
| {"Hash":"0f99f2acff77da93de76faff6976dcc4c77c043d3c362d7a1a60cf702546b5dc", "Timelock":"0","Amount":"84998663"}, | |||||
| {"Hash":"57cbd37b4af4c95e56c8ecd2d630092bcd69c8ff21cc42ff02ac432b857c9900", "Timelock":"0","Amount":"1466751"}, | |||||
| {"Hash":"964a6ed783cf7308f3ff6772c2d5ff63a3bd4bb39ffdcc4081873943705e546b", "Timelock":"0","Amount":"6509"}, | |||||
| {"Hash":"efb97e437c294603de145eae3ad958a6ff4126f3aed33e7b55dcba081bdb2e1a", "Timelock":"0","Amount":"93282264"}, | |||||
| {"Hash":"703977a73c8c10d97b599406fd2271e051f1c0cffda752d2a5f594e6685d8261", "Timelock":"610612","Amount":"79687580"}, | |||||
| {"Hash":"51c57ea0d3790def7d66b774a26a0ba98bb6072317ebc90eeab3a80df7b49d20", "Timelock":"0","Amount":"777507037"}, | |||||
| {"Hash":"1126a772cc0529d5fc95db96f7dfa5f5180dcd7477ee6a4ba0a384de6ac17a3b", "Timelock":"610613","Amount":"57169215"}, | |||||
| {"Hash":"5234985816f4c27dccecaed5464774741a17cc488edadcd0e14c6199318167cf", "Timelock":"610611","Amount":"692000"}, | |||||
| {"Hash":"e04c15750207381cc5b8d47bdadc3e0945c3d4ce626099389f454d1d0d99ae7a", "Timelock":"0","Amount":"129130"}, | |||||
| {"Hash":"58ebb62cc184edfc2a242b83d22dd03f6cc5e0982977adeb68f242cfbd076cfb", "Timelock":"0","Amount":"95948947"}, | |||||
| {"Hash":"f3d84b166bbc0f93fbda033eb8b56d5c34efe557451fb48138baa217e7a4273c", "Timelock":"0","Amount":"55938194"}, | |||||
| {"Hash":"47143be5f2ac1be85e424ddd5388d04aa4a77a9ddd4743e887e53d9e10a35214", "Timelock":"0","Amount":"15865380"}, | |||||
| {"Hash":"bb85cca828d6503e470c4d425a1bb75db4af3d3be97234ec8806f3030fe5885f", "Timelock":"610612","Amount":"84370181"}, | |||||
| {"Hash":"810ed0d85d37e4893a399a672e3f91d94f09aa6d84065ab806845eba95dbce2c", "Timelock":"0","Amount":"3386237"}, | |||||
| {"Hash":"9165184e73b8a54ba1e5c16dc5f37e919cf83c59529e6623163cc5088a1e0962", "Timelock":"0","Amount":"1066271"}, | |||||
| {"Hash":"44d5ce2d5640c202bba300fc9d4e78dcd42b0a6a6af34dda3662792c34a3e85b", "Timelock":"0","Amount":"14817954"}, | |||||
| {"Hash":"e35f504d9240169cb1042ca1cb035d3e67754dec6294f0ed7dad2386bfccf0f2", "Timelock":"0","Amount":"5595232"}, | |||||
| {"Hash":"1fc03a9c90ec8eff9c443f79be05461b1d76d018ad817793e87ad54e955f88f3", "Timelock":"0","Amount":"16904522"}, | |||||
| {"Hash":"0d337f6e9ef369b7b0d63654528ebeb9bef149bd9e46178a05b1943c4acfc7ba", "Timelock":"0","Amount":"56054252"}, | |||||
| {"Hash":"4a8799db89c87cdc01030690c8334f07134a745f1bf39de94bc7553b19d0dbff", "Timelock":"0","Amount":"9992155"}, | |||||
| {"Hash":"1f95bca1b96a52dc0369576abfed782aa245940a82ee3bdfeb9ef8782cd7e93a", "Timelock":"0","Amount":"4662624"}, | |||||
| {"Hash":"6ba744f9e596470675decede86bb17aae566a50916d9d552d604a7b8c204d089", "Timelock":"0","Amount":"3146974"}, | |||||
| {"Hash":"d78534e7dcf544126beae5f2403aa8367303b99a6df12dce659e4259bab3b298", "Timelock":"0","Amount":"200306"}, | |||||
| {"Hash":"c1a15a8c6d05d43eaba0e0fd0a75ce2e51df50c04739dd4ddbc39044ade1191d", "Timelock":"0","Amount":"1596303"}, | |||||
| {"Hash":"5208ea98e3c4265943c428917e7c5290ce31320f742d28f9506302dded938638", "Timelock":"0","Amount":"11686374"}, | |||||
| {"Hash":"095e3e956f640ddced8966aa65fade1f3c3b0cb47064464739866be018f6e0b7", "Timelock":"0","Amount":"1729712"}, | |||||
| {"Hash":"474d4140d8e63574ab11bebb82bdec1a27a4fb3e69c777c11ebb46818ad58ad3", "Timelock":"0","Amount":"100890"}, | |||||
| {"Hash":"11c2a22918fa0c52eb3b58c9de0f204baa515bffa76e8ab0bacfb1bcb284e809", "Timelock":"0","Amount":"1307062"}, | |||||
| {"Hash":"574d371439d9a89b600cc330f3476cb7144520167ff8a554bdcd82893461ff0e", "Timelock":"0","Amount":"1223399"}, | |||||
| {"Hash":"96ede43efd211a1c305ee28e22757a3c33cb9ace76bf4a5940b984efdb8c1734", "Timelock":"0","Amount":"33369356"}, | |||||
| {"Hash":"3702029ec7041263a1b2fbe0c803489347c6ca82526361f7ab57ddeff3c61352", "Timelock":"0","Amount":"888722"}, | |||||
| {"Hash":"1c0c4b8d9c48e1787ebb293493d0bc9cec27b6ac14b79b638ee1ec71ff3b5bbb", "Timelock":"0","Amount":"3239060"}, | |||||
| {"Hash":"a5635968d11902b1927142349654adb8ee37d3c66fb65f8ec0446775e62ea839", "Timelock":"0","Amount":"39293"}, | |||||
| {"Hash":"f75e699a3aed32d8754f64fcb8b95ccbe38170a740cbf304e1b16f263b2e532c", "Timelock":"0","Amount":"880501"}, | |||||
| {"Hash":"fc24d67b967e9c3d571e0061b5b22fe63d6c31995b5bfe748580e178064adcac", "Timelock":"0","Amount":"1999501"}, | |||||
| {"Hash":"dfb900019a868e5907b7b646f8675f153bcd314548648431d40260929f8366b1", "Timelock":"0","Amount":"3623549"}, | |||||
| {"Hash":"63f781ca03831a1428719ecc1128cc429796c49f654500ceb9564d49b1a8a0d6", "Timelock":"0","Amount":"4356568"}, | |||||
| {"Hash":"60832cda55888b65da7d0051c74b9a0167207d1e35ca2fa5d756a88d35631c88", "Timelock":"0","Amount":"1191810"}, | |||||
| {"Hash":"20a47f6a23155384dfd724b8ff9fe8721cd2c7f4e63e953c3db6a8d74a776fc9", "Timelock":"0","Amount":"213303"}, | |||||
| {"Hash":"5db600482d5f8b597eeb6df99e6abbfa10851ffc43c9fd0e9e7ebdf1093b7449", "Timelock":"0","Amount":"276881"}, | |||||
| {"Hash":"f14b767fb4d3813d165c0c085d829a57c91144f378ae4bfc353f1251654c071e", "Timelock":"0","Amount":"73236"}, | |||||
| {"Hash":"3203bd34798fd2653f6dafa8dc96906b162b9610a5f3a978dca4cf6462d4877b", "Timelock":"0","Amount":"21647"}, | |||||
| {"Hash":"f9881901ae72f2a2d45900860873e17c42afad5ae939fd9a9508c905c7fd36a0", "Timelock":"0","Amount":"837681"}, | |||||
| {"Hash":"88de4f89b929de2d3693db2a2f2a4f7fb8b09e786cdb84cee28251a54be9eab8", "Timelock":"0","Amount":"945945"}, | |||||
| {"Hash":"23d7451a6fb818b8c5f4a76d2ecbc82fa487876afeea6136887d138897b579ea", "Timelock":"0","Amount":"3055782"}, | |||||
| {"Hash":"5a1e88345111227c80a65b3eecfd4ddf04e81ddf66cb23dc48e684d7b25ac219", "Timelock":"0","Amount":"348590"}, | |||||
| {"Hash":"972069aeddfbf42a90044389619f17fb5eba93492f1e5092e2b45f0e63b1a64a", "Timelock":"0","Amount":"100948"}, | |||||
| {"Hash":"0abe46e255e647f035b8a20ab55a632564a66c8d39eafabca60e59fff8aa4458", "Timelock":"0","Amount":"38190"}, | |||||
| {"Hash":"a89fc18abf2bbc87aa547deb3ea30296497b2106ea9dd179b4fb0c6c8706f159", "Timelock":"0","Amount":"101439"}, | |||||
| {"Hash":"310942f43f904106ac267e404e62f6eb01b4711d7bcd1f1736d990270a308c8a", "Timelock":"0","Amount":"458696"}, | |||||
| {"Hash":"0dc5e678214d604604b2926a5da391668fdd7011d8516c8a2eee3ecb0d87b095", "Timelock":"610612","Amount":"320000000"}, | |||||
| {"Hash":"6f70d9069b382513a148eb79ed54b1ccd4ec158df6c2cb18314304e369f15a52", "Timelock":"0","Amount":"79035653"}, | |||||
| {"Hash":"71dc72310d9a9b994ce19f4c03cdb7f6528b34aca0075cb5d74c6c68915d3a9d", "Timelock":"0","Amount":"2504027"}, | |||||
| {"Hash":"893a4babc462051b8a0155cbdd545908b418ea6e110e5a13ef3a4fad767bda00", "Timelock":"610611","Amount":"1478499"}, | |||||
| {"Hash":"fcc431847d59c950b45722c3f7f0c15561322003c0e3ed56a8aed21267a4cf26", "Timelock":"610611","Amount":"148935329"}, | |||||
| {"Hash":"097d85b4821c32f742eaa41126a40f152424b789e2d4ea103ff8048884dfc871", "Timelock":"610611","Amount":"410979578"}, | |||||
| {"Hash":"3de0395922a468f4582b47fcb86e09de5c300aa7deb564505881718a9f81f990", "Timelock":"610612","Amount":"86910899"}, | |||||
| {"Hash":"7f496800d68732533b10884a448079bb36d5246fcd3944c3213f8fb185d25a5b", "Timelock":"610612","Amount":"1677195"}, | |||||
| {"Hash":"8aa85614c39716ab9ef6c775a8561108c790d953a8f8d6ff41d81098b5caa11b", "Timelock":"0","Amount":"1600823"}, | |||||
| {"Hash":"5b6d8c3ecc320f7d451b329ac5ec92efa755a8fc780f6fdc4a48f19f31b04e1d", "Timelock":"0","Amount":"4898293"}, | |||||
| {"Hash":"6dfc9912e0b488bb9b5e8a289f77fd8a099460b84843a63c32de0d705c4f397e", "Timelock":"0","Amount":"8275011"}, | |||||
| {"Hash":"2eb66f5e336880ec848463403f6e1c527bc7247c397d1ece7e733d1617235798", "Timelock":"0","Amount":"7451649"}, | |||||
| {"Hash":"cd80ebcfd55c08381531a302d157998cca5dc15407d994c2d9e827aaf627bbc2", "Timelock":"0","Amount":"11469618"}, | |||||
| {"Hash":"70fec2714233e91aeb8e1ab2d57f4d32fdbe57b07c056f676d63d1bbdca301f5", "Timelock":"0","Amount":"1799319"}, | |||||
| {"Hash":"20be7a8b20f087ff9ee30c89eba214e74af9bd56e85afc2f415f761886269516", "Timelock":"0","Amount":"157721723"}, | |||||
| {"Hash":"90c027ccf08205b7fe9fcff4510df4b95627d1153ae0056c3c8d80252bfd8205", "Timelock":"0","Amount":"4609322"}, | |||||
| {"Hash":"768b6e5b63b54b3bc37fe2ea495fcf2ae2303fe4dacc6540359561dac7383623", "Timelock":"0","Amount":"21145038"}, | |||||
| {"Hash":"4211d1386b23fabcacd67982b26aae124a88f006494270a5cc86b5601666ceb9", "Timelock":"0","Amount":"124400229"}, | |||||
| {"Hash":"788a270693f8c3c932cdaeda1865ce7872db9899b6bd9a606124ca80146173c4", "Timelock":"0","Amount":"15199613"}, | |||||
| {"Hash":"f5a7146cdb7e75d7897cd70b98fa817fa3c36e1a1c6b42c8dcc9f72198e255d6", "Timelock":"610558","Amount":"1000550"}, | |||||
| {"Hash":"947447dab3ba1b50c801eb37106442e1253595f55b02c14fddf34bde6012c3b3", "Timelock":"0","Amount":"323024"}, | |||||
| {"Hash":"26ac445b31f2bc464dd5eb751ad1a62fec85a9bdb4f0ec47134f7fc75d8cfcc0", "Timelock":"0","Amount":"519323"}, | |||||
| {"Hash":"1243171091b7fed1e1c9f769ebd6226a59023125a7ead697eaa5c6c9f8832427", "Timelock":"0","Amount":"292805217"}, | |||||
| {"Hash":"d36f2df5b4e420e44d0073f53475756ef4d8e404f7e9a1ea3eb3f9ca25f47aad", "Timelock":"0","Amount":"48965812"}, | |||||
| {"Hash":"6431044325da98cd4e321a760d7da40c09d1969316196dcc54381499e5da6c14", "Timelock":"0","Amount":"44999427"}, | |||||
| {"Hash":"9adc8663c50853a0ce7a99723b4e98b06cf4d980ef5738bd4a7155ba2b38d5da", "Timelock":"0","Amount":"1900387"}, | |||||
| {"Hash":"772fd9982e39f71ce3d83f3437364debc6488b1f02b44720b820ad8d48ecaf3b", "Timelock":"0","Amount":"9582288"}, | |||||
| {"Hash":"c40bdca7de3a7df966009833b18673032d3cb875a30a03dd99c91529d13fc6e4", "Timelock":"0","Amount":"4607956"}, | |||||
| {"Hash":"dd8c711a143c68ca88d066cb8c4d78a9312a63a1c95885a90740707e90d6082a", "Timelock":"0","Amount":"35924076"}, | |||||
| {"Hash":"272c78e70846869bf6f2769a9dbfaee799c3a0cd1ec22770a021a43b827ce020", "Timelock":"0","Amount":"1493859"}, | |||||
| {"Hash":"b69bf1d588f2376a695bd8eb0f9ec1a3a06279dd3e1829f3ff6baf6aea6a92f1", "Timelock":"0","Amount":"3615810"}, | |||||
| {"Hash":"f928b036a8d562fd87fd3f3744f95c2a6901d14ba59cb5758cdae45c72771662", "Timelock":"610612","Amount":"4004129"}, | |||||
| {"Hash":"ce7ca845b58a1e894aae420ba70b82f5df865a5024d2d12f59300d5ee8f4640a", "Timelock":"610611","Amount":"2208372"}, | |||||
| {"Hash":"63ebbee7465d03f80a85786519aa88db1d63225d8799d7ab13741185a5dd81bc", "Timelock":"0","Amount":"30607316"}, | |||||
| {"Hash":"e3dd757753ff6cfb3e3a1db8cc2d50295e6eb2641668070e92f5efa8d714b5d0", "Timelock":"0","Amount":"824007"}, | |||||
| {"Hash":"80043c175f15c5c9e9dff94833d4f91aca3655092dd97ae417c93e929537e3b4", "Timelock":"0","Amount":"914375877"}, | |||||
| {"Hash":"a0cc08938f3eef38fb09c4d7055218287bec1ec78e4638f53035f6ca6fed26e2", "Timelock":"0","Amount":"206568328"}, | |||||
| {"Hash":"d8812f2ef12be371800ec26df4a89ffc5d2d2741eb8417c0344c0afebc830d1d", "Timelock":"610611","Amount":"8172299"}, | |||||
| {"Hash":"9c9f4360ab3fe07bcd6c8de670d247c89d9f4b4445dffdd47516bf1bb5691caa", "Timelock":"0","Amount":"34998220"}, | |||||
| {"Hash":"d2abc9f9d4b00b121a05d6c391f0fc8ff66d35ed4dc3a32a21eb935f27e5cfe9", "Timelock":"0","Amount":"6571256"}, | |||||
| {"Hash":"5c616154caa404a59acbc4b2583c626a44af0b39045034d4acdc2df0b56046a4", "Timelock":"610609","Amount":"2426712"}, | |||||
| {"Hash":"c8fded8ee21e0022f21aa87d3a4b35b39406245f6d782883fb8426c93d50f3ab", "Timelock":"0","Amount":"891105"}, | |||||
| {"Hash":"63294c0d34ea9bf1ef4152442582f2fed1348c3fd5d29564877741057e199319", "Timelock":"0","Amount":"640260"}, | |||||
| {"Hash":"5150b3c63b594907ec39de381d9d701298f3f1a331018454c3443e0d53c88c5b", "Timelock":"0","Amount":"545760"}, | |||||
| {"Hash":"ca837ed1bea2f1ee672c746cc9568a493c5b6ea2a93aee7540263f7d01c93e6c", "Timelock":"0","Amount":"237690"}, | |||||
| {"Hash":"f77266d54f00730a84ec701bd14d238fa23a606bf29ee1811b1ceeba5598c4c3", "Timelock":"0","Amount":"846060"}, | |||||
| {"Hash":"46d329aff53be4c395db6fdb6645e108f3b338af70aa7f728714cb389badffd4", "Timelock":"0","Amount":"552060"}, | |||||
| {"Hash":"74b5293ce16ab56c6d37a74ea526b33245ba7b96b388442930b5bd16bcf78734", "Timelock":"0","Amount":"197047"}, | |||||
| {"Hash":"eb4a7762da37b44f346ace0ad0832ea84713f5a7f2845ff7119a260639e1825f", "Timelock":"0","Amount":"186635"}, | |||||
| {"Hash":"8177d1d50789b35a79acc0869bb1ce08bca9b6fed317032242c6b130c7d3fec0", "Timelock":"0","Amount":"197287"}, | |||||
| {"Hash":"f7dfd885bcce8458a74de83d4da4ee7c6cb64b3dba94a47507b422815d4844d6", "Timelock":"0","Amount":"197059"}, | |||||
| {"Hash":"0ea4b003160596991bb76746ce3664545710b10dcd853e3afec51d5b69aacd03", "Timelock":"610612","Amount":"5039070"}, | |||||
| {"Hash":"3f20c30db68a4a52b3fcb4da398f77528724a06ccc2aa54314b07ddbe44bace1", "Timelock":"610612","Amount":"18434512"}, | |||||
| {"Hash":"d82cf4f229c4c8e74f7dc128192c058545eefc01e6528d7eff220681df62be56", "Timelock":"610611","Amount":"23567482"}, | |||||
| {"Hash":"0b5208dd76c0c1549c407dc83b53acaaed700a88049009dc583600f63c944458", "Timelock":"610611","Amount":"1555453"}, | |||||
| {"Hash":"684c01e803731bc88ec0e2419ed19c3890298f7c0b5d495483ece46949f3075f", "Timelock":"610611","Amount":"4602272"}, | |||||
| {"Hash":"8c3442f6157f8c605bea12590ce27e565d2ca05eee2f343893e56b1805a2f195", "Timelock":"610611","Amount":"3254296"}, | |||||
| {"Hash":"cd649ba4f7d5f73a68de9225d6fd8cfbdea825f3976c9a7cb2170886a86352fd", "Timelock":"610612","Amount":"6102583"}, | |||||
| {"Hash":"a3099bf1386a6a768dfdf6964b5b410c18b7db88f21e14446b4a0751548fb230", "Timelock":"610525","Amount":"1232642"}, | |||||
| {"Hash":"da6cf1a622c8465ac940a66e45b4a058aa7bd7c7b6528c7199ee47eb3a5e9186", "Timelock":"610612","Amount":"1662053"}, | |||||
| {"Hash":"054b2fe617c7f3472589711d43a62e964fe954c9bda1199ea90f6eccf07505d5", "Timelock":"610612","Amount":"8196614"}, | |||||
| {"Hash":"fe93ce64f01e56de307402f70ddd320eaefbf4829a5ed0466d908e6842878532", "Timelock":"610611","Amount":"212838070"}, | |||||
| {"Hash":"0dc2c34306fbf5ab99b601163024e63063ed13dc2532371dad0ccbf09013de41", "Timelock":"610612","Amount":"986431394"}, | |||||
| {"Hash":"f61fbd11bd65d03b956c887f2d46ff7cf836c006aad18b7250ad94612f82f30b", "Timelock":"0","Amount":"145385"}, | |||||
| {"Hash":"3dd516cb408189b5576e0a28426778416967328bbd15884c11729e0ed1d5126c", "Timelock":"0","Amount":"194250"}, | |||||
| {"Hash":"b0ccf26e5325aabe1574fc4ec856780a1d3610f02ef85170e36b590682bc426c", "Timelock":"0","Amount":"180677"}, | |||||
| {"Hash":"2367d6bd910dc3fe35eca461919a618774a801127ccf13df695924b2b5e57b70", "Timelock":"0","Amount":"183047"}, | |||||
| {"Hash":"b2909891ee0e4fd942839d760be1c5ad490167c6ea9e747ad0c32f75c6a92e90", "Timelock":"0","Amount":"5404771"}, | |||||
| {"Hash":"a5d0ee16a2a4eba67580d7d15db87bce77163695725845ade652d039f7a7dedf", "Timelock":"610612","Amount":"2431061"}, | |||||
| {"Hash":"d312679befb9d51aa59ae05ad79c6ceff5d73ef732c3ebf5b279e850e3a8a803", "Timelock":"0","Amount":"57124"}, | |||||
| {"Hash":"178d4e0dde468f2f7555397ab103afa9b1a9a794c8712c3c93de8b6c6850360b", "Timelock":"610612","Amount":"1236819"}, | |||||
| {"Hash":"21f823e3e9dfcdb6d7a09f7b0a4a3f1460a7529d94ebd9c62888331aa5c11f15", "Timelock":"0","Amount":"1038899"}, | |||||
| {"Hash":"c1a14678b5e766cdfd10fd82f180f53f1c818bb93b61694c49d3e48bf83ec61c", "Timelock":"610612","Amount":"2085777"}, | |||||
| {"Hash":"44e42e283ddb28adc7d1be3c87a1f1f00cc485d0dce7f13cc2a26592cad7fa3d", "Timelock":"0","Amount":"308249"}, | |||||
| {"Hash":"e497755421aaa563baec3172f4994f5e7d81194bcd73e6435ff1d2e78db45d3e", "Timelock":"610611","Amount":"1430901"}, | |||||
| {"Hash":"c58b725bded8622819c8a630c37d632fb528c0f0faecabcf399efe520c842560", "Timelock":"610612","Amount":"2001785"}, | |||||
| {"Hash":"b4f90cc8ea3c61d5d2c6149e34f4c9ae4845a92890a54b6f3c203fd854f64971", "Timelock":"610612","Amount":"1731654"}, | |||||
| {"Hash":"26b44e3c6733cb7367c63d38f68b5321932bd2989186f7038de4b0888a12e175", "Timelock":"610611","Amount":"26296859"}, | |||||
| {"Hash":"2c30bca6de71e4302090dc121b47e20fc5c9eec2cfacdc69c197e9ced8c10f8e", "Timelock":"0","Amount":"636951"}, | |||||
| {"Hash":"c09ce4f0165b7995d6a1b216657210f5deb376226cab7a58bada7bba362edc93", "Timelock":"610611","Amount":"1998128"}, | |||||
| {"Hash":"32ddf000f48be887acb84f32781d8bf2f24f7ea5e4a13f9f4718f70b6c1fe1a1", "Timelock":"610612","Amount":"1790662"}, | |||||
| {"Hash":"0603251530586c9f731704d09710bcdcd862d58097bd9ec0103713f3439e01b1", "Timelock":"610612","Amount":"2024605"}, | |||||
| {"Hash":"ac2baa16cca1cf50168d712c633962c0abcf08ffe08a065752c0250caedb55c1", "Timelock":"610611","Amount":"1486989"}, | |||||
| {"Hash":"2e4b6bb7c08d696131c790310291dec6b747e3e996bfe3d6e563fb5c51866dc5", "Timelock":"610612","Amount":"2203418"}, | |||||
| {"Hash":"40f5f4a90b626346fcff1f1ba490ab53f996cd6bdcdb9a91c00c84c56307c5cc", "Timelock":"0","Amount":"75698"}, | |||||
| {"Hash":"51289eb491361a921e545addda6aa83eda612b3e9a44db9cd09a2cdeddef5dd4", "Timelock":"610611","Amount":"1057522"}, | |||||
| {"Hash":"91f0965412d263e511a08ec3971c5cd6e1f9c3a8f1c03bca3ac752532fd1d2d5", "Timelock":"0","Amount":"431533"}, | |||||
| {"Hash":"ef0b3e7a40283a62720933537d3c7cd35989236f1d5e4eb6e207338e63b93ad7", "Timelock":"610611","Amount":"1624761"}, | |||||
| {"Hash":"6ddb8af0f8ea045159c90bef1ebc4c87a7ed6600b4117dd811e5e9e5e57094d8", "Timelock":"0","Amount":"449055"}, | |||||
| {"Hash":"9f7db89d3e700fd50972c79ef5149f1d18e2ab03f62b1cdb22204dc9682d54e4", "Timelock":"610612","Amount":"1121060"}, | |||||
| {"Hash":"d49a885914128a01a0642b7bd4424fd6aa65c44e1666768a1d1f5d81068928e5", "Timelock":"610611","Amount":"1242539"}, | |||||
| {"Hash":"fb70e5f8fedc9ba3e3bc418c3cbb777b42cff9585b43513bfb32368d3f3997e6", "Timelock":"0","Amount":"295101"}, | |||||
| {"Hash":"35259952a5ddba69338ddb79df345e7bfd5af96c8a9409b9415a3eefe1c3bff2", "Timelock":"610611","Amount":"1579203"}, | |||||
| {"Hash":"a46c28fe069c151d92a9017d98069395aaf29d2130d57ce5b0f6775acb1641ff", "Timelock":"0","Amount":"1196333"} | |||||
| ], | |||||
| "Amount" : "35563119179" | |||||
| } | |||||
| @ -4,26 +4,53 @@ $alea=rand(0,100); | |||||
| $logo='topisto_vert_tr.png'; | $logo='topisto_vert_tr.png'; | ||||
| if ($alea > 5) | |||||
| $block_image = @imagecreatefrompng($logo); | |||||
| $width = imagesx($block_image); | |||||
| $height = imagesy($block_image); | |||||
| // create the destination/output image. | |||||
| $img=imagecreatetruecolor( $width, $height ); | |||||
| // enable alpha blending on the destination image. | |||||
| imagealphablending($img, true); | |||||
| // Allocate a transparent color and fill the new image with it. | |||||
| // Without this the image will have a black background instead of being transparent. | |||||
| $transparent = imagecolorallocatealpha( $img, 255, 255, 255, 127 ); | |||||
| imagefill( $img, 0, 0, $transparent ); | |||||
| // copy the thumbnail into the output image. | |||||
| imagecopyresampled($img,$block_image, 0, 0, 0, 0, $width, $height, $width, $height ); | |||||
| imagedestroy($block_image); | |||||
| if ($alea < 1000) | |||||
| { | { | ||||
| $files = glob('logo/medium/*/topisto_vert.png'); | |||||
| $files = glob('logo/tr/topisto_*.png'); | |||||
| usort($files, function($a, $b) { | usort($files, function($a, $b) { | ||||
| return filemtime($a) > filemtime($b); | return filemtime($a) > filemtime($b); | ||||
| }); | }); | ||||
| shuffle($files); | shuffle($files); | ||||
| $logo = $files[0]; | |||||
| $superpose = @imagecreatefrompng($files[0]); | |||||
| //imagecopymerge($img, $superpose, 0, 0, 0, 0, $width, $height, 50); | |||||
| imagecopyresampled($img,$superpose, 0, 0, 0, 0, $width, $height, imagesx($superpose), imagesy($superpose)); | |||||
| imagedestroy($superpose); | |||||
| } | } | ||||
| $block_image = @imagecreatefrompng($logo); | |||||
| imagealphablending($img, false); | |||||
| imagesavealpha($img,true); | |||||
| // --- | // --- | ||||
| // --- envoyer l'image au navigateur | // --- envoyer l'image au navigateur | ||||
| // --- | // --- | ||||
| header("Content-Type: image/png"); | header("Content-Type: image/png"); | ||||
| imagepng($block_image); | |||||
| imagepng($img); | |||||
| imagedestroy($block_image); | |||||
| imagedestroy($img); | |||||
| ?> | ?> | ||||
| @ -0,0 +1,6 @@ | |||||
| toto=$1 | |||||
| gmic ../../topisto_vert_tr.png $@ -output topisto_tmp_$toto.png | |||||
| convert topisto_tmp_$toto.png -fuzz 10% -transparent white topisto_$toto.png | |||||
| rm -f topisto_tmp_$toto.png | |||||
| @ -0,0 +1,32 @@ | |||||
| source gmic.sh endgrave fx_engrave 0.5,4,0,7.68,15.2,0,0,1,10,1,0,0,0,1,0 gui_merge_layers | |||||
| source gmic.sh bokeh fx_bokeh 3,8,0,30,8,4,0.3,0.2,210,210,80,160,0.7,30,20,20,1,2,170,130,20,110,0.15,0 | |||||
| source gmic.sh 8bits fx_8bits 25,800,16,0 | |||||
| source gmic.sh 8bits fx_8bits 25,800,16,0 | |||||
| source gmic.sh | |||||
| source gmic.sh fire_edges 0.7,0.25,0.5,25,20 | |||||
| source gmic.sh fire_edges fire_edges 0.7,0.25,0.5,25,20 | |||||
| source gmic.sh diffusiontensors fx_diffusiontensors 10,5,3,1,0.15,1,0,3,0 | |||||
| source gmic.sh feltpen fx_feltpen 300,50,1,0.1,20,5,0 | |||||
| source gmic.sh gtutor_fpaint 0.5,0.5,0,0,45,0.5,0.5,0.5,0 | |||||
| source gmic.sh fx_graphic_novelfxl 0,2,6,5,20,0,0.62,14,0,1,0.5,0.78,1.92,0,0,0,1,1,1,0.5,0.8,1.28 | |||||
| source gmic.sh fx_illustration_look 100,0,0,0,0 | |||||
| source gmic.sh fx_lylejk_painting 10,2,4,10,0 | |||||
| source gmic.sh fx_painting 5,2.5,1.5,50,1,0 | |||||
| source gmic.sh fx_posterize 150,30,1,6,0,0,1,0 | |||||
| source gmic.sh fx_quadtree 2,1024,1.05,0,2.33,0.68,0.39,1,0 | |||||
| source gmic.sh fx_vector_painting 9.37,0 | |||||
| source gmic.sh boxfitting | |||||
| source gmic.sh boxfitting , | |||||
| source gmic.sh cartoon 3,80,15 | |||||
| source gmic.sh cubism , | |||||
| source gmic.sh halftone , | |||||
| source gmic.sh blur 2 light_relief 0.3,4,0.1,0 | |||||
| source gmic.sh +sketchbw 1 reverse blur[-1] 3 blend[-2,-1] overlay | |||||
| source gmic.sh mosaic , | |||||
| source gmic.sh linify 40 | |||||
| source gmic.sh polygonize 300,1%,0.1%,3%,3% | |||||
| source gmic.sh poster_hope , | |||||
| source gmic.sh rodilius 12,10,300,10 normalize_local 10,6 | |||||
| source gmic.sh stained_glass 20%,0.1 | |||||
| source gmic.sh fx_shapes 1,16,10,2,5,106.8,2,0,0,1,0 | |||||
| source gmic.sh fx_shapeism 2,7,0.38,0,1,5,32,8,3,1,5,0.5,1,0,0,0,255 | |||||
| @ -17,6 +17,7 @@ | |||||
| <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> | <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> | ||||
| <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> | <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> | ||||
| <script src="js/console.js" defer></script> | |||||
| <script src="js/lastblock.js" defer></script> | <script src="js/lastblock.js" defer></script> | ||||
| <script src="js/blockexplorer.js" defer></script> | <script src="js/blockexplorer.js" defer></script> | ||||
| @ -215,6 +215,9 @@ blockchainExplorer = function(){ | |||||
| // Mettre les infos dans le div | // Mettre les infos dans le div | ||||
| _addInfoForBlock(data); | _addInfoForBlock(data); | ||||
| topistoConsole.log('Last Block on top : '+data.hash); | |||||
| } | } | ||||
| function _addBottomBlock() | function _addBottomBlock() | ||||
| @ -12,7 +12,7 @@ blockchainListener = function(){ | |||||
| function _logBlockHash(leblock, flag) | function _logBlockHash(leblock, flag) | ||||
| { | { | ||||
| if (flag) return "logBlockHash"; | if (flag) return "logBlockHash"; | ||||
| c onsole.log('Last Block detected : '+leblock.hash); | |||||
| topistoC onsole.log('Last Block detected : '+leblock.hash); | |||||
| }; | }; | ||||
| function _isBlockNew(leblock) | function _isBlockNew(leblock) | ||||
| @ -41,20 +41,20 @@ blockchainListener = function(){ | |||||
| function _addBlockHook(addBlockHook){ | function _addBlockHook(addBlockHook){ | ||||
| var hookname = addBlockHook(null, true); | var hookname = addBlockHook(null, true); | ||||
| var flag_add = tru e; | |||||
| var flag_add = fals e; | |||||
| _last_block_hooks.forEach(function(trigger) { | _last_block_hooks.forEach(function(trigger) { | ||||
| if (trigger instanceof Function) | if (trigger instanceof Function) | ||||
| { | { | ||||
| var local_hookname = trigger(null, true); | var local_hookname = trigger(null, true); | ||||
| flag_add = flag_add && (local_hookname == hookname); | |||||
| flag_add = flag_add || (local_hookname == hookname); | |||||
| } | } | ||||
| }); | }); | ||||
| if ( flag_add) _last_block_hooks.push(addBlockHook); | |||||
| if ( ! flag_add) _last_block_hooks.push(addBlockHook); | |||||
| }; | }; | ||||
| function _init(){ | function _init(){ | ||||
| _addBlockHook(_logBlockHash); | _addBlockHook(_logBlockHash); | ||||
| set Timeout (_lastBlockTrigger, 30000); | |||||
| set Interval (_lastBlockTrigger, 30000); | |||||
| }; | }; | ||||
| return {init: _init, addBlockHook: _addBlockHook}; | return {init: _init, addBlockHook: _addBlockHook}; | ||||
| @ -0,0 +1,675 @@ | |||||
| /*! | |||||
| * simpleParallax - simpleParallax is a simple JavaScript library that gives your website parallax animations on any images, | |||||
| * @date: 07-12-2019 18:53:52, | |||||
| * @version: 5.2.0, | |||||
| * @link: https://simpleparallax.com/ | |||||
| */ | |||||
| (function webpackUniversalModuleDefinition(root, factory) { | |||||
| if(typeof exports === 'object' && typeof module === 'object') | |||||
| module.exports = factory(); | |||||
| else if(typeof define === 'function' && define.amd) | |||||
| define("simpleParallax", [], factory); | |||||
| else if(typeof exports === 'object') | |||||
| exports["simpleParallax"] = factory(); | |||||
| else | |||||
| root["simpleParallax"] = factory(); | |||||
| })(window, function() { | |||||
| return /******/ (function(modules) { // webpackBootstrap | |||||
| /******/ // The module cache | |||||
| /******/ var installedModules = {}; | |||||
| /******/ | |||||
| /******/ // The require function | |||||
| /******/ function __webpack_require__(moduleId) { | |||||
| /******/ | |||||
| /******/ // Check if module is in cache | |||||
| /******/ if(installedModules[moduleId]) { | |||||
| /******/ return installedModules[moduleId].exports; | |||||
| /******/ } | |||||
| /******/ // Create a new module (and put it into the cache) | |||||
| /******/ var module = installedModules[moduleId] = { | |||||
| /******/ i: moduleId, | |||||
| /******/ l: false, | |||||
| /******/ exports: {} | |||||
| /******/ }; | |||||
| /******/ | |||||
| /******/ // Execute the module function | |||||
| /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); | |||||
| /******/ | |||||
| /******/ // Flag the module as loaded | |||||
| /******/ module.l = true; | |||||
| /******/ | |||||
| /******/ // Return the exports of the module | |||||
| /******/ return module.exports; | |||||
| /******/ } | |||||
| /******/ | |||||
| /******/ | |||||
| /******/ // expose the modules object (__webpack_modules__) | |||||
| /******/ __webpack_require__.m = modules; | |||||
| /******/ | |||||
| /******/ // expose the module cache | |||||
| /******/ __webpack_require__.c = installedModules; | |||||
| /******/ | |||||
| /******/ // define getter function for harmony exports | |||||
| /******/ __webpack_require__.d = function(exports, name, getter) { | |||||
| /******/ if(!__webpack_require__.o(exports, name)) { | |||||
| /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); | |||||
| /******/ } | |||||
| /******/ }; | |||||
| /******/ | |||||
| /******/ // define __esModule on exports | |||||
| /******/ __webpack_require__.r = function(exports) { | |||||
| /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { | |||||
| /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); | |||||
| /******/ } | |||||
| /******/ Object.defineProperty(exports, '__esModule', { value: true }); | |||||
| /******/ }; | |||||
| /******/ | |||||
| /******/ // create a fake namespace object | |||||
| /******/ // mode & 1: value is a module id, require it | |||||
| /******/ // mode & 2: merge all properties of value into the ns | |||||
| /******/ // mode & 4: return value when already ns object | |||||
| /******/ // mode & 8|1: behave like require | |||||
| /******/ __webpack_require__.t = function(value, mode) { | |||||
| /******/ if(mode & 1) value = __webpack_require__(value); | |||||
| /******/ if(mode & 8) return value; | |||||
| /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; | |||||
| /******/ var ns = Object.create(null); | |||||
| /******/ __webpack_require__.r(ns); | |||||
| /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); | |||||
| /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); | |||||
| /******/ return ns; | |||||
| /******/ }; | |||||
| /******/ | |||||
| /******/ // getDefaultExport function for compatibility with non-harmony modules | |||||
| /******/ __webpack_require__.n = function(module) { | |||||
| /******/ var getter = module && module.__esModule ? | |||||
| /******/ function getDefault() { return module['default']; } : | |||||
| /******/ function getModuleExports() { return module; }; | |||||
| /******/ __webpack_require__.d(getter, 'a', getter); | |||||
| /******/ return getter; | |||||
| /******/ }; | |||||
| /******/ | |||||
| /******/ // Object.prototype.hasOwnProperty.call | |||||
| /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; | |||||
| /******/ | |||||
| /******/ // __webpack_public_path__ | |||||
| /******/ __webpack_require__.p = ""; | |||||
| /******/ | |||||
| /******/ | |||||
| /******/ // Load entry module and return exports | |||||
| /******/ return __webpack_require__(__webpack_require__.s = 0); | |||||
| /******/ }) | |||||
| /************************************************************************/ | |||||
| /******/ ([ | |||||
| /* 0 */ | |||||
| /***/ (function(module, __webpack_exports__, __webpack_require__) { | |||||
| "use strict"; | |||||
| __webpack_require__.r(__webpack_exports__); | |||||
| // CONCATENATED MODULE: ./src/helpers/viewport.js | |||||
| function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | |||||
| function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } | |||||
| function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } | |||||
| var Viewport = | |||||
| /*#__PURE__*/ | |||||
| function () { | |||||
| function Viewport() { | |||||
| _classCallCheck(this, Viewport); | |||||
| this.positions = { | |||||
| top: 0, | |||||
| bottom: 0, | |||||
| height: 0 | |||||
| }; | |||||
| } | |||||
| _createClass(Viewport, [{ | |||||
| key: "setViewportTop", | |||||
| value: function setViewportTop(container) { | |||||
| // if this is a custom container, user the scrollTop | |||||
| this.positions.top = container ? container.scrollTop : window.pageYOffset; | |||||
| return this.positions; | |||||
| } | |||||
| }, { | |||||
| key: "setViewportBottom", | |||||
| value: function setViewportBottom() { | |||||
| this.positions.bottom = this.positions.top + this.positions.height; | |||||
| return this.positions; | |||||
| } | |||||
| }, { | |||||
| key: "setViewportAll", | |||||
| value: function setViewportAll(container) { | |||||
| // if this is a custom container, user the scrollTop | |||||
| this.positions.top = container ? container.scrollTop : window.pageYOffset; // if this is a custom container, get the height from the custom container itself | |||||
| this.positions.height = container ? container.clientHeight : document.documentElement.clientHeight; | |||||
| this.positions.bottom = this.positions.top + this.positions.height; | |||||
| return this.positions; | |||||
| } | |||||
| }]); | |||||
| return Viewport; | |||||
| }(); | |||||
| var viewport = new Viewport(); | |||||
| // CONCATENATED MODULE: ./src/helpers/convertToArray.js | |||||
| // check wether the element is a Node List, a HTML Collection or an array | |||||
| // return an array of nodes | |||||
| var convertToArray = function convertToArray(elements) { | |||||
| if (NodeList.prototype.isPrototypeOf(elements) || HTMLCollection.prototype.isPrototypeOf(elements)) return Array.from(elements); | |||||
| if (typeof elements === 'string' || elements instanceof String) return document.querySelectorAll(elements); | |||||
| return [elements]; | |||||
| }; | |||||
| /* harmony default export */ var helpers_convertToArray = (convertToArray); | |||||
| // CONCATENATED MODULE: ./src/helpers/cssTransform.js | |||||
| // Detect css transform | |||||
| var cssTransform = function cssTransform() { | |||||
| var prefixes = 'transform webkitTransform mozTransform oTransform msTransform'.split(' '); | |||||
| var transform; | |||||
| var i = 0; | |||||
| while (transform === undefined) { | |||||
| transform = document.createElement('div').style[prefixes[i]] !== undefined ? prefixes[i] : undefined; | |||||
| i += 1; | |||||
| } | |||||
| return transform; | |||||
| }; | |||||
| /* harmony default export */ var helpers_cssTransform = (cssTransform()); | |||||
| // CONCATENATED MODULE: ./src/helpers/isImageLoaded.js | |||||
| // check if image is fully loaded | |||||
| var isImageLoaded = function isImageLoaded(image) { | |||||
| // check if image is set as the parameter | |||||
| if (!image) { | |||||
| return false; | |||||
| } // check if image has been 100% loaded | |||||
| if (!image.complete) { | |||||
| return false; | |||||
| } // check if the image is displayed | |||||
| if (typeof image.naturalWidth !== 'undefined' && image.naturalWidth === 0) { | |||||
| return false; | |||||
| } | |||||
| return true; | |||||
| }; | |||||
| /* harmony default export */ var helpers_isImageLoaded = (isImageLoaded); | |||||
| // CONCATENATED MODULE: ./src/instances/parallax.js | |||||
| function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); } | |||||
| function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); } | |||||
| function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); } | |||||
| function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } } | |||||
| function parallax_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | |||||
| function parallax_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } | |||||
| function parallax_createClass(Constructor, protoProps, staticProps) { if (protoProps) parallax_defineProperties(Constructor.prototype, protoProps); if (staticProps) parallax_defineProperties(Constructor, staticProps); return Constructor; } | |||||
| var parallax_ParallaxInstance = | |||||
| /*#__PURE__*/ | |||||
| function () { | |||||
| function ParallaxInstance(element, options) { | |||||
| parallax_classCallCheck(this, ParallaxInstance); | |||||
| // set the element & settings | |||||
| this.element = element; | |||||
| this.elementContainer = element; | |||||
| this.settings = options; | |||||
| this.isVisible = true; | |||||
| this.isInit = false; | |||||
| this.oldTranslateValue = -1; | |||||
| this.init = this.init.bind(this); // check if images has not been loaded yet | |||||
| if (helpers_isImageLoaded(element)) { | |||||
| this.init(); | |||||
| } else { | |||||
| this.element.addEventListener('load', this.init); | |||||
| } | |||||
| } | |||||
| parallax_createClass(ParallaxInstance, [{ | |||||
| key: "init", | |||||
| value: function init() { | |||||
| var _this = this; | |||||
| // for some reason, <picture> are init an infinite time on windows OS | |||||
| if (this.isInit) return; // check if element has not been already initialized with simpleParallax | |||||
| if (this.element.closest('.simpleParallax')) return; | |||||
| if (this.settings.overflow === false) { | |||||
| // if overflow option is set to false | |||||
| // wrap the element into a div to apply overflow | |||||
| this.wrapElement(this.element); | |||||
| } // apply the transform style on the image | |||||
| this.setTransformCSS(); // get the current element offset | |||||
| this.getElementOffset(); // init the Intesection Observer | |||||
| this.intersectionObserver(); // get its translated value | |||||
| this.getTranslateValue(); // apply its translation even if not visible for the first init | |||||
| this.animate(); // if a delay has been set | |||||
| if (this.settings.delay > 0) { | |||||
| // apply a timeout to avoid buggy effect | |||||
| setTimeout(function () { | |||||
| // apply the transition style on the image | |||||
| _this.setTransitionCSS(); | |||||
| }, 10); | |||||
| } // for some reason, <picture> are init an infinite time on windows OS | |||||
| this.isInit = true; | |||||
| } // if overflow option is set to false | |||||
| // wrap the element into a .simpleParallax div and apply overflow hidden to hide the image excedant (result of the scale) | |||||
| }, { | |||||
| key: "wrapElement", | |||||
| value: function wrapElement() { | |||||
| // check is current image is in a <picture> tag | |||||
| var elementToWrap = this.element.closest('picture') || this.element; // create a .simpleParallax wrapper container | |||||
| var wrapper = document.createElement('div'); | |||||
| wrapper.classList.add('simpleParallax'); | |||||
| wrapper.style.overflow = 'hidden'; // append the image inside the new wrapper | |||||
| elementToWrap.parentNode.insertBefore(wrapper, elementToWrap); | |||||
| wrapper.appendChild(elementToWrap); | |||||
| this.elementContainer = wrapper; | |||||
| } // unwrap the element from .simpleParallax wrapper container | |||||
| }, { | |||||
| key: "unWrapElement", | |||||
| value: function unWrapElement() { | |||||
| var wrapper = this.elementContainer; | |||||
| wrapper.replaceWith.apply(wrapper, _toConsumableArray(wrapper.childNodes)); | |||||
| } // apply default style on element | |||||
| }, { | |||||
| key: "setTransformCSS", | |||||
| value: function setTransformCSS() { | |||||
| if (this.settings.overflow === false) { | |||||
| // if overflow option is set to false | |||||
| // add scale style so the image can be translated without getting out of its container | |||||
| this.element.style[helpers_cssTransform] = "scale(".concat(this.settings.scale, ")"); | |||||
| } // add will-change CSS property to improve perfomance | |||||
| this.element.style.willChange = 'transform'; | |||||
| } // apply the transition effet | |||||
| }, { | |||||
| key: "setTransitionCSS", | |||||
| value: function setTransitionCSS() { | |||||
| // add transition option | |||||
| this.element.style.transition = "transform ".concat(this.settings.delay, "s ").concat(this.settings.transition); | |||||
| } // remove style of the element | |||||
| }, { | |||||
| key: "unSetStyle", | |||||
| value: function unSetStyle() { | |||||
| // remove will change inline style | |||||
| this.element.style.willChange = ''; | |||||
| this.element.style[helpers_cssTransform] = ''; | |||||
| this.element.style.transition = ''; | |||||
| } // get the current element offset | |||||
| }, { | |||||
| key: "getElementOffset", | |||||
| value: function getElementOffset() { | |||||
| // get position of the element | |||||
| var positions = this.elementContainer.getBoundingClientRect(); // get height | |||||
| this.elementHeight = positions.height; // get offset top | |||||
| this.elementTop = positions.top + viewport.positions.top; // if there is a custom container | |||||
| if (this.settings.customContainer) { | |||||
| // we need to do some calculation to get the position from the parent rather than the viewport | |||||
| var parentPositions = this.settings.customContainer.getBoundingClientRect(); | |||||
| this.elementTop = positions.top - parentPositions.top + viewport.positions.top; | |||||
| } // get offset bottom | |||||
| this.elementBottom = this.elementHeight + this.elementTop; | |||||
| } // build the Threshold array to cater change for every pixel scrolled | |||||
| }, { | |||||
| key: "buildThresholdList", | |||||
| value: function buildThresholdList() { | |||||
| var thresholds = []; | |||||
| for (var i = 1.0; i <= this.elementHeight; i++) { | |||||
| var ratio = i / this.elementHeight; | |||||
| thresholds.push(ratio); | |||||
| } | |||||
| return thresholds; | |||||
| } // create the Intersection Observer | |||||
| }, { | |||||
| key: "intersectionObserver", | |||||
| value: function intersectionObserver() { | |||||
| var options = { | |||||
| root: null, | |||||
| threshold: this.buildThresholdList() | |||||
| }; | |||||
| this.observer = new IntersectionObserver(this.intersectionObserverCallback.bind(this), options); | |||||
| this.observer.observe(this.element); | |||||
| } // Intersection Observer Callback to set the element at visible state or not | |||||
| }, { | |||||
| key: "intersectionObserverCallback", | |||||
| value: function intersectionObserverCallback(entries) { | |||||
| for (var i = entries.length - 1; i >= 0; i--) { | |||||
| if (entries[i].isIntersecting) { | |||||
| this.isVisible = true; | |||||
| } else { | |||||
| this.isVisible = false; | |||||
| } | |||||
| } | |||||
| } // check if the current element is visible in the Viewport | |||||
| // for browser that not support Intersection Observer API | |||||
| }, { | |||||
| key: "checkIfVisible", | |||||
| value: function checkIfVisible() { | |||||
| return this.elementBottom > viewport.positions.top && this.elementTop < viewport.positions.bottom; | |||||
| } // calculate the range between image will be translated | |||||
| }, { | |||||
| key: "getRangeMax", | |||||
| value: function getRangeMax() { | |||||
| // get the real height of the image without scale | |||||
| var elementImageHeight = this.element.clientHeight; // range is calculate with the image height by the scale | |||||
| this.rangeMax = elementImageHeight * this.settings.scale - elementImageHeight; | |||||
| } // get the percentage and the translate value to apply on the element | |||||
| }, { | |||||
| key: "getTranslateValue", | |||||
| value: function getTranslateValue() { | |||||
| // calculate the % position of the element comparing to the viewport | |||||
| // rounding percentage to a 1 number float to avoid unn unnecessary calculation | |||||
| var percentage = ((viewport.positions.bottom - this.elementTop) / ((viewport.positions.height + this.elementHeight) / 100)).toFixed(1); // sometime the percentage exceeds 100 or goes below 0 | |||||
| percentage = Math.min(100, Math.max(0, percentage)); // sometime the same percentage is returned | |||||
| // if so we don't do aything | |||||
| if (this.oldPercentage === percentage) { | |||||
| return false; | |||||
| } // if not range max is set, recalculate it | |||||
| if (!this.rangeMax) { | |||||
| this.getRangeMax(); | |||||
| } // transform this % into the max range of the element | |||||
| // rounding translateValue to a non float int - as minimum pixel for browser to render is 1 (no 0.5) | |||||
| this.translateValue = (percentage / 100 * this.rangeMax - this.rangeMax / 2).toFixed(0); // sometime the same translate value is returned | |||||
| // if so we don't do aything | |||||
| if (this.oldTranslateValue === this.translateValue) { | |||||
| return false; | |||||
| } // store the current percentage | |||||
| this.oldPercentage = percentage; | |||||
| this.oldTranslateValue = this.translateValue; | |||||
| return true; | |||||
| } // animate the image | |||||
| }, { | |||||
| key: "animate", | |||||
| value: function animate() { | |||||
| var translateValueY = 0; | |||||
| var translateValueX = 0; | |||||
| var inlineCss; | |||||
| if (this.settings.orientation.includes('left') || this.settings.orientation.includes('right')) { | |||||
| // if orientation option is left or right | |||||
| // use horizontal axe - X axe | |||||
| translateValueX = "".concat(this.settings.orientation.includes('left') ? this.translateValue * -1 : this.translateValue, "px"); | |||||
| } | |||||
| if (this.settings.orientation.includes('up') || this.settings.orientation.includes('down')) { | |||||
| // if orientation option is up or down | |||||
| // use vertical axe - Y axe | |||||
| translateValueY = "".concat(this.settings.orientation.includes('up') ? this.translateValue * -1 : this.translateValue, "px"); | |||||
| } // set style to apply to the element | |||||
| if (this.settings.overflow === false) { | |||||
| // if overflow option is set to false | |||||
| // add the scale style | |||||
| inlineCss = "translate3d(".concat(translateValueX, ", ").concat(translateValueY, ", 0) scale(").concat(this.settings.scale, ")"); | |||||
| } else { | |||||
| inlineCss = "translate3d(".concat(translateValueX, ", ").concat(translateValueY, ", 0)"); | |||||
| } // add style on the element using the adequate CSS transform | |||||
| this.element.style[helpers_cssTransform] = inlineCss; | |||||
| } | |||||
| }]); | |||||
| return ParallaxInstance; | |||||
| }(); | |||||
| /* harmony default export */ var parallax = (parallax_ParallaxInstance); | |||||
| // CONCATENATED MODULE: ./src/simpleParallax.js | |||||
| /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return simpleParallax_SimpleParallax; }); | |||||
| function simpleParallax_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | |||||
| function simpleParallax_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } | |||||
| function simpleParallax_createClass(Constructor, protoProps, staticProps) { if (protoProps) simpleParallax_defineProperties(Constructor.prototype, protoProps); if (staticProps) simpleParallax_defineProperties(Constructor, staticProps); return Constructor; } | |||||
| var intersectionObserverAvailable = true; | |||||
| var isInit = false; | |||||
| var instances = []; | |||||
| var instancesLength; | |||||
| var frameID; | |||||
| var resizeID; | |||||
| var simpleParallax_SimpleParallax = | |||||
| /*#__PURE__*/ | |||||
| function () { | |||||
| function SimpleParallax(elements, options) { | |||||
| simpleParallax_classCallCheck(this, SimpleParallax); | |||||
| if (!elements) return; | |||||
| this.elements = helpers_convertToArray(elements); | |||||
| this.defaults = { | |||||
| delay: 0.4, | |||||
| orientation: 'up', | |||||
| scale: 1.3, | |||||
| overflow: false, | |||||
| transition: 'cubic-bezier(0,0,0,1)', | |||||
| customContainer: false | |||||
| }; | |||||
| this.settings = Object.assign(this.defaults, options); // check if the browser handle the Intersection Observer API | |||||
| if (!('IntersectionObserver' in window)) intersectionObserverAvailable = false; | |||||
| if (this.settings.customContainer) { | |||||
| console.log(helpers_convertToArray(this.settings.customContainer)[0]); | |||||
| this.customContainer = helpers_convertToArray(this.settings.customContainer)[0]; | |||||
| } | |||||
| this.lastPosition = -1; | |||||
| this.resizeIsDone = this.resizeIsDone.bind(this); | |||||
| this.handleResize = this.handleResize.bind(this); | |||||
| this.proceedRequestAnimationFrame = this.proceedRequestAnimationFrame.bind(this); | |||||
| this.init(); | |||||
| } | |||||
| simpleParallax_createClass(SimpleParallax, [{ | |||||
| key: "init", | |||||
| value: function init() { | |||||
| viewport.setViewportAll(this.customContainer); | |||||
| for (var i = this.elements.length - 1; i >= 0; i--) { | |||||
| var instance = new parallax(this.elements[i], this.settings); | |||||
| instances.push(instance); | |||||
| } // update the instance length | |||||
| instancesLength = instances.length; // only if this is the first simpleParallax init | |||||
| if (!isInit) { | |||||
| // init the frame | |||||
| this.proceedRequestAnimationFrame(); | |||||
| window.addEventListener('resize', this.resizeIsDone); | |||||
| isInit = true; | |||||
| } | |||||
| } // wait for resize to be completely done | |||||
| }, { | |||||
| key: "resizeIsDone", | |||||
| value: function resizeIsDone() { | |||||
| clearTimeout(resizeID); | |||||
| resizeID = setTimeout(this.handleResize, 500); | |||||
| } // handle the resize process, some coordonates need to be re-calculate | |||||
| }, { | |||||
| key: "handleResize", | |||||
| value: function handleResize() { | |||||
| // re-get all the viewport positions | |||||
| viewport.setViewportAll(this.customContainer); | |||||
| for (var i = instancesLength - 1; i >= 0; i--) { | |||||
| // re-get the current element offset | |||||
| instances[i].getElementOffset(); // re-get the range if the current element | |||||
| instances[i].getRangeMax(); | |||||
| } // force the request animation frame to fired | |||||
| this.lastPosition = -1; | |||||
| } // animation frame | |||||
| }, { | |||||
| key: "proceedRequestAnimationFrame", | |||||
| value: function proceedRequestAnimationFrame() { | |||||
| // get the offset top of the viewport | |||||
| viewport.setViewportTop(this.customContainer); | |||||
| if (this.lastPosition === viewport.positions.top) { | |||||
| // if last position if the same than the curent one | |||||
| // callback the animationFrame and exit the current loop | |||||
| frameID = window.requestAnimationFrame(this.proceedRequestAnimationFrame); | |||||
| return; | |||||
| } // get the offset bottom of the viewport | |||||
| viewport.setViewportBottom(); // proceed with the current element | |||||
| for (var i = instancesLength - 1; i >= 0; i--) { | |||||
| this.proceedElement(instances[i]); | |||||
| } // callback the animationFrame | |||||
| frameID = window.requestAnimationFrame(this.proceedRequestAnimationFrame); // store the last position | |||||
| this.lastPosition = viewport.positions.top; | |||||
| } // proceed the element | |||||
| }, { | |||||
| key: "proceedElement", | |||||
| value: function proceedElement(instance) { | |||||
| var isVisible = false; // is not support for Intersection Observer API | |||||
| // or if this is a custom container | |||||
| // use old function to check if element visible | |||||
| if (!intersectionObserverAvailable || this.customContainer) { | |||||
| isVisible = instance.checkIfVisible(); // if support | |||||
| // use response from Intersection Observer API Callback | |||||
| } else { | |||||
| isVisible = instance.isVisible; | |||||
| } // if element not visible, stop it | |||||
| if (!isVisible) return; // if percentage is equal to the last one, no need to continue | |||||
| if (!instance.getTranslateValue()) { | |||||
| return; | |||||
| } // animate the image | |||||
| instance.animate(); | |||||
| } | |||||
| }, { | |||||
| key: "destroy", | |||||
| value: function destroy() { | |||||
| var _this = this; | |||||
| var instancesToDestroy = []; // remove all instances that need to be destroyed from the instances array | |||||
| instances = instances.filter(function (instance) { | |||||
| if (_this.elements.includes(instance.element)) { | |||||
| // push instance that need to be destroyed into instancesToDestroy | |||||
| instancesToDestroy.push(instance); | |||||
| return false; | |||||
| } | |||||
| return instance; | |||||
| }); | |||||
| for (var i = instancesToDestroy.length - 1; i >= 0; i--) { | |||||
| // unset style | |||||
| instancesToDestroy[i].unSetStyle(); | |||||
| if (this.settings.overflow === false) { | |||||
| // if overflow option is set to false | |||||
| // unwrap the element from .simpleParallax wrapper container | |||||
| instancesToDestroy[i].unWrapElement(); | |||||
| } | |||||
| } // update the instance length var | |||||
| instancesLength = instances.length; // if no instances left, remove the raf and resize event = simpleParallax fully destroyed | |||||
| if (!instancesLength) { | |||||
| // cancel the animation frame | |||||
| window.cancelAnimationFrame(frameID); // detach the resize event | |||||
| window.removeEventListener('resize', this.handleResize); | |||||
| } | |||||
| } | |||||
| }]); | |||||
| return SimpleParallax; | |||||
| }(); | |||||
| /***/ }) | |||||
| /******/ ])["default"]; | |||||
| }); | |||||
| @ -0,0 +1,21 @@ | |||||
| The MIT License (MIT) | |||||
| Copyright (c) 2016 PixelCog Inc. | |||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | |||||
| of this software and associated documentation files (the "Software"), to deal | |||||
| in the Software without restriction, including without limitation the rights | |||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||||
| copies of the Software, and to permit persons to whom the Software is | |||||
| furnished to do so, subject to the following conditions: | |||||
| The above copyright notice and this permission notice shall be included in all | |||||
| copies or substantial portions of the Software. | |||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||||
| SOFTWARE. | |||||
| @ -0,0 +1,242 @@ | |||||
| Parallax.js | |||||
| =========== | |||||
| Simple parallax scrolling effect inspired by [Spotify.com](http://spotify.com/) implemented as a jQuery plugin | |||||
| [http://pixelcog.com/parallax.js/](http://pixelcog.com/parallax.js/) | |||||
| ## Installation | |||||
| ### NPM | |||||
| ```bash | |||||
| npm i --save jquery-parallax.js | |||||
| ``` | |||||
| ### Yarn | |||||
| ```bash | |||||
| yarn add jquery-parallax.js | |||||
| ``` | |||||
| ### Bower | |||||
| Please note that although Bower is still maintained, they recommend Yarn for new projects. | |||||
| ```bash | |||||
| $ bower i --save parallax.js | |||||
| ``` | |||||
| ### Setup | |||||
| Include `parallax.min.js` in your document after including jQuery (compatible with jQuery >= 1.7). | |||||
| ```html | |||||
| <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> | |||||
| <script src="/path/to/parallax.min.js"></script> | |||||
| ``` | |||||
| Use these CDN links, provided by jsDelivr.com | |||||
| ```html | |||||
| <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> | |||||
| <script src="https://cdn.jsdelivr.net/parallax.js/1.4.2/parallax.min.js"></script> | |||||
| ``` | |||||
| ## Usage | |||||
| Please note, that `<!DOCTYPE html>` on top of your document is required! | |||||
| ### Via data attributes | |||||
| To easily add a parallax effect behind an element, add `data-parallax="scroll"` to the element you want to use, and specify an image with `data-image-src="/path/to/image.jpg"`. | |||||
| ```html | |||||
| <div class="parallax-window" data-parallax="scroll" data-image-src="/path/to/image.jpg"></div> | |||||
| ``` | |||||
| ### Via JavaScript | |||||
| To call the parallax plugin manually, simply select your target element with jQuery and do the following: | |||||
| ```javascript | |||||
| $('.parallax-window').parallax({imageSrc: '/path/to/image.jpg'}); | |||||
| ``` | |||||
| ### Notes | |||||
| What parallax.js will do is create a fixed-position element for each parallax image at the start of the document's body (or another configurable container). This mirror element will sit behind the other elements and match the position and dimensions of its target object. | |||||
| Due to the nature of this implementation, you must ensure that these parallax objects and any layers below them are transparent so that you can see the parallax effect underneath. Also, if there is no other content in this element, you will need to ensure that it has some fixed dimensions otherwise you won't see anything. | |||||
| ```css | |||||
| .parallax-window { | |||||
| min-height: 400px; | |||||
| background: transparent; | |||||
| } | |||||
| ``` | |||||
| Also, keep in mind that once initialized, the parallax plugin presumes a fixed page layout unless it encounters a `scroll` or `resize` event. If you have a dynamic page in which another javascript method may alter the DOM, you must manually refresh the parallax effect with the following commands: | |||||
| ```javascript | |||||
| jQuery(window).trigger('resize').trigger('scroll'); | |||||
| ``` | |||||
| ### Using inner HTML for complex content | |||||
| You can use the following syntax to enable complex content for the parallax: | |||||
| ```html | |||||
| <div class="parallax-window"> | |||||
| <div class="parallax-slider"> | |||||
| <span style="position:absolute; top: 400px; left: 400px;">Some Text</span> | |||||
| <p>Some other Content</p> | |||||
| </div> | |||||
| </div> | |||||
| ``` | |||||
| Please note, that the div with class "parallax-slider" is essential here. | |||||
| You then need to initialize it through JS and provide the naturalWidth and naturalHeight options in order to be rendered correctly. | |||||
| ``` | |||||
| $('.parallax-window').parallax({ | |||||
| naturalWidth: 600, | |||||
| naturalHeight: 400 | |||||
| }); | |||||
| ``` | |||||
| This also makes it possible to use responsive images in the slider: | |||||
| ```html | |||||
| <div class="parallax-window"> | |||||
| <div class="parallax-slider"> | |||||
| <img src="/path/to/image.jpg" srcset="/path/to/image-400px.jpg 400w, /path/to/image-800px.jpg 800w, /path/to/image-1200px.jpg 1200w" sizes="100vw"> | |||||
| </div> | |||||
| </div> | |||||
| ``` | |||||
| ## Options | |||||
| Options can be passed in via data attributes of JavaScript. For data attributes, append the option name to `data-`, as in `data-image-src=""`. | |||||
| Note that when specifying these options as html data-attributes, you should convert "camelCased" variable names into "dash-separated" lower-case names (e.g. `zIndex` would be `data-z-index=""`). | |||||
| <table class="table table-bordered table-striped"> | |||||
| <thead> | |||||
| <tr> | |||||
| <th style="width: 100px;">Name</th> | |||||
| <th style="width: 100px;">type</th> | |||||
| <th style="width: 50px;">default</th> | |||||
| <th>description</th> | |||||
| </tr> | |||||
| </thead> | |||||
| <tbody> | |||||
| <tr> | |||||
| <td>imageSrc</td> | |||||
| <td>path</td> | |||||
| <td>null</td> | |||||
| <td>You must provide a path to the image you wish to apply to the parallax effect.</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td>naturalWidth</td> | |||||
| <td>number</td> | |||||
| <td>auto</td> | |||||
| <td rowspan="2">You can provide the natural width and natural height of an image to speed up loading and reduce error when determining the correct aspect ratio of the image.</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td>naturalHeight</td> | |||||
| <td>number</td> | |||||
| <td>auto</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td>position</td> | |||||
| <td>xPos yPos</td> | |||||
| <td>center center</td> | |||||
| <td rowspan="3">This is analogous to the background-position css property. Specify coordinates as top, bottom, right, left, center, or pixel values (e.g. -10px 0px). The parallax image will be positioned as close to these values as possible while still covering the target element.</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td>positionX</td> | |||||
| <td>xPos</td> | |||||
| <td>center</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td>positionY</td> | |||||
| <td>yPos</td> | |||||
| <td>center</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td>speed</td> | |||||
| <td>float</td> | |||||
| <td>0.2</td> | |||||
| <td>The speed at which the parallax effect runs. 0.0 means the image will appear fixed in place, and 1.0 the image will flow at the same speed as the page content.</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td>zIndex</td> | |||||
| <td>number</td> | |||||
| <td>-100</td> | |||||
| <td>The z-index value of the fixed-position elements. By default these will be behind everything else on the page.</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td>bleed</td> | |||||
| <td>number</td> | |||||
| <td>0</td> | |||||
| <td>You can optionally set the parallax mirror element to extend a few pixels above and below the mirrored element. This can hide slow or stuttering scroll events in certain browsers.</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td>iosFix</td> | |||||
| <td>boolean</td> | |||||
| <td>true</td> | |||||
| <td>iOS devices are incompatable with this plugin. If true, this option will set the parallax image as a static, centered background image whenever it detects an iOS user agent. Disable this if you wish to implement your own graceful degradation.</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td>androidFix</td> | |||||
| <td>boolean</td> | |||||
| <td>true</td> | |||||
| <td>If true, this option will set the parallax image as a static, centered background image whenever it detects an Android user agent. Disable this if you wish to enable the parallax scrolling effect on Android devices.</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td>overScrollFix</td> | |||||
| <td>boolean</td> | |||||
| <td>false</td> | |||||
| <td>(Experimental) If true, will freeze the parallax effect when "over scrolling" in browsers like Safari to prevent unexpected gaps caused by negative scroll positions.</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td>mirrorContainer</td> | |||||
| <td>jQuery Selector</td> | |||||
| <td>body</td> | |||||
| <td>The parallax mirror will be prepended into this container.</td> | |||||
| </tr> | |||||
| </tbody> | |||||
| </table> | |||||
| ## Contributing | |||||
| If you have a pull request you would like to submit, please ensure that you update the minified version of the library along with your code changes. This project uses [uglifyjs](https://www.npmjs.com/package/uglify-js) to perform code compression. | |||||
| Please use the following command: | |||||
| uglifyjs parallax.js --comments -m -c -o parallax.min.js | |||||
| LICENSE | |||||
| ======= | |||||
| The MIT License (MIT) | |||||
| Copyright (c) 2016 PixelCog Inc. | |||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | |||||
| of this software and associated documentation files (the "Software"), to deal | |||||
| in the Software without restriction, including without limitation the rights | |||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||||
| copies of the Software, and to permit persons to whom the Software is | |||||
| furnished to do so, subject to the following conditions: | |||||
| The above copyright notice and this permission notice shall be included in all | |||||
| copies or substantial portions of the Software. | |||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||||
| SOFTWARE. | |||||
| @ -0,0 +1,20 @@ | |||||
| { | |||||
| "name": "parallax.js", | |||||
| "version": "1.5.0", | |||||
| "homepage": "http://pixelcog.com/parallax.js/", | |||||
| "description": "Simple parallax scrolling effect inspired by spotify.com implemented as a jQuery plugin", | |||||
| "authors": [ | |||||
| "Mike Greiling <mike@pixelcog.com> (http://pixelcog.com)", | |||||
| "Wolfgang Stöttinger (http://www.wolfography.at)" | |||||
| ], | |||||
| "main": "parallax.min.js", | |||||
| "license": "MIT", | |||||
| "keywords" : ["parallax", "scroll", "scrolling", "image"], | |||||
| "ignore": [ | |||||
| ".jshintrc", | |||||
| "**/*.txt" | |||||
| ], | |||||
| "dependencies": { | |||||
| "jquery": ">=1.7" | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,31 @@ | |||||
| { | |||||
| "name": "jquery-parallax.js", | |||||
| "version": "1.5.0", | |||||
| "description": "Simple parallax scrolling effect inspired by spotify.com implemented as a jQuery plugin", | |||||
| "main": "parallax.min.js", | |||||
| "scripts": { | |||||
| "test": "echo \"Error: no test specified\" && exit 1" | |||||
| }, | |||||
| "repository": { | |||||
| "type": "git", | |||||
| "url": "git+https://github.com/pixelcog/parallax.js.git" | |||||
| }, | |||||
| "keywords": [ | |||||
| "parallax", | |||||
| "scroll", | |||||
| "scrolling", | |||||
| "image" | |||||
| ], | |||||
| "author": [ | |||||
| "Mike Greiling <mike@pixelcog.com> (http://pixelcog.com)", | |||||
| "Wolfgang Stöttinger (http://www.wolfography.at)" | |||||
| ], | |||||
| "license": "MIT", | |||||
| "bugs": { | |||||
| "url": "https://github.com/pixelcog/parallax.js/issues" | |||||
| }, | |||||
| "homepage": "https://github.com/pixelcog/parallax.js#readme", | |||||
| "dependencies": { | |||||
| "jquery": ">=1.7" | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,412 @@ | |||||
| /*! | |||||
| * parallax.js v1.5.0 (http://pixelcog.github.io/parallax.js/) | |||||
| * @copyright 2016 PixelCog, Inc. | |||||
| * @license MIT (https://github.com/pixelcog/parallax.js/blob/master/LICENSE) | |||||
| */ | |||||
| ;(function ( $, window, document, undefined ) { | |||||
| // Polyfill for requestAnimationFrame | |||||
| // via: https://gist.github.com/paulirish/1579671 | |||||
| (function() { | |||||
| var lastTime = 0; | |||||
| var vendors = ['ms', 'moz', 'webkit', 'o']; | |||||
| for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { | |||||
| window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; | |||||
| window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; | |||||
| } | |||||
| if (!window.requestAnimationFrame) | |||||
| window.requestAnimationFrame = function(callback) { | |||||
| var currTime = new Date().getTime(); | |||||
| var timeToCall = Math.max(0, 16 - (currTime - lastTime)); | |||||
| var id = window.setTimeout(function() { callback(currTime + timeToCall); }, | |||||
| timeToCall); | |||||
| lastTime = currTime + timeToCall; | |||||
| return id; | |||||
| }; | |||||
| if (!window.cancelAnimationFrame) | |||||
| window.cancelAnimationFrame = function(id) { | |||||
| clearTimeout(id); | |||||
| }; | |||||
| }()); | |||||
| // Parallax Constructor | |||||
| function Parallax(element, options) { | |||||
| var self = this; | |||||
| if (typeof options == 'object') { | |||||
| delete options.refresh; | |||||
| delete options.render; | |||||
| $.extend(this, options); | |||||
| } | |||||
| this.$element = $(element); | |||||
| if (!this.imageSrc && this.$element.is('img')) { | |||||
| this.imageSrc = this.$element.attr('src'); | |||||
| } | |||||
| var positions = (this.position + '').toLowerCase().match(/\S+/g) || []; | |||||
| if (positions.length < 1) { | |||||
| positions.push('center'); | |||||
| } | |||||
| if (positions.length == 1) { | |||||
| positions.push(positions[0]); | |||||
| } | |||||
| if (positions[0] == 'top' || positions[0] == 'bottom' || positions[1] == 'left' || positions[1] == 'right') { | |||||
| positions = [positions[1], positions[0]]; | |||||
| } | |||||
| if (this.positionX !== undefined) positions[0] = this.positionX.toLowerCase(); | |||||
| if (this.positionY !== undefined) positions[1] = this.positionY.toLowerCase(); | |||||
| self.positionX = positions[0]; | |||||
| self.positionY = positions[1]; | |||||
| if (this.positionX != 'left' && this.positionX != 'right') { | |||||
| if (isNaN(parseInt(this.positionX))) { | |||||
| this.positionX = 'center'; | |||||
| } else { | |||||
| this.positionX = parseInt(this.positionX); | |||||
| } | |||||
| } | |||||
| if (this.positionY != 'top' && this.positionY != 'bottom') { | |||||
| if (isNaN(parseInt(this.positionY))) { | |||||
| this.positionY = 'center'; | |||||
| } else { | |||||
| this.positionY = parseInt(this.positionY); | |||||
| } | |||||
| } | |||||
| this.position = | |||||
| this.positionX + (isNaN(this.positionX)? '' : 'px') + ' ' + | |||||
| this.positionY + (isNaN(this.positionY)? '' : 'px'); | |||||
| if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)) { | |||||
| if (this.imageSrc && this.iosFix && !this.$element.is('img')) { | |||||
| this.$element.css({ | |||||
| backgroundImage: 'url(' + this.imageSrc + ')', | |||||
| backgroundSize: 'cover', | |||||
| backgroundPosition: this.position | |||||
| }); | |||||
| } | |||||
| return this; | |||||
| } | |||||
| if (navigator.userAgent.match(/(Android)/)) { | |||||
| if (this.imageSrc && this.androidFix && !this.$element.is('img')) { | |||||
| this.$element.css({ | |||||
| backgroundImage: 'url(' + this.imageSrc + ')', | |||||
| backgroundSize: 'cover', | |||||
| backgroundPosition: this.position | |||||
| }); | |||||
| } | |||||
| return this; | |||||
| } | |||||
| this.$mirror = $('<div />').prependTo(this.mirrorContainer); | |||||
| var slider = this.$element.find('>.parallax-slider'); | |||||
| var sliderExisted = false; | |||||
| if (slider.length == 0) | |||||
| this.$slider = $('<img />').prependTo(this.$mirror); | |||||
| else { | |||||
| this.$slider = slider.prependTo(this.$mirror) | |||||
| sliderExisted = true; | |||||
| } | |||||
| this.$mirror.addClass('parallax-mirror').css({ | |||||
| visibility: 'hidden', | |||||
| zIndex: this.zIndex, | |||||
| position: 'fixed', | |||||
| top: 0, | |||||
| left: 0, | |||||
| overflow: 'hidden' | |||||
| }); | |||||
| this.$slider.addClass('parallax-slider').one('load', function() { | |||||
| if (!self.naturalHeight || !self.naturalWidth) { | |||||
| self.naturalHeight = this.naturalHeight || this.height || 1; | |||||
| self.naturalWidth = this.naturalWidth || this.width || 1; | |||||
| } | |||||
| self.aspectRatio = self.naturalWidth / self.naturalHeight; | |||||
| Parallax.isSetup || Parallax.setup(); | |||||
| Parallax.sliders.push(self); | |||||
| Parallax.isFresh = false; | |||||
| Parallax.requestRender(); | |||||
| }); | |||||
| if (!sliderExisted) | |||||
| this.$slider[0].src = this.imageSrc; | |||||
| if (this.naturalHeight && this.naturalWidth || this.$slider[0].complete || slider.length > 0) { | |||||
| this.$slider.trigger('load'); | |||||
| } | |||||
| } | |||||
| // Parallax Instance Methods | |||||
| $.extend(Parallax.prototype, { | |||||
| speed: 0.2, | |||||
| bleed: 0, | |||||
| zIndex: -100, | |||||
| iosFix: true, | |||||
| androidFix: true, | |||||
| position: 'center', | |||||
| overScrollFix: false, | |||||
| mirrorContainer: 'body', | |||||
| refresh: function() { | |||||
| this.boxWidth = this.$element.outerWidth(); | |||||
| this.boxHeight = this.$element.outerHeight() + this.bleed * 2; | |||||
| this.boxOffsetTop = this.$element.offset().top - this.bleed; | |||||
| this.boxOffsetLeft = this.$element.offset().left; | |||||
| this.boxOffsetBottom = this.boxOffsetTop + this.boxHeight; | |||||
| var winHeight = Parallax.winHeight; | |||||
| var docHeight = Parallax.docHeight; | |||||
| var maxOffset = Math.min(this.boxOffsetTop, docHeight - winHeight); | |||||
| var minOffset = Math.max(this.boxOffsetTop + this.boxHeight - winHeight, 0); | |||||
| var imageHeightMin = this.boxHeight + (maxOffset - minOffset) * (1 - this.speed) | 0; | |||||
| var imageOffsetMin = (this.boxOffsetTop - maxOffset) * (1 - this.speed) | 0; | |||||
| var margin; | |||||
| if (imageHeightMin * this.aspectRatio >= this.boxWidth) { | |||||
| this.imageWidth = imageHeightMin * this.aspectRatio | 0; | |||||
| this.imageHeight = imageHeightMin; | |||||
| this.offsetBaseTop = imageOffsetMin; | |||||
| margin = this.imageWidth - this.boxWidth; | |||||
| if (this.positionX == 'left') { | |||||
| this.offsetLeft = 0; | |||||
| } else if (this.positionX == 'right') { | |||||
| this.offsetLeft = - margin; | |||||
| } else if (!isNaN(this.positionX)) { | |||||
| this.offsetLeft = Math.max(this.positionX, - margin); | |||||
| } else { | |||||
| this.offsetLeft = - margin / 2 | 0; | |||||
| } | |||||
| } else { | |||||
| this.imageWidth = this.boxWidth; | |||||
| this.imageHeight = this.boxWidth / this.aspectRatio | 0; | |||||
| this.offsetLeft = 0; | |||||
| margin = this.imageHeight - imageHeightMin; | |||||
| if (this.positionY == 'top') { | |||||
| this.offsetBaseTop = imageOffsetMin; | |||||
| } else if (this.positionY == 'bottom') { | |||||
| this.offsetBaseTop = imageOffsetMin - margin; | |||||
| } else if (!isNaN(this.positionY)) { | |||||
| this.offsetBaseTop = imageOffsetMin + Math.max(this.positionY, - margin); | |||||
| } else { | |||||
| this.offsetBaseTop = imageOffsetMin - margin / 2 | 0; | |||||
| } | |||||
| } | |||||
| }, | |||||
| render: function() { | |||||
| var scrollTop = Parallax.scrollTop; | |||||
| var scrollLeft = Parallax.scrollLeft; | |||||
| var overScroll = this.overScrollFix ? Parallax.overScroll : 0; | |||||
| var scrollBottom = scrollTop + Parallax.winHeight; | |||||
| if (this.boxOffsetBottom > scrollTop && this.boxOffsetTop <= scrollBottom) { | |||||
| this.visibility = 'visible'; | |||||
| this.mirrorTop = this.boxOffsetTop - scrollTop; | |||||
| this.mirrorLeft = this.boxOffsetLeft - scrollLeft; | |||||
| this.offsetTop = this.offsetBaseTop - this.mirrorTop * (1 - this.speed); | |||||
| } else { | |||||
| this.visibility = 'hidden'; | |||||
| } | |||||
| this.$mirror.css({ | |||||
| transform: 'translate3d('+this.mirrorLeft+'px, '+(this.mirrorTop - overScroll)+'px, 0px)', | |||||
| visibility: this.visibility, | |||||
| height: this.boxHeight, | |||||
| width: this.boxWidth | |||||
| }); | |||||
| this.$slider.css({ | |||||
| transform: 'translate3d('+this.offsetLeft+'px, '+this.offsetTop+'px, 0px)', | |||||
| position: 'absolute', | |||||
| height: this.imageHeight, | |||||
| width: this.imageWidth, | |||||
| maxWidth: 'none' | |||||
| }); | |||||
| } | |||||
| }); | |||||
| // Parallax Static Methods | |||||
| $.extend(Parallax, { | |||||
| scrollTop: 0, | |||||
| scrollLeft: 0, | |||||
| winHeight: 0, | |||||
| winWidth: 0, | |||||
| docHeight: 1 << 30, | |||||
| docWidth: 1 << 30, | |||||
| sliders: [], | |||||
| isReady: false, | |||||
| isFresh: false, | |||||
| isBusy: false, | |||||
| setup: function() { | |||||
| if (this.isReady) return; | |||||
| var self = this; | |||||
| var $doc = $(document), $win = $(window); | |||||
| var loadDimensions = function() { | |||||
| Parallax.winHeight = $win.height(); | |||||
| Parallax.winWidth = $win.width(); | |||||
| Parallax.docHeight = $doc.height(); | |||||
| Parallax.docWidth = $doc.width(); | |||||
| }; | |||||
| var loadScrollPosition = function() { | |||||
| var winScrollTop = $win.scrollTop(); | |||||
| var scrollTopMax = Parallax.docHeight - Parallax.winHeight; | |||||
| var scrollLeftMax = Parallax.docWidth - Parallax.winWidth; | |||||
| Parallax.scrollTop = Math.max(0, Math.min(scrollTopMax, winScrollTop)); | |||||
| Parallax.scrollLeft = Math.max(0, Math.min(scrollLeftMax, $win.scrollLeft())); | |||||
| Parallax.overScroll = Math.max(winScrollTop - scrollTopMax, Math.min(winScrollTop, 0)); | |||||
| }; | |||||
| $win.on('resize.px.parallax load.px.parallax', function() { | |||||
| loadDimensions(); | |||||
| self.refresh(); | |||||
| Parallax.isFresh = false; | |||||
| Parallax.requestRender(); | |||||
| }) | |||||
| .on('scroll.px.parallax load.px.parallax', function() { | |||||
| loadScrollPosition(); | |||||
| Parallax.requestRender(); | |||||
| }); | |||||
| loadDimensions(); | |||||
| loadScrollPosition(); | |||||
| this.isReady = true; | |||||
| var lastPosition = -1; | |||||
| function frameLoop() { | |||||
| if (lastPosition == window.pageYOffset) { // Avoid overcalculations | |||||
| window.requestAnimationFrame(frameLoop); | |||||
| return false; | |||||
| } else lastPosition = window.pageYOffset; | |||||
| self.render(); | |||||
| window.requestAnimationFrame(frameLoop); | |||||
| } | |||||
| frameLoop(); | |||||
| }, | |||||
| configure: function(options) { | |||||
| if (typeof options == 'object') { | |||||
| delete options.refresh; | |||||
| delete options.render; | |||||
| $.extend(this.prototype, options); | |||||
| } | |||||
| }, | |||||
| refresh: function() { | |||||
| $.each(this.sliders, function(){ this.refresh(); }); | |||||
| this.isFresh = true; | |||||
| }, | |||||
| render: function() { | |||||
| this.isFresh || this.refresh(); | |||||
| $.each(this.sliders, function(){ this.render(); }); | |||||
| }, | |||||
| requestRender: function() { | |||||
| var self = this; | |||||
| self.render(); | |||||
| self.isBusy = false; | |||||
| }, | |||||
| destroy: function(el){ | |||||
| var i, | |||||
| parallaxElement = $(el).data('px.parallax'); | |||||
| parallaxElement.$mirror.remove(); | |||||
| for(i=0; i < this.sliders.length; i+=1){ | |||||
| if(this.sliders[i] == parallaxElement){ | |||||
| this.sliders.splice(i, 1); | |||||
| } | |||||
| } | |||||
| $(el).data('px.parallax', false); | |||||
| if(this.sliders.length === 0){ | |||||
| $(window).off('scroll.px.parallax resize.px.parallax load.px.parallax'); | |||||
| this.isReady = false; | |||||
| Parallax.isSetup = false; | |||||
| } | |||||
| } | |||||
| }); | |||||
| // Parallax Plugin Definition | |||||
| function Plugin(option) { | |||||
| return this.each(function () { | |||||
| var $this = $(this); | |||||
| var options = typeof option == 'object' && option; | |||||
| if (this == window || this == document || $this.is('body')) { | |||||
| Parallax.configure(options); | |||||
| } | |||||
| else if (!$this.data('px.parallax')) { | |||||
| options = $.extend({}, $this.data(), options); | |||||
| $this.data('px.parallax', new Parallax(this, options)); | |||||
| } | |||||
| else if (typeof option == 'object') | |||||
| { | |||||
| $.extend($this.data('px.parallax'), options); | |||||
| } | |||||
| if (typeof option == 'string') { | |||||
| if(option == 'destroy'){ | |||||
| Parallax.destroy(this); | |||||
| }else{ | |||||
| Parallax[option](); | |||||
| } | |||||
| } | |||||
| }); | |||||
| } | |||||
| var old = $.fn.parallax; | |||||
| $.fn.parallax = Plugin; | |||||
| $.fn.parallax.Constructor = Parallax; | |||||
| // Parallax No Conflict | |||||
| $.fn.parallax.noConflict = function () { | |||||
| $.fn.parallax = old; | |||||
| return this; | |||||
| }; | |||||
| // Parallax Data-API | |||||
| $( function () { | |||||
| $('[data-parallax="scroll"]').parallax(); | |||||
| }); | |||||
| }(jQuery, window, document)); | |||||
| @ -0,0 +1,3 @@ | |||||
| { | |||||
| "presets": ["@babel/preset-env"] | |||||
| } | |||||
| @ -0,0 +1,4 @@ | |||||
| # Browsers that we support | |||||
| last 2 versions | |||||
| not IE > 0 | |||||
| not ie_mob > 0 | |||||
| @ -0,0 +1,21 @@ | |||||
| module.exports = { | |||||
| env: { | |||||
| browser: true, | |||||
| es6: true | |||||
| }, | |||||
| extends: 'airbnb-base', | |||||
| globals: { | |||||
| Atomics: 'readonly', | |||||
| SharedArrayBuffer: 'readonly' | |||||
| }, | |||||
| parserOptions: { | |||||
| ecmaVersion: 2018, | |||||
| sourceType: 'module' | |||||
| }, | |||||
| rules: { | |||||
| indent: ['error', 4], | |||||
| 'no-plusplus': ['error', { allowForLoopAfterthoughts: true }], | |||||
| 'max-len': ['error', { code: 150 }], | |||||
| 'no-prototype-builtins': 0 | |||||
| } | |||||
| }; | |||||
| @ -0,0 +1,8 @@ | |||||
| node_modules/ | |||||
| dist/index\.html | |||||
| dist/test\.js | |||||
| package-lock\.json | |||||
| dist/index\.js | |||||
| @ -0,0 +1 @@ | |||||
| v11.5.0 | |||||
| @ -0,0 +1 @@ | |||||
| dist/ | |||||
| @ -0,0 +1,9 @@ | |||||
| { | |||||
| "useTabs": false, | |||||
| "printWidth": 300, | |||||
| "tabWidth": 4, | |||||
| "singleQuote": true, | |||||
| "trailingComma": "none", | |||||
| "jsxBracketSameLine": false, | |||||
| "semi": true | |||||
| } | |||||
| @ -0,0 +1,46 @@ | |||||
| # Contributor Covenant Code of Conduct | |||||
| ## Our Pledge | |||||
| In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. | |||||
| ## Our Standards | |||||
| Examples of behavior that contributes to creating a positive environment include: | |||||
| - Using welcoming and inclusive language | |||||
| - Being respectful of differing viewpoints and experiences | |||||
| - Gracefully accepting constructive criticism | |||||
| - Focusing on what is best for the community | |||||
| - Showing empathy towards other community members | |||||
| Examples of unacceptable behavior by participants include: | |||||
| - The use of sexualized language or imagery and unwelcome sexual attention or advances | |||||
| - Trolling, insulting/derogatory comments, and personal or political attacks | |||||
| - Public or private harassment | |||||
| - Publishing others' private information, such as a physical or electronic address, without explicit permission | |||||
| - Other conduct which could reasonably be considered inappropriate in a professional setting | |||||
| ## Our Responsibilities | |||||
| Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. | |||||
| Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. | |||||
| ## Scope | |||||
| This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. | |||||
| ## Enforcement | |||||
| Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at geoffrey.signorato@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. | |||||
| Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. | |||||
| ## Attribution | |||||
| This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] | |||||
| [homepage]: http://contributor-covenant.org | |||||
| [version]: http://contributor-covenant.org/version/1/4/ | |||||
| @ -0,0 +1,21 @@ | |||||
| MIT License | |||||
| Copyright (c) 2017 geosenna | |||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | |||||
| of this software and associated documentation files (the "Software"), to deal | |||||
| in the Software without restriction, including without limitation the rights | |||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||||
| copies of the Software, and to permit persons to whom the Software is | |||||
| furnished to do so, subject to the following conditions: | |||||
| The above copyright notice and this permission notice shall be included in all | |||||
| copies or substantial portions of the Software. | |||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||||
| SOFTWARE. | |||||
| @ -0,0 +1,130 @@ | |||||
|  | |||||
| [](https://badge.fury.io/gh/geosenna%2FsimpleParallax) | |||||
| [](https://www.jsdelivr.com/package/npm/simple-parallax-js) | |||||
| [](https://github.com/prettier/prettier) | |||||
| # What is simpleParallax? | |||||
| simpleParallax is a very simple and tiny Vanilla JS library which adds parallax animations on any images. | |||||
| Where it may be laborious to get results through other plugins, simpleParallax stands out for its ease and its visual rendering. The parallax effect is directly applied on image tags, there is no need to use background images. You can read one case study [here](https://medium.com/@geoffrey.signorato/case-study-create-a-parallax-effect-directly-on-img-tags-with-javascript-35b8daf81471). | |||||
| Any image will fit. Try it out! | |||||
| ## Installation | |||||
| Simply copy/paste the below snippet just before your closing `</body>` tag: | |||||
| ```html | |||||
| <script src="simpleParallax.js"></script> | |||||
| ``` | |||||
| or use the below CDN link provided by [jsDelivr.com](https://www.jsdelivr.com/package/npm/simple-parallax-js): | |||||
| ```html | |||||
| <script src="https://cdn.jsdelivr.net/npm/simple-parallax-js@5.2.0/dist/simpleParallax.min.js"></script> | |||||
| ``` | |||||
| or you can install it via [npm/yarn](https://www.npmjs.com/package/simple-parallax-js): | |||||
| ```sh | |||||
| #npm | |||||
| npm install simple-parallax-js | |||||
| #yarn | |||||
| yarn add simple-parallax-js | |||||
| ``` | |||||
| You can import it as follow: | |||||
| ```javascript | |||||
| import simpleParallax from 'simple-parallax-js'; | |||||
| ``` | |||||
| ## Initialization | |||||
| Giving the following HTML: | |||||
| ```html | |||||
| <img class="thumbnail" src="image.jpg" alt="image"> | |||||
| ``` | |||||
| Simply add the following JavaScript code: | |||||
| ```javascript | |||||
| var image = document.getElementsByClassName('thumbnail'); | |||||
| new simpleParallax(image); | |||||
| ``` | |||||
| This also work with several images: | |||||
| ```javascript | |||||
| var images = document.querySelectorAll('img'); | |||||
| new simpleParallax(images); | |||||
| ``` | |||||
| ## Settings | |||||
| Setting | Type | Default | Hint | |||||
| --- | --- | --- | --- | |||||
| orientation | string | up | up - right - down - left - up left - up right - down left - down right | |||||
| scale | int | 1.3 | need to be above 1.0 | |||||
| overflow | boolean | false | | |||||
| delay | int | 0.4 | the delay is in second | |||||
| transition | string | false | any CSS transition | |||||
| customContainer | string or node | false | this can be a string of directly a node | |||||
| You can apply these settings with the following JS code: | |||||
| ```javascript | |||||
| var images = document.querySelectorAll('.thumbnail'); | |||||
| new simpleParallax(images, { | |||||
| delay: 0, | |||||
| orientation: 'down', | |||||
| scale: 1.3, | |||||
| overflow: true, | |||||
| customContainer: '.container' | |||||
| }); | |||||
| ``` | |||||
| ### orientation - *string* | |||||
| This is the direction of the parallax effect. Choose *up* and when scrolling down, the image will translate from bottom to top. When scroll up, the image will translate from top to bottom. | |||||
| ### scale - *int* | |||||
| The higher the scale is set, the more visible the parallax effect will be. In return, the image will lose in quality. To reduce the lossless effect, if the scale is set at 1.5 and you image is 500px width, do the simple math 500 * 1.5 = 750. So you can choose a 750px image to replace your 500px one, and don't see any quality leak. | |||||
| ### overflow - *boolean* | |||||
| By default, the image is scaled to apply a parallax effect without any overflow on the layout (you can check the [case study](https://medium.com/@geoffrey.signorato/case-study-create-a-parallax-effect-directly-on-img-tags-with-javascript-35b8daf81471) to have a better understanding). when overflow is set to true, the image will translate out of its natural flow. | |||||
| ### delay - *int* | |||||
| When a delay is set, the translation of the image will slightly continue when the user stop scrolling. That gives a very nice effect. | |||||
| ### transition - *string* | |||||
| The transition works closely with the delay setting. The transition will add any CSS effect to the delay setting. | |||||
| ### customContainer - *string or node* | |||||
| In some cases, you want the parallax effects to be apply on a container that have its own scroll, and not apply the parallax effects via the document scroll. | |||||
| ## Methods | |||||
| Destroy a simpleParallax instance: | |||||
| ```javascript | |||||
| var images = document.querySelectorAll('img'); | |||||
| var instance = new simpleParallax(images); | |||||
| instance.destroy(); | |||||
| ``` | |||||
| ## Examples | |||||
| You can find some examples [here](https://simpleparallax.com/#examples). | |||||
| ## Compatibility | |||||
| You can apply simpleParallax on picture tags/srcset images. | |||||
| ## Author | |||||
| [Geoffrey Signorato](https://github.com/geosigno/) | |||||
| ## Contributing | |||||
| Open an issue or a pull request to suggest changes or additions. | |||||
| @ -0,0 +1,675 @@ | |||||
| /*! | |||||
| * simpleParallax - simpleParallax is a simple JavaScript library that gives your website parallax animations on any images, | |||||
| * @date: 07-12-2019 18:53:52, | |||||
| * @version: 5.2.0, | |||||
| * @link: https://simpleparallax.com/ | |||||
| */ | |||||
| (function webpackUniversalModuleDefinition(root, factory) { | |||||
| if(typeof exports === 'object' && typeof module === 'object') | |||||
| module.exports = factory(); | |||||
| else if(typeof define === 'function' && define.amd) | |||||
| define("simpleParallax", [], factory); | |||||
| else if(typeof exports === 'object') | |||||
| exports["simpleParallax"] = factory(); | |||||
| else | |||||
| root["simpleParallax"] = factory(); | |||||
| })(window, function() { | |||||
| return /******/ (function(modules) { // webpackBootstrap | |||||
| /******/ // The module cache | |||||
| /******/ var installedModules = {}; | |||||
| /******/ | |||||
| /******/ // The require function | |||||
| /******/ function __webpack_require__(moduleId) { | |||||
| /******/ | |||||
| /******/ // Check if module is in cache | |||||
| /******/ if(installedModules[moduleId]) { | |||||
| /******/ return installedModules[moduleId].exports; | |||||
| /******/ } | |||||
| /******/ // Create a new module (and put it into the cache) | |||||
| /******/ var module = installedModules[moduleId] = { | |||||
| /******/ i: moduleId, | |||||
| /******/ l: false, | |||||
| /******/ exports: {} | |||||
| /******/ }; | |||||
| /******/ | |||||
| /******/ // Execute the module function | |||||
| /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); | |||||
| /******/ | |||||
| /******/ // Flag the module as loaded | |||||
| /******/ module.l = true; | |||||
| /******/ | |||||
| /******/ // Return the exports of the module | |||||
| /******/ return module.exports; | |||||
| /******/ } | |||||
| /******/ | |||||
| /******/ | |||||
| /******/ // expose the modules object (__webpack_modules__) | |||||
| /******/ __webpack_require__.m = modules; | |||||
| /******/ | |||||
| /******/ // expose the module cache | |||||
| /******/ __webpack_require__.c = installedModules; | |||||
| /******/ | |||||
| /******/ // define getter function for harmony exports | |||||
| /******/ __webpack_require__.d = function(exports, name, getter) { | |||||
| /******/ if(!__webpack_require__.o(exports, name)) { | |||||
| /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); | |||||
| /******/ } | |||||
| /******/ }; | |||||
| /******/ | |||||
| /******/ // define __esModule on exports | |||||
| /******/ __webpack_require__.r = function(exports) { | |||||
| /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { | |||||
| /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); | |||||
| /******/ } | |||||
| /******/ Object.defineProperty(exports, '__esModule', { value: true }); | |||||
| /******/ }; | |||||
| /******/ | |||||
| /******/ // create a fake namespace object | |||||
| /******/ // mode & 1: value is a module id, require it | |||||
| /******/ // mode & 2: merge all properties of value into the ns | |||||
| /******/ // mode & 4: return value when already ns object | |||||
| /******/ // mode & 8|1: behave like require | |||||
| /******/ __webpack_require__.t = function(value, mode) { | |||||
| /******/ if(mode & 1) value = __webpack_require__(value); | |||||
| /******/ if(mode & 8) return value; | |||||
| /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; | |||||
| /******/ var ns = Object.create(null); | |||||
| /******/ __webpack_require__.r(ns); | |||||
| /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); | |||||
| /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); | |||||
| /******/ return ns; | |||||
| /******/ }; | |||||
| /******/ | |||||
| /******/ // getDefaultExport function for compatibility with non-harmony modules | |||||
| /******/ __webpack_require__.n = function(module) { | |||||
| /******/ var getter = module && module.__esModule ? | |||||
| /******/ function getDefault() { return module['default']; } : | |||||
| /******/ function getModuleExports() { return module; }; | |||||
| /******/ __webpack_require__.d(getter, 'a', getter); | |||||
| /******/ return getter; | |||||
| /******/ }; | |||||
| /******/ | |||||
| /******/ // Object.prototype.hasOwnProperty.call | |||||
| /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; | |||||
| /******/ | |||||
| /******/ // __webpack_public_path__ | |||||
| /******/ __webpack_require__.p = ""; | |||||
| /******/ | |||||
| /******/ | |||||
| /******/ // Load entry module and return exports | |||||
| /******/ return __webpack_require__(__webpack_require__.s = 0); | |||||
| /******/ }) | |||||
| /************************************************************************/ | |||||
| /******/ ([ | |||||
| /* 0 */ | |||||
| /***/ (function(module, __webpack_exports__, __webpack_require__) { | |||||
| "use strict"; | |||||
| __webpack_require__.r(__webpack_exports__); | |||||
| // CONCATENATED MODULE: ./src/helpers/viewport.js | |||||
| function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | |||||
| function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } | |||||
| function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } | |||||
| var Viewport = | |||||
| /*#__PURE__*/ | |||||
| function () { | |||||
| function Viewport() { | |||||
| _classCallCheck(this, Viewport); | |||||
| this.positions = { | |||||
| top: 0, | |||||
| bottom: 0, | |||||
| height: 0 | |||||
| }; | |||||
| } | |||||
| _createClass(Viewport, [{ | |||||
| key: "setViewportTop", | |||||
| value: function setViewportTop(container) { | |||||
| // if this is a custom container, user the scrollTop | |||||
| this.positions.top = container ? container.scrollTop : window.pageYOffset; | |||||
| return this.positions; | |||||
| } | |||||
| }, { | |||||
| key: "setViewportBottom", | |||||
| value: function setViewportBottom() { | |||||
| this.positions.bottom = this.positions.top + this.positions.height; | |||||
| return this.positions; | |||||
| } | |||||
| }, { | |||||
| key: "setViewportAll", | |||||
| value: function setViewportAll(container) { | |||||
| // if this is a custom container, user the scrollTop | |||||
| this.positions.top = container ? container.scrollTop : window.pageYOffset; // if this is a custom container, get the height from the custom container itself | |||||
| this.positions.height = container ? container.clientHeight : document.documentElement.clientHeight; | |||||
| this.positions.bottom = this.positions.top + this.positions.height; | |||||
| return this.positions; | |||||
| } | |||||
| }]); | |||||
| return Viewport; | |||||
| }(); | |||||
| var viewport = new Viewport(); | |||||
| // CONCATENATED MODULE: ./src/helpers/convertToArray.js | |||||
| // check wether the element is a Node List, a HTML Collection or an array | |||||
| // return an array of nodes | |||||
| var convertToArray = function convertToArray(elements) { | |||||
| if (NodeList.prototype.isPrototypeOf(elements) || HTMLCollection.prototype.isPrototypeOf(elements)) return Array.from(elements); | |||||
| if (typeof elements === 'string' || elements instanceof String) return document.querySelectorAll(elements); | |||||
| return [elements]; | |||||
| }; | |||||
| /* harmony default export */ var helpers_convertToArray = (convertToArray); | |||||
| // CONCATENATED MODULE: ./src/helpers/cssTransform.js | |||||
| // Detect css transform | |||||
| var cssTransform = function cssTransform() { | |||||
| var prefixes = 'transform webkitTransform mozTransform oTransform msTransform'.split(' '); | |||||
| var transform; | |||||
| var i = 0; | |||||
| while (transform === undefined) { | |||||
| transform = document.createElement('div').style[prefixes[i]] !== undefined ? prefixes[i] : undefined; | |||||
| i += 1; | |||||
| } | |||||
| return transform; | |||||
| }; | |||||
| /* harmony default export */ var helpers_cssTransform = (cssTransform()); | |||||
| // CONCATENATED MODULE: ./src/helpers/isImageLoaded.js | |||||
| // check if image is fully loaded | |||||
| var isImageLoaded = function isImageLoaded(image) { | |||||
| // check if image is set as the parameter | |||||
| if (!image) { | |||||
| return false; | |||||
| } // check if image has been 100% loaded | |||||
| if (!image.complete) { | |||||
| return false; | |||||
| } // check if the image is displayed | |||||
| if (typeof image.naturalWidth !== 'undefined' && image.naturalWidth === 0) { | |||||
| return false; | |||||
| } | |||||
| return true; | |||||
| }; | |||||
| /* harmony default export */ var helpers_isImageLoaded = (isImageLoaded); | |||||
| // CONCATENATED MODULE: ./src/instances/parallax.js | |||||
| function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); } | |||||
| function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); } | |||||
| function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); } | |||||
| function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } } | |||||
| function parallax_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | |||||
| function parallax_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } | |||||
| function parallax_createClass(Constructor, protoProps, staticProps) { if (protoProps) parallax_defineProperties(Constructor.prototype, protoProps); if (staticProps) parallax_defineProperties(Constructor, staticProps); return Constructor; } | |||||
| var parallax_ParallaxInstance = | |||||
| /*#__PURE__*/ | |||||
| function () { | |||||
| function ParallaxInstance(element, options) { | |||||
| parallax_classCallCheck(this, ParallaxInstance); | |||||
| // set the element & settings | |||||
| this.element = element; | |||||
| this.elementContainer = element; | |||||
| this.settings = options; | |||||
| this.isVisible = true; | |||||
| this.isInit = false; | |||||
| this.oldTranslateValue = -1; | |||||
| this.init = this.init.bind(this); // check if images has not been loaded yet | |||||
| if (helpers_isImageLoaded(element)) { | |||||
| this.init(); | |||||
| } else { | |||||
| this.element.addEventListener('load', this.init); | |||||
| } | |||||
| } | |||||
| parallax_createClass(ParallaxInstance, [{ | |||||
| key: "init", | |||||
| value: function init() { | |||||
| var _this = this; | |||||
| // for some reason, <picture> are init an infinite time on windows OS | |||||
| if (this.isInit) return; // check if element has not been already initialized with simpleParallax | |||||
| if (this.element.closest('.simpleParallax')) return; | |||||
| if (this.settings.overflow === false) { | |||||
| // if overflow option is set to false | |||||
| // wrap the element into a div to apply overflow | |||||
| this.wrapElement(this.element); | |||||
| } // apply the transform style on the image | |||||
| this.setTransformCSS(); // get the current element offset | |||||
| this.getElementOffset(); // init the Intesection Observer | |||||
| this.intersectionObserver(); // get its translated value | |||||
| this.getTranslateValue(); // apply its translation even if not visible for the first init | |||||
| this.animate(); // if a delay has been set | |||||
| if (this.settings.delay > 0) { | |||||
| // apply a timeout to avoid buggy effect | |||||
| setTimeout(function () { | |||||
| // apply the transition style on the image | |||||
| _this.setTransitionCSS(); | |||||
| }, 10); | |||||
| } // for some reason, <picture> are init an infinite time on windows OS | |||||
| this.isInit = true; | |||||
| } // if overflow option is set to false | |||||
| // wrap the element into a .simpleParallax div and apply overflow hidden to hide the image excedant (result of the scale) | |||||
| }, { | |||||
| key: "wrapElement", | |||||
| value: function wrapElement() { | |||||
| // check is current image is in a <picture> tag | |||||
| var elementToWrap = this.element.closest('picture') || this.element; // create a .simpleParallax wrapper container | |||||
| var wrapper = document.createElement('div'); | |||||
| wrapper.classList.add('simpleParallax'); | |||||
| wrapper.style.overflow = 'hidden'; // append the image inside the new wrapper | |||||
| elementToWrap.parentNode.insertBefore(wrapper, elementToWrap); | |||||
| wrapper.appendChild(elementToWrap); | |||||
| this.elementContainer = wrapper; | |||||
| } // unwrap the element from .simpleParallax wrapper container | |||||
| }, { | |||||
| key: "unWrapElement", | |||||
| value: function unWrapElement() { | |||||
| var wrapper = this.elementContainer; | |||||
| wrapper.replaceWith.apply(wrapper, _toConsumableArray(wrapper.childNodes)); | |||||
| } // apply default style on element | |||||
| }, { | |||||
| key: "setTransformCSS", | |||||
| value: function setTransformCSS() { | |||||
| if (this.settings.overflow === false) { | |||||
| // if overflow option is set to false | |||||
| // add scale style so the image can be translated without getting out of its container | |||||
| this.element.style[helpers_cssTransform] = "scale(".concat(this.settings.scale, ")"); | |||||
| } // add will-change CSS property to improve perfomance | |||||
| this.element.style.willChange = 'transform'; | |||||
| } // apply the transition effet | |||||
| }, { | |||||
| key: "setTransitionCSS", | |||||
| value: function setTransitionCSS() { | |||||
| // add transition option | |||||
| this.element.style.transition = "transform ".concat(this.settings.delay, "s ").concat(this.settings.transition); | |||||
| } // remove style of the element | |||||
| }, { | |||||
| key: "unSetStyle", | |||||
| value: function unSetStyle() { | |||||
| // remove will change inline style | |||||
| this.element.style.willChange = ''; | |||||
| this.element.style[helpers_cssTransform] = ''; | |||||
| this.element.style.transition = ''; | |||||
| } // get the current element offset | |||||
| }, { | |||||
| key: "getElementOffset", | |||||
| value: function getElementOffset() { | |||||
| // get position of the element | |||||
| var positions = this.elementContainer.getBoundingClientRect(); // get height | |||||
| this.elementHeight = positions.height; // get offset top | |||||
| this.elementTop = positions.top + viewport.positions.top; // if there is a custom container | |||||
| if (this.settings.customContainer) { | |||||
| // we need to do some calculation to get the position from the parent rather than the viewport | |||||
| var parentPositions = this.settings.customContainer.getBoundingClientRect(); | |||||
| this.elementTop = positions.top - parentPositions.top + viewport.positions.top; | |||||
| } // get offset bottom | |||||
| this.elementBottom = this.elementHeight + this.elementTop; | |||||
| } // build the Threshold array to cater change for every pixel scrolled | |||||
| }, { | |||||
| key: "buildThresholdList", | |||||
| value: function buildThresholdList() { | |||||
| var thresholds = []; | |||||
| for (var i = 1.0; i <= this.elementHeight; i++) { | |||||
| var ratio = i / this.elementHeight; | |||||
| thresholds.push(ratio); | |||||
| } | |||||
| return thresholds; | |||||
| } // create the Intersection Observer | |||||
| }, { | |||||
| key: "intersectionObserver", | |||||
| value: function intersectionObserver() { | |||||
| var options = { | |||||
| root: null, | |||||
| threshold: this.buildThresholdList() | |||||
| }; | |||||
| this.observer = new IntersectionObserver(this.intersectionObserverCallback.bind(this), options); | |||||
| this.observer.observe(this.element); | |||||
| } // Intersection Observer Callback to set the element at visible state or not | |||||
| }, { | |||||
| key: "intersectionObserverCallback", | |||||
| value: function intersectionObserverCallback(entries) { | |||||
| for (var i = entries.length - 1; i >= 0; i--) { | |||||
| if (entries[i].isIntersecting) { | |||||
| this.isVisible = true; | |||||
| } else { | |||||
| this.isVisible = false; | |||||
| } | |||||
| } | |||||
| } // check if the current element is visible in the Viewport | |||||
| // for browser that not support Intersection Observer API | |||||
| }, { | |||||
| key: "checkIfVisible", | |||||
| value: function checkIfVisible() { | |||||
| return this.elementBottom > viewport.positions.top && this.elementTop < viewport.positions.bottom; | |||||
| } // calculate the range between image will be translated | |||||
| }, { | |||||
| key: "getRangeMax", | |||||
| value: function getRangeMax() { | |||||
| // get the real height of the image without scale | |||||
| var elementImageHeight = this.element.clientHeight; // range is calculate with the image height by the scale | |||||
| this.rangeMax = elementImageHeight * this.settings.scale - elementImageHeight; | |||||
| } // get the percentage and the translate value to apply on the element | |||||
| }, { | |||||
| key: "getTranslateValue", | |||||
| value: function getTranslateValue() { | |||||
| // calculate the % position of the element comparing to the viewport | |||||
| // rounding percentage to a 1 number float to avoid unn unnecessary calculation | |||||
| var percentage = ((viewport.positions.bottom - this.elementTop) / ((viewport.positions.height + this.elementHeight) / 100)).toFixed(1); // sometime the percentage exceeds 100 or goes below 0 | |||||
| percentage = Math.min(100, Math.max(0, percentage)); // sometime the same percentage is returned | |||||
| // if so we don't do aything | |||||
| if (this.oldPercentage === percentage) { | |||||
| return false; | |||||
| } // if not range max is set, recalculate it | |||||
| if (!this.rangeMax) { | |||||
| this.getRangeMax(); | |||||
| } // transform this % into the max range of the element | |||||
| // rounding translateValue to a non float int - as minimum pixel for browser to render is 1 (no 0.5) | |||||
| this.translateValue = (percentage / 100 * this.rangeMax - this.rangeMax / 2).toFixed(0); // sometime the same translate value is returned | |||||
| // if so we don't do aything | |||||
| if (this.oldTranslateValue === this.translateValue) { | |||||
| return false; | |||||
| } // store the current percentage | |||||
| this.oldPercentage = percentage; | |||||
| this.oldTranslateValue = this.translateValue; | |||||
| return true; | |||||
| } // animate the image | |||||
| }, { | |||||
| key: "animate", | |||||
| value: function animate() { | |||||
| var translateValueY = 0; | |||||
| var translateValueX = 0; | |||||
| var inlineCss; | |||||
| if (this.settings.orientation.includes('left') || this.settings.orientation.includes('right')) { | |||||
| // if orientation option is left or right | |||||
| // use horizontal axe - X axe | |||||
| translateValueX = "".concat(this.settings.orientation.includes('left') ? this.translateValue * -1 : this.translateValue, "px"); | |||||
| } | |||||
| if (this.settings.orientation.includes('up') || this.settings.orientation.includes('down')) { | |||||
| // if orientation option is up or down | |||||
| // use vertical axe - Y axe | |||||
| translateValueY = "".concat(this.settings.orientation.includes('up') ? this.translateValue * -1 : this.translateValue, "px"); | |||||
| } // set style to apply to the element | |||||
| if (this.settings.overflow === false) { | |||||
| // if overflow option is set to false | |||||
| // add the scale style | |||||
| inlineCss = "translate3d(".concat(translateValueX, ", ").concat(translateValueY, ", 0) scale(").concat(this.settings.scale, ")"); | |||||
| } else { | |||||
| inlineCss = "translate3d(".concat(translateValueX, ", ").concat(translateValueY, ", 0)"); | |||||
| } // add style on the element using the adequate CSS transform | |||||
| this.element.style[helpers_cssTransform] = inlineCss; | |||||
| } | |||||
| }]); | |||||
| return ParallaxInstance; | |||||
| }(); | |||||
| /* harmony default export */ var parallax = (parallax_ParallaxInstance); | |||||
| // CONCATENATED MODULE: ./src/simpleParallax.js | |||||
| /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return simpleParallax_SimpleParallax; }); | |||||
| function simpleParallax_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | |||||
| function simpleParallax_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } | |||||
| function simpleParallax_createClass(Constructor, protoProps, staticProps) { if (protoProps) simpleParallax_defineProperties(Constructor.prototype, protoProps); if (staticProps) simpleParallax_defineProperties(Constructor, staticProps); return Constructor; } | |||||
| var intersectionObserverAvailable = true; | |||||
| var isInit = false; | |||||
| var instances = []; | |||||
| var instancesLength; | |||||
| var frameID; | |||||
| var resizeID; | |||||
| var simpleParallax_SimpleParallax = | |||||
| /*#__PURE__*/ | |||||
| function () { | |||||
| function SimpleParallax(elements, options) { | |||||
| simpleParallax_classCallCheck(this, SimpleParallax); | |||||
| if (!elements) return; | |||||
| this.elements = helpers_convertToArray(elements); | |||||
| this.defaults = { | |||||
| delay: 0.4, | |||||
| orientation: 'up', | |||||
| scale: 1.3, | |||||
| overflow: false, | |||||
| transition: 'cubic-bezier(0,0,0,1)', | |||||
| customContainer: false | |||||
| }; | |||||
| this.settings = Object.assign(this.defaults, options); // check if the browser handle the Intersection Observer API | |||||
| if (!('IntersectionObserver' in window)) intersectionObserverAvailable = false; | |||||
| if (this.settings.customContainer) { | |||||
| console.log(helpers_convertToArray(this.settings.customContainer)[0]); | |||||
| this.customContainer = helpers_convertToArray(this.settings.customContainer)[0]; | |||||
| } | |||||
| this.lastPosition = -1; | |||||
| this.resizeIsDone = this.resizeIsDone.bind(this); | |||||
| this.handleResize = this.handleResize.bind(this); | |||||
| this.proceedRequestAnimationFrame = this.proceedRequestAnimationFrame.bind(this); | |||||
| this.init(); | |||||
| } | |||||
| simpleParallax_createClass(SimpleParallax, [{ | |||||
| key: "init", | |||||
| value: function init() { | |||||
| viewport.setViewportAll(this.customContainer); | |||||
| for (var i = this.elements.length - 1; i >= 0; i--) { | |||||
| var instance = new parallax(this.elements[i], this.settings); | |||||
| instances.push(instance); | |||||
| } // update the instance length | |||||
| instancesLength = instances.length; // only if this is the first simpleParallax init | |||||
| if (!isInit) { | |||||
| // init the frame | |||||
| this.proceedRequestAnimationFrame(); | |||||
| window.addEventListener('resize', this.resizeIsDone); | |||||
| isInit = true; | |||||
| } | |||||
| } // wait for resize to be completely done | |||||
| }, { | |||||
| key: "resizeIsDone", | |||||
| value: function resizeIsDone() { | |||||
| clearTimeout(resizeID); | |||||
| resizeID = setTimeout(this.handleResize, 500); | |||||
| } // handle the resize process, some coordonates need to be re-calculate | |||||
| }, { | |||||
| key: "handleResize", | |||||
| value: function handleResize() { | |||||
| // re-get all the viewport positions | |||||
| viewport.setViewportAll(this.customContainer); | |||||
| for (var i = instancesLength - 1; i >= 0; i--) { | |||||
| // re-get the current element offset | |||||
| instances[i].getElementOffset(); // re-get the range if the current element | |||||
| instances[i].getRangeMax(); | |||||
| } // force the request animation frame to fired | |||||
| this.lastPosition = -1; | |||||
| } // animation frame | |||||
| }, { | |||||
| key: "proceedRequestAnimationFrame", | |||||
| value: function proceedRequestAnimationFrame() { | |||||
| // get the offset top of the viewport | |||||
| viewport.setViewportTop(this.customContainer); | |||||
| if (this.lastPosition === viewport.positions.top) { | |||||
| // if last position if the same than the curent one | |||||
| // callback the animationFrame and exit the current loop | |||||
| frameID = window.requestAnimationFrame(this.proceedRequestAnimationFrame); | |||||
| return; | |||||
| } // get the offset bottom of the viewport | |||||
| viewport.setViewportBottom(); // proceed with the current element | |||||
| for (var i = instancesLength - 1; i >= 0; i--) { | |||||
| this.proceedElement(instances[i]); | |||||
| } // callback the animationFrame | |||||
| frameID = window.requestAnimationFrame(this.proceedRequestAnimationFrame); // store the last position | |||||
| this.lastPosition = viewport.positions.top; | |||||
| } // proceed the element | |||||
| }, { | |||||
| key: "proceedElement", | |||||
| value: function proceedElement(instance) { | |||||
| var isVisible = false; // is not support for Intersection Observer API | |||||
| // or if this is a custom container | |||||
| // use old function to check if element visible | |||||
| if (!intersectionObserverAvailable || this.customContainer) { | |||||
| isVisible = instance.checkIfVisible(); // if support | |||||
| // use response from Intersection Observer API Callback | |||||
| } else { | |||||
| isVisible = instance.isVisible; | |||||
| } // if element not visible, stop it | |||||
| if (!isVisible) return; // if percentage is equal to the last one, no need to continue | |||||
| if (!instance.getTranslateValue()) { | |||||
| return; | |||||
| } // animate the image | |||||
| instance.animate(); | |||||
| } | |||||
| }, { | |||||
| key: "destroy", | |||||
| value: function destroy() { | |||||
| var _this = this; | |||||
| var instancesToDestroy = []; // remove all instances that need to be destroyed from the instances array | |||||
| instances = instances.filter(function (instance) { | |||||
| if (_this.elements.includes(instance.element)) { | |||||
| // push instance that need to be destroyed into instancesToDestroy | |||||
| instancesToDestroy.push(instance); | |||||
| return false; | |||||
| } | |||||
| return instance; | |||||
| }); | |||||
| for (var i = instancesToDestroy.length - 1; i >= 0; i--) { | |||||
| // unset style | |||||
| instancesToDestroy[i].unSetStyle(); | |||||
| if (this.settings.overflow === false) { | |||||
| // if overflow option is set to false | |||||
| // unwrap the element from .simpleParallax wrapper container | |||||
| instancesToDestroy[i].unWrapElement(); | |||||
| } | |||||
| } // update the instance length var | |||||
| instancesLength = instances.length; // if no instances left, remove the raf and resize event = simpleParallax fully destroyed | |||||
| if (!instancesLength) { | |||||
| // cancel the animation frame | |||||
| window.cancelAnimationFrame(frameID); // detach the resize event | |||||
| window.removeEventListener('resize', this.handleResize); | |||||
| } | |||||
| } | |||||
| }]); | |||||
| return SimpleParallax; | |||||
| }(); | |||||
| /***/ }) | |||||
| /******/ ])["default"]; | |||||
| }); | |||||
| @ -0,0 +1,15 @@ | |||||
| declare module 'simple-parallax-js' { | |||||
| interface IParallaxSettings { | |||||
| orientation?: 'up' | 'down' | 'left' | 'right'; | |||||
| scale?: number; | |||||
| overflow?: boolean; | |||||
| delay?: number; | |||||
| transition?: string; | |||||
| breakpoint?: number; | |||||
| } | |||||
| export default class SimpleParallax { | |||||
| constructor(images: Element | Element[], settings?: IParallaxSettings); | |||||
| public destroy: () => void; | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,217 @@ | |||||
| <!DOCTYPE html> | |||||
| <html lang="en"> | |||||
| <head> | |||||
| <meta charset="UTF-8" /> | |||||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |||||
| <meta http-equiv="X-UA-Compatible" content="ie=edge" /> | |||||
| <title>simpleParallax</title> | |||||
| <style> | |||||
| .container { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| flex-wrap: wrap; | |||||
| max-width: 900px; | |||||
| margin: 600px auto; | |||||
| /* max-height: 400px; | |||||
| overflow: auto; */ | |||||
| } | |||||
| .container > div { | |||||
| flex: 33%; | |||||
| } | |||||
| img { | |||||
| max-width: 100%; | |||||
| height: auto; | |||||
| } | |||||
| .simpleParallax { | |||||
| /* margin: 0 0 48px; */ | |||||
| } | |||||
| </style> | |||||
| </head> | |||||
| <body> | |||||
| <section class="container"> | |||||
| <div> | |||||
| <picture> | |||||
| <source media="(min-width: 650px)" srcset="https://simpleparallax.com/images/image03.jpg" /> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </picture> | |||||
| </div> | |||||
| <div> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </div> | |||||
| <div> | |||||
| <picture> | |||||
| <source media="(min-width: 650px)" srcset="https://simpleparallax.com/images/image03.jpg" /> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </picture> | |||||
| </div> | |||||
| <div> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </div> | |||||
| <div> | |||||
| <picture> | |||||
| <source media="(min-width: 650px)" srcset="https://simpleparallax.com/images/image03.jpg" /> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </picture> | |||||
| </div> | |||||
| <div> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </div> | |||||
| <div> | |||||
| <picture> | |||||
| <source media="(min-width: 650px)" srcset="https://simpleparallax.com/images/image03.jpg" /> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </picture> | |||||
| </div> | |||||
| <div> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </div> | |||||
| <div> | |||||
| <picture> | |||||
| <source media="(min-width: 650px)" srcset="https://simpleparallax.com/images/image03.jpg" /> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </picture> | |||||
| </div> | |||||
| <div> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </div> | |||||
| <div> | |||||
| <picture> | |||||
| <source media="(min-width: 650px)" srcset="https://simpleparallax.com/images/image03.jpg" /> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </picture> | |||||
| </div> | |||||
| <div> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </div> | |||||
| <div> | |||||
| <picture> | |||||
| <source media="(min-width: 650px)" srcset="https://simpleparallax.com/images/image03.jpg" /> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </picture> | |||||
| </div> | |||||
| <div> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </div> | |||||
| <div> | |||||
| <picture> | |||||
| <source media="(min-width: 650px)" srcset="https://simpleparallax.com/images/image03.jpg" /> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </picture> | |||||
| </div> | |||||
| <div> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </div> | |||||
| <div> | |||||
| <picture> | |||||
| <source media="(min-width: 650px)" srcset="https://simpleparallax.com/images/image03.jpg" /> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </picture> | |||||
| </div> | |||||
| <div> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </div> | |||||
| <div> | |||||
| <picture> | |||||
| <source media="(min-width: 650px)" srcset="https://simpleparallax.com/images/image03.jpg" /> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </picture> | |||||
| </div> | |||||
| <div> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </div> | |||||
| <div> | |||||
| <picture> | |||||
| <source media="(min-width: 650px)" srcset="https://simpleparallax.com/images/image03.jpg" /> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </picture> | |||||
| </div> | |||||
| <div> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </div> | |||||
| <div> | |||||
| <picture> | |||||
| <source media="(min-width: 650px)" srcset="https://simpleparallax.com/images/image03.jpg" /> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </picture> | |||||
| </div> | |||||
| <div> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </div> | |||||
| <div> | |||||
| <picture> | |||||
| <source media="(min-width: 650px)" srcset="https://simpleparallax.com/images/image03.jpg" /> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </picture> | |||||
| </div> | |||||
| <div> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </div> | |||||
| <div> | |||||
| <picture> | |||||
| <source media="(min-width: 650px)" srcset="https://simpleparallax.com/images/image03.jpg" /> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </picture> | |||||
| </div> | |||||
| <div> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </div> | |||||
| <div> | |||||
| <picture> | |||||
| <source media="(min-width: 650px)" srcset="https://simpleparallax.com/images/image03.jpg" /> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </picture> | |||||
| </div> | |||||
| <div> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </div> | |||||
| <div> | |||||
| <picture> | |||||
| <source media="(min-width: 650px)" srcset="https://simpleparallax.com/images/image03.jpg" /> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </picture> | |||||
| </div> | |||||
| <div> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </div> | |||||
| <div> | |||||
| <picture> | |||||
| <source media="(min-width: 650px)" srcset="https://simpleparallax.com/images/image03.jpg" /> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </picture> | |||||
| </div> | |||||
| <div> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </div> | |||||
| <div> | |||||
| <picture> | |||||
| <source media="(min-width: 650px)" srcset="https://simpleparallax.com/images/image03.jpg" /> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </picture> | |||||
| </div> | |||||
| <div> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </div> | |||||
| <div> | |||||
| <picture> | |||||
| <source media="(min-width: 650px)" srcset="https://simpleparallax.com/images/image03.jpg" /> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </picture> | |||||
| </div> | |||||
| <div> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </div> | |||||
| <div> | |||||
| <picture> | |||||
| <source media="(min-width: 650px)" srcset="https://simpleparallax.com/images/image03.jpg" /> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </picture> | |||||
| </div> | |||||
| <div> | |||||
| <img class="up" src="https://simpleparallax.com/images/image03.jpg" alt="simpleParallax image" /> | |||||
| </div> | |||||
| </section> | |||||
| </body> | |||||
| </html> | |||||
| @ -0,0 +1,69 @@ | |||||
| { | |||||
| "name": "simple-parallax-js", | |||||
| "version": "5.2.0", | |||||
| "description": "simpleParallax is a simple JavaScript library that gives your website parallax animations on any images", | |||||
| "homepage": "https://simpleparallax.com/", | |||||
| "main": "./dist/simpleParallax.min.js", | |||||
| "types": "./index.d.ts", | |||||
| "repository": { | |||||
| "type": "git", | |||||
| "url": "git+https://github.com/geosigno/simpleParallax.git" | |||||
| }, | |||||
| "keywords": [ | |||||
| "parallax", | |||||
| "javascript", | |||||
| "scroll", | |||||
| "simple", | |||||
| "easy", | |||||
| "fast", | |||||
| "light", | |||||
| "image", | |||||
| "effect", | |||||
| "vanilla", | |||||
| "es6" | |||||
| ], | |||||
| "author": "Geoffrey Signorato <geoffrey.signorato@gmail.com>", | |||||
| "license": "MIT", | |||||
| "scripts": { | |||||
| "start": "webpack-dev-server --mode development --open --port 3000 --hot", | |||||
| "build": "webpack --mode production", | |||||
| "format": "prettier --write '**/**.{js,json,html}'", | |||||
| "lint": "eslint src --ext .js --fix", | |||||
| "test": "jest" | |||||
| }, | |||||
| "husky": { | |||||
| "hooks": { | |||||
| "pre-commit": "lint-staged" | |||||
| } | |||||
| }, | |||||
| "lint-staged": { | |||||
| "**/**.{json,html}": [ | |||||
| "prettier --write", | |||||
| "git add" | |||||
| ] | |||||
| }, | |||||
| "bugs": { | |||||
| "url": "https://github.com/geosigno/simpleParallax/issues" | |||||
| }, | |||||
| "dependencies": { | |||||
| "html-webpack-plugin": "^3.2.0", | |||||
| "webpack": "^4.41.2", | |||||
| "webpack-dev-server": "^3.9.0" | |||||
| }, | |||||
| "devDependencies": { | |||||
| "@babel/core": "^7.7.4", | |||||
| "@babel/preset-env": "^7.7.4", | |||||
| "babel-loader": "^8.0.6", | |||||
| "eslint": "^6.7.2", | |||||
| "eslint-config-airbnb-base": "^14.0.0", | |||||
| "eslint-plugin-import": "^2.18.2", | |||||
| "eslint-plugin-node": "^10.0.0", | |||||
| "husky": "^3.1.0", | |||||
| "jest": "^24.9.0", | |||||
| "lint-staged": "^9.5.0", | |||||
| "moment": "^2.24.0", | |||||
| "prettier": "^1.19.1", | |||||
| "uglifyjs-webpack-plugin": "^2.2.0", | |||||
| "webpack-cli": "^3.3.10" | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,9 @@ | |||||
| // check wether the element is a Node List, a HTML Collection or an array | |||||
| // return an array of nodes | |||||
| const convertToArray = (elements) => { | |||||
| if (NodeList.prototype.isPrototypeOf(elements) || HTMLCollection.prototype.isPrototypeOf(elements)) return Array.from(elements); | |||||
| if (typeof elements === 'string' || elements instanceof String) return document.querySelectorAll(elements); | |||||
| return [elements]; | |||||
| }; | |||||
| export default convertToArray; | |||||
| @ -0,0 +1,13 @@ | |||||
| // Detect css transform | |||||
| const cssTransform = () => { | |||||
| const prefixes = 'transform webkitTransform mozTransform oTransform msTransform'.split(' '); | |||||
| let transform; | |||||
| let i = 0; | |||||
| while (transform === undefined) { | |||||
| transform = document.createElement('div').style[prefixes[i]] !== undefined ? prefixes[i] : undefined; | |||||
| i += 1; | |||||
| } | |||||
| return transform; | |||||
| }; | |||||
| export default cssTransform(); | |||||
| @ -0,0 +1,21 @@ | |||||
| // check if image is fully loaded | |||||
| const isImageLoaded = (image) => { | |||||
| // check if image is set as the parameter | |||||
| if (!image) { | |||||
| return false; | |||||
| } | |||||
| // check if image has been 100% loaded | |||||
| if (!image.complete) { | |||||
| return false; | |||||
| } | |||||
| // check if the image is displayed | |||||
| if (typeof image.naturalWidth !== 'undefined' && image.naturalWidth === 0) { | |||||
| return false; | |||||
| } | |||||
| return true; | |||||
| }; | |||||
| export default isImageLoaded; | |||||
| @ -0,0 +1,33 @@ | |||||
| class Viewport { | |||||
| constructor() { | |||||
| this.positions = { | |||||
| top: 0, | |||||
| bottom: 0, | |||||
| height: 0, | |||||
| }; | |||||
| } | |||||
| setViewportTop(container) { | |||||
| // if this is a custom container, user the scrollTop | |||||
| this.positions.top = (container ? container.scrollTop : window.pageYOffset); | |||||
| return this.positions; | |||||
| } | |||||
| setViewportBottom() { | |||||
| this.positions.bottom = this.positions.top + this.positions.height; | |||||
| return this.positions; | |||||
| } | |||||
| setViewportAll(container) { | |||||
| // if this is a custom container, user the scrollTop | |||||
| this.positions.top = (container ? container.scrollTop : window.pageYOffset); | |||||
| // if this is a custom container, get the height from the custom container itself | |||||
| this.positions.height = (container ? container.clientHeight : document.documentElement.clientHeight); | |||||
| this.positions.bottom = this.positions.top + this.positions.height; | |||||
| return this.positions; | |||||
| } | |||||
| } | |||||
| export const viewport = new Viewport(); | |||||
| export { viewport as default }; | |||||
| @ -0,0 +1,249 @@ | |||||
| import cssTransform from '../helpers/cssTransform'; | |||||
| import isImageLoaded from '../helpers/isImageLoaded'; | |||||
| import { viewport } from '../helpers/viewport'; | |||||
| class ParallaxInstance { | |||||
| constructor(element, options) { | |||||
| // set the element & settings | |||||
| this.element = element; | |||||
| this.elementContainer = element; | |||||
| this.settings = options; | |||||
| this.isVisible = true; | |||||
| this.isInit = false; | |||||
| this.oldTranslateValue = -1; | |||||
| this.init = this.init.bind(this); | |||||
| // check if images has not been loaded yet | |||||
| if (isImageLoaded(element)) { | |||||
| this.init(); | |||||
| } else { | |||||
| this.element.addEventListener('load', this.init); | |||||
| } | |||||
| } | |||||
| init() { | |||||
| // for some reason, <picture> are init an infinite time on windows OS | |||||
| if (this.isInit) return; | |||||
| // check if element has not been already initialized with simpleParallax | |||||
| if (this.element.closest('.simpleParallax')) return; | |||||
| if (this.settings.overflow === false) { | |||||
| // if overflow option is set to false | |||||
| // wrap the element into a div to apply overflow | |||||
| this.wrapElement(this.element); | |||||
| } | |||||
| // apply the transform style on the image | |||||
| this.setTransformCSS(); | |||||
| // get the current element offset | |||||
| this.getElementOffset(); | |||||
| // init the Intesection Observer | |||||
| this.intersectionObserver(); | |||||
| // get its translated value | |||||
| this.getTranslateValue(); | |||||
| // apply its translation even if not visible for the first init | |||||
| this.animate(); | |||||
| // if a delay has been set | |||||
| if (this.settings.delay > 0) { | |||||
| // apply a timeout to avoid buggy effect | |||||
| setTimeout(() => { | |||||
| // apply the transition style on the image | |||||
| this.setTransitionCSS(); | |||||
| }, 10); | |||||
| } | |||||
| // for some reason, <picture> are init an infinite time on windows OS | |||||
| this.isInit = true; | |||||
| } | |||||
| // if overflow option is set to false | |||||
| // wrap the element into a .simpleParallax div and apply overflow hidden to hide the image excedant (result of the scale) | |||||
| wrapElement() { | |||||
| // check is current image is in a <picture> tag | |||||
| const elementToWrap = this.element.closest('picture') || this.element; | |||||
| // create a .simpleParallax wrapper container | |||||
| const wrapper = document.createElement('div'); | |||||
| wrapper.classList.add('simpleParallax'); | |||||
| wrapper.style.overflow = 'hidden'; | |||||
| // append the image inside the new wrapper | |||||
| elementToWrap.parentNode.insertBefore(wrapper, elementToWrap); | |||||
| wrapper.appendChild(elementToWrap); | |||||
| this.elementContainer = wrapper; | |||||
| } | |||||
| // unwrap the element from .simpleParallax wrapper container | |||||
| unWrapElement() { | |||||
| const wrapper = this.elementContainer; | |||||
| wrapper.replaceWith(...wrapper.childNodes); | |||||
| } | |||||
| // apply default style on element | |||||
| setTransformCSS() { | |||||
| if (this.settings.overflow === false) { | |||||
| // if overflow option is set to false | |||||
| // add scale style so the image can be translated without getting out of its container | |||||
| this.element.style[cssTransform] = `scale(${this.settings.scale})`; | |||||
| } | |||||
| // add will-change CSS property to improve perfomance | |||||
| this.element.style.willChange = 'transform'; | |||||
| } | |||||
| // apply the transition effet | |||||
| setTransitionCSS() { | |||||
| // add transition option | |||||
| this.element.style.transition = `transform ${this.settings.delay}s ${this.settings.transition}`; | |||||
| } | |||||
| // remove style of the element | |||||
| unSetStyle() { | |||||
| // remove will change inline style | |||||
| this.element.style.willChange = ''; | |||||
| this.element.style[cssTransform] = ''; | |||||
| this.element.style.transition = ''; | |||||
| } | |||||
| // get the current element offset | |||||
| getElementOffset() { | |||||
| // get position of the element | |||||
| const positions = this.elementContainer.getBoundingClientRect(); | |||||
| // get height | |||||
| this.elementHeight = positions.height; | |||||
| // get offset top | |||||
| this.elementTop = positions.top + viewport.positions.top; | |||||
| // if there is a custom container | |||||
| if (this.settings.customContainer) { | |||||
| // we need to do some calculation to get the position from the parent rather than the viewport | |||||
| const parentPositions = this.settings.customContainer.getBoundingClientRect(); | |||||
| this.elementTop = (positions.top - parentPositions.top) + viewport.positions.top; | |||||
| } | |||||
| // get offset bottom | |||||
| this.elementBottom = this.elementHeight + this.elementTop; | |||||
| } | |||||
| // build the Threshold array to cater change for every pixel scrolled | |||||
| buildThresholdList() { | |||||
| const thresholds = []; | |||||
| for (let i = 1.0; i <= this.elementHeight; i++) { | |||||
| const ratio = i / this.elementHeight; | |||||
| thresholds.push(ratio); | |||||
| } | |||||
| return thresholds; | |||||
| } | |||||
| // create the Intersection Observer | |||||
| intersectionObserver() { | |||||
| const options = { | |||||
| root: null, | |||||
| threshold: this.buildThresholdList(), | |||||
| }; | |||||
| this.observer = new IntersectionObserver(this.intersectionObserverCallback.bind(this), options); | |||||
| this.observer.observe(this.element); | |||||
| } | |||||
| // Intersection Observer Callback to set the element at visible state or not | |||||
| intersectionObserverCallback(entries) { | |||||
| for (let i = entries.length - 1; i >= 0; i--) { | |||||
| if (entries[i].isIntersecting) { | |||||
| this.isVisible = true; | |||||
| } else { | |||||
| this.isVisible = false; | |||||
| } | |||||
| } | |||||
| } | |||||
| // check if the current element is visible in the Viewport | |||||
| // for browser that not support Intersection Observer API | |||||
| checkIfVisible() { | |||||
| return this.elementBottom > viewport.positions.top && this.elementTop < viewport.positions.bottom; | |||||
| } | |||||
| // calculate the range between image will be translated | |||||
| getRangeMax() { | |||||
| // get the real height of the image without scale | |||||
| const elementImageHeight = this.element.clientHeight; | |||||
| // range is calculate with the image height by the scale | |||||
| this.rangeMax = elementImageHeight * this.settings.scale - elementImageHeight; | |||||
| } | |||||
| // get the percentage and the translate value to apply on the element | |||||
| getTranslateValue() { | |||||
| // calculate the % position of the element comparing to the viewport | |||||
| // rounding percentage to a 1 number float to avoid unn unnecessary calculation | |||||
| let percentage = ((viewport.positions.bottom - this.elementTop) / ((viewport.positions.height + this.elementHeight) / 100)).toFixed(1); | |||||
| // sometime the percentage exceeds 100 or goes below 0 | |||||
| percentage = Math.min(100, Math.max(0, percentage)); | |||||
| // sometime the same percentage is returned | |||||
| // if so we don't do aything | |||||
| if (this.oldPercentage === percentage) { | |||||
| return false; | |||||
| } | |||||
| // if not range max is set, recalculate it | |||||
| if (!this.rangeMax) { | |||||
| this.getRangeMax(); | |||||
| } | |||||
| // transform this % into the max range of the element | |||||
| // rounding translateValue to a non float int - as minimum pixel for browser to render is 1 (no 0.5) | |||||
| this.translateValue = ((percentage / 100) * this.rangeMax - this.rangeMax / 2).toFixed(0); | |||||
| // sometime the same translate value is returned | |||||
| // if so we don't do aything | |||||
| if (this.oldTranslateValue === this.translateValue) { | |||||
| return false; | |||||
| } | |||||
| // store the current percentage | |||||
| this.oldPercentage = percentage; | |||||
| this.oldTranslateValue = this.translateValue; | |||||
| return true; | |||||
| } | |||||
| // animate the image | |||||
| animate() { | |||||
| let translateValueY = 0; | |||||
| let translateValueX = 0; | |||||
| let inlineCss; | |||||
| if (this.settings.orientation.includes('left') || this.settings.orientation.includes('right')) { | |||||
| // if orientation option is left or right | |||||
| // use horizontal axe - X axe | |||||
| translateValueX = `${this.settings.orientation.includes('left') ? this.translateValue * -1 : this.translateValue}px`; | |||||
| } | |||||
| if (this.settings.orientation.includes('up') || this.settings.orientation.includes('down')) { | |||||
| // if orientation option is up or down | |||||
| // use vertical axe - Y axe | |||||
| translateValueY = `${this.settings.orientation.includes('up') ? this.translateValue * -1 : this.translateValue}px`; | |||||
| } | |||||
| // set style to apply to the element | |||||
| if (this.settings.overflow === false) { | |||||
| // if overflow option is set to false | |||||
| // add the scale style | |||||
| inlineCss = `translate3d(${translateValueX}, ${translateValueY}, 0) scale(${this.settings.scale})`; | |||||
| } else { | |||||
| inlineCss = `translate3d(${translateValueX}, ${translateValueY}, 0)`; | |||||
| } | |||||
| // add style on the element using the adequate CSS transform | |||||
| this.element.style[cssTransform] = inlineCss; | |||||
| } | |||||
| } | |||||
| export default ParallaxInstance; | |||||
| @ -0,0 +1,181 @@ | |||||
| import { viewport } from './helpers/viewport'; | |||||
| import convertToArray from './helpers/convertToArray'; | |||||
| import ParallaxInstance from './instances/parallax'; | |||||
| let intersectionObserverAvailable = true; | |||||
| let isInit = false; | |||||
| let instances = []; | |||||
| let instancesLength; | |||||
| let frameID; | |||||
| let resizeID; | |||||
| export default class SimpleParallax { | |||||
| constructor(elements, options) { | |||||
| if (!elements) return; | |||||
| this.elements = convertToArray(elements); | |||||
| this.defaults = { | |||||
| delay: 0.4, | |||||
| orientation: 'up', | |||||
| scale: 1.3, | |||||
| overflow: false, | |||||
| transition: 'cubic-bezier(0,0,0,1)', | |||||
| customContainer: false, | |||||
| }; | |||||
| this.settings = Object.assign(this.defaults, options); | |||||
| // check if the browser handle the Intersection Observer API | |||||
| if (!('IntersectionObserver' in window)) intersectionObserverAvailable = false; | |||||
| if (this.settings.customContainer) { | |||||
| console.log(convertToArray(this.settings.customContainer)[0]) | |||||
| this.customContainer = convertToArray(this.settings.customContainer)[0]; | |||||
| } | |||||
| this.lastPosition = -1; | |||||
| this.resizeIsDone = this.resizeIsDone.bind(this); | |||||
| this.handleResize = this.handleResize.bind(this); | |||||
| this.proceedRequestAnimationFrame = this.proceedRequestAnimationFrame.bind(this); | |||||
| this.init(); | |||||
| } | |||||
| init() { | |||||
| viewport.setViewportAll(this.customContainer); | |||||
| for (let i = this.elements.length - 1; i >= 0; i--) { | |||||
| const instance = new ParallaxInstance(this.elements[i], this.settings); | |||||
| instances.push(instance); | |||||
| } | |||||
| // update the instance length | |||||
| instancesLength = instances.length; | |||||
| // only if this is the first simpleParallax init | |||||
| if (!isInit) { | |||||
| // init the frame | |||||
| this.proceedRequestAnimationFrame(); | |||||
| window.addEventListener('resize', this.resizeIsDone); | |||||
| isInit = true; | |||||
| } | |||||
| } | |||||
| // wait for resize to be completely done | |||||
| resizeIsDone() { | |||||
| clearTimeout(resizeID); | |||||
| resizeID = setTimeout(this.handleResize, 500); | |||||
| } | |||||
| // handle the resize process, some coordonates need to be re-calculate | |||||
| handleResize() { | |||||
| // re-get all the viewport positions | |||||
| viewport.setViewportAll(this.customContainer); | |||||
| for (let i = instancesLength - 1; i >= 0; i--) { | |||||
| // re-get the current element offset | |||||
| instances[i].getElementOffset(); | |||||
| // re-get the range if the current element | |||||
| instances[i].getRangeMax(); | |||||
| } | |||||
| // force the request animation frame to fired | |||||
| this.lastPosition = -1; | |||||
| } | |||||
| // animation frame | |||||
| proceedRequestAnimationFrame() { | |||||
| // get the offset top of the viewport | |||||
| viewport.setViewportTop(this.customContainer); | |||||
| if (this.lastPosition === viewport.positions.top) { | |||||
| // if last position if the same than the curent one | |||||
| // callback the animationFrame and exit the current loop | |||||
| frameID = window.requestAnimationFrame(this.proceedRequestAnimationFrame); | |||||
| return; | |||||
| } | |||||
| // get the offset bottom of the viewport | |||||
| viewport.setViewportBottom(); | |||||
| // proceed with the current element | |||||
| for (let i = instancesLength - 1; i >= 0; i--) { | |||||
| this.proceedElement(instances[i]); | |||||
| } | |||||
| // callback the animationFrame | |||||
| frameID = window.requestAnimationFrame(this.proceedRequestAnimationFrame); | |||||
| // store the last position | |||||
| this.lastPosition = viewport.positions.top; | |||||
| } | |||||
| // proceed the element | |||||
| proceedElement(instance) { | |||||
| let isVisible = false; | |||||
| // is not support for Intersection Observer API | |||||
| // or if this is a custom container | |||||
| // use old function to check if element visible | |||||
| if (!intersectionObserverAvailable || this.customContainer) { | |||||
| isVisible = instance.checkIfVisible(); | |||||
| // if support | |||||
| // use response from Intersection Observer API Callback | |||||
| } else { | |||||
| isVisible = instance.isVisible; | |||||
| } | |||||
| // if element not visible, stop it | |||||
| if (!isVisible) return; | |||||
| // if percentage is equal to the last one, no need to continue | |||||
| if (!instance.getTranslateValue()) { | |||||
| return; | |||||
| } | |||||
| // animate the image | |||||
| instance.animate(); | |||||
| } | |||||
| destroy() { | |||||
| const instancesToDestroy = []; | |||||
| // remove all instances that need to be destroyed from the instances array | |||||
| instances = instances.filter((instance) => { | |||||
| if (this.elements.includes(instance.element)) { | |||||
| // push instance that need to be destroyed into instancesToDestroy | |||||
| instancesToDestroy.push(instance); | |||||
| return false; | |||||
| } | |||||
| return instance; | |||||
| }); | |||||
| for (let i = instancesToDestroy.length - 1; i >= 0; i--) { | |||||
| // unset style | |||||
| instancesToDestroy[i].unSetStyle(); | |||||
| if (this.settings.overflow === false) { | |||||
| // if overflow option is set to false | |||||
| // unwrap the element from .simpleParallax wrapper container | |||||
| instancesToDestroy[i].unWrapElement(); | |||||
| } | |||||
| } | |||||
| // update the instance length var | |||||
| instancesLength = instances.length; | |||||
| // if no instances left, remove the raf and resize event = simpleParallax fully destroyed | |||||
| if (!instancesLength) { | |||||
| // cancel the animation frame | |||||
| window.cancelAnimationFrame(frameID); | |||||
| // detach the resize event | |||||
| window.removeEventListener('resize', this.handleResize); | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,63 @@ | |||||
| import SimpleParallax from '../src/simpleParallax'; | |||||
| // let images = document.querySelectorAll('img'), | |||||
| // instance; | |||||
| let instanceUp; | |||||
| const optionUp = { | |||||
| orientation: 'left', | |||||
| // customContainer: document.querySelector('.container') | |||||
| }; | |||||
| const imageUp = document.getElementsByTagName('img'); | |||||
| const images = document.querySelectorAll('img'); | |||||
| images.forEach((image) => { | |||||
| new SimpleParallax(image, optionUp); | |||||
| }); | |||||
| // instanceUp = new SimpleParallax('img', optionUp); | |||||
| // let instanceDown, | |||||
| // optionDown = { | |||||
| // orientation: 'down' | |||||
| // }, | |||||
| // imageDown = document.querySelectorAll('img.down'); | |||||
| // instanceDown = new SimpleParallax(imageDown, optionDown); | |||||
| // setTimeout(() => { | |||||
| // instanceDown.destroy(); | |||||
| // }, 3000); | |||||
| // setTimeout(() => { | |||||
| // instanceDown.destroy(); | |||||
| // }, 6000); | |||||
| // images.forEach(image => { | |||||
| // let options = { | |||||
| // breakpoint: '480' | |||||
| // // orientation: 'down', | |||||
| // // scale: 1.5, | |||||
| // // overflow: true | |||||
| // }; | |||||
| // if (image.classList.contains('up')) { | |||||
| // options.orientation = 'up'; | |||||
| // } | |||||
| // if (image.classList.contains('down')) { | |||||
| // options.orientation = 'down'; | |||||
| // } | |||||
| // if (image.classList.contains('right')) { | |||||
| // options.orientation = 'right'; | |||||
| // } | |||||
| // if (image.classList.contains('left')) { | |||||
| // options.orientation = 'left'; | |||||
| // } | |||||
| // // console.log(options); | |||||
| // instance = new SimpleParallax(image, options); | |||||
| // // console.log(instance); | |||||
| // }); | |||||
| // setTimeout(() => { | |||||
| // instance.destroy(); | |||||
| // }, 3000); | |||||
| @ -0,0 +1,58 @@ | |||||
| const path = require('path'); | |||||
| const webpack = require('webpack'); | |||||
| const HtmlWebPackPlugin = require('html-webpack-plugin'); | |||||
| const moment = require('moment'); | |||||
| const now = moment().format('DD-MM-YYYY H:m:s'); | |||||
| const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); | |||||
| const PACKAGE = require('./package.json'), | |||||
| version = PACKAGE.version, | |||||
| description = PACKAGE.description, | |||||
| homepage = PACKAGE.homepage; | |||||
| const htmlPlugin = new HtmlWebPackPlugin({ | |||||
| template: './index.html', | |||||
| filename: './index.html' | |||||
| }); | |||||
| const BannerPlugin = new webpack.BannerPlugin({ | |||||
| banner: `[name] - ${description}, | |||||
| @date: ${now}, | |||||
| @version: ${version}, | |||||
| @link: ${homepage}` | |||||
| }); | |||||
| module.exports = { | |||||
| entry: { | |||||
| simpleParallax: './src/simpleParallax.js', | |||||
| 'simpleParallax.min': './src/simpleParallax.js', | |||||
| index: './test/index.js' | |||||
| }, | |||||
| output: { | |||||
| path: path.resolve(__dirname, 'dist'), | |||||
| filename: '[name].js', | |||||
| library: 'simpleParallax', | |||||
| libraryTarget: 'umd', | |||||
| umdNamedDefine: true, | |||||
| libraryExport: 'default' | |||||
| }, | |||||
| optimization: { | |||||
| minimize: true, | |||||
| minimizer: [ | |||||
| new UglifyJsPlugin({ | |||||
| include: /\.min\.js$/ | |||||
| }) | |||||
| ] | |||||
| }, | |||||
| module: { | |||||
| rules: [ | |||||
| { | |||||
| test: /\.js$/, | |||||
| exclude: /node_modules/, | |||||
| use: ['babel-loader'] | |||||
| } | |||||
| ] | |||||
| }, | |||||
| plugins: [htmlPlugin, BannerPlugin] | |||||
| }; | |||||