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.8KB

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