Wedding Invitation
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

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