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

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

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
Mr.doob 已提交
17 18
	var config = editor.config;

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

22 23 24 25
	var title = new UI.Panel();
	title.setClass( 'title' );
	title.setTextContent( 'File' );
	container.add( title );
M
Mr.doob 已提交
26

27 28 29
	var options = new UI.Panel();
	options.setClass( 'options' );
	container.add( options );
M
Mr.doob 已提交
30

31
	// New
32

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

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

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

		}
43

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

47
	//
48

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

51
	// Import
52

53 54 55 56
	var form = document.createElement( 'form' );
	form.style.display = 'none';
	document.body.appendChild( form );

57 58 59
	var fileInput = document.createElement( 'input' );
	fileInput.type = 'file';
	fileInput.addEventListener( 'change', function ( event ) {
60

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

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

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

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

74 75
	} );
	options.add( option );
76

77
	//
78

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

81
	// Export Geometry
82

M
Mr.doob 已提交
83
	var option = new UI.Row();
84 85 86
	option.setClass( 'option' );
	option.setTextContent( 'Export Geometry' );
	option.onClick( function () {
87

88
		var object = editor.selected;
89

90
		if ( object === null ) {
91

92 93
			alert( 'No object selected.' );
			return;
94

95
		}
96

97 98 99 100 101 102
		var geometry = object.geometry;

		if ( geometry === undefined ) {

			alert( 'The selected object doesn\'t have geometry.' );
			return;
103

104
		}
105

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

M
makc 已提交
108
		try {
M
Mr.doob 已提交
109

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

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

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

M
makc 已提交
117
		}
118

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

121 122 123 124
	} );
	options.add( option );

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

M
Mr.doob 已提交
126
	var option = new UI.Row();
127 128 129
	option.setClass( 'option' );
	option.setTextContent( 'Export Object' );
	option.onClick( function () {
130

131 132 133
		var object = editor.selected;

		if ( object === null ) {
134 135 136 137 138 139

			alert( 'No object selected' );
			return;

		}

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

M
makc 已提交
142
		try {
M
Mr.doob 已提交
143

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

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

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

M
makc 已提交
151
		}
152

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

155 156 157 158
	} );
	options.add( option );

	// Export Scene
159

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

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

M
makc 已提交
167
		try {
M
Mr.doob 已提交
168

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

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

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

M
makc 已提交
176
		}
177

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

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

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

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

	// Export GLTF
188

M
Mr.doob 已提交
189
	var option = new UI.Row();
190
	option.setClass( 'option' );
M
Mr.doob 已提交
191
	option.setTextContent( 'Export GLTF' );
192
	option.onClick( function () {
193

M
Mr.doob 已提交
194
		var exporter = new THREE.GLTFExporter();
195

M
Mr.doob 已提交
196
		exporter.parse( editor.scene, function ( result ) {
197

M
Mr.doob 已提交
198
			saveString( JSON.stringify( result, null, 2 ), 'scene.gltf' );
199

M
Mr.doob 已提交
200
		} );
201

202

203 204 205
	} );
	options.add( option );

M
Mr.doob 已提交
206
	// Export OBJ
F
Fernando Serrano 已提交
207 208 209

	var option = new UI.Row();
	option.setClass( 'option' );
M
Mr.doob 已提交
210
	option.setTextContent( 'Export OBJ' );
F
Fernando Serrano 已提交
211 212
	option.onClick( function () {

M
Mr.doob 已提交
213
		var object = editor.selected;
F
Fernando Serrano 已提交
214

M
Mr.doob 已提交
215
		if ( object === null ) {
F
Fernando Serrano 已提交
216

M
Mr.doob 已提交
217 218
			alert( 'No object selected.' );
			return;
F
Fernando Serrano 已提交
219

M
Mr.doob 已提交
220
		}
F
Fernando Serrano 已提交
221

M
Mr.doob 已提交
222 223 224
		var exporter = new THREE.OBJExporter();

		saveString( exporter.parse( object ), 'model.obj' );
F
Fernando Serrano 已提交
225 226 227 228

	} );
	options.add( option );

229
	// Export STL
230

M
Mr.doob 已提交
231
	var option = new UI.Row();
