feat: add outline to themes

This commit is contained in:
2024-04-19 02:36:11 +02:00
parent d8ada83db3
commit c62cfbf75e
15 changed files with 315 additions and 277 deletions

View File

@ -1,164 +1,163 @@
<script lang="ts">
import type { GraphManager } from './graph-manager.js';
import { HTML } from '@threlte/extras';
import { onMount } from 'svelte';
import type { GraphManager } from "./graph-manager.js";
import { HTML } from "@threlte/extras";
import { onMount } from "svelte";
export let position: [x: number, y: number] | null;
export let position: [x: number, y: number] | null;
export let graph: GraphManager;
export let graph: GraphManager;
let input: HTMLInputElement;
let value: string = '';
let activeNodeId: string = '';
let input: HTMLInputElement;
let value: string = "";
let activeNodeId: string = "";
const allNodes = graph.getNodeTypes();
const allNodes = graph.getNodeTypes();
function filterNodes() {
return allNodes.filter((node) => node.id.includes(value));
}
function filterNodes() {
return allNodes.filter((node) => node.id.includes(value));
}
$: nodes = value === '' ? allNodes : filterNodes();
$: if (nodes) {
if (activeNodeId === '') {
activeNodeId = nodes[0].id;
} else if (nodes.length) {
const node = nodes.find((node) => node.id === activeNodeId);
if (!node) {
activeNodeId = nodes[0].id;
}
}
}
$: nodes = value === "" ? allNodes : filterNodes();
$: if (nodes) {
if (activeNodeId === "") {
activeNodeId = nodes[0].id;
} else if (nodes.length) {
const node = nodes.find((node) => node.id === activeNodeId);
if (!node) {
activeNodeId = nodes[0].id;
}
}
}
function handleKeyDown(event: KeyboardEvent) {
event.stopImmediatePropagation();
const value = (event.target as HTMLInputElement).value;
function handleKeyDown(event: KeyboardEvent) {
event.stopImmediatePropagation();
if (event.key === 'Escape') {
position = null;
return;
}
if (event.key === "Escape") {
position = null;
return;
}
if (event.key === 'ArrowDown') {
const index = nodes.findIndex((node) => node.id === activeNodeId);
activeNodeId = nodes[(index + 1) % nodes.length].id;
return;
}
if (event.key === "ArrowDown") {
const index = nodes.findIndex((node) => node.id === activeNodeId);
activeNodeId = nodes[(index + 1) % nodes.length].id;
return;
}
if (event.key === 'ArrowUp') {
const index = nodes.findIndex((node) => node.id === activeNodeId);
activeNodeId = nodes[(index - 1 + nodes.length) % nodes.length].id;
return;
}
if (event.key === "ArrowUp") {
const index = nodes.findIndex((node) => node.id === activeNodeId);
activeNodeId = nodes[(index - 1 + nodes.length) % nodes.length].id;
return;
}
if (event.key === 'Enter') {
if (activeNodeId && position) {
graph.createNode({ type: activeNodeId, position });
position = null;
}
return;
}
}
if (event.key === "Enter") {
if (activeNodeId && position) {
graph.createNode({ type: activeNodeId, position });
position = null;
}
return;
}
}
onMount(() => {
input.disabled = false;
setTimeout(() => input.focus(), 50);
});
onMount(() => {
input.disabled = false;
setTimeout(() => input.focus(), 50);
});
</script>
<HTML position.x={position?.[0]} position.z={position?.[1]} transform={false}>
<div class="add-menu-wrapper">
<div class="header">
<input
id="add-menu"
type="text"
aria-label="Search for a node type"
role="searchbox"
placeholder="Search..."
disabled={false}
on:keydown={handleKeyDown}
bind:value
bind:this={input}
/>
</div>
<div class="add-menu-wrapper">
<div class="header">
<input
id="add-menu"
type="text"
aria-label="Search for a node type"
role="searchbox"
placeholder="Search..."
disabled={false}
on:keydown={handleKeyDown}
bind:value
bind:this={input}
/>
</div>
<div class="content">
{#each nodes as node}
<div
class="result"
role="treeitem"
tabindex="0"
aria-selected={node.id === activeNodeId}
on:keydown={(event) => {
if (event.key === 'Enter') {
if (position) {
graph.createNode({ type: node.id, position });
position = null;
}
}
}}
on:mousedown={() => {
if (position) {
graph.createNode({ type: node.id, position });
position = null;
}
}}
on:focus={() => {
activeNodeId = node.id;
}}
class:selected={node.id === activeNodeId}
on:mouseover={() => {
activeNodeId = node.id;
}}
>
{node.id}
</div>
{/each}
</div>
</div>
<div class="content">
{#each nodes as node}
<div
class="result"
role="treeitem"
tabindex="0"
aria-selected={node.id === activeNodeId}
on:keydown={(event) => {
if (event.key === "Enter") {
if (position) {
graph.createNode({ type: node.id, position, props: {} });
position = null;
}
}
}}
on:mousedown={() => {
if (position) {
graph.createNode({ type: node.id, position, props: {} });
position = null;
}
}}
on:focus={() => {
activeNodeId = node.id;
}}
class:selected={node.id === activeNodeId}
on:mouseover={() => {
activeNodeId = node.id;
}}
>
{node.id}
</div>
{/each}
</div>
</div>
</HTML>
<style>
input {
background: var(--background-color-lighter);
font-family: var(--font-family);
border: none;
color: var(--text-color);
padding: 0.8em;
width: calc(100% - 2px);
box-sizing: border-box;
font-size: 1em;
margin-left: 1px;
margin-top: 1px;
}
input {
background: var(--layer-0);
font-family: var(--font-family);
border: none;
color: var(--text-color);
padding: 0.8em;
width: calc(100% - 2px);
box-sizing: border-box;
font-size: 1em;
margin-left: 1px;
margin-top: 1px;
}
input:focus {
outline: solid 2px rgba(255, 255, 255, 0.2);
}
input:focus {
outline: solid 2px rgba(255, 255, 255, 0.2);
}
.add-menu-wrapper {
position: absolute;
background: var(--background-color);
border-radius: 7px;
overflow: hidden;
border: solid 2px var(--background-color-lighter);
width: 150px;
}
.content {
min-height: none;
width: 100%;
color: var(--text-color);
}
.add-menu-wrapper {
position: absolute;
background: var(--layer-1);
border-radius: 7px;
overflow: hidden;
border: solid 2px var(--layer-2);
width: 150px;
}
.content {
min-height: none;
width: 100%;
color: var(--text-color);
}
.result {
padding: 1em 0.9em;
border-bottom: solid 1px var(--background-color-lighter);
opacity: 0.7;
font-size: 0.9em;
cursor: pointer;
}
.result {
padding: 1em 0.9em;
border-bottom: solid 1px var(--layer-2);
opacity: 0.7;
font-size: 0.9em;
cursor: pointer;
}
.result[aria-selected='true'] {
background: var(--background-color-lighter);
opacity: 1;
}
.result[aria-selected="true"] {
background: var(--layer-2);
opacity: 1;
}
</style>

View File

@ -1,28 +1,31 @@
<script lang="ts">
import { HTML } from '@threlte/extras';
import { HTML } from "@threlte/extras";
export let p1 = { x: 0, y: 0 };
export let p2 = { x: 0, y: 0 };
export let p1 = { x: 0, y: 0 };
export let p2 = { x: 0, y: 0 };
export let cameraPosition = [0, 1, 0];
export let cameraPosition = [0, 1, 0];
$: width = Math.abs(p1.x - p2.x) * cameraPosition[2];
$: height = Math.abs(p1.y - p2.y) * cameraPosition[2];
$: width = Math.abs(p1.x - p2.x) * cameraPosition[2];
$: height = Math.abs(p1.y - p2.y) * cameraPosition[2];
$: x = Math.max(p1.x, p2.x) - width / cameraPosition[2];
$: y = Math.max(p1.y, p2.y) - height / cameraPosition[2];
$: x = Math.max(p1.x, p2.x) - width / cameraPosition[2];
$: y = Math.max(p1.y, p2.y) - height / cameraPosition[2];
</script>
<HTML position.x={x} position.z={y} transform={false}>
<div class="box-selection" style={`width: ${width}px; height: ${height}px;`}></div>
<div
class="box-selection"
style={`width: ${width}px; height: ${height}px;`}
></div>
</HTML>
<style>
.box-selection {
width: 40px;
height: 20px;
border: solid 0.2px rgba(200, 200, 200, 0.8);
border-style: dashed;
border-radius: 2px;
}
.box-selection {
width: 40px;
height: 20px;
border: solid 0.2px var(--outline);
border-style: dashed;
border-radius: 2px;
}
</style>

View File

@ -746,7 +746,7 @@
<div
on:wheel={handleMouseScroll}
bind:this={wrapper}
class="wrapper"
class="graph-wrapper"
aria-label="Graph"
role="button"
tabindex="0"
@ -794,8 +794,9 @@
</div>
<style>
.wrapper {
.graph-wrapper {
position: relative;
transition: opacity 0.3s ease;
height: 100%;
}
</style>

View File

@ -12,6 +12,8 @@
const manager = new GraphManager(registry);
export const status = manager.status;
const updateSettings = debounce((s) => {
manager.setSettings(s);
}, 200);

View File

@ -16,6 +16,8 @@ export const colors = writable({
layer2: new Color().setStyle("#2D2D2D"),
layer3: new Color().setStyle("#A6A6A6"),
outline: new Color().setStyle("#000000"),
active: new Color().setStyle("#c65a19"),
selected: new Color().setStyle("#ffffff"),
});
if ("getComputedStyle" in globalThis) {
@ -30,6 +32,8 @@ if ("getComputedStyle" in globalThis) {
const layer2 = style.getPropertyValue("--layer-2");
const layer3 = style.getPropertyValue("--layer-3");
const outline = style.getPropertyValue("--outline");
const active = style.getPropertyValue("--active");
const selected = style.getPropertyValue("--selected");
colors.update(col => {
col.layer0.setStyle(layer0);
@ -42,6 +46,10 @@ if ("getComputedStyle" in globalThis) {
col.layer3.convertLinearToSRGB();
col.outline.setStyle(outline);
col.outline.convertLinearToSRGB();
col.active.setStyle(active);
col.active.convertLinearToSRGB();
col.selected.setStyle(selected);
col.selected.convertLinearToSRGB();
return col;
});

View File

@ -6,12 +6,8 @@ uniform float uHeight;
uniform vec3 uColorDark;
uniform vec3 uColorBright;
uniform vec3 uSelectedColor;
uniform vec3 uActiveColor;
uniform bool uSelected;
uniform bool uActive;
uniform vec3 uStrokeColor;
uniform float uStrokeWidth;
float msign(in float x) { return (x < 0.0) ? -1.0 : 1.0; }
@ -47,16 +43,9 @@ void main(){
// outside
gl_FragColor = vec4(0.0,0.0,0.0, 0.0);
}else{
if (distance.w > -uStrokeWidth || mod(y+5.0, 10.0) < uStrokeWidth/2.0) {
// draw the outer stroke
if (uSelected) {
gl_FragColor = vec4(uSelectedColor, 1.0);
} else if (uActive) {
gl_FragColor = vec4(uActiveColor, 1.0);
} else {
gl_FragColor = vec4(uColorBright, 1.0);
}
gl_FragColor = vec4(uStrokeColor, 1.0);
}else if (y<5.0){
// draw the header
gl_FragColor = vec4(uColorBright, 1.0);

View File

@ -67,18 +67,18 @@
uniforms={{
uColorBright: { value: new Color("#171717") },
uColorDark: { value: new Color("#151515") },
uSelectedColor: { value: new Color("#9d5f28") },
uActiveColor: { value: new Color("white") },
uSelected: { value: false },
uActive: { value: false },
uStrokeColor: { value: new Color("#9d5f28") },
uStrokeWidth: { value: 1.0 },
uWidth: { value: 20 },
uHeight: { value: height },
}}
uniforms.uSelected.value={isSelected}
uniforms.uActive.value={isActive}
uniforms.uColorBright.value={$colors.layer2}
uniforms.uColorDark.value={$colors.layer1}
uniforms.uStrokeColor.value={isSelected
? $colors.selected
: isActive
? $colors.active
: $colors.outline}
uniforms.uStrokeWidth.value={(7 - z) / 3}
/>
</T.Mesh>
@ -122,12 +122,12 @@
}
.node.active {
--stroke: white;
--stroke-width: 1px;
--stroke: var(--active);
--stroke-width: 2px;
}
.node.selected {
--stroke: #9d5f28;
--stroke-width: 1px;
--stroke: var(--selected);
--stroke-width: 2px;
}
</style>