Improve responsive gallery layout

This commit is contained in:
Emil
2026-07-29 23:14:53 +03:00
parent 2f7315016c
commit 2c5d146201
3 changed files with 45 additions and 13 deletions
+15 -7
View File
@@ -575,17 +575,24 @@ function pathProgress(path,progress){
function updateView(){
const bounds=state.current?.bounds||geometryBounds(state.current?.paths);
const galleryRect=galleryOpen?ui.gallery.getBoundingClientRect():null;
const actionTop=document.querySelector('.action-bar').getBoundingClientRect().top;
const formulaVisible=ui.formula.getClientRects().length>0;
const compactLandscape=galleryOpen&&height<520;
let left,right,top,bottom;
if(width>=1180){
left=386;right=galleryOpen?width-326:width-34;top=82;bottom=height-116;
}else if(compactLandscape){
left=22;right=galleryRect.left-14;top=82;bottom=actionTop-14;
}else if(width>760){
left=356;right=width-28;top=82;bottom=height-112;
left=formulaVisible?356:22;right=width-28;top=82;
bottom=galleryOpen?galleryRect.top-14:actionTop-14;
}else{
left=22;right=width-22;top=Math.max(270,ui.formula.getBoundingClientRect().bottom+14);
bottom=Math.min(height-112,document.querySelector('.action-bar').getBoundingClientRect().top-14);
left=22;right=width-22;top=formulaVisible?Math.max(270,ui.formula.getBoundingClientRect().bottom+14):82;
bottom=galleryOpen?galleryRect.top-14:actionTop-14;
}
if(right-left<160){left=22;right=width-22}
if(bottom-top<150&&width>760){top=76;bottom=height-98}
if(bottom-top<90)top=Math.max(72,bottom-90);
const worldWidth=Math.max(.08,bounds.maxX-bounds.minX),worldHeight=Math.max(.08,bounds.maxY-bounds.minY);
const scale=Math.min((right-left)/worldWidth,(bottom-top)/worldHeight)*.88;
view.scale=Math.min(scale,Math.min(width,height)*2.1);
@@ -1036,6 +1043,7 @@ function renderArchive(){
function setGallery(open){
galleryOpen=open;
ui.gallery.classList.toggle('open',open);ui.gallery.classList.toggle('closed',!open);
document.body.classList.toggle('gallery-open',open);
document.querySelector('#gallery-toggle').setAttribute('aria-expanded',String(open));
hideArchivePreview();updateView();render(lastProgress);
}
@@ -1092,8 +1100,7 @@ document.addEventListener('keydown',event=>{
if(event.code==='Space'){event.preventDefault();if(!ui.cross.disabled)crossSelected()}
});
addEventListener('resize',()=>{
const wasDesktop=width>=1180;resize();
if(wasDesktop!==(width>=1180))setGallery(width>=1180);
resize();
});
addEventListener('beforeunload',saveState);
@@ -1102,8 +1109,9 @@ async function boot(){
syncBreedingUI();
await refreshStorageStatus();
ensureInitialPopulation();
galleryOpen=innerWidth>=1180;
galleryOpen=true;
ui.gallery.classList.toggle('closed',!galleryOpen);ui.gallery.classList.toggle('open',galleryOpen);
document.body.classList.toggle('gallery-open',galleryOpen);
document.querySelector('#gallery-toggle').setAttribute('aria-expanded',String(galleryOpen));
if(state.current)state.current=runtimeFormula(state.current);
resize();renderArchive();
+2 -2
View File
@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#07100f" />
<title>Fractalier — Mathematical Fractal Generator</title>
<link rel="stylesheet" href="style.css?v=39" />
<link rel="stylesheet" href="style.css?v=40" />
</head>
<body>
<main>
@@ -134,6 +134,6 @@
<span id="storage-status">checking local storage…</span>
</footer>
</main>
<script src="app.js?v=39"></script>
<script src="app.js?v=40"></script>
</body>
</html>
+28 -4
View File
@@ -121,10 +121,14 @@ footer span:last-child{text-align:right}
.live{display:inline-block;width:5px;height:5px;margin-right:7px;border-radius:50%;background:var(--lime);box-shadow:0 0 7px var(--lime)}
@media(max-width:1179px){
.gallery-panel{display:none;top:76px;right:12px;bottom:105px;width:300px;box-shadow:0 20px 60px rgba(0,0,0,.55)}
.gallery-panel{
display:none;top:auto;right:12px;bottom:128px;left:12px;width:auto;height:clamp(200px,32vh,260px);
box-shadow:0 20px 60px rgba(0,0,0,.55)
}
.gallery-panel.open{display:block}
.gallery-head button{display:block}
.formula-panel{top:78px;left:12px;width:320px}
.archive{grid-template-columns:repeat(auto-fill,minmax(112px,1fr))}
.action-bar{width:min(620px,calc(100% - 48px));min-width:0}
}
@@ -141,8 +145,12 @@ footer span:last-child{text-align:right}
.equation{margin-top:9px;padding:8px 0;font-size:7.5px}
.equation span{overflow:hidden;text-overflow:ellipsis}
.traits{gap:6px 8px;margin-top:8px}
.gallery-panel,.gallery-panel.open{top:72px;right:10px;bottom:158px;left:10px;width:auto}
.archive{grid-template-columns:repeat(3,1fr)}
body.gallery-open .formula-panel{display:none}
.gallery-panel,.gallery-panel.open{
top:auto;right:10px;bottom:158px;left:10px;width:auto;height:clamp(190px,32vh,230px)
}
.gallery-help{display:none}
.archive{grid-template-columns:repeat(3,1fr);max-height:calc(100% - 75px)}
.genome-preview{display:none!important}
.action-bar{right:10px;bottom:40px;left:10px;width:auto;flex-direction:column;gap:7px;padding:8px;transform:none}
.action-copy{display:none}
@@ -157,10 +165,26 @@ footer span:last-child{text-align:right}
footer>span:nth-child(2){display:none}
}
@media(max-height:700px) and (max-width:1179px){
body.gallery-open .formula-panel{display:none}
}
@media(max-height:520px) and (max-width:1179px){
.gallery-panel,.gallery-panel.open{
top:72px;right:10px;bottom:158px;left:auto;width:min(280px,44vw);height:auto
}
.gallery-help{display:none}
.archive{grid-template-columns:repeat(2,1fr);max-height:calc(100% - 75px)}
.action-copy{display:none}
}
@media(max-height:620px) and (min-width:761px){
.action-bar{bottom:38px}
}
@media(max-height:620px) and (min-width:1180px){
.formula-panel{top:74px}
.gallery-panel{top:74px;bottom:94px}
.action-bar{bottom:38px}
}
@media(prefers-reduced-motion:reduce){