232 233 234
	option.setClass( 'option' );
	option.setTextContent( 'Export STL' );
	option.onClick( function () {
M
Mr.doob 已提交
235

M
Mr.doob 已提交
236
		var exporter = new THREE.STLExporter();
237

M
Mr.doob 已提交
238
		saveString( exporter.parse( editor.scene ), 'model.stl' );
M
Mr.doob 已提交
239

240 241 242
	} );
	options.add( option );

M
Mr.doob 已提交
243
	//
244 245

	options.add( new UI.HorizontalRule() );
M
Mr.doob 已提交
246

247
	// Publish
248

M
Mr.doob 已提交
249
	var option = new UI.Row();
250
	option.setClass( 'option' );
251
	option.setTextContent( 'Publish' );
252
	option.onClick( function () {
253

M
Mr.doob 已提交
254 255 256 257
		var zip = new JSZip();

		//

M
Mr.doob 已提交
258
		var output = editor.toJSON();
M
Mr.doob 已提交
259 260 261
		output.metadata.type = 'App';
		delete output.history;

262 263
		var vr = output.project.vr;

264
		output = JSON.stringify( output, parseNumber, '\t' );
M
Mr.doob 已提交
265 266
		output = output.replace( /[\n\t]+([\d\.e\-\[\]]+)/g, '$1' );

M
Mr.doob 已提交
267
		zip.file( 'app.json', output );
M
Mr.doob 已提交
268 269 270

		//

M
Mr.doob 已提交
271 272
		var title = config.getKey( 'project/title' );

M
Mr.doob 已提交
273 274
		var manager = new THREE.LoadingManager( function () {

M
Mr.doob 已提交
275
			save( zip.generate( { type: 'blob' } ), ( title !== '' ? title : 'untitled' ) + '.zip' );
M
Mr.doob 已提交
276 277 278

		} );

279
		var loader = new THREE.FileLoader( manager );
280 281
		loader.load( 'js/libs/app/index.html', function ( content ) {

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

284 285 286 287
			var includes = [];

			if ( vr ) {

M
Mr.doob 已提交
288
				includes.push( '<script src="js/WebVR.js"></script>' );
289 290 291 292 293

			}

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

294 295
			var editButton = '';

M
Mr.doob 已提交
296
			if ( config.getKey( 'project/editable' ) ) {
297

298 299 300 301 302 303 304
				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 );";
305 306 307 308
			}

			content = content.replace( '/* edit button */', editButton );

309 310 311
			zip.file( 'index.html', content );

		} );
M
Mr.doob 已提交
312
		loader.load( 'js/libs/app.js', function ( content ) {
M
Mr.doob 已提交
313

M
Mr.doob 已提交
314
			zip.file( 'js/app.js', content );
M
Mr.doob 已提交
315 316

		} );
M
Mr.doob 已提交
317
		loader.load( '../build/three.min.js', function ( content ) {
M
Mr.doob 已提交
318

M
Mr.doob 已提交
319
			zip.file( 'js/three.min.js', content );
M
Mr.doob 已提交
320 321

		} );
322

323
		if ( vr ) {
324

M
Mr.doob 已提交
325
			loader.load( '../examples/js/vr/WebVR.js', function ( content ) {
M
Mr.doob 已提交
326 327 328 329 330

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

			} );

331
		}
332

333 334
	} );
	options.add( option );
335

336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355
	/*
	// 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 );
	*/

356

357
	//
358

M
Mr.doob 已提交
359 360 361 362
	var link = document.createElement( 'a' );
	link.style.display = 'none';
	document.body.appendChild( link ); // Firefox workaround, see #6594

M
Mr.doob 已提交
363
	function save( blob, filename ) {
364

M
Mr.doob 已提交
365
		link.href = URL.createObjectURL( blob );
M
Mr.doob 已提交
366
		link.download = filename || 'data.json';
M
Mr.doob 已提交
367 368 369 370 371 372 373
		link.click();

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

	}

	function saveString( text, filename ) {
G
gero3 已提交
374

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

M
Mr.doob 已提交
377
	}
378

379
	return container;
M
Mr.doob 已提交
380

381
};