Menubar.File.js 7.6 KB
Newer Older
M
r69  
Mr.doob 已提交
1 2 3 4
/**
 * @author mrdoob / http://mrdoob.com/
 */

M
r59  
Mr.doob 已提交
5
Menubar.File = function ( editor ) {
M
Mr.doob 已提交
6

M
r84  
Mr.doob 已提交
7 8 9 10 11 12 13 14 15 16
	var NUMBER_PRECISION = 6;

	function parseNumber( key, value ) {

		return typeof value === 'number' ? parseFloat( value.toFixed( NUMBER_PRECISION ) ) : value;

	}

	//

M
r88  
Mr.doob 已提交
17 18
	var config = editor.config;

M
r69  
Mr.doob 已提交
19 20
	var container = new UI.Panel();
	container.setClass( 'menu' );
M
Mr.doob 已提交
21

M
r69  
Mr.doob 已提交
22 23 24 25 26 27 28 29 30 31 32
	var title = new UI.Panel();
	title.setClass( 'title' );
	title.setTextContent( 'File' );
	container.add( title );

	var options = new UI.Panel();
	options.setClass( 'options' );
	container.add( options );

	// New

M
r74  
Mr.doob 已提交
33
	var option = new UI.Row();
M
r69  
Mr.doob 已提交
34 35 36
	option.setClass( 'option' );
	option.setTextContent( 'New' );
	option.onClick( function () {
M
Mr.doob 已提交
37

M
r70  
Mr.doob 已提交
38
		if ( confirm( 'Any unsaved data will be lost. Are you sure?' ) ) {
M
Mr.doob 已提交
39

M
r70  
Mr.doob 已提交
40
			editor.clear();
M
Mr.doob 已提交
41

M
r67  
Mr.doob 已提交
42
		}
M
r58  
Mr.doob 已提交
43

M
r69  
Mr.doob 已提交
44 45
	} );
	options.add( option );
M
r58  
Mr.doob 已提交
46

M
r69  
Mr.doob 已提交
47
	//
M
r58  
Mr.doob 已提交
48

M
r69  
Mr.doob 已提交
49
	options.add( new UI.HorizontalRule() );
M
r58  
Mr.doob 已提交
50

M
r69  
Mr.doob 已提交
51
	// Import
M
r67  
Mr.doob 已提交
52

M
Mr.doob 已提交
53 54 55 56
	var form = document.createElement( 'form' );
	form.style.display = 'none';
	document.body.appendChild( form );

M
r69  
Mr.doob 已提交
57 58 59
	var fileInput = document.createElement( 'input' );
	fileInput.type = 'file';
	fileInput.addEventListener( 'change', function ( event ) {
M
r67  
Mr.doob 已提交
60

M
r69  
Mr.doob 已提交
61
		editor.loader.loadFile( fileInput.files[ 0 ] );
M
Mr.doob 已提交
62
		form.reset();
M
r67  
Mr.doob 已提交
63

M
r69  
Mr.doob 已提交
64
	} );
M
Mr.doob 已提交
65
	form.appendChild( fileInput );
M
r67  
Mr.doob 已提交
66

M
r74  
Mr.doob 已提交
67
	var option = new UI.Row();
M
r69  
Mr.doob 已提交
68 69 70
	option.setClass( 'option' );
	option.setTextContent( 'Import' );
	option.onClick( function () {
M
r67  
Mr.doob 已提交
71

M
r69  
Mr.doob 已提交
72
		fileInput.click();
M
r67  
Mr.doob 已提交
73

M
r69  
Mr.doob 已提交
74 75
	} );
	options.add( option );
M
r67  
Mr.doob 已提交
76

M
r69  
Mr.doob 已提交
77
	//
M
r67  
Mr.doob 已提交
78

M
r69  
Mr.doob 已提交
79
	options.add( new UI.HorizontalRule() );
M
r67  
Mr.doob 已提交
80

M
r69  
Mr.doob 已提交
81
	// Export Geometry
M
r67  
Mr.doob 已提交
82

M
r74  
Mr.doob 已提交
83
	var option = new UI.Row();
M
r69  
Mr.doob 已提交
84 85 86 87 88 89 90 91 92 93
	option.setClass( 'option' );
	option.setTextContent( 'Export Geometry' );
	option.onClick( function () {

		var object = editor.selected;

		if ( object === null ) {

			alert( 'No object selected.' );
			return;
M
r58  
Mr.doob 已提交
94 95 96

		}

M
r69  
Mr.doob 已提交
97
		var geometry = object.geometry;
M
r67  
Mr.doob 已提交
98

M
r69  
Mr.doob 已提交
99
		if ( geometry === undefined ) {
M
r58  
Mr.doob 已提交
100

M
r69  
Mr.doob 已提交
101 102
			alert( 'The selected object doesn\'t have geometry.' );
			return;
M
Mr.doob 已提交
103

M
r69  
Mr.doob 已提交
104
		}
M
Mr.doob 已提交
105

M
r69  
Mr.doob 已提交
106
		var output = geometry.toJSON();
M
r73  
Mr.doob 已提交
107 108

		try {
M
r74  
Mr.doob 已提交
109

M
r84  
Mr.doob 已提交
110
			output = JSON.stringify( output, parseNumber, '\t' );
M
r73  
Mr.doob 已提交
111
			output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
M
r74  
Mr.doob 已提交
112

M
r73  
Mr.doob 已提交
113
		} catch ( e ) {
M
r74  
Mr.doob 已提交
114

M
r73  
Mr.doob 已提交
115
			output = JSON.stringify( output );
M
r74  
Mr.doob 已提交
116

M
r73  
Mr.doob 已提交
117
		}
M
Mr.doob 已提交
118

M
r74  
Mr.doob 已提交
119
		saveString( output, 'geometry.json' );
M
r67  
Mr.doob 已提交
120

M
r69  
Mr.doob 已提交
121 122
	} );
	options.add( option );
M
r67  
Mr.doob 已提交
123

M
r69  
Mr.doob 已提交
124
	// Export Object
M
Mr.doob 已提交
125

M
r74  
Mr.doob 已提交
126
	var option = new UI.Row();
M
r69  
Mr.doob 已提交
127 128 129 130 131 132 133 134 135 136
	option.setClass( 'option' );
	option.setTextContent( 'Export Object' );
	option.onClick( function () {

		var object = editor.selected;

		if ( object === null ) {

			alert( 'No object selected' );
			return;
M
Mr.doob 已提交
137

M
r67  
Mr.doob 已提交
138
		}
M
Mr.doob 已提交
139

M
r69  
Mr.doob 已提交
140
		var output = object.toJSON();
M
r73  
Mr.doob 已提交
141 142

		try {
M
r74  
Mr.doob 已提交
143

M
r84  
Mr.doob 已提交
144
			output = JSON.stringify( output, parseNumber, '\t' );
M
r73  
Mr.doob 已提交
145
			output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
M
r74  
Mr.doob 已提交
146

M
r73  
Mr.doob 已提交
147
		} catch ( e ) {
M
r74  
Mr.doob 已提交
148

M
r73  
Mr.doob 已提交
149
			output = JSON.stringify( output );
M
r74  
Mr.doob 已提交
150

M
r73  
Mr.doob 已提交
151
		}
M
Mr.doob 已提交
152

M
r74  
Mr.doob 已提交
153
		saveString( output, 'model.json' );
M
Mr.doob 已提交
154

M
r69  
Mr.doob 已提交
155 156
	} );
	options.add( option );
M
Mr.doob 已提交
157

M
r69  
Mr.doob 已提交
158
	// Export Scene
M
Mr.doob 已提交
159

M
r74  
Mr.doob 已提交
160
	var option = new UI.Row();
M
r69  
Mr.doob 已提交
161 162 163
	option.setClass( 'option' );
	option.setTextContent( 'Export Scene' );
	option.onClick( function () {
M
Mr.doob 已提交
164

M
r69  
Mr.doob 已提交
165
		var output = editor.scene.toJSON();
M
r73  
Mr.doob 已提交
166 167

		try {
M
r74  
Mr.doob 已提交
168

M
r84  
Mr.doob 已提交
169
			output = JSON.stringify( output, parseNumber, '\t' );
M
r73  
Mr.doob 已提交
170
			output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );
M
r74  
Mr.doob 已提交
171

M
r73  
Mr.doob 已提交
172
		} catch ( e ) {
M
r74  
Mr.doob 已提交
173

M
r73  
Mr.doob 已提交
174
			output = JSON.stringify( output );
M
r74  
Mr.doob 已提交
175

M
r73  
Mr.doob 已提交
176
		}
M
r69  
Mr.doob 已提交
177

M
r74  
Mr.doob 已提交
178
		saveString( output, 'scene.json' );
M
r69  
Mr.doob 已提交
179 180 181

	} );
	options.add( option );
