threejs 编辑器源码分析1
Commands解析
Commands目录
threejs 编辑器的所有操作都封装成命令。
继承结构
解释:
- /js/Command.js是所有命令类的父类,包含序列化和反序列化方法,各种命令的公共属性。
- ***Command.js继承了/js/Command.js,实现了各自的序列化、反序列化、execute()、undo()。
- /js/Commands/Command.js是所有命令的集合,把全部***Command.js收集起来,一起导出,方便用户使用命令。
例子
将SetScriptValueCommand作为例子,解析代码。
SetScriptValueCommand.js :
import { Command } from '../Command.js';
/**
* @param editor Editor
* @param object THREE.Object3D
* @param script javascript object
* @param attributeName string
* @param newValue string, object
* @constructor
*/
class SetScriptValueCommand extends Command {
constructor( editor, object, script, attributeName, newValue ) {
//命令基类
super( editor );
this.type = 'SetScriptValueCommand';
this.name = `Set Script.${attributeName}`;
this.updatable = true;
//操作的对象、操作的脚本
this.object = object;
this.script = script; //这是一个对象的脚本,一个对象可以有多个脚本
//脚本名称
this.attributeName = attributeName;
//存储上次更改的这个脚本
this.oldValue = ( script !== undefined ) ? script[ this.attributeName ] : undefined;
//设置新的脚本
this.newValue = newValue;
}
//执行
execute() {
//将新脚本绑定到当前对象的脚本的this.attributeName上
this.script[ this.attributeName ] = this.newValue;
//脚本改变后派发消息
this.editor.signals.scriptChanged.dispatch();
}
undo() {
//恢复上次的脚本
this.script[ this.attributeName ] = this.oldValue;
//脚本改变时触发
this.editor.signals.scriptChanged.dispatch();
}
//更新,将原来的脚本更新为现在的脚本
update( cmd ) {
//更新新的脚本
this.newValue = cmd.newValue;
}
//将脚本信息存储为json 序列化
toJSON() {
//获取基本信息
const output = super.toJSON( this );
//添加自身信息
output.objectUuid = this.object.uuid;
//脚本索引
output.index = this.editor.scripts[ this.object.uuid ].indexOf( this.script );
//脚本名称
output.attributeName = this.attributeName;
//之前的脚本
output.oldValue = this.oldValue;
//现在的脚本
output.newValue = this.newValue;
return output;
}
//将json文件传入 反序列化
fromJSON( json ) {
//将基本信息添加到父类中
super.fromJSON( json );
//复制信息
this.oldValue = json.oldValue;
this.newValue = json.newValue;
this.attributeName = json.attributeName;
this.object = this.editor.objectByUuid( json.objectUuid );
//哪一个对象的哪一个脚本
this.script = this.editor.scripts[ json.objectUuid ][ json.index ];
}
}
export { SetScriptValueCommand };
/js/Command.js:
**/**
* @param editor pointer to main editor object used to initialize
* each command object with a reference to the editor
* @constructor
*/
class Command {
constructor( editor ) {
this.id = - 1;
this.inMemory = false;
this.updatable = false;
this.type = '';
this.name = '';
this.editor = editor;
}
toJSON() {
const output = {};
output.type = this.type;
output.id = this.id;
output.name = this.name;
return output;
}
fromJSON( json ) {
this.inMemory = true;
this.type = json.type;
this.id = json.id;
this.name = json.name;
}
}
export { Command };
**
/js/Commands/Command.js:
**export { AddObjectCommand } from './AddObjectCommand.js';
export { AddScriptCommand } from './AddScriptCommand.js';
export { MoveObjectCommand } from './MoveObjectCommand.js';
export { MultiCmdsCommand } from './MultiCmdsCommand.js';
export { RemoveObjectCommand } from './RemoveObjectCommand.js';
export { RemoveScriptCommand } from './RemoveScriptCommand.js';
export { SetColorCommand } from './SetColorCommand.js';
export { SetGeometryCommand } from './SetGeometryCommand.js';
export { SetGeometryValueCommand } from './SetGeometryValueCommand.js';
export { SetMaterialColorCommand } from './SetMaterialColorCommand.js';
export { SetMaterialCommand } from './SetMaterialCommand.js';
export { SetMaterialMapCommand } from './SetMaterialMapCommand.js';
export { SetMaterialValueCommand } from './SetMaterialValueCommand.js';
export { SetMaterialVectorCommand } from './SetMaterialVectorCommand.js';
export { SetPositionCommand } from './SetPositionCommand.js';
export { SetRotationCommand } from './SetRotationCommand.js';
export { SetScaleCommand } from './SetScaleCommand.js';
export { SetSceneCommand } from './SetSceneCommand.js';
export { SetScriptValueCommand } from './SetScriptValueCommand.js';
export { SetUuidCommand } from './SetUuidCommand.js';
export { SetValueCommand } from './SetValueCommand.js';
**