diff --git a/sandbox/embed_selfhost_snapshot.html b/sandbox/embed_selfhost_snapshot.html
index 585abca..9074cbb 100644
--- a/sandbox/embed_selfhost_snapshot.html
+++ b/sandbox/embed_selfhost_snapshot.html
@@ -22,7 +22,7 @@
for (let embeddedViewer of embeddedViewers) {
let viewer = embeddedViewer.GetViewer ();
let img = document.createElement ('img');
- img.src = viewer.GetImageAsDataUrl (400, 300);
+ img.src = viewer.GetImageAsDataUrl (400, 300, false);
document.body.appendChild (img);
}
}
diff --git a/source/engine/viewer/viewer.js b/source/engine/viewer/viewer.js
index 1f90aa3..ae5d13f 100644
--- a/source/engine/viewer/viewer.js
+++ b/source/engine/viewer/viewer.js
@@ -587,7 +587,7 @@ export class Viewer
};
}
- GetImageAsDataUrl (width, height)
+ GetImageAsDataUrl (width, height, isTransparent)
{
let originalSize = this.GetImageSize ();
let renderWidth = width;
@@ -596,10 +596,15 @@ export class Viewer
renderWidth /= window.devicePixelRatio;
renderHeight /= window.devicePixelRatio;
}
+ let clearAlpha = this.renderer.getClearAlpha ();
+ if (isTransparent) {
+ this.renderer.setClearAlpha (0.0);
+ }
this.ResizeRenderer (renderWidth, renderHeight);
this.Render ();
let url = this.renderer.domElement.toDataURL ();
this.ResizeRenderer (originalSize.width, originalSize.height);
+ this.renderer.setClearAlpha (clearAlpha);
return url;
}
diff --git a/source/website/css/dialogs.css b/source/website/css/dialogs.css
index f8f8efa..ff8f27f 100644
--- a/source/website/css/dialogs.css
+++ b/source/website/css/dialogs.css
@@ -79,7 +79,7 @@ div.ov_dialog div.ov_dialog_submessage
div.ov_dialog input.ov_dialog_text
{
padding: 5px;
- border: 1px solid var(--ov_border_color);
+ border: 1px solid var(--ov_dialog_control_border_color);
border-radius: 5px;
overflow: auto;
}
@@ -89,7 +89,7 @@ div.ov_dialog textarea.ov_dialog_textarea
margin: 10px 0px;
width: 100%;
height: 120px;
- border: 1px solid var(--ov_border_color);
+ border: 1px solid var(--ov_dialog_control_border_color);
box-sizing: border-box;
}
@@ -130,7 +130,7 @@ div.ov_dialog div.ov_dialog_file_link div.ov_dialog_file_link_text
div.ov_dialog div.ov_dialog_copyable_input
{
padding: 3px;
- border: 1px solid var(--ov_border_color);
+ border: 1px solid var(--ov_dialog_control_border_color);
border-radius: 5px;
overflow: auto;
}
@@ -176,6 +176,7 @@ div.ov_dialog div.ov_dialog_row_value
div.ov_dialog select.ov_select
{
width: 100%;
+ border: 1px solid var(--ov_dialog_control_border_color);
box-sizing: border-box;
}
@@ -251,20 +252,27 @@ div.ov_progress div.ov_progress_text
text-align: center;
}
-div.ov_snapshot_dialog_left
+div.ov_snapshot_dialog
{
- width: 190px;
- float: left;
+ width: 480px;
+ float: right;
+}
+
+div.ov_snapshot_dialog_options
+{
+ width: 230px;
+ float: right;
}
img.ov_snapshot_dialog_preview
{
background: var(--ov_border_color);
- border: 1px solid var(--ov_border_color);
- width: 183px;
- height: 183px;
+ border: 1px solid var(--ov_dialog_control_border_color);
+ width: 230px;
+ height: 230px;
object-fit: contain;
- float: right;
+ float: left;
+ border-radius: 5px;
}
div.ov_snapshot_dialog_param_name
@@ -282,6 +290,12 @@ input.ov_snapshot_dialog_param_value
float: left;
}
+div.ov_snapshot_dialog_separator
+{
+ margin: 10px 0px;
+ border-bottom: 1px solid var(--ov_border_color);
+}
+
@media (hover)
{
diff --git a/source/website/css/themes.css b/source/website/css/themes.css
index f2ae8c9..8215978 100644
--- a/source/website/css/themes.css
+++ b/source/website/css/themes.css
@@ -23,6 +23,7 @@
--ov_treeview_selected_color: #eeeeee;
--ov_dialog_foreground_color: #000000;
--ov_dialog_background_color: #ffffff;
+ --ov_dialog_control_border_color: #e1e1e1;
--ov_border_color: #dddddd;
--ov_shadow: 0px 0px 10px #cccccc;
@@ -48,7 +49,8 @@
--ov_toolbar_separator_color_dark: #888888;
--ov_treeview_selected_color_dark: #38393d;
--ov_dialog_foreground_color_dark: #fafafa;
- --ov_dialog_background_color_dark: #333333;
+ --ov_dialog_background_color_dark: #3c3c40;
+ --ov_dialog_control_border_color_dark: #e1e1e1;
--ov_border_color_dark: #444444;
--ov_shadow_dark: 0px 0px 10px #222222;
}
diff --git a/source/website/snapshotdialog.js b/source/website/snapshotdialog.js
index c1186f6..26dd97c 100644
--- a/source/website/snapshotdialog.js
+++ b/source/website/snapshotdialog.js
@@ -1,8 +1,8 @@
-import { AddDiv, CreateDomElement } from '../engine/viewer/domutils.js';
-import { AddNumberInput, AddRadioButton } from '../website/utils.js';
+import { AddDiv, AddDomElement, CreateDomElement } from '../engine/viewer/domutils.js';
+import { AddCheckbox, AddNumberInput, AddRadioButton } from '../website/utils.js';
import { ButtonDialog } from './dialog.js';
import { DownloadUrlAsFile } from './utils.js';
-import { CookieGetIntVal, CookieGetStringVal, CookieSetIntVal, CookieSetStringVal } from './cookiehandler.js';
+import { CookieGetBoolVal, CookieGetIntVal, CookieGetStringVal, CookieSetBoolVal, CookieSetIntVal, CookieSetStringVal } from './cookiehandler.js';
import { HandleEvent } from './eventhandler.js';
export function ShowSnapshotDialog (viewer)
@@ -13,19 +13,19 @@ export function ShowSnapshotDialog (viewer)
AddRadioButton (line, id, 'snapshot_size', text, isSelected, onChange);
}
- function GetImageUrl (viewer, size)
+ function GetImageUrl (viewer, size, isTransparent)
{
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]);
+ return viewer.GetImageAsDataUrl (size[0], size[1], isTransparent);
}
- function UpdatePreview (viewer, previewImage, size)
+ function UpdatePreview (viewer, previewImage, size, isTransparent)
{
- let url = GetImageUrl (viewer, size);
+ let url = GetImageUrl (viewer, size, isTransparent);
previewImage.src = url;
}
@@ -62,6 +62,7 @@ export function ShowSnapshotDialog (viewer)
}
let selectedIndex = 0;
+ let isTransparent = CookieGetBoolVal ('ov_last_snapshot_transparent', false);
let customIndex = 3;
let sizes = [
{
@@ -98,7 +99,7 @@ export function ShowSnapshotDialog (viewer)
onClick () {
dialog.Close ();
HandleEvent ('snapshot_created', sizes[selectedIndex].name);
- let url = GetImageUrl (viewer, GetSize (sizes, selectedIndex));
+ let url = GetImageUrl (viewer, GetSize (sizes, selectedIndex), isTransparent);
if (url !== null) {
DownloadUrlAsFile (url, 'model.png');
}
@@ -106,8 +107,13 @@ export function ShowSnapshotDialog (viewer)
}
]);
- let optionsDiv = AddDiv (contentDiv, 'ov_snapshot_dialog_left');
+ let dialogDiv = dialog.GetContentDiv ();
+ dialogDiv.classList.add ('ov_snapshot_dialog');
+
let previewImage = CreateDomElement ('img', 'ov_snapshot_dialog_preview');
+ contentDiv.appendChild (previewImage);
+
+ let optionsDiv = AddDiv (contentDiv, 'ov_snapshot_dialog_options');
let lastSnapshotSizeName = CookieGetStringVal ('ov_last_snapshot_size', sizes[1].name);
for (let i = 0; i < sizes.length; i++) {
@@ -124,25 +130,32 @@ export function ShowSnapshotDialog (viewer)
AddSizeRadioButton (optionsDiv, 'snapshot_' + i.toString (), size.name, selected, () => {
selectedIndex = i;
CookieSetStringVal ('ov_last_snapshot_size', size.name);
- UpdatePreview (viewer, previewImage, GetSize (sizes, i));
+ UpdatePreview (viewer, previewImage, GetSize (sizes, i), isTransparent);
UpdateCustomStatus (sizes, customIndex, selectedIndex);
});
}
customSize.widthInput = AddWidthHeightNumberInput (optionsDiv, 'Width', (val) => {
- UpdatePreview (viewer, previewImage, GetSize (sizes, selectedIndex));
+ UpdatePreview (viewer, previewImage, GetSize (sizes, selectedIndex), isTransparent);
CookieSetIntVal ('ov_snapshot_custom_width', val);
});
customSize.heightInput = AddWidthHeightNumberInput (optionsDiv, 'Height', (val) => {
- UpdatePreview (viewer, previewImage, GetSize (sizes, selectedIndex));
+ UpdatePreview (viewer, previewImage, GetSize (sizes, selectedIndex), isTransparent);
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, GetSize (sizes, selectedIndex));
+ AddDomElement (optionsDiv, 'div', 'ov_snapshot_dialog_separator', null);
+
+ let transparentCheckbox = AddCheckbox (optionsDiv, 'snapshot_transparent_background', 'Transparent background', isTransparent, () => {
+ isTransparent = transparentCheckbox.checked;
+ UpdatePreview (viewer, previewImage, GetSize (sizes, selectedIndex), isTransparent);
+ CookieSetBoolVal ('ov_last_snapshot_transparent', isTransparent);
+ });
+
+ UpdatePreview (viewer, previewImage, GetSize (sizes, selectedIndex), isTransparent);
dialog.Open ();
return dialog;
diff --git a/source/website/themehandler.js b/source/website/themehandler.js
index 24a1f71..78f2183 100644
--- a/source/website/themehandler.js
+++ b/source/website/themehandler.js
@@ -27,6 +27,7 @@ export class ThemeHandler
'--ov_treeview_selected_color': {},
'--ov_dialog_foreground_color': {},
'--ov_dialog_background_color': {},
+ '--ov_dialog_control_border_color': {},
'--ov_border_color': {},
'--ov_shadow': {}
};