M
Mr.doob 已提交
182

M
r87  
Mr.doob 已提交
183 184 185 186
	//

	options.add( new UI.HorizontalRule() );

M
Mr.doob 已提交
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
	// Export GLB

	var option = new UI.Row();
	option.setClass( 'option' );
	option.setTextContent( 'Export GLB' );
	option.onClick( function () {

		var exporter = new THREE.GLTFExporter();

		exporter.parse( editor.scene, function ( result ) {

			saveArrayBuffer( result, 'scene.glb' );

		}, { binary: true } );


	} );
	options.add( option );

M
r87  
Mr.doob 已提交
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
	// Export GLTF

	var option = new UI.Row();
	option.setClass( 'option' );
	option.setTextContent( 'Export GLTF' );
	option.onClick( function () {

		var exporter = new THREE.GLTFExporter();

		exporter.parse( editor.scene, function ( result ) {

			saveString( JSON.stringify( result, null, 2 ), 'scene.gltf' );

		} );


	} );
	options.add( option );

M
r69  
Mr.doob 已提交
225 226
	// Export OBJ

M
r74  
Mr.doob 已提交
227
	var option = new UI.Row();
M
r69  
Mr.doob 已提交
228 229 230
	option.setClass( 'option' );
	option.setTextContent( 'Export OBJ' );
	option.onClick( function () {
M
r58  
Mr.doob 已提交
231

M
r65  
Mr.doob 已提交
232
		var object = editor.selected;
M
r60  
Mr.doob 已提交
233

M
r65  
Mr.doob 已提交
234
		if ( object === null ) {
M
r60  
Mr.doob 已提交
235

M
r65  
Mr.doob 已提交
236 237
			alert( 'No object selected.' );
			return;
M
r60  
Mr.doob 已提交
238

M
r65  
Mr.doob 已提交
239
		}
M
r60  
Mr.doob 已提交
240

M
r69  
Mr.doob 已提交
241
		var exporter = new THREE.OBJExporter();
M
Mr.doob 已提交
242

M
r74  
Mr.doob 已提交
243
		saveString( exporter.parse( object ), 'model.obj' );
M
r58  
Mr.doob 已提交
244

M
r69  
Mr.doob 已提交
245 246
	} );
	options.add( option );
