hyprlink logo iteration

by phloe

HTML

<svg viewBox="0 0 12 8" width="360" height="240">
	<defs>
		<path d="
			M-2,-2
			a2 2 0 0 1 4 0
			v2
			a2 2 0 0 1 -4 0
			Z
		" fill="transparent" stroke-width="2" id="link" />
		<clipPath id="clip">
			<rect id="clip_rect" x="1" y="-5" width="2" height="7" />
		</clipPath>
		<mask id="mask">
			<rect x="-3" y="-5" width="6" height="8" fill="#FFF" />
			<path d="
				M-3,1
				v-2
				h1
				A3 3 0 0 1 0.7071067811865479 0.7071067811865479
				A1 1 0 0 1 0 1
				Z
			" />
		</mask>
	</defs>
	<g id="logo" transform="translate(4.6 4.6) rotate(-45)">
		<use xlink:href="#link" stroke="#8426da" />
		<use xlink:href="#link" stroke="#5EBDF4" transform="translate(2 2) rotate(90)" id="second_link" mask="url(#mask)" />
		<!--use xlink:href="#link" stroke="#8426da" clip-path="url(#clip)" /-->
	</g>
</svg>

CSS

fieldset {
	border: 0;
	background-color: rgba(0, 0, 0, .1);
	padding: 20px;
	position: fixed;
	right: 0;
	bottom: 0;
}
input {
	display: block;
}
fieldset label {
	display: block;
}
fieldset label + label {
	margin-top: 20px;
}

JavaScript

function setPaths (radius, stroke = 2, angle = 90) {
	var r = radius + (stroke / 2);
	link.setAttribute("d", `
		M-${radius + stroke / 2},-${stroke}
		a${r} ${r} 0 0 1 ${r * 2} 0
		v${stroke}
		a${r} ${r} 0 0 1 ${-r * 2} 0
		Z
	`);
	link.setAttribute("stroke-width", stroke);
	logo.setAttribute("transform", `translate(4.6 4.6) rotate(-${90 - (angle / 2)})`);
	second_link.setAttribute("transform", `translate(${radius * 2} ${radius * 2}) rotate(${180 - angle})`);
	clip_rect.setAttribute("x", `${radius}`);
	clip_rect.setAttribute("y", `-${radius + stroke * 2}`);
	clip_rect.setAttribute("width", `${radius + stroke}`);
	clip_rect.setAttribute("height", `${radius * 3 + stroke * 2}`);
}

var inputs = {
	radius: { value: 1, min: 0, max: 2, step: 0.01 },
	stroke: { value: 2, min: 0.01, max: 4, step: 0.01 },
	angle: { value: 90, min: 0, max: 90, step: 0.1 }
};

var fieldset = document.createElement("fieldset");

Object.keys(inputs).forEach(function (key) {
	var data = inputs[key];
	var label = document.createElement("label");
	var text = document.createTextNode(`${key[0].toUpperCase()}${key.slice(1)}: `);
	var span = document.createElement("span");
	span.textContent = data.value;
	var input = document.createElement("input");
	input.value = data.value;
	input.min = data.min;
	input.max = data.max;
	input.step = data.step;
	input.type = "range";
	
	input.oninput = updateInput;

	function updateInput (event) {
		var value = parseFloat(input.value, 10);
		if (data.value !== value) {
			data.value = value;
			span.textContent = value;
			if (event) {
				update();
			}
		}
	}
	
	label.appendChild(text);
	label.appendChild(span);
	label.appendChild(input);

	fieldset.appendChild(label);
});

document.body.appendChild(fieldset);

function update () {
	setPaths(inputs.radius.value, inputs.stroke.value, inputs.angle.value);
} 

update();

var startTime = new Date();
var duration = 1000;

function animate () {
	var frame = (new Date() - startTime) % duration;
	var p =...