LOADING...

Preview

Pen ID
Unlock Campus Themeforest adv

 

Code

  
    
    
  
  
CSS
body {
  display: flex;
  margin: 0;
  height: 100vh;
  background: url(http://www.blirk.net/wallpapers/1920x1080/music-wallpaper-33.jpg) 100% 50%/cover #999;
  background-blend-mode: screen;
}

svg {
  flex: 1;
}

[id='s'] {
  mask: url(#m);
}
JS
const DATA = {
				p: {
					_el: document.querySelector('path'),
					att: {}
				},
				e: {
					_el: document.querySelector('ellipse'),
					att: {}
				}
			}, 
			RE = /\s+|[a-z]/g,
			NF = 40 /* total number of frames for transition */, 
      TFN = { /* timing functions */
        'ease-in-out': function(k) {
          return .5*(Math.sin((k - .5)*Math.PI) + 1)
        },
        'bounce-ini-fin': function(k, s = -.675*Math.PI, e = -s) {
          return (Math.sin(k*(e - s) + s) - Math.sin(s))/(Math.sin(e) - Math.sin(s))
        }
      };

let dir = -1, rID = null, cf = 0, m;

function extractStr(el, attr = 'ini') {
	const SEP_RE = /(\d)\-/g;
	
	return el.getAttribute(attr).slice(1, -1)
					 .replace(SEP_RE, '$1 -');
};

function extractPts(str) {
	return str.split(RE).map(c => +c)
};

function extractSep(str) {
	return str.match(RE)
};

function range(ini, fin) {
	return (typeof ini == 'number') ? 
					fin - ini : 
					ini.map((c, i) => range(ini[i], fin[i]))
};

function int(ini, rng, tfn, k, cnt) {
	return (typeof ini == 'number') ? 
					+(ini + cnt*(m + dir*tfn(m + dir*k))*rng).toFixed(2) : 
					ini.map((c, i) => int(ini[i], rng[i], tfn, k, cnt))
};

function stopAni() {
  cancelAnimationFrame(rID);
  rID = null;  
};

function update() {
	cf += dir;
	
  let k = cf/NF;
	
	for(let e in DATA) {
		for(let p in DATA[e].att) {
			let o = DATA[e].att[p];
			
			DATA[e]._el.setAttribute(...[
				p, 
				o.afn(int(o.ini, o.rng, TFN[o.tfn], k, o.cnt ? dir : 1), o.sep)
			]);
		}
	}
  
  if(!(cf%NF)) {
    stopAni();
    return
  }
  
  rID = requestAnimationFrame(update)
};

(function init() {
	const INI_STR = extractStr(DATA.p._el);
	
	DATA.p.att.d = {
		sep: extractSep(INI_STR),
		ini: extractPts(INI_STR), 
		fin: extractPts(extractStr(DATA.p._el, 'fin')),
		afn: function(pts, sep) {
			return pts.reduce((a, c, i) => a + c + (sep[i] || 'z'), 'M')
		},
		tfn: 'bounce-ini-fin'
	};
	
	['rx', 'ry', 'opacity'].forEach(c => {
		DATA.e.att[c] = {
			ini: 0, 
			fin: DATA.e._el.getAttribute(c) || 1,
			afn: i => i,
			tfn: 'ease-in-out'
		}
	});
	
	for(let e in DATA) {
		for(let p in DATA[e].att) {
			let o = DATA[e].att[p];
			
			o.rng = range(o.ini, o.fin);
			DATA[e]._el.setAttribute(p, o.afn(o.ini, o.sep))
		}
	}
	
	addEventListener('click', e => {
		if(rID) stopAni();
		dir *= -1;
		m = .5*(1 - dir);
		update();
	}, false);
})();

Description

Inspiration for the ♪ and 9. Didn't just copy the SVG, but handcoded my own versions from scratch for a much more compact result. The original ♪ file on Wikipedia is 6.61KB, while my version is under 300B, so over 22 times smaller.
Term
Wed, 12/06/2017 - 19:43

Related Codes

Pen ID
Pen ID
Pen ID
Square Adv