M
Mr.doob 已提交
247

M
r69  
Mr.doob 已提交
248
	// Export STL
M
r58  
Mr.doob 已提交
249

M
r74  
Mr.doob 已提交
250
	var option = new UI.Row();
M
r69  
Mr.doob 已提交
251 252 253
	option.setClass( 'option' );
	option.setTextContent( 'Export STL' );
	option.onClick( function () {
M
r58  
Mr.doob 已提交
254

M
r69  
Mr.doob 已提交
255
		var exporter = new THREE.STLExporter();
M
r65  
Mr.doob 已提交
256

M
r74  
Mr.doob 已提交
257
		saveString( exporter.parse( editor.scene ), 'model.stl' );
M
r65  
Mr.doob 已提交
258

M
r69  
Mr.doob 已提交
259 260
	} );
	options.add( option );
M
r58  
Mr.doob 已提交
261

M
r69  
Mr.doob 已提交
262
	//
M
r58  
Mr.doob 已提交
263

M
r69  
Mr.doob 已提交
264
	options.add( new UI.HorizontalRule() );
M
r58  
Mr.doob 已提交
265

M
r69  
Mr.doob 已提交
266
	// Publish
M
r58  
Mr.doob 已提交
267

M
r74  
Mr.doob 已提交
268
	var option = new UI.Row();
