Skip to content

Commit

Permalink
Merge pull request #301 from Smithsonian/rc-44
Browse files Browse the repository at this point in the history
Merging Rc 44
  • Loading branch information
gjcope authored Aug 29, 2024
2 parents 647ce8f + 338d2a9 commit d52eb1d
Show file tree
Hide file tree
Showing 14 changed files with 146 additions and 51 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "voyager",
"version": "0.42.0",
"version": "0.44.0",
"description": "Smithsonian DPO Voyager - 3D Explorer and Tool Suite",
"scripts": {
"start": "npm run server",
Expand Down
4 changes: 2 additions & 2 deletions source/client/annotations/CircleSprite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,10 +303,10 @@ class CircleAnnotation extends AnnotationElement
// Handle shifting annotation body when out-of-bounds
if (this.isExpanded) {
this.contentElement.style.removeProperty("transform");
if (this.classList.contains("sv-align-right")) {
if (this.classList.contains("sv-align-right") && !this.overlayed) {
this.contentElement.style.transform = `translateX(-${this.offsetWidth}px)`;
}
if (this.classList.contains("sv-align-bottom")) {
if (this.classList.contains("sv-align-bottom") && !this.overlayed) {
this.contentElement.style.transform = `translateY(-${this.offsetHeight-this.markerElement.offsetHeight}px)`;
}
}
Expand Down
8 changes: 7 additions & 1 deletion source/client/components/CVAudioManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,12 @@ export default class CVAudioManager extends Component
play(id: string)
{
const { outs } = this;
const uri = this.getAudioClipUri(id);

if(!uri) {
Notification.show("Failed to play audio clip - no uri", "warning");
return;
}

// handle currently playing track
if(outs.isPlaying.value) {
Expand All @@ -309,7 +315,7 @@ export default class CVAudioManager extends Component
this.activeId = id;
this.isPlaying = true;
Object.keys(this.audioViews).forEach((key) => this.audioViews[key].requestUpdate());
this.analytics.sendProperty("Audio_Play", this.getAudioClipUri(id));
this.analytics.sendProperty("Audio_Play", uri);
})
.catch(error => Notification.show(`Failed to play audio at '${this.audioPlayer.getAttribute("src")}':${error}`, "warning"));
}
Expand Down
32 changes: 12 additions & 20 deletions source/client/components/CVStaticAnnotationView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,16 @@ import { ITypedEvent, Node, types } from "@ff/graph/Component";
import Viewport, { IViewportDisposeEvent } from "@ff/three/Viewport";
import HTMLSpriteGroup, { HTMLSprite } from "@ff/three/HTMLSpriteGroup";

import CObject3D, { IPointerEvent, IRenderContext } from "@ff/scene/components/CObject3D";
import CRenderer from "@ff/scene/components/CRenderer";
import CObject3D, { IRenderContext } from "@ff/scene/components/CObject3D";

import CVModel2 from "./CVModel2";
import CVMeta from "./CVMeta";
import CVReader from "./CVReader";
import unitScaleFactor from "../utils/unitScaleFactor";

import { IAnnotation } from "client/schema/model";
import Annotation from "../models/Annotation";

import AnnotationSprite, { IAnnotationClickEvent, IAnnotationLinkEvent } from "../annotations/AnnotationSprite";
import { IAnnotationClickEvent } from "../annotations/AnnotationSprite";
import AnnotationFactory from "../annotations/AnnotationFactory";

import "../annotations/StandardSprite";
import "../annotations/ExtendedSprite";
import "../annotations/CircleSprite";
import CVARManager from "./CVARManager";
import CVLanguageManager from "./CVLanguageManager";
import { ELanguageType, EUnitType } from "client/schema/common";
import CVAssetReader from "./CVAssetReader";
import CVAudioManager from "./CVAudioManager";
import CVAssetManager from "./CVAssetManager";

////////////////////////////////////////////////////////////////////////////////

Expand All @@ -63,9 +50,9 @@ export default class CVStaticAnnotationView extends CObject3D
{
static readonly typeName: string = "CVStaticAnnotationView";

/*static readonly ins = {
unitScale: types.Number("Transform.UnitScale", { preset: 1, precision: 5 }),
activeTags: types.String("Tags.Active"),
static readonly ins = {
unitScale: types.Number("Transform.UnitScale", { preset: 1, precision: 5 })
/*activeTags: types.String("Tags.Active"),
title: types.String("Annotation.Title"),
lead: types.String("Annotation.Lead"),
marker: types.String("Annotation.Marker"),
Expand All @@ -80,10 +67,10 @@ export default class CVStaticAnnotationView extends CObject3D
audioId: types.String("Annotation.AudioID"),
tilt: types.Number("Annotation.Tilt"),
azimuth: types.Number("Annotation.Azimuth"),
color: types.ColorRGB("Annotation.Color"),
color: types.ColorRGB("Annotation.Color"),*/
};

ins = this.addInputs<CObject3D, typeof CVStaticAnnotationView.ins>(CVStaticAnnotationView.ins);*/
ins = this.addInputs<CObject3D, typeof CVStaticAnnotationView.ins>(CVStaticAnnotationView.ins);

//private _activeAnnotation: Annotation = null;
private _annotations: Dictionary<Annotation> = {};
Expand All @@ -106,6 +93,11 @@ export default class CVStaticAnnotationView extends CObject3D

const ins = this.ins;
const object3D = this.object3D;

if (ins.unitScale.changed) {
object3D.scale.setScalar(ins.unitScale.value);
object3D.updateMatrix();
}

if (ins.visible.changed) {
(object3D as HTMLSpriteGroup).setVisible(ins.visible.value);
Expand Down
8 changes: 7 additions & 1 deletion source/client/components/CVTape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ export default class CVTape extends CObject3D
lineMaterial.transparent = true;
this.line = new Line(lineGeometry, lineMaterial);
this.line.visible = false;
this.line.frustumCulled = false;

// add distance label
this.annotationView = this.node.createComponent(CVStaticAnnotationView);
Expand Down Expand Up @@ -164,6 +165,10 @@ export default class CVTape extends CObject3D

endPin.scale.setScalar(radius * 0.003);
endPin.updateMatrix();

const defaultScale = radius * 0.05;
this.annotationView.ins.unitScale.setValue(defaultScale);
ins.endPosition.set(); // always trigger recalculation
}

// if tape is enabled, listen for pointer events to set tape start/end
Expand Down Expand Up @@ -234,7 +239,8 @@ export default class CVTape extends CObject3D

// update distance label
const data = this.label.data;
data.position = [(positions[0]+positions[3])/2.0,(positions[1]+positions[4])/2.0,(positions[2]+positions[5])/2.0];
const scaleFactor = 1/this.annotationView.ins.unitScale.value;
data.position = [scaleFactor*(positions[0]+positions[3])/2.0,scaleFactor*(positions[1]+positions[4])/2.0,scaleFactor*(positions[2]+positions[5])/2.0];
const units = this.ins.globalUnits.getOptionText();
this.label.title = tapeLength.toFixed(2) + " " + units;
this.annotationView.updateAnnotation(this.label, true);
Expand Down
4 changes: 2 additions & 2 deletions source/client/models/DerivativeList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ export default class DerivativeList
createModelAsset(assetPath: string, quality: EDerivativeQuality | string): Derivative
{
quality = (typeof quality === "string" ? EDerivativeQuality[quality] : quality) as EDerivativeQuality;
quality = isFinite(quality) ? quality : EDerivativeQuality.Medium;
quality = quality != null ? quality : EDerivativeQuality.Medium;

const derivative = this.getOrCreate(EDerivativeUsage.Web3D, quality);

Expand All @@ -173,7 +173,7 @@ export default class DerivativeList
createMeshAsset(geoPath: string, colorMapPath?: string, occlusionMapPath?: string, normalMapPath?: string, quality?: EDerivativeQuality | string): Derivative
{
quality = (typeof quality === "string" ? EDerivativeQuality[quality] : quality) as EDerivativeQuality;
quality = isFinite(quality) ? quality : EDerivativeQuality.Medium;
quality = quality != null ? quality : EDerivativeQuality.Medium;

const derivative = this.getOrCreate(EDerivativeUsage.Web3D, quality);

Expand Down
68 changes: 61 additions & 7 deletions source/client/ui/PropertyColor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,10 @@ import Property from "@ff/graph/Property";
import CustomElement, { customElement, property, PropertyValues, html } from "@ff/ui/CustomElement";

import "@ff/ui/Button";
import { IButtonClickEvent } from "@ff/ui/Button";

import "@ff/ui/ColorEdit";
import { IColorEditChangeEvent } from "@ff/ui/ColorEdit";

import {getFocusableElements, focusTrap} from "../utils/focusHelpers";
import type { IColorEditChangeEvent } from "@ff/ui/ColorEdit";
import { focusTrap, getFocusableElements } from "client/utils/focusHelpers";

////////////////////////////////////////////////////////////////////////////////

Expand All @@ -39,8 +37,12 @@ export default class PropertyColor extends CustomElement
@property({ type: String })
name = "";

@property({attribute: false, type: Boolean})
pickerActive :boolean = false;

protected color: Color = new Color();


constructor()
{
super();
Expand All @@ -52,6 +54,11 @@ export default class PropertyColor extends CustomElement
this.classList.add("sv-property", "sv-property-color");
}

protected disconnected()
{
this.pickerActive = false;
}

protected update(changedProperties: PropertyValues): void
{
if (!this.property) {
Expand All @@ -73,6 +80,15 @@ export default class PropertyColor extends CustomElement
}
}

if(changedProperties.has("pickerActive")){
if(this.pickerActive){
this.setPickerFocus();
document.addEventListener("pointerdown", this.onPointerDown, { capture: true, passive: true });
}else{
document.removeEventListener("pointerdown", this.onPointerDown, {capture: true});
}
}

super.update(changedProperties);
}

Expand All @@ -83,13 +99,25 @@ export default class PropertyColor extends CustomElement
const color = this.color.toString();

return html`<label class="ff-label ff-off">${name}</label>
<input type="color" tabindex="0" .value="${color}" @change=${this.onColorChange}>
<ff-button style="background-color: ${color}" title="${name} Color Picker" @click=${this.onButtonClick}></ff-button>
${this.pickerActive ? html`<ff-color-edit .color=${this.color} @keydown=${e =>this.onKeyDown(e)} @change=${this.onColorChange}></ff-color-edit>` : null}
`;
}

protected onColorChange(event: Event)
protected async setPickerFocus()
{
await this.updateComplete;
const container = this.getElementsByTagName("ff-color-edit").item(0) as HTMLElement;
(getFocusableElements(container)[0] as HTMLElement).focus();
}

protected onButtonClick(event: Event)
{
this.pickerActive = !this.pickerActive;
}

protected onColorChange(event: IColorEditChangeEvent)
{
this.color = new Color((event.target as HTMLInputElement).value);
this.property.setValue(this.color.toRGBArray());
}

Expand All @@ -98,4 +126,30 @@ export default class PropertyColor extends CustomElement
this.color.fromArray(value);
this.requestUpdate();
}
// if color picker is active and user clicks outside, close picker
protected onPointerDown = (event: PointerEvent) => {
if (!this.pickerActive) {
return;
}

if (event.composedPath()[0] instanceof Node && this.contains(event.composedPath()[0] as Node)) {
return;
}
this.pickerActive = false;
}

protected onKeyDown(e: KeyboardEvent)
{
if (e.code === "Escape" || e.code === "Enter") {
e.preventDefault();
e.stopPropagation();
this.pickerActive = false;

(this.getElementsByTagName("ff-button")[0] as HTMLElement).focus();
}
else if(e.code === "Tab") {
const element = this.getElementsByTagName("ff-color-edit")[0] as HTMLElement;
focusTrap(getFocusableElements(element) as HTMLElement[], e);
}
}
}
2 changes: 1 addition & 1 deletion source/client/ui/PropertyOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export default class PropertyOptions extends CustomElement
return html`
<label class="ff-label ff-off">${name}</label>
<select ?multiple=${property.isMulti()} .value=${live(value)} class="sv-property-field" @change=${(e)=>{
this.property.setValue(e.target.value)
this.property.setValue(parseInt(e.target.value))
}}>
${optionsList}
</select>
Expand Down
52 changes: 38 additions & 14 deletions source/client/ui/explorer/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,6 @@ $pad: $canvas-border-width + $main-menu-button-size + 8px;
}

&:has(:focus-visible) {
outline: none;
background-color: $menu-color-background-dark;
box-shadow: 0 0 3pt 2pt lighten($color-primary, 50%);
opacity: 1 !important;
}

Expand Down Expand Up @@ -293,6 +290,12 @@ $pad: $canvas-border-width + $main-menu-button-size + 8px;
font-size: 0.9em;
color: #fff;
-webkit-tap-highlight-color: transparent;

&:focus-visible {
outline: none;
background-color: $menu-color-background-dark;
box-shadow: 0 0 3pt 2pt lighten($color-primary, 50%);
}
}

.sv-annotation-body {
Expand All @@ -302,6 +305,12 @@ $pad: $canvas-border-width + $main-menu-button-size + 8px;
margin: 0px 1px;
width: 100%;

&:has(:focus-visible) {
outline: none;
background-color: $menu-color-background-dark;
box-shadow: 0 0 3pt 2pt lighten($color-primary, 50%);
}

.sv-title {
padding: 0 0 2px 0;
font-weight: bold;
Expand Down Expand Up @@ -360,6 +369,12 @@ $pad: $canvas-border-width + $main-menu-button-size + 8px;
pointer-events: auto;
overflow-wrap: normal;

&:has(:focus-visible) {
outline: none;
background-color: $menu-color-background-dark;
box-shadow: 0 0 3pt 2pt lighten($color-primary, 50%);
}

&.sv-expanded {
width: 20%;
min-width: 180px;
Expand Down Expand Up @@ -1230,22 +1245,31 @@ $tour-entry-indent: 12px;
}

&.sv-property-color {
input[type="color"] {
cursor: pointer;
border: none;
margin: 2px;
position: relative;
display: block;

& > .ff-button {
width: 26px;
max-width: 20ch;
height: 26px;
inline-size: 26px;
box-sizing: border-box;
padding: 1px;
background: $color-background;
border-radius: 2px;
&::-webkit-color-swatch-wrapper {
padding: 0;
}
&::-webkit-color-swatch, &::-moz-color-swatch {
border: none;
border-radius: 2px;
}
border: none;
margin: 2px;
}

.ff-color-edit {
position: absolute;
width: 200px;
height: 180px;
right: 0px;
top: -188px;
background: $color-background-dark;
padding: 8px;
border-radius: 2px;
}
}

Expand Down
4 changes: 4 additions & 0 deletions source/client/ui/story/AnnotationsTaskView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ export default class AnnotationsTaskView extends TaskView<CVAnnotationsTask>

protected render()
{
if(!this.activeDocument) {
return;
}

const node = this.activeNode;
const annotations = node && node.getComponent(CVAnnotationView, true);
const languageManager = this.activeDocument.setup.language;
Expand Down
4 changes: 4 additions & 0 deletions source/client/ui/story/ArticlesTaskView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ export default class ArticlesTaskView extends TaskView<CVArticlesTask>

protected render()
{
if(!this.activeDocument) {
return;
}

const task = this.task;
const articles = task.articles;
const activeArticle = task.activeArticle;
Expand Down
Loading

0 comments on commit d52eb1d

Please sign in to comment.