Create a separate toolbar button for image export #221

This commit is contained in:
kovacsv 2022-03-07 18:17:46 +01:00
parent f4f6228426
commit da1c019fd0
7 changed files with 53 additions and 115 deletions

View File

@ -13,22 +13,15 @@ import { DownloadArrayBufferAsFile, DownloadUrlAsFile } from './utils.js';
import { CookieGetStringVal, CookieSetStringVal } from './cookiehandler.js';
import { HandleEvent } from './eventhandler.js';
const ExportType =
class ModelExporterUI
{
Model : 0,
Image : 1
};
class ExporterUI
{
constructor (name)
constructor (name, format, extension)
{
this.name = name;
}
GetType ()
{
return null;
this.format = format;
this.extension = extension;
this.visibleOnlySelect = null;
this.rotationSelect = null;
}
GetName ()
@ -38,38 +31,16 @@ class ExporterUI
GenerateParametersUI (parametersDiv)
{
function AddSelectItem (parametersDiv, name, values, defaultIndex)
{
let parameterRow = AddDiv (parametersDiv, 'ov_dialog_row');
AddDiv (parameterRow, 'ov_dialog_row_name', name);
let parameterValueDiv = AddDiv (parameterRow, 'ov_dialog_row_value');
return AddSelect (parameterValueDiv, values, defaultIndex);
}
}
AddSelectItem (parametersDiv, name, values, defaultIndex)
{
let parameterRow = AddDiv (parametersDiv, 'ov_dialog_row');
AddDiv (parameterRow, 'ov_dialog_row_name', name);
let parameterValueDiv = AddDiv (parameterRow, 'ov_dialog_row_value');
return AddSelect (parameterValueDiv, values, defaultIndex);
}
}
class ModelExporterUI extends ExporterUI
{
constructor (name, format, extension)
{
super (name);
this.format = format;
this.extension = extension;
this.visibleOnlySelect = null;
this.rotationSelect = null;
}
GetType ()
{
return ExportType.Model;
}
GenerateParametersUI (parametersDiv)
{
this.visibleOnlySelect = this.AddSelectItem (parametersDiv, 'Scope', ['Entire Model', 'Visible Only'], 1);
this.rotationSelect = this.AddSelectItem (parametersDiv, 'Rotation', ['No Rotation', '-90 Degrees', '90 Degrees'], 0);
this.visibleOnlySelect = AddSelectItem (parametersDiv, 'Scope', ['Entire Model', 'Visible Only'], 1);
this.rotationSelect = AddSelectItem (parametersDiv, 'Rotation', ['No Rotation', '-90 Degrees', '90 Degrees'], 0);
}
ExportModel (model, callbacks)
@ -136,45 +107,6 @@ class ModelExporterUI extends ExporterUI
}
}
class ImageExporterUI extends ExporterUI
{
constructor (name, extension)
{
super (name);
this.extension = extension;
this.sizeSelect = null;
this.sizes = [
{ name : 'Current size', value : null },
{ name : '1280 x 720', value : [1280, 720] },
{ name : '1920 x 1080', value : [1920, 1080] }
];
}
GetType ()
{
return ExportType.Image;
}
GenerateParametersUI (parametersDiv)
{
let sizeNames = this.sizes.map (size => size.name);
this.sizeSelect = this.AddSelectItem (parametersDiv, 'Image size', sizeNames, 1);
}
ExportImage (viewer)
{
let selectedSize = this.sizes[this.sizeSelect.selectedIndex];
let url = null;
if (selectedSize.value === null) {
let size = viewer.GetImageSize ();
url = viewer.GetImageAsDataUrl (size.width, size.height);
} else {
url = viewer.GetImageAsDataUrl (selectedSize.value[0], selectedSize.value[1]);
}
DownloadUrlAsFile (url, 'model.' + this.extension);
}
}
class ExportDialog
{
constructor (callbacks)
@ -192,8 +124,7 @@ class ExportDialog
new ModelExporterUI ('glTF Text (.gltf)', FileFormat.Text, 'gltf'),
new ModelExporterUI ('glTF Binary (.glb)', FileFormat.Binary, 'glb'),
new ModelExporterUI ('Object File Format Text (.off)', FileFormat.Text, 'off'),
new ModelExporterUI ('Rhinoceros 3D (.3dm)', FileFormat.Binary, '3dm'),
new ImageExporterUI ('PNG Image (.png)', 'png')
new ModelExporterUI ('Rhinoceros 3D (.3dm)', FileFormat.Binary, '3dm')
];
}
@ -246,16 +177,12 @@ class ExportDialog
ExportFormat (model, viewer)
{
if (this.selectedExporter.GetType () === ExportType.Model) {
this.selectedExporter.ExportModel (model, {
isMeshVisible : (meshInstanceId) => {
return this.callbacks.isMeshVisible (meshInstanceId);
}
});
HandleEvent ('model_exported', this.selectedExporter.GetName ());
} else if (this.selectedExporter.GetType () === ExportType.Image) {
this.selectedExporter.ExportImage (viewer);
}
this.selectedExporter.ExportModel (model, {
isMeshVisible : (meshInstanceId) => {
return this.callbacks.isMeshVisible (meshInstanceId);
}
});
HandleEvent ('model_exported', this.selectedExporter.GetName ());
}
}
@ -318,6 +245,7 @@ export function ShowSnapshotDialog (viewer)
name : 'Create',
onClick () {
dialog.Close ();
HandleEvent ('snapshot_created', sizes[selectedIndex].name);
let url = GetImageUrl (viewer, sizes[selectedIndex]);
DownloadUrlAsFile (url, 'model.png');
}
@ -327,7 +255,7 @@ export function ShowSnapshotDialog (viewer)
let optionsDiv = AddDiv (contentDiv, 'ov_snapshot_dialog_left');
let previewImage = CreateDomElement ('img', 'ov_snapshot_dialog_preview');
let lastSnapshotSizeName = CookieGetStringVal ('ov_last_snapshot_size', sizes[0].name);
let lastSnapshotSizeName = CookieGetStringVal ('ov_last_snapshot_size', sizes[1].name);
for (let i = 0; i < sizes.length; i++) {
if (lastSnapshotSizeName === sizes[i].name) {
selectedIndex = i;

View File

@ -11,7 +11,7 @@ import { Sidebar } from './sidebar.js';
import { ThemeHandler } from './themehandler.js';
import { ThreeModelLoaderUI } from './threemodelloaderui.js';
import { Toolbar } from './toolbar.js';
import { ShowExportDialog } from './exportdialog.js';
import { ShowExportDialog, ShowSnapshotDialog } from './exportdialog.js';
import { AddSmallWidthChangeEventListener, GetFilesFromDataTransfer, IsSmallWidth } from './utils.js';
import { ShowOpenUrlDialog } from './openurldialog.js';
import { ShowSharingDialog } from './sharingdialog.js';
@ -565,6 +565,9 @@ export class Website
});
this.measureTool.SetButton (measureToolButton);
AddSeparator (this.toolbar, ['only_full_width', 'only_on_model']);
AddButton (this.toolbar, 'snapshot', 'Create snapshot', ['only_full_width', 'only_on_model'], () => {
ShowSnapshotDialog (this.viewer);
});
AddButton (this.toolbar, 'export', 'Export model', ['only_full_width', 'only_on_model'], () => {
ShowExportDialog (this.model, this.viewer, {
isMeshVisible : (meshInstanceId) => {

Binary file not shown.

View File

@ -258,8 +258,9 @@ div.ov_snapshot_dialog_left
img.ov_snapshot_dialog_preview
{
background: var(--ov_border_color);
width: 250px;
height: 140px;
border: 1px solid var(--ov_border_color);
width: 240px;
height: 135px;
object-fit: contain;
float: right;
}

View File

@ -1,6 +1,6 @@
@font-face {
font-family: "O3DVIcons";
src: url("O3DVIcons/O3DVIcons.woff?8e8ff80e3f2f51d21873c070a35e0f3c") format("woff");
src: url("O3DVIcons/O3DVIcons.woff?3aa6f39e888e50c0858037b7381ba7ac") format("woff");
}
i[class^="icon-"]:before, i[class*=" icon-"]:before {
@ -119,24 +119,27 @@ i[class^="icon-"]:before, i[class*=" icon-"]:before {
.icon-share:before {
content: "\f123";
}
.icon-tree_mesh:before {
.icon-snapshot:before {
content: "\f124";
}
.icon-tree_view:before {
.icon-tree_mesh:before {
content: "\f125";
}
.icon-twitter:before {
.icon-tree_view:before {
content: "\f126";
}
.icon-up_y:before {
.icon-twitter:before {
content: "\f127";
}
.icon-up_z:before {
.icon-up_y:before {
content: "\f128";
}
.icon-visible:before {
.icon-up_z:before {
content: "\f129";
}
.icon-warning:before {
.icon-visible:before {
content: "\f12a";
}
.icon-warning:before {
content: "\f12b";
}

Binary file not shown.

View File

@ -1,6 +1,6 @@
@font-face {
font-family: "O3DVIcons";
src: url("./O3DVIcons.woff?8e8ff80e3f2f51d21873c070a35e0f3c") format("woff");
src: url("./O3DVIcons.woff?3aa6f39e888e50c0858037b7381ba7ac") format("woff");
}
i[class^="icon-"]:before, i[class*=" icon-"]:before {
@ -119,24 +119,27 @@ i[class^="icon-"]:before, i[class*=" icon-"]:before {
.icon-share:before {
content: "\f123";
}
.icon-tree_mesh:before {
.icon-snapshot:before {
content: "\f124";
}
.icon-tree_view:before {
.icon-tree_mesh:before {
content: "\f125";
}
.icon-twitter:before {
.icon-tree_view:before {
content: "\f126";
}
.icon-up_y:before {
.icon-twitter:before {
content: "\f127";
}
.icon-up_z:before {
.icon-up_y:before {
content: "\f128";
}
.icon-visible:before {
.icon-up_z:before {
content: "\f129";
}
.icon-warning:before {
.icon-visible:before {
content: "\f12a";
}
.icon-warning:before {
content: "\f12b";
}