1
0

Sidebar.Project.App.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. import * as THREE from 'three';
  2. import { zipSync, strToU8 } from 'three/addons/libs/fflate.module.js';
  3. import { UIButton, UICheckbox, UIPanel, UIInput, UIRow, UIText } from './libs/ui.js';
  4. function SidebarProjectApp( editor ) {
  5. const config = editor.config;
  6. const signals = editor.signals;
  7. const strings = editor.strings;
  8. const save = editor.utils.save;
  9. const container = new UIPanel();
  10. container.setId( 'app' );
  11. const headerRow = new UIRow();
  12. headerRow.add( new UIText( strings.getKey( 'sidebar/project/app' ).toUpperCase() ) );
  13. container.add( headerRow );
  14. // Title
  15. const titleRow = new UIRow();
  16. const title = new UIInput( config.getKey( 'project/title' ) ).setLeft( '100px' ).setWidth( '150px' ).onChange( function () {
  17. config.setKey( 'project/title', this.getValue() );
  18. } );
  19. titleRow.add( new UIText( strings.getKey( 'sidebar/project/app/title' ) ).setClass( 'Label' ) );
  20. titleRow.add( title );
  21. container.add( titleRow );
  22. // Editable
  23. const editableRow = new UIRow();
  24. const editable = new UICheckbox( config.getKey( 'project/editable' ) ).setLeft( '100px' ).onChange( function () {
  25. config.setKey( 'project/editable', this.getValue() );
  26. } );
  27. editableRow.add( new UIText( strings.getKey( 'sidebar/project/app/editable' ) ).setClass( 'Label' ) );
  28. editableRow.add( editable );
  29. container.add( editableRow );
  30. // Play/Stop
  31. let isPlaying = false;
  32. const playButton = new UIButton( strings.getKey( 'sidebar/project/app/play' ) );
  33. playButton.setWidth( '170px' );
  34. playButton.setMarginLeft( '120px' );
  35. playButton.setMarginBottom( '10px' );
  36. playButton.onClick( function () {
  37. if ( isPlaying === false ) {
  38. isPlaying = true;
  39. playButton.setTextContent( strings.getKey( 'sidebar/project/app/stop' ) );
  40. signals.startPlayer.dispatch();
  41. } else {
  42. isPlaying = false;
  43. playButton.setTextContent( strings.getKey( 'sidebar/project/app/play' ) );
  44. signals.stopPlayer.dispatch();
  45. }
  46. } );
  47. container.add( playButton );
  48. // Publish
  49. const publishButton = new UIButton( strings.getKey( 'sidebar/project/app/publish' ) );
  50. publishButton.setWidth( '170px' );
  51. publishButton.setMarginLeft( '120px' );
  52. publishButton.setMarginBottom( '10px' );
  53. publishButton.onClick( function () {
  54. const toZip = {};
  55. //
  56. let output = editor.toJSON();
  57. output.metadata.type = 'App';
  58. delete output.history;
  59. output = JSON.stringify( output, null, '\t' );
  60. output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
  61. toZip[ 'app.json' ] = strToU8( output );
  62. //
  63. const title = config.getKey( 'project/title' );
  64. const manager = new THREE.LoadingManager( function () {
  65. const zipped = zipSync( toZip, { level: 9 } );
  66. const blob = new Blob( [ zipped.buffer ], { type: 'application/zip' } );
  67. save( blob, ( title !== '' ? title : 'untitled' ) + '.zip' );
  68. } );
  69. const loader = new THREE.FileLoader( manager );
  70. loader.load( 'js/libs/app/index.html', function ( content ) {
  71. content = content.replace( '<!-- title -->', title );
  72. let editButton = '';
  73. if ( config.getKey( 'project/editable' ) ) {
  74. editButton = [
  75. ' let button = document.createElement( \'a\' );',
  76. ' button.href = \'https://threejs.org/editor/#file=\' + location.href.split( \'/\' ).slice( 0, - 1 ).join( \'/\' ) + \'/app.json\';',
  77. ' button.style.cssText = \'position: absolute; bottom: 20px; right: 20px; padding: 10px 16px; color: #fff; border: 1px solid #fff; border-radius: 20px; text-decoration: none;\';',
  78. ' button.target = \'_blank\';',
  79. ' button.textContent = \'EDIT\';',
  80. ' document.body.appendChild( button );',
  81. ].join( '\n' );
  82. }
  83. content = content.replace( '\t\t\t/* edit button */', editButton );
  84. toZip[ 'index.html' ] = strToU8( content );
  85. } );
  86. loader.load( 'js/libs/app.js', function ( content ) {
  87. toZip[ 'js/app.js' ] = strToU8( content );
  88. } );
  89. loader.load( '../build/three.module.js', function ( content ) {
  90. toZip[ 'js/three.module.js' ] = strToU8( content );
  91. } );
  92. } );
  93. container.add( publishButton );
  94. // Signals
  95. signals.editorCleared.add( function () {
  96. title.setValue( '' );
  97. config.setKey( 'project/title', '' );
  98. } );
  99. return container;
  100. }
  101. export { SidebarProjectApp };