Skip to content

Commit

Permalink
add option to show cell as surface, wireframe or not at all, add rang…
Browse files Browse the repository at this point in the history
…e slider for cell opacity

close structure control panel on click outside
fix build + drop non-functional structure tooltip
  • Loading branch information
janosh committed Apr 23, 2023
1 parent 7644f55 commit 072d57a
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 62 deletions.
1 change: 0 additions & 1 deletion src/lib/ScatterPlot.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
hovered = true
// returns point to right of our current mouse position
let idx = bisect(data, x_scale.invert(event.offsetX))
if (idx < data.length) {
Expand Down
110 changes: 57 additions & 53 deletions src/lib/Structure.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -17,41 +17,49 @@
export let show_controls: boolean = false
// TODO whether to make the canvas fill the whole screen
// export let fullscreen: boolean = false
// whether to show the structure's lattice cell as a wireframe
export let show_cell: 'surface' | 'wireframe' | null = 'wireframe'
// the control panel DOM element
export let controls: HTMLElement | null = null
// the button to toggle the control panel
export let toggle_controls_btn: HTMLButtonElement | null = null
// cell opacity
export let cell_opacity: number | undefined = undefined
function on_keydown(event: KeyboardEvent) {
if (event.key === 'Escape') {
show_controls = false
}
}
let tooltip = { visible: false, content: '', x: 0, y: 0 }
function on_mouse_enter(event, position, element) {
console.log(`event`, event)
const { clientX, clientY } = event.detail.event
tooltip.visible = true
tooltip.content = `${element} - (${position.join(', ')})`
tooltip.x = clientX
tooltip.y = clientY
}
function on_mouse_leave() {
tooltip.visible = false
}
$: ({ a, b, c } = structure.lattice)
const lattice = structure.lattice.matrix
const on_window_click =
(node: (HTMLElement | null)[], cb: () => void) => (event: MouseEvent) => {
if (!node || !event.target) return
$: ({ a, b, c } = structure.lattice)
if (node && !node.some((n) => n?.contains(event.target as Node))) {
cb()
}
}
</script>

<svelte:window on:keydown={on_keydown} />
<svelte:window
on:keydown={on_keydown}
on:click={on_window_click([controls, toggle_controls_btn], () => {
if (show_controls) show_controls = false
})}
/>

<div>
<button class="controls-toggle" on:click={() => (show_controls = !show_controls)}>
<button
class="controls-toggle"
on:click={() => (show_controls = !show_controls)}
bind:this={toggle_controls_btn}
>
{show_controls ? 'Hide' : 'Show'} controls
</button>
<section class="controls" class:open={show_controls}>
<section bind:this={controls} class="controls" class:open={show_controls}>
<label>
Atom radius
<input type="range" min="0.1" max="2" step="0.05" bind:value={atom_radius} />
Expand All @@ -60,17 +68,20 @@
<input type="checkbox" bind:checked={same_size_atoms} />
Scale atoms according to atomic radius (if false, all atoms have same size)
</label>
<label>
Show lattice matrix as
<select bind:value={show_cell}>
<option value="surface">surface</option>
<option value="wireframe">wireframe</option>
<option value={null}>none</option>
</select>
</label>
<label>
Cell opacity
<input type="range" min="0" max="1" step="0.01" bind:value={cell_opacity} />
</label>
</section>

<div
class="tooltip"
style="top: {tooltip.y}px; left: {tooltip.x}px; display: {tooltip.visible
? 'block'
: 'none'};"
>
{tooltip.content}
</div>

<Canvas>
<T.PerspectiveCamera makeDefault position={camera_position} fov={zoom}>
<OrbitControls enableZoom enablePan target={{ x: a / 2, y: b / 2, z: c / 2 }} />
Expand All @@ -80,31 +91,27 @@
<T.DirectionalLight position={[-3, 10, -10]} intensity={0.2} />
<T.AmbientLight intensity={0.2} />