M
r69  
Mr.doob 已提交
269 270 271
	option.setClass( 'option' );
	option.setTextContent( 'Publish' );
	option.onClick( function () {
M
Mr.doob 已提交
272

M
r70  
Mr.doob 已提交
273 274 275 276 277
		var zip = new JSZip();

		//

		var output = editor.toJSON();
M
r74  
Mr.doob 已提交
278 279 280
		output.metadata.type = 'App';
		delete output.history;

M
Mr.doob 已提交
281 282
		var vr = output.project.vr;

M
r84  
Mr.doob 已提交
283
		output = JSON.stringify( output, parseNumber, '\t' );
M
r70  
Mr.doob 已提交
284 285 286 287 288 289
		output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );

		zip.file( 'app.json', output );

		//

M
r88  
Mr.doob 已提交
290 291
		var title = config.getKey( 'project/title' );

M
r70  
Mr.doob 已提交
292 293
		var manager = new THREE.LoadingManager( function () {

M
r88  
Mr.doob 已提交
294
			save( zip.generate( { type: 'blob' } ), ( title !== '' ? title : 'untitled' ) + '.zip' );
M
r70  
Mr.doob 已提交
295 296 297

		} );

M
r83  
Mr.doob 已提交
298
		var loader = new THREE.FileLoader( manager );
M
r74  
Mr.doob 已提交
299 300
		loader.load( 'js/libs/app/index.html', function ( content ) {

M
r88  
Mr.doob 已提交
301 302
			content = content.replace( '<!-- title -->', title );

M
Mr.doob 已提交
303 304 305 306
			var includes = [];

			if ( vr ) {

M
Mr.doob 已提交
307
				includes.push( '<script src="js/WebVR.js"></script>' );
M
Mr.doob 已提交
308 309 310 311 312

			}

			content = content.replace( '<!-- includes -->', includes.join( '\n\t\t' ) );

M
r88  
Mr.doob 已提交
313 314 315 316
			var editButton = '';

			if ( config.getKey( 'project/editable' ) ) {

M
r90  
Mr.doob 已提交
317 318 319 320 321 322 323 324 325 326
				editButton = [
					'',
					'			var button = document.createElement( \'a\' );',
					'			button.href = \'https://threejs.org/editor/#file=\' + location.href.split( \'/\' ).slice( 0, - 1 ).join( \'/\' ) + \'/app.json\';',
					'			button.style.cssText = \'position: absolute; bottom: 20px; right: 20px; padding: 12px 14px; color: #fff; border: 1px solid #fff; border-radius: 4px; text-decoration: none;\';',
					'			button.target = \'_blank\';',
					'			button.textContent = \'EDIT\';',
					'			document.body.appendChild( button );',
					''
				].join( '\n' );
M
r88  
Mr.doob 已提交
327 328
			}

M
r90  
Mr.doob 已提交
329
			content = content.replace( '\n\t\t\t/* edit button */\n', editButton );
M
r88  
Mr.doob 已提交
330

M
r74  
Mr.doob 已提交
331 332 333
			zip.file( 'index.html', content );

		} );
M
r70  
Mr.doob 已提交
334 335 336 337 338 339 340 341 342 343
		loader.load( 'js/libs/app.js', function ( content ) {

			zip.file( 'js/app.js', content );

		} );
		loader.load( '../build/three.min.js', function ( content ) {

			zip.file( 'js/three.min.js', content );

		} );
M
r58  
Mr.doob 已提交
344

M
Mr.doob 已提交
345
		if ( vr ) {
M
Mr.doob 已提交
346

M
r87  
Mr.doob 已提交
347
			loader.load( '../examples/js/vr/WebVR.js', function ( content ) {
M
Mr.doob 已提交
348 349 350 351 352

				zip.file( 'js/WebVR.js', content );

			} );

M
Mr.doob 已提交
353
		}
M
Mr.doob 已提交
354

M
r69  
Mr.doob 已提交
355 356
	} );
	options.add( option );
M
r58  
Mr.doob 已提交
357

M
r74  
Mr.doob 已提交
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
	/*
	// Publish (Dropbox)

	var option = new UI.Row();
	option.setClass( 'option' );
	option.setTextContent( 'Publish (Dropbox)' );
	option.onClick( function () {

		var parameters = {
			files: [
				{ 'url': 'data:text/plain;base64,' + window.btoa( "Hello, World" ), 'filename': 'app/test.txt' }
			]
		};

		Dropbox.save( parameters );

	} );
	options.add( option );
	*/

M
r58  
Mr.doob 已提交
378

M
r69  
Mr.doob 已提交
379
	//
M
r58  
Mr.doob 已提交
380

M
r72  
Mr.doob 已提交
381 382 383 384
	var link = document.createElement( 'a' );
	link.style.display = 'none';
	document.body.appendChild( link ); // Firefox workaround, see #6594

M
r74  
Mr.doob 已提交
385
	function save( blob, filename ) {
M
r58  
Mr.doob 已提交
386

M
r74  
Mr.doob 已提交
387
		link.href = URL.createObjectURL( blob );
M
r71  
Mr.doob 已提交
388
		link.download = filename || 'data.json';
M
r74  
Mr.doob 已提交
389 390 391 392 393 394
		link.click();

		// URL.revokeObjectURL( url ); breaks Firefox...

	}

M
Mr.doob 已提交
395 396 397 398 399 400
	function saveArrayBuffer( buffer, filename ) {

		save( new Blob( [ buffer ], { type: 'application/octet-stream' } ), filename );

	}

M
r74  
Mr.doob 已提交
401
	function saveString( text, filename ) {
M
r72  
Mr.doob 已提交
402

M
r74  
Mr.doob 已提交
403
		save( new Blob( [ text ], { type: 'text/plain' } ), filename );
M
r59  
Mr.doob 已提交
404

M
r74  
Mr.doob 已提交
405
	}
M
r58  
Mr.doob 已提交
406

M
r69  
Mr.doob 已提交
407
	return container;
M
Mr.doob 已提交
408

M
r69  
Mr.doob 已提交
409
};