Browse Source

refactor: studio hero → native vanilla fade-carousel (drop Bootstrap Carousel + Tab + jQuery + backstretch)

Rebuild the studio showcase without Bootstrap/jQuery, keeping the spectacle:
- page-studio.php: .carousel/.carousel-fade → .dw-fade-carousel; carousel-items
  → .dw-fade-slide; add a bg layer + <video> (data-bg0/bg5 carry the WP image
  URLs); subnav data-bs tab/slide api → vanilla .dw-studio-tab[data-slide]
  (also fixes a duplicate id=studio-tab).
- js/studio.js: rewritten pure-vanilla — fade-carousel engine (5s autoplay +
  wrap, hover-pause), tab/panel sync, per-slide gradient + navbar-light + bg
  image/video, DrawFillSVG line-draws replayed on Web/UX/Graphic, and the
  .hide-svg reveal on the active slide. dw_hidenav ported off jQuery.
- css/styles.scss: .dw-fade-carousel / bg layer / <video> / tab-pane styles.

Bootstrap Tab is now unused site-wide; backstretch has no users left.
windhamdavid 2 days ago
parent
commit
d43c72f3cf
4 changed files with 198 additions and 123 deletions
  1. 54 0
      css/styles.scss
  2. 124 107
      js/studio.js
  3. 20 16
      page-studio.php
  4. 0 0
      v4-style.min.css

+ 54 - 0
css/styles.scss

@@ -211,3 +211,57 @@ $enable-negative-margins: true;
     scroll-behavior: auto;
   }
 }
+
+// Studio hero — vanilla fade-carousel (replaces Bootstrap carousel-fade + the
+// backstretch background). #studio-caro keeps its caro-grad* solid-colour
+// classes + 1s transition from style.css; the bg layer / <video> show through
+// when the gradient is caro-grad5 (transparent). Driven by js/studio.js.
+#studio-caro {
+  position: relative;
+  overflow: hidden;
+  min-height: 80vh;
+}
+.dw-studio-bg {
+  position: absolute;
+  inset: 0;
+  z-index: 0;
+  background-size: cover;
+  background-position: center;
+}
+.dw-studio-video {
+  position: absolute;
+  inset: 0;
+  width: 100%;
+  height: 100%;
+  object-fit: cover;
+  display: none; // shown only on the Media slide, by studio.js
+}
+.dw-fade-carousel {
+  position: relative;
+  z-index: 1;
+}
+.dw-fade-slide {
+  position: absolute;
+  inset: 0;
+  opacity: 0;
+  visibility: hidden;
+  transition: opacity 0.8s ease;
+}
+.dw-fade-slide.active {
+  position: relative; // the active slide defines the track height
+  opacity: 1;
+  visibility: visible;
+}
+@media (prefers-reduced-motion: reduce) {
+  .dw-fade-slide {
+    transition: none;
+  }
+}
+
+// Studio tab panes — vanilla show/hide (replaces Bootstrap Tab).
+#studio-tab .tab-pane {
+  display: none;
+}
+#studio-tab .tab-pane.active {
+  display: block;
+}

+ 124 - 107
js/studio.js

@@ -1,113 +1,130 @@
-const studioCarouselElement = document.querySelector('#caro')
-const carousel = new bootstrap.Carousel(studioCarouselElement, {
-  interval: 5000,
-  wrap: true
-});
+// Studio page — vanilla fade-carousel + tab sync + per-slide choreography.
+// Replaces Bootstrap Carousel/Tab, jQuery, and backstretch. Keeps DrawFillSVG
+// (window.DrawFillSVG, self-exposed from the v4-script bundle).
 
