Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save EncodeTheCode/601ae2ac716269ca8faa677e411b2f20 to your computer and use it in GitHub Desktop.

Select an option

Save EncodeTheCode/601ae2ac716269ca8faa677e411b2f20 to your computer and use it in GitHub Desktop.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>PS1 Demo One Menu</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<style>
:root{
--menu-radius:420px;
--label-size:48px;
--ribbon-height:120px;
--dot-spacing:25px;
}
body{
margin:0;
overflow:hidden;
background:#021822;
font-family:Trebuchet MS, Arial;
}
#bgCanvas{
position:fixed;
width:100%;
height:100%;
z-index:0;
}
.stage{
position:absolute;
width:100%;
height:100%;
display:flex;
align-items:center;
justify-content:center;
perspective:1200px;
}
.menu3d{
position:relative;
width:900px;
height:600px;
transform-style:preserve-3d;
}
.menu-item{
position:absolute;
left:50%;
top:50%;
transform-style:preserve-3d;
transform-origin:center;
}
svg{
overflow:visible;
}
.label-text{
font-size:48px;
font-weight:900;
fill:#eaff6a;
stroke:#000;
stroke-width:2px;
paint-order:stroke fill;
}
.dot{
fill:#ff7a2c;
}
.front{
opacity:1;
}
.side{
opacity:0.45;
}
.back{
opacity:0.2;
}
#star{
position:absolute;
left:50%;
top:50%;
transform:translate(-50%,-50%);
width:300px;
z-index:5;
}
.submenu{
position:absolute;
bottom:80px;
width:100%;
text-align:center;
color:#eaffc8;
font-size:22px;
font-weight:bold;
z-index:20;
}
.submenu div{
margin:6px 0;
}
</style>
</head>
<body>
<canvas id="bgCanvas"></canvas>
<div class="stage">
<img id="star" src="https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Starfish_red.svg/512px-Starfish_red.svg.png">
<div class="menu3d" id="menu"></div>
<div class="submenu" id="submenu"></div>
</div>
<script>
const labels=[
{ name:"Games", items:["Tomb Raider 3","Tekken 3","Crash Bandicoot"] },
{ name:"Video", items:["Play Movie","Scene Select","Options"] },
{ name:"Music", items:["Track 1","Track 2","Track 3"] },
{ name:"Memory", items:["Memory Card 1","Memory Card 2","Format Card"] },
{ name:"Network", items:["Connect","Settings","Status"] }
];
const radius=420;
const step=360/labels.length;
let rotation=0;
let speed=-6;
let selected=0;
let inMenu=false;
const menu=$("#menu");
function createLabel(text){
let spacing=25;
return `
<svg width="500" height="200" viewBox="-250 -100 500 200">
<text class="label-text" text-anchor="middle" x="0" y="0">
${text}
</text>
<circle class="dot" cx="${text.length*14 + spacing}" cy="-8" r="8"/>
</svg>
`;
}
labels.forEach((l,i)=>{
let el=$(`<div class="menu-item">${createLabel(l.name)}</div>`);
el.attr("data-index",i);
menu.append(el);
});
function updateMenu(){
$(".menu-item").each(function(){
let i=parseInt($(this).attr("data-index"));
let angle=i*step+rotation;
let rad=angle*Math.PI/180;
let z=radius*Math.cos(rad);
let x=radius*Math.sin(rad);
let scale=(z+radius)/(2*radius);
let tilt=Math.sin(rad)*20;
$(this).css("transform",
`translate(-50%,-50%) translateX(${x}px) translateZ(${z}px) rotateX(${tilt}deg) scale(${0.6+scale*0.5})`
);
let diff=Math.abs(i-selected);
$(this).removeClass("front side back");
if(diff===0)$(this).addClass("front");
else if(diff===1 || diff===labels.length-1)$(this).addClass("side");
else $(this).addClass("back");
});
}
function animate(){
if(!inMenu){
rotation+=speed*0.016;
}
updateMenu();
requestAnimationFrame(animate);
}
animate();
function openMenu(){
let menuItems=labels[selected].items;
let html="";
menuItems.forEach(i=>{
html+=`<div>${i}</div>`;
});
$("#submenu").html(html);
inMenu=true;
}
function closeMenu(){
$("#submenu").html("");
inMenu=false;
}
$(document).keydown(function(e){
if(e.key==="ArrowRight" && !inMenu){
selected=(selected+1)%labels.length;
rotation=-selected*step;
}
if(e.key==="ArrowLeft" && !inMenu){
selected=(selected-1+labels.length)%labels.length;
rotation=-selected*step;
}
if(e.key==="Enter"){
openMenu();
}
if(e.key==="Escape"){
closeMenu();
}
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment