Question:
Hello everyone! Tell me, please: what technology is used to implement the menu button like on the website https://www.panoply.co.uk/ ? The customer asks to copy .. I see that it is canvas, but I can’t understand if the code is written manually or maybe some framework .. Thank you in advance for any information.
Answer:
Here I put together something similar for you from improvised means, in this example there is no WebGL, everything is calculated and drawn through a 2d context.
let ctx = canvas.getContext('2d');
let k = 300, a1 = 0, a2 = 0, dir = 0, far = 300,
w = canvas.width, h = canvas.height, planes = [];
ctx.translate(w/2, h/2);
for (var i=-20; i<21; i+=20) {
addRect(10,10,20,i,-20)
addRect(10,10,-20,i,-20)
addDiag(15,10,20,i,-20)
addDiag(-15,10,20,i,-20)
}
addTopDiag(25,15,-25,20)
addTopDiag(-25,-15,-25,20)
function addTopDiag(x1,x2,dy,dz) {
whitePlane([
pt(-x1, dy, -dz),
pt(-x2, dy, -dz),
pt(x1, dy, dz),
pt(x2, dy, dz)
]);
}
function addDiag(w, h, dx=0, dy=0, dz=0){
whitePlane([
pt(0, h/2+dy, -5),
pt(0, -h/2+dy, -5),
pt(w, -h/2+dy, dz),
pt(w, h/2+dy, dz)
]);
}
function addRect(w, h, dx=0, dy=0, dz=0){
whitePlane([
pt(-w/2+dx, -h/2+dy, dz),
pt(-w/2+dx, h/2+dy, dz),
pt(w/2+dx, h/2+dy, dz),
pt(w/2+dx, -h/2+dy,dz)
]);
}
requestAnimationFrame(render)
function whitePlane(points){
planes.push({color: 'white', points});
}
function pt(x,y,z) {
return {x, y, z};
}
function project(p) {
let sinA1 = Math.sin(a1), cosA1 = Math.cos(a1);
let sinA2 = Math.sin(a2), cosA2 = Math.cos(a2);
let x = p.x*cosA1 + p.z*sinA1;
let z = p.z*cosA1 - p.x*sinA1;
let y = p.y*cosA2 + z*sinA2;
let kd = k/(z*cosA2 - p.y*sinA2 + far);
p.X = kd*x;
p.Y = kd*y;
}
function render() {
a2 += dir * 0.1;
if (a2 < -Math.PI/2 || a2 > 0) {
dir = 0;
a2 = a2 > 0 ? 0 : -Math.PI/2;
}
if (a2 < 0 && a2 > -Math.PI/2)
requestAnimationFrame(render);
planes.forEach(plane => plane.points.forEach(project));
ctx.clearRect(-w/2, -h/2, w, h);
planes.forEach(drawPlane);
}
function drawPlane(plane) {
ctx.fillStyle = plane.color;
ctx.beginPath();
ctx.moveTo(plane.points[0].X, plane.points[0].Y);
for (var i = 1; i < plane.points.length; i++)
ctx.lineTo(plane.points[i].X, plane.points[i].Y);
ctx.fill();
ctx.closePath();
}
function toggle() {
if (a2 < 0 && a2 > -Math.PI/2)
return;
dir = a2 === 0 ? -1 : 1
requestAnimationFrame(render);
}
body {
background: url(https://picsum.photos/id/22/700/200);
}
canvas {
cursor: pointer;
}
<canvas id=canvas width=90 height=90 onclick="toggle()" ></canvas>