-jQuery(document).ready(function($) {
-
-	$('.nav-toggle').on('touchstart click', function(e) {
-		e.preventDefault();
-		$( this ).toggleClass( 'active' );
-	});
-
-
-  $(function dw_hidenav() {
-    var headerHeight = $('.navbar').height();
-    $(window).on('scroll', { previousTop: 0 },
-    function() {
-      var currentTop = $(window).scrollTop();
-      if (currentTop < this.previousTop) {
-        if (currentTop > 0 && $('.navbar').hasClass('fixed')) {
-          $('.navbar').addClass('visible');
-          $('.site-title a').removeClass('light');
-        } else {
-          $('.navbar').removeClass('visible fixed');
-          $('.site-title a').addClass('light');
-          }
-        }
-        else {
-          $('.navbar').removeClass('visible');
-          if (currentTop > headerHeight && !$('.navbar').hasClass('fixed')) $('.navbar').addClass('fixed');
-        }
-        this.previousTop = currentTop;
+// --- shared chrome: navbar hide/show on scroll (ported from jQuery dw_hidenav) ---
+(function () {
+  const navbar = document.querySelector('.navbar');
+  if (!navbar) return;
+  const title = document.querySelector('.site-title a');
+  const headerHeight = navbar.offsetHeight;
+  let previousTop = 0;
+  window.addEventListener('scroll', function () {
+    const currentTop = window.scrollY;
+    if (currentTop < previousTop) {
+      if (currentTop > 0 && navbar.classList.contains('fixed')) {
+        navbar.classList.add('visible');
+        if (title) title.classList.remove('light');
+      } else {
+        navbar.classList.remove('visible', 'fixed');
+        if (title) title.classList.add('light');
+      }
+    } else {
+      navbar.classList.remove('visible');
+      if (currentTop > headerHeight && !navbar.classList.contains('fixed')) {
+        navbar.classList.add('fixed');
       }
-    );
+    }
+    previousTop = currentTop;
+  }, { passive: true });
+})();
+
+document.querySelectorAll('.nav-toggle').forEach(function (el) {
+  el.addEventListener('click', function (e) {
+    e.preventDefault();
+    el.classList.toggle('active');
   });
+});
 
+// --- studio fade-carousel ---
+(function () {
+  const stage = document.getElementById('studio-caro');
+  const caro = document.getElementById('caro');
+  if (!stage || !caro) return;
 
-  $("#studio-caro").backstretch("../wp-content/themes/daw/img/studio-26.jpg");
-	$('#caro').on('slid.bs.carousel', function(e) {
-    var consta = e.to;
-    console.log('target: ' + consta );
-		setTimeout(function() {
-			if (consta === 0) {
-				$('a[href="#studio"]').tab('show')
-				$('#studio-caro').addClass('caro-grad5').removeClass('caro-grad caro-grad3 caro-grad2 caro-grad5');
-				$('.site-title a').addClass('light');
-				$('.carousel-indicators li').removeClass('darken-carousel-indicators');
-				$("#studio-caro").backstretch({url:'../wp-content/themes/daw/img/studio-26.jpg', fade: 250 });
-			}
-			if (consta === 1) {
-				$('a[href="#webdev"]').tab('show')
-				$('.active #svg-imac.screen').delay(2500).queue(function(screenit){
-				    $(this).attr('class', 'bg');
-				    screenit();
-				});
-				$('#studio-caro').addClass('caro-grad').removeClass('caro-grad3 caro-grad2 caro-grad5');
-				$('.site-title a').addClass('light');
-				$('.carousel-indicators li').removeClass('darken-carousel-indicators');
-        $("#studio-caro").backstretch('destroy');
-			}
-			if (consta === 2) {
-				$('a[href="#ux"]').tab('show')
-				$('#studio-caro').addClass('caro-grad2').removeClass('caro-grad caro-grad3 caro-grad5');
-				$('.site-title a').addClass('light');
-				$('.carousel-indicators li').removeClass('darken-carousel-indicators');
-        $("#studio-caro").backstretch('destroy');
-			}
-			if (consta === 3) {
-				$('a[href="#graphic"]').tab('show')
-				$( '#studio-caro' ).addClass('caro-grad3').removeClass('caro-grad2 caro-grad caro-grad5');
-				$('.site-title a').removeClass('light');
-				$('.carousel-indicators li').addClass('darken-carousel-indicators');
-        $("#studio-caro").backstretch('destroy');
-			}
-			if (consta === 4) {
-				$('a[href="#media"]').tab('show')
-				$('#studio-caro').removeClass('caro-grad caro-grad3').addClass('caro-grad5');
-				$('.site-title a').addClass('light');
-				$('.carousel-indicators li').removeClass('darken-carousel-indicators');
-				$("#studio-caro").backstretch({isVideo: true, url:'../wp-content/themes/daw/img/camera.mp4', poster:'../wp-content/themes/daw/img/camera.jpg'});
-			}
-			if (consta === 5) {
-				$('a[href="#art"]').tab('show')
-				$( '#studio-caro' ).addClass('caro-grad5').removeClass('caro-grad2 caro-grad caro-grad3');
-				$('.site-title a').addClass('light');
-				$('.carousel-indicators li').removeClass('darken-carousel-indicators');
-				$("#studio-caro").backstretch({url:'../wp-content/themes/daw/img/paints2.jpg', fade: 250 });
-			}
-		}, 10);
-	});
-
-	$('#caro').on('slide.bs.carousel', function() {
-		$('.active #svg-imac.bg').attr('class', 'svg screen');
-		$('.active .animac').addClass('fade-svg').delay(1000).queue(function(hideit){
-		    $(this).addClass('hide-svg');
-		    hideit();
-		});
-	});
-
-	$('#caro').on('slid.bs.carousel', function() {
-		$('.active .animac').removeClass('hide-svg fade-svg');
-		var animac = new DrawFillSVG({elementId: 'svg-imac'});
-		var animac1 = new DrawFillSVG({elementId: 'sv'});
-		var animac2 = new DrawFillSVG({elementId: 'svg-mac'});
-		var animac3 = new DrawFillSVG({elementId: 'svg-device'});
-		animac.replay();
-		animac1.replay();
-		animac2.replay();
-		animac3.replay();
-	});
+  const slides = Array.from(caro.querySelectorAll('.dw-fade-slide'));
+  const tabs = Array.from(document.querySelectorAll('.dw-studio-tab'));
+  const panes = Array.from(document.querySelectorAll('#studio-tab .tab-pane'));
+  const bg = stage.querySelector('.dw-studio-bg');
+  const video = stage.querySelector('.dw-studio-video');
+  const title = document.querySelector('.site-title a');
 
-});
+  const GRADS = ['caro-grad', 'caro-grad2', 'caro-grad3', 'caro-grad5'];
+  // per slide: gradient class · background image · show video · navbar-title light
+  const CONFIG = [
+    { grad: 'caro-grad5', img: stage.dataset.bg0 || null, video: false, light: true  }, // 0 Studio
+    { grad: 'caro-grad',  img: null,                      video: false, light: true  }, // 1 Web
+    { grad: 'caro-grad2', img: null,                      video: false, light: true  }, // 2 UX
+    { grad: 'caro-grad3', img: null,                      video: false, light: false }, // 3 Graphic
+    { grad: 'caro-grad5', img: null,                      video: true,  light: true  }, // 4 Media
+    { grad: 'caro-grad5', img: stage.dataset.bg5 || null, video: false, light: true  }, // 5 Art
+  ];
+  const INTERVAL = 5000;
+
+  let index = 0;
+  let timer = null;
+
+  function drawSVGs(slide) {
+    if (!window.DrawFillSVG) return;
+    slide.querySelectorAll('svg[id]').forEach(function (svg) {
+      try {
+        new window.DrawFillSVG({ elementId: svg.id }).replay();
+      } catch (e) {
+        /* svg not animatable — skip */
+      }
+    });
+  }
+
+  function activate(i) {
+    i = (i + slides.length) % slides.length;
+    index = i;
+    const cfg = CONFIG[i];
+
+    slides.forEach((s, n) => {
+      const on = n === i;
+      s.classList.toggle('active', on);
+      // reveal the active slide's content (slides 2/3/5 ship with .hide-svg)
+      const animac = s.querySelector('.animac');
+      if (animac && on) animac.classList.remove('hide-svg');
+    });
+    tabs.forEach((t, n) => t.classList.toggle('active', n === i));
+    panes.forEach((p, n) => p.classList.toggle('active', n === i));
+
+    GRADS.forEach((g) => stage.classList.remove(g));
+    stage.classList.add(cfg.grad);
+
+    if (bg) bg.style.backgroundImage = cfg.img ? 'url("' + cfg.img + '")' : '';
+    if (video) {
+      if (cfg.video) {
+        video.style.display = 'block';
+        video.play().catch(function () {});
+      } else {
+        video.pause();
+        video.style.display = 'none';
+      }
+    }
+
+    if (title) title.classList.toggle('light', cfg.light);
+
+    drawSVGs(slides[i]);
+  }
+
+  function next() { activate(index + 1); }
+  function start() { stop(); timer = window.setInterval(next, INTERVAL); }
+  function stop() { if (timer) { window.clearInterval(timer); timer = null; } }
+
+  tabs.forEach(function (t) {
+    t.addEventListener('click', function (e) {
+      e.preventDefault();
+      activate(parseInt(t.dataset.slide, 10) || 0);
+      start(); // restart the autoplay clock after manual navigation
+    });
+  });
+
+  // pause autoplay while the pointer is over the hero
+  stage.addEventListener('mouseenter', stop);
+  stage.addEventListener('mouseleave', start);
+
+  activate(0);
+  start();
+})();

+ 20 - 16
page-studio.php

@@ -1,10 +1,14 @@
 <?php get_header(); ?>
 <?php get_template_part( 'loader' ); ?>
-	<div id="studio-caro" class="container-fluid leader">
-		<div id="caro" class="carousel slide carousel-fade">
-
-			<div class="carousel-inner">
-				<div class="carousel-item active" data-id="0">
+	<div id="studio-caro" class="container-fluid leader" data-bg0="<?php echo get_template_directory_uri(); ?>/img/studio-26.jpg" data-bg5="<?php echo get_template_directory_uri(); ?>/img/paints2.jpg">
+		<div class="dw-studio-bg" aria-hidden="true">
+			<video class="dw-studio-video" muted loop playsinline preload="none" poster="<?php echo get_template_directory_uri(); ?>/img/camera.jpg">
+				<source src="<?php echo get_template_directory_uri(); ?>/img/camera.mp4" type="video/mp4">
+			</video>
+		</div>
+		<div id="caro" class="dw-fade-carousel">
+			<div class="dw-fade-track">
+				<div class="dw-fade-slide active" data-id="0">
 					<div class="container animac">
 						<div class="row">
 							<div class="col-sm-12">
@@ -13,7 +17,7 @@
 						</div>
 					</div>
 				</div>
-				<div class="carousel-item" data-id="1">
+				<div class="dw-fade-slide" data-id="1">
 					<div class="container animac">
 						<div class="row">
 							<div class="col-sm-7">
@@ -43,7 +47,7 @@
 						</div>
 					</div>
 				</div>
-				<div class="carousel-item" data-id="2">
+				<div class="dw-fade-slide" data-id="2">
 					<div class="container animac hide-svg">
 						<div class="row">
 							<div class="col-sm-3">
@@ -74,7 +78,7 @@
 						</div>
 					</div>
 				</div>
-				<div class="carousel-item" data-id="3">
+				<div class="dw-fade-slide" data-id="3">
 					<div class="container animac hide-svg">
 						<div class="row">
 							<div class="col-sm-4">
@@ -96,7 +100,7 @@
 						</div>
 					</div>
 				</div>
-				<div class="carousel-item" data-id="4">
+				<div class="dw-fade-slide" data-id="4">
 					<div class="container">
 						<div class="row">
 							<div class="col-sm-6">
@@ -109,7 +113,7 @@
 						</div>
 					</div>
 				</div>
-				<div class="carousel-item" data-id="5">
+				<div class="dw-fade-slide" data-id="5">
 					<div class="container animac hide-svg">
 						<div class="row">
 							<div class="col-sm-3">
@@ -128,12 +132,12 @@
 		<div class="row">
 			<div class="col-sm-2 bg-dark">
 				<ul class="nav studio-subnav">
-					<li class="list-group-item mt-0" data-bs-target="#caro" data-bs-slide-to="0"><a id="studio-tab" class="nav-item active" href="#studio" aria-controls="studio" role="tab" data-bs-toggle="tab" data-bs-target="#studio"><span class="fa fa-eye fa-fw"></span> <em>Studio</em></a></li>
-					<li class="list-group-item mt-1" data-bs-target="#caro" data-bs-slide-to="1"><a id="webdev-tab" class="nav-item" href="#webdev" aria-controls="webdev" role="tab" data-bs-toggle="tab" data-bs-target="#webdev"><span class="fa fa-desktop fa-fw"></span> <em>Web</em></a></li>
-					<li class="list-group-item mt-1" data-bs-target="#caro" data-bs-slide-to="2"><a id="ux-tab" class="nav-item" href="#ux" aria-controls="ux" role="tab" data-bs-toggle="tab" data-bs-target="#ux"><span class="fa fa-terminal fa-fw"></span> <em>UX/UI</em></a></li>
-					<li class="list-group-item mt-1" data-bs-target="#caro" data-bs-slide-to="3"><a id="graphic-tab" class="nav-item" href="#graphic" aria-controls="graphic" role="tab" data-bs-toggle="tab" data-bs-target="#graphic"><span class="fa fa-pencil fa-fw"></span> <em>Graphic</em></a></li>
-					<li class="list-group-item mt-1" data-bs-target="#caro" data-bs-slide-to="4"><a id="media-tab" class="nav-item" href="#media" aria-controls="media" role="tab" data-bs-toggle="tab" data-bs-target="#media"><span class="fa fa-film fa-fw"></span> <em>Media</em></a></li>
-					<li class="list-group-item mt-1" data-bs-target="#caro" data-bs-slide-to="5"><a id="art-tab" class="nav-item" href="#art" aria-controls="art" role="tab" data-bs-toggle="tab" data-bs-target="#art"><span class="fa fa-paint-brush fa-fw"></span> <em>Art</em></a></li>
+					<li class="list-group-item mt-0"><a class="dw-studio-tab nav-item active" data-slide="0" href="#studio"><span class="fa fa-eye fa-fw"></span> <em>Studio</em></a></li>
+					<li class="list-group-item mt-1"><a class="dw-studio-tab nav-item" data-slide="1" href="#webdev"><span class="fa fa-desktop fa-fw"></span> <em>Web</em></a></li>
+					<li class="list-group-item mt-1"><a class="dw-studio-tab nav-item" data-slide="2" href="#ux"><span class="fa fa-terminal fa-fw"></span> <em>UX/UI</em></a></li>
+					<li class="list-group-item mt-1"><a class="dw-studio-tab nav-item" data-slide="3" href="#graphic"><span class="fa fa-pencil fa-fw"></span> <em>Graphic</em></a></li>
+					<li class="list-group-item mt-1"><a class="dw-studio-tab nav-item" data-slide="4" href="#media"><span class="fa fa-film fa-fw"></span> <em>Media</em></a></li>
+					<li class="list-group-item mt-1"><a class="dw-studio-tab nav-item" data-slide="5" href="#art"><span class="fa fa-paint-brush fa-fw"></span> <em>Art</em></a></li>
 				</ul>
 			</div>
 			<div class="col-sm-10">

File diff suppressed because it is too large
+ 0 - 0
v4-style.min.css


Some files were not shown because too many files changed in this diff