diff --git a/source/website/sharingdialog.js b/source/website/sharingdialog.js index 05e3be4..4e539f1 100644 --- a/source/website/sharingdialog.js +++ b/source/website/sharingdialog.js @@ -22,7 +22,8 @@ export function ShowSharingDialog (fileList, settings, camera) let copyText = 'Copy'; let copiedText = 'Copied'; let container = AddDiv (parentDiv, 'ov_dialog_copyable_input'); - let input = AddDomElement (container, 'input', 'ov_dialog_text'); + let input = AddDomElement (container, 'input', null); + input.setAttribute ('type', 'text'); input.readOnly = true; let button = AddDiv (container, 'ov_button outline ov_dialog_copyable_input_button', copyText); button.addEventListener ('click', () => { diff --git a/source/website/snapshotdialog.js b/source/website/snapshotdialog.js index 4180ee0..4db006c 100644 --- a/source/website/snapshotdialog.js +++ b/source/website/snapshotdialog.js @@ -1,8 +1,8 @@ import { AddDiv, CreateDomElement } from '../engine/viewer/domutils.js'; -import { AddRadioButton } from '../website/utils.js'; +import { AddNumberInput, AddRadioButton } from '../website/utils.js'; import { ButtonDialog } from './dialog.js'; import { DownloadUrlAsFile } from './utils.js'; -import { CookieGetStringVal, CookieSetStringVal } from './cookiehandler.js'; +import { CookieGetIntVal, CookieGetStringVal, CookieSetIntVal, CookieSetStringVal } from './cookiehandler.js'; import { HandleEvent } from './eventhandler.js'; export function ShowSnapshotDialog (viewer) @@ -13,35 +13,71 @@ export function ShowSnapshotDialog (viewer) AddRadioButton (line, id, 'snapshot_size', text, isSelected, onChange); } - function GetImageUrl (viewer, snapshotSize) + function GetImageUrl (viewer, size) { - if (snapshotSize.size === null) { - let size = viewer.GetImageSize (); - return viewer.GetImageAsDataUrl (size.width, size.height); - } else { - return viewer.GetImageAsDataUrl (snapshotSize.size[0], snapshotSize.size[1]); + let width = parseInt (size[0], 10); + let height = parseInt (size[1], 10); + if (width < 1 || height < 1) { + return null; } + return viewer.GetImageAsDataUrl (size[0], size[1]); } - function UpdatePreview (viewer, previewImage, snapshotSize) + function UpdatePreview (viewer, previewImage, size) { - let url = GetImageUrl (viewer, snapshotSize); + let url = GetImageUrl (viewer, size); previewImage.src = url; } + function UpdateCustomStatus (sizes, customIndex, selectedIndex) + { + let customSize = sizes[customIndex]; + customSize.widthInput.disabled = (selectedIndex !== customIndex); + customSize.heightInput.disabled = (selectedIndex !== customIndex); + } + + function GetSize (sizes, selectedIndex) + { + let selectedSize = sizes[selectedIndex]; + if (selectedSize.size !== null) { + return selectedSize.size; + } else { + return [ + selectedSize.widthInput.value, + selectedSize.heightInput.value + ]; + } + } + + function AddWidthHeightNumberInput (parentDiv, text, onChange) + { + let line = AddDiv (parentDiv, 'ov_dialog_row'); + AddDiv (line, 'ov_snapshot_dialog_param_name', text); + let numberInput = AddNumberInput (line, 'ov_dialog_text', onChange); + numberInput.classList.add ('ov_snapshot_dialog_param_value'); + return numberInput; + } + let selectedIndex = 0; + let customIndex = 3; let sizes = [ { - name : 'Current size', - size : null - }, - { - name : '1280 x 720', + name : 'Small (1280x720)', size : [1280, 720] }, { - name : '1920 x 1080', + name : 'Medium (1920x1080)', size : [1920, 1080] + }, + { + name : 'Large (2560x1440)', + size : [2560, 1440] + }, + { + name : 'Custom', + size : null, + widthInput : null, + heightInput : null } ]; @@ -59,8 +95,10 @@ export function ShowSnapshotDialog (viewer) onClick () { dialog.Close (); HandleEvent ('snapshot_created', sizes[selectedIndex].name); - let url = GetImageUrl (viewer, sizes[selectedIndex]); - DownloadUrlAsFile (url, 'model.png'); + let url = GetImageUrl (viewer, GetSize (sizes, selectedIndex)); + if (url !== null) { + DownloadUrlAsFile (url, 'model.png'); + } } } ]); @@ -76,18 +114,32 @@ export function ShowSnapshotDialog (viewer) } } + let customSize = sizes[customIndex]; for (let i = 0; i < sizes.length; i++) { let size = sizes[i]; let selected = (i === selectedIndex); AddSizeRadioButton (optionsDiv, 'snapshot_' + i.toString (), size.name, selected, () => { selectedIndex = i; CookieSetStringVal ('ov_last_snapshot_size', size.name); - UpdatePreview (viewer, previewImage, size); + UpdatePreview (viewer, previewImage, GetSize (sizes, i)); + UpdateCustomStatus (sizes, customIndex, selectedIndex); }); } + customSize.widthInput = AddWidthHeightNumberInput (optionsDiv, 'Width', (val) => { + UpdatePreview (viewer, previewImage, GetSize (sizes, selectedIndex)); + CookieSetIntVal ('ov_snapshot_custom_width', val); + }); + customSize.heightInput = AddWidthHeightNumberInput (optionsDiv, 'Height', (val) => { + UpdatePreview (viewer, previewImage, GetSize (sizes, selectedIndex)); + CookieSetIntVal ('ov_snapshot_custom_height', val); + }); + customSize.widthInput.value = CookieGetIntVal ('ov_snapshot_custom_width', 1000); + customSize.heightInput.value = CookieGetIntVal ('ov_snapshot_custom_height', 1000); + UpdateCustomStatus (sizes, customIndex, selectedIndex); + contentDiv.appendChild (previewImage); - UpdatePreview (viewer, previewImage, sizes[selectedIndex]); + UpdatePreview (viewer, previewImage, GetSize (sizes, selectedIndex)); dialog.Open (); return dialog; diff --git a/source/website/themehandler.js b/source/website/themehandler.js index 17b2325..24a1f71 100644 --- a/source/website/themehandler.js +++ b/source/website/themehandler.js @@ -6,6 +6,7 @@ export class ThemeHandler this.css = { '--ov_foreground_color': {}, '--ov_background_color': {}, + '--ov_disabled_foreground_color': {}, '--ov_button_color': {}, '--ov_button_hover_color': {}, '--ov_button_text_color': {}, diff --git a/source/website/utils.js b/source/website/utils.js index 1b109fa..63f3eff 100644 --- a/source/website/utils.js +++ b/source/website/utils.js @@ -265,6 +265,25 @@ export function GetFilesFromDataTransfer (dataTransfer, onReady) } } +export function AddNumberInput (parentElement, className, onChange) +{ + let numberInput = AddDomElement (parentElement, 'input', className); + numberInput.setAttribute ('type', 'text'); + let onChangeTimeout = null; + numberInput.addEventListener ('input', () => { + numberInput.value = numberInput.value.replace (/[^0-9]/g, ''); + if (onChange) { + if (onChangeTimeout !== null) { + clearTimeout (onChangeTimeout); + } + onChangeTimeout = setTimeout (() => { + onChange (numberInput.value); + }, 1000); + } + }); + return numberInput; +} + export function AddCheckbox (parentElement, id, text, isChecked, onChange) { let label = AddDomElement (parentElement, 'label'); diff --git a/website/css/controls.css b/website/css/controls.css index cb058db..af084e9 100644 --- a/website/css/controls.css +++ b/website/css/controls.css @@ -79,7 +79,18 @@ div.ov_tooltip box-shadow: var(--ov_shadow); } -input.ov_dialog_text +input[type=text] +{ + color: var(--ov_dialog_foreground_color); + background: var(--ov_dialog_background_color); +} + +input[type=text]:disabled +{ + color: var(--ov_disabled_foreground_color); +} + +textarea { color: var(--ov_dialog_foreground_color); background: var(--ov_dialog_background_color); diff --git a/website/css/dialogs.css b/website/css/dialogs.css index 2e43567..4ea868e 100644 --- a/website/css/dialogs.css +++ b/website/css/dialogs.css @@ -22,12 +22,6 @@ div.ov_dialog border-radius: 5px; } -div.ov_dialog textarea -{ - color: var(--ov_dialog_foreground_color); - background: var(--ov_dialog_background_color); -} - div.ov_dialog div.ov_dialog_title { font-size: 19px; @@ -82,6 +76,14 @@ div.ov_dialog div.ov_dialog_submessage margin-top: 10px; } +div.ov_dialog input.ov_dialog_text +{ + padding: 5px; + border: 1px solid var(--ov_border_color); + border-radius: 5px; + overflow: auto; +} + div.ov_dialog textarea.ov_dialog_textarea { margin: 10px 0px; @@ -251,7 +253,7 @@ div.ov_progress div.ov_progress_text div.ov_snapshot_dialog_left { - width: 140px; + width: 190px; float: left; } @@ -259,12 +261,27 @@ img.ov_snapshot_dialog_preview { background: var(--ov_border_color); border: 1px solid var(--ov_border_color); - width: 240px; - height: 135px; + width: 183px; + height: 183px; object-fit: contain; float: right; } +div.ov_snapshot_dialog_param_name +{ + width: 60px; + margin-left: 30px; + margin-top: 3px; + float: left; +} + +input.ov_snapshot_dialog_param_value +{ + width: 80px; + text-align: right; + float: left; +} + @media (hover) { diff --git a/website/css/themes.css b/website/css/themes.css index a137218..f2ae8c9 100644 --- a/website/css/themes.css +++ b/website/css/themes.css @@ -2,6 +2,7 @@ { --ov_foreground_color: #000000; --ov_background_color: #ffffff; + --ov_disabled_foreground_color: #cccccc; --ov_button_color: #3393bd; --ov_button_hover_color: #146a8f; --ov_button_text_color: #ffffff; @@ -27,6 +28,7 @@ --ov_foreground_color_dark: #fafafa; --ov_background_color_dark: #2a2b2e; + --ov_disabled_foreground_color_dark: #888888; --ov_button_color_dark: #3393bd; --ov_button_hover_color_dark: #146a8f; --ov_button_text_color_dark: #ffffff;