{#each structure.sites as { xyz: position, species }}
{#each structure.sites as { xyz, species }}
{@const symbol = species[0].element}
{@const radius = (same_size_atoms ? 1 : atomic_radii[symbol]) * atom_radius}
<T.Mesh
{position}
interactive
on:pointerenter={(e) => on_mouse_enter(e, position, symbol)}
on:pointerleave={on_mouse_leave}
>
<T.Mesh position={xyz}>
<T.SphereGeometry args={[radius, 20, 20]} />
<T.MeshStandardMaterial
color="rgb({atomic_colors[symbol].map((x) => Math.floor(x * 255)).join(',')})"
/>
</T.Mesh>
{/each}

<!-- Render lattice as a cuboid of white lines -->
<T.Mesh position={[lattice[0][0] / 2, lattice[1][1] / 2, lattice[2][2] / 2]}>
<T.BoxGeometry args={[lattice[0][0], lattice[1][1], lattice[2][2]]} />
<T.MeshBasicMaterial transparent opacity={0.2} />
<T.LineSegments>
<T.EdgesGeometry />
<T.LineBasicMaterial color="white" />
</T.LineSegments>
</T.Mesh>
{#if show_cell}
<T.Mesh position={[a / 2, b / 2, c / 2]}>
<T.BoxGeometry args={[a, b, c]} />
<T.MeshBasicMaterial
transparent
opacity={cell_opacity ?? (show_cell === 'surface' ? 0.2 : 1)}
wireframe={show_cell === 'wireframe'}
/>
</T.Mesh>
{/if}
</Canvas>
</div>

Expand All @@ -130,7 +137,7 @@
top: 5pt;
right: 5pt;
background-color: rgba(255, 255, 255, 0.2);
padding: 2em 5pt 0;
padding: 2em 6pt 3pt;
border-radius: 3pt;
visibility: hidden;
opacity: 0;
Expand All @@ -141,13 +148,10 @@
visibility: visible;
opacity: 1;
}
.tooltip {
position: absolute;
background-color: rgba(0, 0, 0, 0.7);
select {
margin-left: 5pt;
color: white;
padding: 5px;
border-radius: 5px;
pointer-events: none;
/* transparent */
background-color: rgba(255, 255, 255, 0.2);
}
</style>
7 changes: 7 additions & 0 deletions src/lib/StructureCard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@
{pretty_num(alpha)}°, {pretty_num(beta)}°, {pretty_num(gamma)}°
</span>
</strong>
{#if structure?.charge}
<strong>
Charge:
<span class="value">{pretty_num(structure?.charge)}</span>
</strong>
{/if}
</div>

<style>
Expand All @@ -55,6 +61,7 @@
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
border-radius: var(--sc-radius, 3pt);
padding: var(--sc-padding, 1ex 1em);
margin: var(--sc-margin, 1em 0);
gap: var(--sc-gap, 1ex 1em);
background-color: var(--sc-bg, rgba(255, 255, 255, 0.1));
font-size: var(--sc-font-size);
Expand Down
10 changes: 2 additions & 8 deletions src/routes/(demos)/structure/+page.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,17 @@

```svelte example stackblitz code_above
<script>
import { Structure, StructureCard, alphabetical_formula } from '$lib'
import { Structure, StructureCard } from '$lib'
import structure from './mp-1234.json'
const mp_id = 'mp-1234'
const href = `https://materialsproject.org/materials/${mp_id}`
</script>
<StructureCard {structure} --sc-padding="1ex 1em 2em">
<StructureCard {structure}>
<a slot="title" {href}>{mp_id}</a>
</StructureCard>
<Structure {structure} />
<style>
h2 {
text-align: center;
}
</style>
```

<details>
Expand Down
1 change: 1 addition & 0 deletions src/site/DemoNav.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
margin: 1em auto 3em;
max-width: 45em;
flex-wrap: wrap;
font-size: 14pt;
}
nav > a {
padding: 0 4pt;
Expand Down
4 changes: 4 additions & 0 deletions vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ export default {
port: 3000,
},

ssr: {
noExternal: [`three`],
},

preview: {
port: 3000,
},
Expand Down

0 comments on commit 072d57a

Please sign in to comment.