javascript – Canvas button menu

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>
Scroll to Top