btm testimonials

by electronoob

HTML

<figure class="testimonial">
💬 Testimonial
 <blockquote>
  <p id="testimony" class="testimony">👧 The children were mesmerised by Kris and the team. They really allowed the children to explore and challenges themselves. Ensuring they knew that making mistakes was okay. The confidence our children now have is down to the dedication and hard work from Kris and the team. Our children now want to go and create their own activities and have the confidence to do this themselves.</p>
 </blockquote>
 
 <figcaption class="author">
   <abbr title="Name or anonymised initials of witness. Miss Merry.">Miss Merry</abbr>
   - Social inclusion manager
 </figcaption>
</figure>

CSS

@font-face {
  font-family: 'Recursive';
  src: url(https://fonts.gstatic.com/s/recursive/v31/8vI-7wMr0mhh-RQChyHEH06TlXhq_gukbYrFMk1QuAIcyEwG_X-dpEfaE5YaERmK-CImKsvxvU-MXGX2fSqasNfUlTGZnA.woff2) format('woff2');
}


.testimonial {
  font-family: "Recursive";
  font-variation-settings: "wght" 100;
  font-size: 2.5rem;
  line-height: 1.3em;
  
}
span {
  transition: 128ms;
  height: 1em;
  display: inline-block;
}

JavaScript

let testimony = document.getElementById("testimony");
let mouse = {
	x: -10000,
  y: -10000,
};
let expanded = expan(testimony.innerText);
let count = expanded.length;
testimony.innerHTML = expanded.html;
window.requestAnimationFrame(weightset);

function weightset () {
	for (let i = 0; i<count-1; i++) {
  	let span = document.getElementById("char_" + i);
    // since Math.hypot is slow.. we do it this ugly way
    let x1 = mouse.x;
    let y1 = mouse.y;
    let x2 = span.getBoundingClientRect().left + (span.getBoundingClientRect().width / 2);
    let y2 = span.getBoundingClientRect().top + document.documentElement.scrollTop + (span.getBoundingClientRect().height / 2);
    let a = x1 - x2;
    let b = y1 - y2;
    let c = Math.sqrt( a*a + b*b );
    c = c * 2;
    let topweight = 800;
    c = clamp(c, 1, topweight);
    
    let scale = topweight/document.documentElement.clientWidth;
    let calcedweight = topweight - Math.trunc(Math.abs(c * scale));

    span.style["font-variation-settings"] = "'wght' " + calcedweight;
  }
	window.requestAnimationFrame(weightset);
}

// let's explode the text into spans. [exp]lode-sp[an]
// 
function expan (text, granularity) {
	// for short strings spltting by each char is nice
	// let chars = Array.from(text);
  // but since that's slow 
  let split = ' ';
  let chars = text.split(split);
  let shards = [];
  let index = 0;
  for (let char of chars) {
  	// since math.hypot is slow let's do it this ugly way
  	let shard = '<span id="char_'+index+'">' + char + split + '</span>';
  	shards.push (shard);
    index++;
  }
	return {
  	'html': shards.join(split),
    'length': index + 1,
  };
}

document.addEventListener('mousemove', (event) => {
	mouse = { x: event.clientX, y: event.clientY};
});

// https://stackoverflow.com/a/11410079
function clamp(current, min, max) {
    return current <= min ? min : current >= max ? max : current;
}

let testimonials = [
    {
        'category': '',
        'location': '',
        'name':...