From e4d822f818178a6860627f2f0e229ee942b65186 Mon Sep 17 00:00:00 2001 From: btzr-io Date: Sat, 25 Apr 2020 03:24:42 -0500 Subject: [PATCH] Fix and enable 3D viewer: #4035 Fix 3d viewer styles Fix minor warnings from three.js Remove deprecated themes Fix #4074 --- ui/component/fileRenderInline/view.jsx | 16 +++- ui/component/viewers/threeViewer/index.jsx | 91 +++++++----------- .../viewers/threeViewer/internal/scene.js | 17 ++-- ui/constants/file_render_modes.js | 7 +- ui/scss/component/_dat-gui.scss | 93 ++----------------- ui/scss/component/_file-render.scss | 9 ++ 6 files changed, 79 insertions(+), 154 deletions(-) diff --git a/ui/component/fileRenderInline/view.jsx b/ui/component/fileRenderInline/view.jsx index 79fe323ac..ca11075a1 100644 --- a/ui/component/fileRenderInline/view.jsx +++ b/ui/component/fileRenderInline/view.jsx @@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react'; import FileRender from 'component/fileRender'; import LoadingScreen from 'component/common/loading-screen'; +import { NON_STREAM_MODES } from 'constants/file_render_modes'; type Props = { isPlaying: boolean, @@ -14,9 +15,18 @@ type Props = { }; export default function FileRenderInline(props: Props) { - const { isPlaying, fileInfo, uri, streamingUrl, triggerAnalyticsView, claimRewards } = props; + const { isPlaying, fileInfo, uri, streamingUrl, triggerAnalyticsView, claimRewards, renderMode } = props; const [playTime, setPlayTime] = useState(); - const isReadyToPlay = streamingUrl || (fileInfo && fileInfo.completed); + const isReadyToView = fileInfo && fileInfo.completed; + const isReadyToPlay = streamingUrl || isReadyToView; + + // Render if any source is ready + let renderContent = isReadyToPlay; + + // Force non-streaming content to wait for download + if (NON_STREAM_MODES.includes(renderMode)) { + renderContent = isReadyToView; + } useEffect(() => { if (isPlaying) { @@ -39,5 +49,5 @@ export default function FileRenderInline(props: Props) { return null; } - return isReadyToPlay ? : ; + return renderContent ? : ; } diff --git a/ui/component/viewers/threeViewer/index.jsx b/ui/component/viewers/threeViewer/index.jsx index e698e8136..64dae60dd 100644 --- a/ui/component/viewers/threeViewer/index.jsx +++ b/ui/component/viewers/threeViewer/index.jsx @@ -1,7 +1,6 @@ // @flow import * as React from 'react'; import * as dat from 'dat.gui'; -import classNames from 'classnames'; import LoadingScreen from 'component/common/loading-screen'; // ThreeJS @@ -52,14 +51,13 @@ const ThreeLoader = ({ fileType = null, downloadPath = null }, renderModel, mana }; type viewerTheme = { - gridColor: string, - groundColor: string, - backgroundColor: string, - centerLineColor: string, + showFog: boolean, + gridColor: number, + backgroundColor: number, + centerLineColor: number, }; type Props = { - theme: string, source: { fileType: string, downloadPath: string, @@ -131,26 +129,15 @@ class ThreeViewer extends React.PureComponent { constructor(props: Props) { super(props); - const { theme } = this.props; // Object defualt color - this.materialColor = '#44b098'; - // Viewer themes - this.themes = { - dark: { - gridColor: '#414e5c', - groundColor: '#13233C', - backgroundColor: '#13233C', - centerLineColor: '#7f8c8d', - }, - light: { - gridColor: '#7f8c8d', - groundColor: '#DDD', - backgroundColor: '#EEE', - centerLineColor: '#2F2F2F', - }, + this.materialColor = 0xffffff; + // Default viewer Theme + this.theme = { + showFog: true, + gridColor: 0x414e5c, + centerLineColor: 0x7f8c8d, + backgroundColor: 0x0b0c0d, }; - // Select current theme - this.theme = this.themes[theme] || this.themes.light; // State this.state = { error: null, @@ -212,29 +199,27 @@ class ThreeViewer extends React.PureComponent { }); // Clean up controls if (this.controls) this.controls.dispose(); - // It's unclear if we need this: + // Clean up scene + if (this.scene) this.scene.dispose(); + if (this.renderer) { + this.renderer.context = null; + this.renderer.domElement = null; this.renderer.renderLists.dispose(); + this.renderer.forceContextLoss(); this.renderer.dispose(); + this.renderer = null; } // Stop animation cancelAnimationFrame(this.frameID); // Destroy GUI Controls if (this.gui) this.gui.destroy(); - // Empty objects - this.grid = null; - this.mesh = null; - this.renderer = null; - this.material = null; - this.geometry = null; - this.bufferGeometry = null; } } // Define component types theme: viewerTheme; - themes: { dark: viewerTheme, light: viewerTheme }; - materialColor: string; + materialColor: number; // Refs viewer: ?HTMLElement; guiContainer: ?HTMLElement; @@ -265,10 +250,10 @@ class ThreeViewer extends React.PureComponent { transformGroup(group: any) { ThreeViewer.fitMeshToCamera(group); - if (!this.targetCenter) { const box = new Box3(); - this.targetCenter = box.setFromObject(this.mesh).getCenter(); + const center = new Vector3(); + this.targetCenter = box.setFromObject(this.mesh).getCenter(center); } this.updateControlsTarget(this.targetCenter); } @@ -452,10 +437,7 @@ class ThreeViewer extends React.PureComponent { gammaCorrection: true, }); - this.scene = ThreeScene({ - showFog: true, - ...this.theme, - }); + this.scene = ThreeScene(this.theme); const canvas = this.renderer.domElement; const { offsetWidth: width, offsetHeight: height } = this.viewer || {}; @@ -473,7 +455,7 @@ class ThreeViewer extends React.PureComponent { // Set viewer size this.renderer.setSize(width, height); - // Create model material + // Create material this.material = new MeshPhongMaterial({ depthWrite: true, flatShading: true, @@ -501,26 +483,21 @@ class ThreeViewer extends React.PureComponent { } render() { - const { theme } = this.props; const { error, isReady, isLoading } = this.state; const loadingMessage = __('Loading 3D model.'); - const showViewer = isReady && !error; - const showLoading = isLoading && !error; - - // Adaptive theme for gui controls - const containerClass = classNames('gui-container', { light: theme === 'light' }); + const showLoading = isLoading && !error && !isReady; + const containerClass = 'gui-container'; return ( - - {error && } - {showLoading && } -
(this.guiContainer = element)} className={containerClass} /> -
(this.viewer = viewer)} - /> - + <> +
+
(this.guiContainer = element)} className={containerClass} /> +
(this.viewer = viewer)}> + {error && } + {showLoading && } +
+
+ ); } } diff --git a/ui/component/viewers/threeViewer/internal/scene.js b/ui/component/viewers/threeViewer/internal/scene.js index 40979f8f3..886217f67 100644 --- a/ui/component/viewers/threeViewer/internal/scene.js +++ b/ui/component/viewers/threeViewer/internal/scene.js @@ -21,17 +21,18 @@ const addLights = (scene, color, groundColor) => { scene.add(shadowLight); }; -const ViewerScene = ({ backgroundColor, groundColor, showFog }) => { - // Convert color - const bgColor = new Color(backgroundColor); +const ViewerScene = ({ backgroundColor, showFog }) => { // New scene + const bg = new Color(backgroundColor); const scene = new Scene(); - // Background color - scene.background = bgColor; - // Fog effect - scene.fog = showFog === true ? new Fog(bgColor, 1, 95) : null; + // Transparent background + scene.background = bg; + // Add fog + if (showFog) { + scene.fog = new Fog(bg, 1, 54); + } // Add basic lights - addLights(scene, '#FFFFFF', groundColor); + addLights(scene, 0xffffff, bg); // Return new three scene return scene; }; diff --git a/ui/constants/file_render_modes.js b/ui/constants/file_render_modes.js index 6736416bf..fc1f71481 100644 --- a/ui/constants/file_render_modes.js +++ b/ui/constants/file_render_modes.js @@ -16,7 +16,10 @@ export const IMAGE = 'image'; export const CAD = 'cad'; export const COMIC = 'comic'; -export const AUTO_RENDER_MODES = [IMAGE, CAD, COMIC].concat(TEXT_MODES); // these types will render (and thus download) automatically (if free) +// These types can only be render if download completed +export const NON_STREAM_MODES = [CAD, COMIC]; + +export const AUTO_RENDER_MODES = [IMAGE].concat(TEXT_MODES); export const WEB_SHAREABLE_MODES = AUTO_RENDER_MODES.concat(FLOATING_MODES); export const DOWNLOAD = 'download'; @@ -25,7 +28,7 @@ export const UNSUPPORTED = 'unsupported'; // PDFs disabled on desktop until we update Electron: https://github.com/electron/electron/issues/12337 // Comics disabled because nothing is actually reporting as a comic type -export const UNSUPPORTED_IN_THIS_APP = IS_WEB ? [CAD, COMIC, APPLICATION] : [CAD, APPLICATION, PDF]; +export const UNSUPPORTED_IN_THIS_APP = IS_WEB ? [CAD, COMIC, APPLICATION] : [APPLICATION, PDF]; export const UNRENDERABLE_MODES = Array.from( new Set(UNSUPPORTED_IN_THIS_APP.concat([DOWNLOAD, APPLICATION, UNSUPPORTED])) diff --git a/ui/scss/component/_dat-gui.scss b/ui/scss/component/_dat-gui.scss index 557a54e99..6ce94a903 100644 --- a/ui/scss/component/_dat-gui.scss +++ b/ui/scss/component/_dat-gui.scss @@ -3,101 +3,26 @@ .gui-container { top: 0; right: 0; - position: absolute; - z-index: 2; .dg.main { margin: 0; padding: 0; overflow: inherit; - } - // Light theme: - // https://github.com/liabru/dat-gui-light-theme - - &.light { - .dg.main.taller-than-window .close-button { - border-top: 1px solid #ddd; + li { + margin: 0; } - .dg.main .close-button { - &:not(:hover) { - background-color: #e8e8e8; - } - - &:hover { - background-color: #ddd; - } + input { + height: initial; } - .dg { - color: #555; - text-shadow: none !important; - - &.main { - &::-webkit-scrollbar { - background-color: #fafafa; - } - - &::-webkit-scrollbar-thumb { - background-color: #bbb; - } - } - - li { - &:not(.folder) { - background-color: #fafafa; - border-bottom: 1px solid #ddd; - } - - &.save-row .button { - text-shadow: none !important; - } - - &.title { - background: #e8e8e8 - url('data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==') - 6px 10px no-repeat; - } - } - - .cr { - &.function:hover, - &.boolean:hover { - background-color: white; - } - } - - .c { - input { - &[type='text'] { - &:not(:focus), - &:not(:hover) { - background-color: #e9e9e9; - } - - &:focus, - &:hover { - background-color: #eee; - } - - &:focus { - color: #555; - } - } - } - - .slider { - &:not(:hover) { - background-color: #e9e9e9; - } - - &:hover { - background-color: #eee; - } - } - } + input[type='checkbox'] { + height: 12px; + width: 12px; + padding: 0; + margin: 0; } } } diff --git a/ui/scss/component/_file-render.scss b/ui/scss/component/_file-render.scss index 1f5894b30..111e781aa 100644 --- a/ui/scss/component/_file-render.scss +++ b/ui/scss/component/_file-render.scss @@ -119,6 +119,15 @@ } } +.file-render__viewer--three { + position: relative; + overflow: hidden; + + .three-viewer { + height: calc(100vh - var(--header-height) - var(--spacing-medium) * 2); + } +} + .file-render__content { width: 100%; height: 100%;