about.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // About page hero — vanilla fade-carousel (replaces Bootstrap Carousel).
  2. (function () {
  3. const caro = document.getElementById('caro-lead');
  4. const tv = document.getElementById('tv'); // full-bleed grayscale bg video
  5. if (tv) { try { tv.play(); } catch (e) {} }
  6. if (!caro) return;
  7. const slides = Array.from(caro.querySelectorAll('.dw-fade-slide'));
  8. const dots = Array.from(caro.querySelectorAll('.dw-fade-dot'));
  9. const INTERVAL = 5000;
  10. let index = 0;
  11. let timer = null;
  12. // The brain slide's #brain SVG ships with .hide-svg; reveal + line-draw it.
  13. function drawBrain(slide) {
  14. const brain = slide.querySelector('#brain');
  15. if (!brain || !window.DrawFillSVG) return;
  16. window.setTimeout(function () {
  17. brain.classList.remove('hide-svg', 'fade-svg');
  18. try { new window.DrawFillSVG({ elementId: 'brain' }).replay(); } catch (e) {}
  19. }, 600);
  20. }
  21. function activate(i) {
  22. i = Math.max(0, Math.min(slides.length - 1, i)); // wrap:false → clamp
  23. index = i;
  24. slides.forEach((s, n) => s.classList.toggle('active', n === i));
  25. dots.forEach((d, n) => d.classList.toggle('active', n === i));
  26. drawBrain(slides[i]);
  27. }
  28. function next() {
  29. if (index >= slides.length - 1) { stop(); return; } // wrap:false — stop at end
  30. activate(index + 1);
  31. }
  32. function start() { stop(); timer = window.setInterval(next, INTERVAL); }
  33. function stop() { if (timer) { window.clearInterval(timer); timer = null; } }
  34. dots.forEach(function (d) {
  35. d.addEventListener('click', function (e) {
  36. e.preventDefault();
  37. activate(parseInt(d.dataset.slide, 10) || 0);
  38. start();
  39. });
  40. });
  41. document.addEventListener('keyup', function (e) {
  42. if (e.key === 'ArrowRight') activate(index + 1);
  43. else if (e.key === 'ArrowLeft') activate(index - 1);
  44. });
  45. caro.addEventListener('mouseenter', stop);
  46. caro.addEventListener('mouseleave', start);
  47. activate(0);
  48. start();
  49. })();
  50. // navbar hide/show on scroll (ported from jQuery dw_hidenav)
  51. (function () {
  52. const navbar = document.querySelector('.navbar');
  53. if (!navbar) return;
  54. const title = document.querySelector('.site-title a');
  55. const headerHeight = navbar.offsetHeight;
  56. let previousTop = 0;
  57. window.addEventListener('scroll', function () {
  58. const currentTop = window.scrollY;
  59. if (currentTop < previousTop) {
  60. if (currentTop > 0 && navbar.classList.contains('fixed')) {
  61. navbar.classList.add('visible');
  62. if (title) title.classList.remove('light');
  63. } else {
  64. navbar.classList.remove('visible', 'fixed');
  65. if (title) title.classList.add('light');
  66. }
  67. } else {
  68. navbar.classList.remove('visible');
  69. if (currentTop > headerHeight && !navbar.classList.contains('fixed')) {
  70. navbar.classList.add('fixed');
  71. }
  72. }
  73. previousTop = currentTop;
  74. }, { passive: true });
  75. })();
  76. document.querySelectorAll('.nav-toggle').forEach(function (el) {
  77. el.addEventListener('click', function (e) {
  78. e.preventDefault();
  79. el.classList.toggle('active');
  80. });
  81. });
  82. // Comment-form validation (jquery-validation) + FullCalendar still use jQuery.
  83. jQuery(document).ready(function ($) {
  84. $('#commentform').validate({
  85. rules: {
  86. author: { required: true, minlength: 2 },
  87. email: { required: true, email: true },
  88. comment: { required: true, minlength: 3 }
  89. },
  90. messages: {
  91. author: 'Please enter in your name.',
  92. email: 'Please enter a valid email address.',
  93. comment: 'Nothing to Say?'
  94. },
  95. errorElement: 'div',
  96. errorPlacement: function (error, element) {
  97. element.before(error);
  98. }
  99. });
  100. var calendarEl = document.getElementById('calendar');
  101. if (calendarEl) {
  102. var calendar = new FullCalendar.Calendar(calendarEl, {
  103. headerToolbar: { start: 'title', center: '', end: 'prev,next' },
  104. firstDay: 1,
  105. height: 380,
  106. views: {
  107. dayGrid: { hiddenDays: [0, 6, 7] },
  108. timeGrid: {
  109. slotMinTime: '08:00:00',
  110. slotMaxTime: '17:00:00',
  111. dayHeaderFormat: { weekday: 'short' },
  112. hiddenDays: [0, 6, 7]
  113. }
  114. },
  115. googleCalendarApiKey: 'AIzaSyAGowGJYx6dOaQvG_vSUI73uT88VWOTcNQ',
  116. events: {
  117. googleCalendarId: 'davidawindham.com_bvrht1f8n2vgldgjenpgfdd4bk@group.calendar.google.com',
  118. className: 'gcal-event'
  119. },
  120. eventDataTransform: function (event) { event.url = ''; return event; },
  121. eventClick: function (info) { info.jsEvent.preventDefault(); }
  122. });
  123. calendar.render();
  124. }
  125. });