add zoom indicator in lower left corner (#39)
it looks like this: - 3200% + I'm giving up on the 100% zoom button from the original idea, because rkgk's scaling curve makes it easy to go back to 100% if you need to.
This commit is contained in:
		
							parent
							
								
									9f62582ef5
								
							
						
					
					
						commit
						6b82593414
					
				
					 7 changed files with 127 additions and 6 deletions
				
			
		| 
						 | 
				
			
			@ -59,6 +59,14 @@ button {
 | 
			
		|||
    background-color: var(--color-panel-background);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
button.icon {
 | 
			
		||||
    border: none;
 | 
			
		||||
    border-radius: 0;
 | 
			
		||||
    padding: 0;
 | 
			
		||||
    width: 24px;
 | 
			
		||||
    height: 24px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Text areas */
 | 
			
		||||
 | 
			
		||||
input {
 | 
			
		||||
| 
						 | 
				
			
			@ -66,7 +74,7 @@ input {
 | 
			
		|||
    border-bottom: 1px solid var(--color-panel-border);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
*:focus {
 | 
			
		||||
*:focus-visible {
 | 
			
		||||
    outline: 1px solid var(--color-brand-blue);
 | 
			
		||||
    outline-offset: 4px;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -172,6 +180,8 @@ pre:has(code) {
 | 
			
		|||
    --icon-memory: url("data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgMTYgMTYiIHdpZHRoPSIxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjMDAwIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iLjEiPjxwYXRoIGQ9Im01LjA1IDMuMDVoNS45djkuOWgtNS45eiIvPjxwYXRoIGQ9Im0zLjA1IDQuMDVoMS45djEuOWgtMS45eiIvPjxwYXRoIGQ9Im0xMS4wNSA0LjA1aDEuOXYxLjloLTEuOXoiLz48cGF0aCBkPSJtMy4wNSA3LjA1aDEuOXYxLjloLTEuOXoiLz48cGF0aCBkPSJtMTEuMDUgNy4wNWgxLjl2MS45aC0xLjl6Ii8+PHBhdGggZD0ibTMuMDUgMTAuMDVoMS45djEuOWgtMS45eiIvPjxwYXRoIGQ9Im0xMS4wNSAxMC4wNWgxLjl2MS45aC0xLjl6Ii8+PC9nPjwvc3ZnPg==");
 | 
			
		||||
    --icon-object: url("data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgMTYgMTYiIHdpZHRoPSIxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Im0xMiA2YzAgMS4xMDQ1Ny0uODk1NCAyLTIgMnYyYzIuMjA5MSAwIDQtMS43OTA4NiA0LTRzLTEuNzkwOS00LTQtNGMtMi4yMDkxNCAwLTQgMS43OTA4Ni00IDRoMmMwLTEuMTA0NTcuODk1NDMtMiAyLTIgMS4xMDQ2IDAgMiAuODk1NDMgMiAyeiIgZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIi8+PHBhdGggZD0ibTMgN2g2djZoLTZ6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMiIvPjwvc3ZnPg==");
 | 
			
		||||
    --icon-rkgk-grayscale: url("data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgMTYgMTYiIHdpZHRoPSIxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGNsaXBQYXRoIGlkPSJhIj48cGF0aCBkPSJtMCAwaDE2djE2aC0xNnoiLz48L2NsaXBQYXRoPjxnIGNsaXAtcGF0aD0idXJsKCNhKSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjIiPjxwYXRoIGQ9Im0xMiAxNy00LjU1Mjc5LTkuMTA1NTdjLS42NjQ5LTEuMzI5ODEuMzAyMDktMi44OTQ0MyAxLjc4ODg2LTIuODk0NDNoOC43NjM5MyIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPjxnIHN0cm9rZS1saW5lY2FwPSJyb3VuZCI+PHBhdGggZD0ibTUuNSAxMi0yLjUgNSIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLW9wYWNpdHk9Ii41Ii8+PHBhdGggZD0ibTMgNWgxIi8+PC9nPjwvZz48L3N2Zz4=");
 | 
			
		||||
    --icon-plus: url("data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgMTYgMTYiIHdpZHRoPSIxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjMDAwIj48cGF0aCBkPSJtNyA0aDJ2OGgtMnoiLz48cGF0aCBkPSJtNCA3aDh2MmgtOHoiLz48L2c+PC9zdmc+");
 | 
			
		||||
    --icon-minus: url("data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgMTYgMTYiIHdpZHRoPSIxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNCA3aDh2MmgtOHoiIGZpbGw9IiMwMDAiLz48L3N2Zz4=");
 | 
			
		||||
 | 
			
		||||
    --icon-brackets-white: url("data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgMTYgMTYiIHdpZHRoPSIxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNyA0aC0zdjhoM20yLThoM3Y4aC0zIiBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iMiIvPjwvc3ZnPg==");
 | 
			
		||||
    --icon-droplet-white: url("data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgMTYgMTYiIHdpZHRoPSIxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNSAxMGMwLTEuNjM0NzIgMS4wMDIxMi00LjI3MTU2IDIuMTg3MjYtNi41NDUzNy4zNDg5My0uNjY5NDQgMS4yNzY1NS0uNjY5NDQgMS42MjU0OCAwIDEuMTg1MTQgMi4yNzM4MSAyLjE4NzI2IDQuOTEwNjUgMi4xODcyNiA2LjU0NTM3IDAgMi0xLjUgMy0zIDNzLTMtMS0zLTN6IiBmaWxsPSIjZmZmIi8+PC9zdmc+");
 | 
			
		||||
| 
						 | 
				
			
			@ -205,6 +215,12 @@ pre:has(code) {
 | 
			
		|||
    &.icon-rkgk-grayscale {
 | 
			
		||||
        background-image: var(--icon-rkgk-grayscale);
 | 
			
		||||
    }
 | 
			
		||||
    &.icon-plus {
 | 
			
		||||
        background-image: var(--icon-plus);
 | 
			
		||||
    }
 | 
			
		||||
    &.icon-minus {
 | 
			
		||||
        background-image: var(--icon-minus);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &.icon-brackets-white {
 | 
			
		||||
        background-image: var(--icon-brackets-white);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								static/icon/minus.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								static/icon/minus.svg
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
 | 
			
		||||
<rect x="4" y="7" width="8" height="2" fill="black"/>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 157 B  | 
							
								
								
									
										4
									
								
								static/icon/plus.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								static/icon/plus.svg
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,4 @@
 | 
			
		|||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
 | 
			
		||||
<rect x="7" y="4" width="2" height="8" fill="black"/>
 | 
			
		||||
<rect x="4" y="7" width="8" height="2" fill="black"/>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 211 B  | 
| 
						 | 
				
			
			@ -54,6 +54,21 @@ main {
 | 
			
		|||
            pointer-events: all;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        & > .left {
 | 
			
		||||
            display: flex;
 | 
			
		||||
            flex-direction: column;
 | 
			
		||||
 | 
			
		||||
            pointer-events: none;
 | 
			
		||||
 | 
			
		||||
            & > * {
 | 
			
		||||
                pointer-events: auto;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            & > rkgk-zoom-indicator {
 | 
			
		||||
                margin-block-start: auto;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        & > .right {
 | 
			
		||||
            grid-column: right / right;
 | 
			
		||||
            min-height: 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -439,6 +454,38 @@ rkgk-brush-cost-gauges.rkgk-panel {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Zoom indicator */
 | 
			
		||||
 | 
			
		||||
rkgk-zoom-indicator,
 | 
			
		||||
rkgk-zoom-indicator.rkgk-panel {
 | 
			
		||||
    border-radius: 4px;
 | 
			
		||||
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: row;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
 | 
			
		||||
    width: min-content;
 | 
			
		||||
 | 
			
		||||
    overflow: clip; /* corners */
 | 
			
		||||
 | 
			
		||||
    & > button {
 | 
			
		||||
        width: 24px;
 | 
			
		||||
        height: 24px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & > p {
 | 
			
		||||
        margin: 0;
 | 
			
		||||
        padding: 0 4px;
 | 
			
		||||
        line-height: 1;
 | 
			
		||||
        width: 6ch;
 | 
			
		||||
 | 
			
		||||
        user-select: none;
 | 
			
		||||
 | 
			
		||||
        font-variant-numeric: tabular-nums;
 | 
			
		||||
        text-align: center;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Welcome screen */
 | 
			
		||||
 | 
			
		||||
rkgk-welcome {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,6 +19,7 @@ let reticleRenderer = main.querySelector("rkgk-reticle-renderer");
 | 
			
		|||
let brushEditor = main.querySelector("rkgk-brush-editor");
 | 
			
		||||
let brushPreview = main.querySelector("rkgk-brush-preview");
 | 
			
		||||
let brushCostGauges = main.querySelector("rkgk-brush-cost-gauges");
 | 
			
		||||
let zoomIndicator = main.querySelector("rkgk-zoom-indicator");
 | 
			
		||||
let welcome = main.querySelector("rkgk-welcome");
 | 
			
		||||
let connectionStatus = main.querySelector("rkgk-connection-status");
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -62,6 +63,8 @@ function readUrl(urlString) {
 | 
			
		|||
 | 
			
		||||
// In the background, connect to the server.
 | 
			
		||||
(async () => {
 | 
			
		||||
    // Initialization
 | 
			
		||||
 | 
			
		||||
    console.info("checking for user registration status");
 | 
			
		||||
    if (!isUserLoggedIn()) {
 | 
			
		||||
        await welcome.show({
 | 
			
		||||
| 
						 | 
				
			
			@ -79,6 +82,7 @@ function readUrl(urlString) {
 | 
			
		|||
    canvasRenderer.viewport.panX = urlData.viewport.x;
 | 
			
		||||
    canvasRenderer.viewport.panY = urlData.viewport.y;
 | 
			
		||||
    canvasRenderer.viewport.zoomLevel = urlData.viewport.zoom;
 | 
			
		||||
    zoomIndicator.setZoom(canvasRenderer.viewport.zoom);
 | 
			
		||||
 | 
			
		||||
    let session = await newSession({
 | 
			
		||||
        userId: getUserId(),
 | 
			
		||||
| 
						 | 
				
			
			@ -124,6 +128,7 @@ function readUrl(urlString) {
 | 
			
		|||
            canvasRenderer.viewport.panX = newUrlData.viewport.x;
 | 
			
		||||
            canvasRenderer.viewport.panY = newUrlData.viewport.y;
 | 
			
		||||
            canvasRenderer.viewport.zoomLevel = newUrlData.viewport.zoom;
 | 
			
		||||
            zoomIndicator.setZoom(canvasRenderer.viewport.zoom);
 | 
			
		||||
            canvasRenderer.sendViewportUpdate();
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
| 
						 | 
				
			
			@ -140,6 +145,8 @@ function readUrl(urlString) {
 | 
			
		|||
 | 
			
		||||
    let currentUser = wall.onlineUsers.getUser(session.sessionId);
 | 
			
		||||
 | 
			
		||||
    // Event loop
 | 
			
		||||
 | 
			
		||||
    session.addEventListener("error", (event) => console.error(event));
 | 
			
		||||
 | 
			
		||||
    session.addEventListener("wallEvent", (event) => {
 | 
			
		||||
| 
						 | 
				
			
			@ -248,6 +255,8 @@ function readUrl(urlString) {
 | 
			
		|||
        updateUrl(session, canvasRenderer.viewport),
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // Brush editor
 | 
			
		||||
 | 
			
		||||
    function compileBrush() {
 | 
			
		||||
        let compileResult = currentUser.setBrush(brushEditor.code);
 | 
			
		||||
        brushEditor.renderHakuResult("Compilation", compileResult);
 | 
			
		||||
| 
						 | 
				
			
			@ -279,5 +288,17 @@ function readUrl(urlString) {
 | 
			
		|||
        });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Zoom indicator
 | 
			
		||||
 | 
			
		||||
    canvasRenderer.addEventListener(".viewportUpdate", () => {
 | 
			
		||||
        zoomIndicator.setZoom(canvasRenderer.viewport.zoom);
 | 
			
		||||
    });
 | 
			
		||||
    zoomIndicator.addEventListener(".zoomUpdate", (event) => {
 | 
			
		||||
        canvasRenderer.viewport.zoomLevel += event.delta;
 | 
			
		||||
        canvasRenderer.sendViewportUpdate();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // All done.
 | 
			
		||||
 | 
			
		||||
    session.eventLoop();
 | 
			
		||||
})();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										25
									
								
								static/zoom-indicator.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								static/zoom-indicator.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,25 @@
 | 
			
		|||
class ZoomIndicator extends HTMLElement {
 | 
			
		||||
    connectedCallback() {
 | 
			
		||||
        this.zoomOutButton = this.appendChild(document.createElement("button"));
 | 
			
		||||
        this.zoomOutButton.classList.add("icon", "icon-minus");
 | 
			
		||||
 | 
			
		||||
        this.zoomLevelText = this.appendChild(document.createElement("p"));
 | 
			
		||||
        this.zoomLevelText.innerText = "100%";
 | 
			
		||||
 | 
			
		||||
        this.zoomInButton = this.appendChild(document.createElement("button"));
 | 
			
		||||
        this.zoomInButton.classList.add("icon", "icon-plus");
 | 
			
		||||
 | 
			
		||||
        this.zoomInButton.addEventListener("click", () => {
 | 
			
		||||
            this.dispatchEvent(Object.assign(new Event(".zoomUpdate"), { delta: +1 }));
 | 
			
		||||
        });
 | 
			
		||||
        this.zoomOutButton.addEventListener("click", () => {
 | 
			
		||||
            this.dispatchEvent(Object.assign(new Event(".zoomUpdate"), { delta: -1 }));
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setZoom(value) {
 | 
			
		||||
        this.zoomLevelText.innerText = `${Math.round(value * 100)}%`;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
customElements.define("rkgk-zoom-indicator", ZoomIndicator);
 | 
			
		||||
| 
						 | 
				
			
			@ -18,7 +18,7 @@
 | 
			
		|||
            const HAKU_WASM_PATH = "{{{ static 'wasm/haku.wasm' }}}";
 | 
			
		||||
        </script>
 | 
			
		||||
        
 | 
			
		||||
        <script type="module">
 | 
			
		||||
        <script type="module" async>
 | 
			
		||||
            import "rkgk/live-reload.js";
 | 
			
		||||
 | 
			
		||||
            import "rkgk/brush-cost.js";
 | 
			
		||||
| 
						 | 
				
			
			@ -33,6 +33,7 @@
 | 
			
		|||
            import "rkgk/throbber.js";
 | 
			
		||||
            import "rkgk/viewport.js";
 | 
			
		||||
            import "rkgk/welcome.js";
 | 
			
		||||
            import "rkgk/zoom-indicator.js";
 | 
			
		||||
    
 | 
			
		||||
            import "rkgk/index.js";
 | 
			
		||||
        </script>
 | 
			
		||||
| 
						 | 
				
			
			@ -56,10 +57,14 @@
 | 
			
		|||
            <rkgk-canvas-renderer class="fullscreen"></rkgk-canvas-renderer>
 | 
			
		||||
            <rkgk-reticle-renderer class="fullscreen"></rkgk-reticle-renderer>
 | 
			
		||||
            <div class="panels fullscreen" id="panels-overlay">
 | 
			
		||||
                <div class="rkgk-panel menu-bar">
 | 
			
		||||
                    <a class="icon icon-rkgk-grayscale" title="I know this menu bar is really ugly. Sorry about that."></a>
 | 
			
		||||
                    <hr>
 | 
			
		||||
                    <a href="/docs/rkgk.html">Manual</a>
 | 
			
		||||
                <div class="left">
 | 
			
		||||
                    <div class="rkgk-panel menu-bar">
 | 
			
		||||
                        <a class="icon icon-rkgk-grayscale" title="I know this menu bar is really ugly. Sorry about that."></a>
 | 
			
		||||
                        <hr>
 | 
			
		||||
                        <a href="/docs/rkgk.html">Manual</a>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <rkgk-zoom-indicator class="rkgk-panel"></rkgk-zoom-indicator>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
                <div class="right">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue