add a menu bar; and also a favicon because there's now a logo
|
@ -44,7 +44,9 @@ With that said, there are several types of values in haku that can be passed int
|
||||||
- `fn` - a function, as returned by `(fn (x) x)` literals.
|
- `fn` - a function, as returned by `(fn (x) x)` literals.
|
||||||
- `list` - a list of values, where each value can have a different type (even `list` itself.)
|
- `list` - a list of values, where each value can have a different type (even `list` itself.)
|
||||||
- `shape` - a mathematical shape.
|
- `shape` - a mathematical shape.
|
||||||
|
|
||||||
- `shape-like` - anything that can be turned into a `shape` using `to-shape`.
|
- `shape-like` - anything that can be turned into a `shape` using `to-shape`.
|
||||||
|
|
||||||
- `scribble` - something that can be drawn on the wall.
|
- `scribble` - something that can be drawn on the wall.
|
||||||
|
|
||||||
Additionally, the syntax `(type-a type-b ...)` may be used to signify that one of the listed types is accepted or returned.
|
Additionally, the syntax `(type-a type-b ...)` may be used to signify that one of the listed types is accepted or returned.
|
||||||
|
@ -122,8 +124,10 @@ Whether two values are considered equal depends on their type:
|
||||||
|
|
||||||
- If the type of the two values differs, `false` is returned.
|
- If the type of the two values differs, `false` is returned.
|
||||||
- If the two values are `number`s:
|
- If the two values are `number`s:
|
||||||
|
|
||||||
- If any of the values are `NaN`, `false` is returned.
|
- If any of the values are `NaN`, `false` is returned.
|
||||||
- Otherwise `true` is returned if the two numbers have the exact same bit representation.
|
- Otherwise `true` is returned if the two numbers have the exact same bit representation.
|
||||||
|
|
||||||
- If the two values are `vec`s, `true` is returned if each of their `number` components is equal to each other using the rules above.
|
- If the two values are `vec`s, `true` is returned if each of their `number` components is equal to each other using the rules above.
|
||||||
- Likewise with `rgba`s.
|
- Likewise with `rgba`s.
|
||||||
- All other types of values use _reference_ equality - `true` is returned only if `a` and `b` are located in the same place in memory.
|
- All other types of values use _reference_ equality - `true` is returned only if `a` and `b` are located in the same place in memory.
|
||||||
|
|
7
scripts/mkicon.fish
Executable file
|
@ -0,0 +1,7 @@
|
||||||
|
#!/usr/bin/env fish
|
||||||
|
|
||||||
|
set filename $argv[1]
|
||||||
|
set icon_name (basename $filename .svg)
|
||||||
|
set icon_base64 (svgcleaner --stdout $filename 2>/dev/null | base64 -w0)
|
||||||
|
|
||||||
|
printf "--icon-%s: url('data:image/svg+xml;base64,%s');" "$icon_name" "$icon_base64"
|
|
@ -10,9 +10,6 @@
|
||||||
--color-panel-background: #fff;
|
--color-panel-background: #fff;
|
||||||
--color-shaded-background: rgba(0, 0, 0, 5%);
|
--color-shaded-background: rgba(0, 0, 0, 5%);
|
||||||
|
|
||||||
--panel-border-radius: 16px;
|
|
||||||
--panel-box-shadow: 0 0 0 1px var(--color-panel-border);
|
|
||||||
--panel-padding: 12px;
|
|
||||||
--dialog-backdrop: rgba(255, 255, 255, 0.5);
|
--dialog-backdrop: rgba(255, 255, 255, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +99,7 @@ input {
|
||||||
}
|
}
|
||||||
|
|
||||||
*:focus {
|
*:focus {
|
||||||
outline: 1px solid #40b1f4;
|
outline: 1px solid var(--color-brand-blue);
|
||||||
outline-offset: 4px;
|
outline-offset: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,12 +161,15 @@ rkgk-throbber {
|
||||||
/* Panels */
|
/* Panels */
|
||||||
|
|
||||||
.rkgk-panel {
|
.rkgk-panel {
|
||||||
|
--panel-border-radius: 8px;
|
||||||
|
|
||||||
display: block;
|
display: block;
|
||||||
background: var(--color-panel-background);
|
background: var(--color-panel-background);
|
||||||
padding: var(--panel-border-radius);
|
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 16px;
|
border-radius: var(--panel-border-radius);
|
||||||
box-shadow: var(--panel-box-shadow);
|
box-shadow:
|
||||||
|
0 0 0 1px var(--color-panel-border);
|
||||||
|
/* 4px 4px 0 0 var(--color-panel-border); */
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,3 +194,23 @@ pre:has(code) {
|
||||||
padding: 1em 1em;
|
padding: 1em 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Icons */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--icon-rkgk-grayscale: url('data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgMTYgMTYiIHdpZHRoPSIxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGNsaXBQYXRoIGlkPSJhIj48cGF0aCBkPSJtMCAwaDE2djE2aC0xNnoiLz48L2NsaXBQYXRoPjxnIGNsaXAtcGF0aD0idXJsKCNhKSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjIiPjxwYXRoIGQ9Im0xMiAxNy00LjU1Mjc5LTkuMTA1NTdjLS42NjQ5LTEuMzI5ODEuMzAyMDktMi44OTQ0MyAxLjc4ODg2LTIuODk0NDNoOC43NjM5MyIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPjxnIHN0cm9rZS1saW5lY2FwPSJyb3VuZCI+PHBhdGggZD0ibTUuNSAxMi0yLjUgNSIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLW9wYWNpdHk9Ii41Ii8+PHBhdGggZD0ibTMgNWgxIi8+PC9nPjwvZz48L3N2Zz4=');
|
||||||
|
--icon-external-link: url('data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgMTYgMTYiIHdpZHRoPSIxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBzdHJva2U9IiMwMDAiPjxwYXRoIGQ9Im0xMC41IDl2Mi41aC02di02aDIuNSIvPjxwYXRoIGQ9Im03IDkgNC41LTQuNW0wIDBoLTMuNW0zLjUgMHYzLjUiLz48L2c+PC9zdmc+');
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 50% 50%;
|
||||||
|
|
||||||
|
&.icon-rkgk-grayscale { background-image: var(--icon-rkgk-grayscale); }
|
||||||
|
&.icon-external-link { background-image: var(--icon-external-link); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ export class BrushEditor extends HTMLElement {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
requestAnimationFrame(() => this.#resizeTextArea());
|
requestAnimationFrame(() => this.#resizeTextArea());
|
||||||
|
document.fonts.addEventListener("loadingdone", () => this.#resizeTextArea());
|
||||||
|
|
||||||
this.errorHeader = this.appendChild(document.createElement("h1"));
|
this.errorHeader = this.appendChild(document.createElement("h1"));
|
||||||
this.errorHeader.classList.add("error-header");
|
this.errorHeader.classList.add("error-header");
|
||||||
|
|
BIN
static/favicon/rkgk@16x.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
static/favicon/rkgk@1x.png
Normal file
After Width: | Height: | Size: 311 B |
BIN
static/favicon/rkgk@2x.png
Normal file
After Width: | Height: | Size: 505 B |
BIN
static/favicon/rkgk@32x.png
Normal file
After Width: | Height: | Size: 7.1 KiB |
BIN
static/favicon/rkgk@4x.png
Normal file
After Width: | Height: | Size: 820 B |
BIN
static/favicon/rkgk@8x.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
4
static/icon/external-link.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">
|
||||||
|
<path d="M10.5 9V11.5H4.5V5.5H7" stroke="black"/>
|
||||||
|
<path d="M7 9L11.5 4.5M11.5 4.5H8M11.5 4.5V8" stroke="black"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 216 B |
12
static/icon/rkgk-grayscale.svg
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_6_28)">
|
||||||
|
<path d="M12 17L7.44721 7.89443C6.78231 6.56462 7.7493 5 9.23607 5H18" stroke="black" stroke-width="2" stroke-linejoin="round"/>
|
||||||
|
<path d="M5.5 12L3 17" stroke="black" stroke-opacity="0.5" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M3 5H4" stroke="black" stroke-width="2" stroke-linecap="round"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_6_28">
|
||||||
|
<rect width="16" height="16" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 567 B |
|
@ -123,6 +123,8 @@ rkgk-reticle-cursor {
|
||||||
/* Brush editor */
|
/* Brush editor */
|
||||||
|
|
||||||
rkgk-brush-editor {
|
rkgk-brush-editor {
|
||||||
|
padding: 12px;
|
||||||
|
|
||||||
&>.text-area {
|
&>.text-area {
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -187,3 +189,50 @@ rkgk-connection-status {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Menu bar */
|
||||||
|
|
||||||
|
.menu-bar {
|
||||||
|
--border-radius: 4px;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
width: fit-content;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
|
||||||
|
&>a {
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
color: var(--color-text);
|
||||||
|
padding: 4px 8px;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--color-shaded-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon {
|
||||||
|
padding: 4px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
border-top-left-radius: var(--border-radius);
|
||||||
|
border-bottom-left-radius: var(--border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-top-right-radius: var(--border-radius);
|
||||||
|
border-bottom-right-radius: var(--border-radius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&>hr {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
border: none;
|
||||||
|
border-right: 1px solid var(--color-panel-border);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,19 @@
|
||||||
<script src="static/welcome.js" type="module"></script>
|
<script src="static/welcome.js" type="module"></script>
|
||||||
|
|
||||||
<script src="static/index.js" type="module" defer></script>
|
<script src="static/index.js" type="module" defer></script>
|
||||||
|
|
||||||
|
<link rel="icon" sizes="16x16" href="/static/favicon/rkgk@1x.png">
|
||||||
|
<link rel="icon" sizes="32x32" href="/static/favicon/rkgk@2x.png">
|
||||||
|
<link rel="icon" sizes="64x64" href="/static/favicon/rkgk@4x.png">
|
||||||
|
<link rel="icon" sizes="128x128" href="/static/favicon/rkgk@8x.png">
|
||||||
|
<link rel="icon" sizes="256x256" href="/static/favicon/rkgk@16x.png">
|
||||||
|
<link rel="icon" sizes="512x512" href="/static/favicon/rkgk@32x.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="16x16" href="/static/favicon/rkgk@1x.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="32x32" href="/static/favicon/rkgk@2x.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="64x64" href="/static/favicon/rkgk@4x.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="128x128" href="/static/favicon/rkgk@8x.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="256x256" href="/static/favicon/rkgk@16x.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="512x512" href="/static/favicon/rkgk@32x.png">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
@ -31,6 +44,11 @@
|
||||||
<rkgk-canvas-renderer class="fullscreen"></rkgk-canvas-renderer>
|
<rkgk-canvas-renderer class="fullscreen"></rkgk-canvas-renderer>
|
||||||
<rkgk-reticle-renderer class="fullscreen"></rkgk-reticle-renderer>
|
<rkgk-reticle-renderer class="fullscreen"></rkgk-reticle-renderer>
|
||||||
<div class="panels fullscreen">
|
<div class="panels fullscreen">
|
||||||
|
<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-brush-editor></rkgk-brush-editor>
|
<rkgk-brush-editor></rkgk-brush-editor>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|