Wedding Invitation
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

app.js 7.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. import './bootstrap';
  2. //import 'resources/js/app.js';
  3. import '@fortawesome/fontawesome-free/css/all.min.css';
  4. document.addEventListener('DOMContentLoaded', function () {
  5. imageLoading()
  6. scrollOpenCover();
  7. reset() // reset everrything to ensure smooth
  8. sessionStorage.setItem("initial-load", "true"); // will be used by click event
  9. });
  10. document.addEventListener('click', function () {
  11. let initLoad = sessionStorage.getItem("initial-load")
  12. let pointer = document.getElementById("pointer")
  13. pointer.remove()
  14. // parts is intro cover
  15. let parts = document.getElementsByClassName("part");
  16. for (let part of parts) {
  17. part.classList.add("shadow-lg")
  18. }
  19. // the intro - only done once and
  20. if (initLoad == "true") {
  21. playMusic();
  22. let leftCover = document.querySelector(".dummy-cover .left-dummy");
  23. let rightCover = document.querySelector(".dummy-cover .right-dummy");
  24. leftCover.classList.add("to-left-animation")
  25. rightCover.classList.add("to-right-animation")
  26. setTimeout(()=>{
  27. //dummy-cover
  28. let parts = document.querySelectorAll(".dummy-cover .part");
  29. for (let part of parts) {
  30. part.remove("hidden")
  31. }
  32. let body = document.querySelector("body");
  33. body.classList.remove("no-scroll");
  34. },2500)
  35. sessionStorage.removeItem("initial-load")
  36. }
  37. setTimeout(() => {
  38. eventCountdown();
  39. let petalOverlay = document.getElementById("petalOverlay");
  40. petalOverlay.classList.remove("hidden");
  41. }, 2000)
  42. });
  43. // to ensure all images is loaded before starting animation and gimmick
  44. function imageLoading() {
  45. const images = document.querySelectorAll("img");
  46. let loadedCount = 0;
  47. const totalImages = images.length;
  48. images.forEach(image => {
  49. if (image.complete) {
  50. loadedCount++;
  51. } else {
  52. image.addEventListener("load", () => {
  53. loadedCount++;
  54. checkAllImagesLoaded();
  55. });
  56. image.addEventListener("error", () => {
  57. loadedCount++;
  58. checkAllImagesLoaded();
  59. });
  60. }
  61. });
  62. function checkAllImagesLoaded() {
  63. if (loadedCount === totalImages) {
  64. let loading = document.getElementById("loading");
  65. loading.remove();
  66. // parts is intro cover
  67. let parts = document.getElementsByClassName("part");
  68. for (let part of parts) {
  69. part.classList.remove("hidden")
  70. }
  71. let pointer = document.getElementById("pointer")
  72. setTimeout(() => {
  73. pointer.classList.remove("hidden")
  74. }, 1500);
  75. }
  76. }
  77. //somehow the server work so fast, script doesn't have much time to set the load eventlistener
  78. //thus we check here, to ensure checkAllImagesLoaded run
  79. checkAllImagesLoaded();
  80. }
  81. // enable open close cover
  82. function scrollOpenCover() {
  83. var partLeftPos = 0;
  84. var partRightPos = 0;
  85. function updatePositions() {
  86. var distance = $(window).scrollTop() * 2;
  87. var left = partLeftPos - distance;
  88. var right = partRightPos - distance;
  89. $('.left').css('left', left + "px");
  90. $('.right').css('right', right + "px");
  91. //Calculate boundaries
  92. var leftPartRightEdge = $('.left').offset().left + $('.left').outerWidth();
  93. //Check if both parts are completely off-screen
  94. var isLeftOffScreen = leftPartRightEdge <= 0;
  95. //Toggle visibility and z-index
  96. if (isLeftOffScreen && left < 0) {
  97. $('.parent').removeClass('z-30');
  98. } else {
  99. $('.parent').addClass('z-30');
  100. }
  101. }
  102. //Initial positions update
  103. updatePositions();
  104. //Listen to scroll events using requestAnimationFrame for smooth animation
  105. var ticking = false;
  106. $(window).scroll(function () {
  107. if (!ticking) {
  108. window.requestAnimationFrame(function () {
  109. updatePositions();
  110. ticking = false;
  111. });
  112. }
  113. ticking = true;
  114. });
  115. }
  116. function reset() {
  117. // reset to top
  118. let body = document.querySelector("body");
  119. window.scrollTo(0, document.body.scrollHeight * 0.05);
  120. body.classList.add("no-scroll");
  121. }
  122. function playMusic() {
  123. var audioElement = document.getElementById('player');
  124. var hasPlayed = false;
  125. if (!hasPlayed) {
  126. console.log('play')
  127. var playPromise = audioElement.play();
  128. if (playPromise !== undefined) {
  129. playPromise.then(function () {
  130. // Automatic playback started!
  131. hasPlayed = true; // Prevent further attempts to play
  132. }).catch(function (error) {
  133. // Automatic playback failed.
  134. console.log('Autoplay failed: ' + error);
  135. });
  136. }
  137. }
  138. }
  139. function eventCountdown() {
  140. //Countdown date (adjust this date to your desired countdown target)
  141. const countdownDate = new Date('2024-08-17T11:00:00').getTime();
  142. //Update the countdown every second
  143. const countdownElement = document.getElementById('countdown');
  144. const countdownTimer = setInterval(() => {
  145. //Get the current date and time
  146. const now = new Date().getTime();
  147. //Calculate the time remaining
  148. const distance = countdownDate - now;
  149. //Calculate days, hours, minutes, and seconds
  150. const days = Math.floor(distance / (1000 * 60 * 60 * 24));
  151. const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
  152. const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
  153. const seconds = Math.floor((distance % (1000 * 60)) / 1000);
  154. //Format the countdown into a string
  155. const countdownHTML = `
  156. <div class="flex flex-col">
  157. <div class="flex gap-8 justify-center">
  158. <div class="font-medium text-gray-500">${days}</div>
  159. <div class="font-medium text-gray-500">:</div>
  160. <div class="font-medium text-gray-500">${hours.toString().padStart(2, '0')}</div>
  161. <div class="font-medium text-gray-500">:</div>
  162. <div class="font-medium text-gray-500">${minutes.toString().padStart(2, '0')}</div>
  163. <div class="font-medium text-gray-500">:</div>
  164. <div class="font-medium text-gray-500">${seconds.toString().padStart(2, '0')}</div>
  165. </div>
  166. <div class="flex gap-14 justify-center">
  167. <div class="font-medium text-gray-600">Hari</div>
  168. <div class="font-medium text-gray-600">Jam</div>
  169. <div class="font-medium text-gray-600">Minit</div>
  170. <div class="font-medium text-gray-600">Saat</div>
  171. </div>
  172. </div>
  173. `;
  174. //Display the countdown in the element
  175. countdownElement.innerHTML = countdownHTML;
  176. //If the countdown is over, clear the timer and display a message
  177. if (distance < 0) {
  178. clearInterval(countdownTimer);
  179. countdownElement.innerHTML = 'Majlis berlangsung';
  180. }
  181. }, 1000); // Update every second (1000 milliseconds)
  182. }
  183. const observerOptions = {
  184. root: null,
  185. rootMargin: '0px',
  186. threshold: 0.1
  187. };
  188. const observer = new IntersectionObserver((entries, observer) => {
  189. entries.forEach(entry => {
  190. if (entry.isIntersecting) {
  191. entry.target.classList.add('fade-in');
  192. observer.unobserve(entry.target);
  193. }
  194. });
  195. }, observerOptions);
  196. document.querySelectorAll('.fade-element').forEach(element => {
  197. observer.observe(element);
  198. });