将ui.js和ui.three.js打包到项目中。

This commit is contained in:
liteng 2018-06-13 20:33:47 +08:00
parent 79db8b94c0
commit 98445da8c4
63 changed files with 1672 additions and 38 deletions

View File

@ -80,8 +80,6 @@
<script src="third_party/tern-threejs/threejs.js"></script>
<script src="third_party/signals.min.js"></script>
<script src="third_party/ui.js"></script>
<script src="third_party/ui.three.js"></script>
<script src="third_party/app.js"></script>

View File

@ -5,6 +5,7 @@ import Player from './core/Player';
import Toolbar from './ui/Toolbar';
import Menubar from './menu/Menubar';
import Panel from './panel/Panel';
import UI from './ui/UI';
/**
* Application

View File

@ -1,3 +1,5 @@
import UI from '../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/
*/

View File

@ -1,3 +1,4 @@
import UI from '../ui/UI';
import SetScriptValueCommand from '../command/SetScriptValueCommand';
/**

View File

@ -1,4 +1,5 @@
import AddObjectCommand from '../command/AddObjectCommand';
import UI from '../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/

View File

@ -1,3 +1,5 @@
import UI from '../ui/UI';
function AssetMenu(editor) {
var NUMBER_PRECISION = 6;

View File

@ -2,6 +2,7 @@
import RemoveObjectCommand from '../command/RemoveObjectCommand';
import SetMaterialValueCommand from '../command/SetMaterialValueCommand';
import MultiCmdsCommand from '../command/MultiCmdsCommand';
import UI from '../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/

View File

@ -1,4 +1,6 @@
/**
import UI from '../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/
*/

View File

@ -1,4 +1,6 @@
/**
import UI from '../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/
*/

View File

@ -1,4 +1,6 @@
/**
import UI from '../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/
*/

View File

@ -7,6 +7,7 @@ import ExampleMenu from './ExampleMenu';
import HelpMenu from './HelpMenu';
import StatusMenu from './StatusMenu';
import ViewMenu from './ViewMenu';
import UI from '../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/

View File

@ -1,4 +1,6 @@
/**
import UI from '../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/
*/

View File

@ -1,4 +1,6 @@
/**
import UI from '../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/
*/
@ -7,7 +9,7 @@ function StatusMenu(editor) {
var container = new UI.Panel();
container.setClass('menu right');
var autosave = new UI.THREE.Boolean(editor.config.getKey('autosave'), '自动保存');
var autosave = new UI.Boolean(editor.config.getKey('autosave'), '自动保存');
autosave.text.setColor('#888');
autosave.onChange(function () {

View File

@ -1,4 +1,6 @@
/**
import UI from '../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/
*/

View File

@ -1,4 +1,6 @@
/**
import UI from '../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/
*/

View File

@ -1,4 +1,6 @@
/**
import UI from '../ui/UI';
/**
* @author dforrer / https://github.com/dforrer
* Developed as part of a project at University of Applied Sciences and Arts Northwestern Switzerland (www.fhnw.ch)
*/
@ -17,7 +19,7 @@ function HistoryPanel(editor) {
//
var persistent = new UI.THREE.Boolean(config.getKey('settings/history'), '永久');
var persistent = new UI.Boolean(config.getKey('settings/history'), '永久');
persistent.setPosition('absolute').setRight('8px');
persistent.onChange(function () {

View File

@ -2,6 +2,7 @@
import SetMaterialValueCommand from '../command/SetMaterialValueCommand';
import SetMaterialColorCommand from '../command/SetMaterialColorCommand';
import SetMaterialMapCommand from '../command/SetMaterialMapCommand';
import UI from '../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/
@ -1235,11 +1236,11 @@ function MaterialPanel(editor) {
}
if ( material.flatShading !== undefined ) {
if (material.flatShading !== undefined) {
materialShading.setValue( material.flatShading );
materialShading.setValue(material.flatShading);
}
}
if (material.blending !== undefined) {

View File

@ -4,6 +4,7 @@ import SetScaleCommand from '../command/SetScaleCommand';
import SetUuidCommand from '../command/SetUuidCommand';
import SetValueCommand from '../command/SetValueCommand';
import SetColorCommand from '../command/SetColorCommand';
import UI from '../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/
@ -245,10 +246,10 @@ function ObjectPanel(editor) {
objectShadowRow.add(new UI.Text('阴影').setWidth('90px'));
var objectCastShadow = new UI.THREE.Boolean(false, '产生').onChange(update);
var objectCastShadow = new UI.Boolean(false, '产生').onChange(update);
objectShadowRow.add(objectCastShadow);
var objectReceiveShadow = new UI.THREE.Boolean(false, '接收').onChange(update);
var objectReceiveShadow = new UI.Boolean(false, '接收').onChange(update);
objectShadowRow.add(objectReceiveShadow);
var objectShadowRadius = new UI.Number(1).onChange(update);

View File

@ -5,6 +5,7 @@ import ScriptPanel from './ScriptPanel';
import ProjectPanel from './ProjectPanel';
import SettingPanel from './SettingPanel';
import HistoryPanel from './HistoryPanel';
import UI from '../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/

View File

@ -1,4 +1,6 @@
/**
import UI from '../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/
*/
@ -59,7 +61,7 @@ function ProjectPanel(editor) {
var rendererPropertiesRow = new UI.Row().setMarginLeft('90px');
var rendererAntialias = new UI.THREE.Boolean(config.getKey('project/renderer/antialias'), '抗锯齿').onChange(function () {
var rendererAntialias = new UI.Boolean(config.getKey('project/renderer/antialias'), '抗锯齿').onChange(function () {
config.setKey('project/renderer/antialias', this.getValue());
updateRenderer();
@ -69,7 +71,7 @@ function ProjectPanel(editor) {
// shadow
var rendererShadows = new UI.THREE.Boolean(config.getKey('project/renderer/shadows'), '阴影').onChange(function () {
var rendererShadows = new UI.Boolean(config.getKey('project/renderer/shadows'), '阴影').onChange(function () {
config.setKey('project/renderer/shadows', this.getValue());
updateRenderer();
@ -81,7 +83,7 @@ function ProjectPanel(editor) {
// gamma input
var rendererGammaInput = new UI.THREE.Boolean(config.getKey('project/renderer/gammaInput'), 'γ输入').onChange(function () {
var rendererGammaInput = new UI.Boolean(config.getKey('project/renderer/gammaInput'), 'γ输入').onChange(function () {
config.setKey('project/renderer/gammaInput', this.getValue());
updateRenderer();
@ -91,7 +93,7 @@ function ProjectPanel(editor) {
// gamma output
var rendererGammaOutput = new UI.THREE.Boolean(config.getKey('project/renderer/gammaOutput'), 'γ输出').onChange(function () {
var rendererGammaOutput = new UI.Boolean(config.getKey('project/renderer/gammaOutput'), 'γ输出').onChange(function () {
config.setKey('project/renderer/gammaOutput', this.getValue());
updateRenderer();

View File

@ -1,6 +1,7 @@
import ObjectPanel from './ObjectPanel';
import GeometryPanel from './geometry/GeometryPanel';
import MaterialPanel from './MaterialPanel';
import UI from '../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/

View File

@ -1,4 +1,6 @@
/**
import UI from '../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/
*/

View File

@ -1,6 +1,7 @@
import AddScriptCommand from '../command/AddScriptCommand';
import SetScriptValueCommand from '../command/SetScriptValueCommand';
import RemoveScriptCommand from '../command/RemoveScriptCommand';
import UI from '../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/

View File

@ -1,4 +1,6 @@
/**
import UI from '../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/
*/

View File

@ -1,4 +1,5 @@
import SetGeometryCommand from '../../command/SetGeometryCommand';
import UI from '../../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/

View File

@ -1,4 +1,6 @@
/**
import UI from '../../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/
*/

View File

@ -1,4 +1,6 @@
/**
import UI from '../../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/
*/

View File

@ -1,4 +1,6 @@
/**
import UI from '../../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/
*/

View File

@ -1,4 +1,6 @@
/**
import UI from '../../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/
*/

View File

@ -1,4 +1,6 @@
/**
import UI from '../../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/
*/

View File

@ -14,6 +14,8 @@ import TeapotBufferGeometryPanel from './TeapotBufferGeometryPanel';
import TorusGeometryPanel from './TorusGeometryPanel';
import TorusKnotGeometryPanel from './TorusKnotGeometryPanel';
import UI from '../../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/
*/

View File

@ -1,4 +1,5 @@
import SetGeometryCommand from '../../command/SetGeometryCommand';
import UI from '../../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/

View File

@ -1,4 +1,6 @@
/**
import UI from '../../ui/UI';
/**
* @author rfm1201
*/

View File

@ -1,4 +1,5 @@
import SetGeometryCommand from '../../command/SetGeometryCommand';
import UI from '../../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/

View File

@ -1,4 +1,5 @@
import SetGeometryCommand from '../../command/SetGeometryCommand';
import UI from '../../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/

View File

@ -1,4 +1,6 @@
/**
import UI from '../../ui/UI';
/**
* @author tschw
*/

View File

@ -1,4 +1,5 @@
import SetGeometryCommand from '../../command/SetGeometryCommand';
import UI from '../../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/

View File

@ -1,4 +1,5 @@
import SetGeometryCommand from '../../command/SetGeometryCommand';
import UI from '../../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/

34
src/ui/Boolean.js Normal file
View File

@ -0,0 +1,34 @@
import Span from './Span';
import Checkbox from './Checkbox';
import Text from './Text';
function Boolean(boolean, text) {
Span.call(this);
this.setMarginRight('10px');
this.checkbox = new Checkbox(boolean);
this.text = new Text(text).setMarginLeft('3px');
this.add(this.checkbox);
this.add(this.text);
};
Boolean.prototype = Object.create(Span.prototype);
Boolean.prototype.constructor = Boolean;
Boolean.prototype.getValue = function () {
return this.checkbox.getValue();
};
Boolean.prototype.setValue = function (value) {
return this.checkbox.setValue(value);
};
export default Boolean;

21
src/ui/Break.js Normal file
View File

@ -0,0 +1,21 @@
import Element from './Element';
// Break
function Break() {
Element.call(this);
var dom = document.createElement('br');
dom.className = 'Break';
this.dom = dom;
return this;
};
Break.prototype = Object.create(Element.prototype);
Break.prototype.constructor = Break;
export default Break;

30
src/ui/Button.js Normal file
View File

@ -0,0 +1,30 @@
import Element from './Element';
// Button
function Button(value) {
Element.call(this);
var dom = document.createElement('button');
dom.className = 'Button';
this.dom = dom;
this.dom.textContent = value;
return this;
};
Button.prototype = Object.create(Element.prototype);
Button.prototype.constructor = Button;
Button.prototype.setLabel = function (value) {
this.dom.textContent = value;
return this;
};
export default Button;

43
src/ui/Checkbox.js Normal file
View File

@ -0,0 +1,43 @@
import Element from './Element';
// Checkbox
function Checkbox(boolean) {
Element.call(this);
var scope = this;
var dom = document.createElement('input');
dom.className = 'Checkbox';
dom.type = 'checkbox';
this.dom = dom;
this.setValue(boolean);
return this;
};
Checkbox.prototype = Object.create(Element.prototype);
Checkbox.prototype.constructor = Checkbox;
Checkbox.prototype.getValue = function () {
return this.dom.checked;
};
Checkbox.prototype.setValue = function (value) {
if (value !== undefined) {
this.dom.checked = value;
}
return this;
};
export default Checkbox;

63
src/ui/Color.js Normal file
View File

@ -0,0 +1,63 @@
import Element from './Element';
// Color
function Color() {
Element.call(this);
var scope = this;
var dom = document.createElement('input');
dom.className = 'Color';
dom.style.width = '64px';
dom.style.height = '17px';
dom.style.border = '0px';
dom.style.padding = '2px';
dom.style.backgroundColor = 'transparent';
try {
dom.type = 'color';
dom.value = '#ffffff';
} catch (exception) { }
this.dom = dom;
return this;
};
Color.prototype = Object.create(Element.prototype);
Color.prototype.constructor = Color;
Color.prototype.getValue = function () {
return this.dom.value;
};
Color.prototype.getHexValue = function () {
return parseInt(this.dom.value.substr(1), 16);
};
Color.prototype.setValue = function (value) {
this.dom.value = value;
return this;
};
Color.prototype.setHexValue = function (hex) {
this.dom.value = '#' + ('000000' + hex.toString(16)).slice(- 6);
return this;
};
export default Color;

18
src/ui/Div.js Normal file
View File

@ -0,0 +1,18 @@
import Element from './Element';
// Div
function Div() {
Element.call(this);
this.dom = document.createElement('div');
return this;
};
Div.prototype = Object.create(Element.prototype);
Div.prototype.constructor = Div;
export default Div;

151
src/ui/Element.js Normal file
View File

@ -0,0 +1,151 @@
/**
* @author mrdoob / http://mrdoob.com/
*/
function Element(dom) {
this.dom = dom;
};
Element.prototype = {
add: function () {
for (var i = 0; i < arguments.length; i++) {
var argument = arguments[i];
if (argument instanceof Element) {
this.dom.appendChild(argument.dom);
} else {
console.error('Element:', argument, 'is not an instance of Element.');
}
}
return this;
},
remove: function () {
for (var i = 0; i < arguments.length; i++) {
var argument = arguments[i];
if (argument instanceof Element) {
this.dom.removeChild(argument.dom);
} else {
console.error('Element:', argument, 'is not an instance of Element.');
}
}
return this;
},
clear: function () {
while (this.dom.children.length) {
this.dom.removeChild(this.dom.lastChild);
}
},
setId: function (id) {
this.dom.id = id;
return this;
},
setClass: function (name) {
this.dom.className = name;
return this;
},
setStyle: function (style, array) {
for (var i = 0; i < array.length; i++) {
this.dom.style[style] = array[i];
}
return this;
},
setDisabled: function (value) {
this.dom.disabled = value;
return this;
},
setTextContent: function (value) {
this.dom.textContent = value;
return this;
}
};
// properties
var properties = ['position', 'left', 'top', 'right', 'bottom', 'width', 'height', 'border', 'borderLeft',
'borderTop', 'borderRight', 'borderBottom', 'borderColor', 'display', 'overflow', 'margin', 'marginLeft', 'marginTop', 'marginRight', 'marginBottom', 'padding', 'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom', 'color',
'background', 'backgroundColor', 'opacity', 'fontSize', 'fontWeight', 'textAlign', 'textDecoration', 'textTransform', 'cursor', 'zIndex'];
properties.forEach(function (property) {
var method = 'set' + property.substr(0, 1).toUpperCase() + property.substr(1, property.length);
Element.prototype[method] = function () {
this.setStyle(property, arguments);
return this;
};
});
// events
var events = ['KeyUp', 'KeyDown', 'MouseOver', 'MouseOut', 'Click', 'DblClick', 'Change'];
events.forEach(function (event) {
var method = 'on' + event;
Element.prototype[method] = function (callback) {
this.dom.addEventListener(event.toLowerCase(), callback.bind(this), false);
return this;
};
});
export default Element;

21
src/ui/HorizontalRule.js Normal file
View File

@ -0,0 +1,21 @@
import Element from './Element';
// HorizontalRule
function HorizontalRule() {
Element.call(this);
var dom = document.createElement('hr');
dom.className = 'HorizontalRule';
this.dom = dom;
return this;
};
HorizontalRule.prototype = Object.create(Element.prototype);
HorizontalRule.prototype.constructor = HorizontalRule;
export default HorizontalRule;

46
src/ui/Input.js Normal file
View File

@ -0,0 +1,46 @@
import Element from './Element';
// Input
function Input(text) {
Element.call(this);
var scope = this;
var dom = document.createElement('input');
dom.className = 'Input';
dom.style.padding = '2px';
dom.style.border = '1px solid transparent';
dom.addEventListener('keydown', function (event) {
event.stopPropagation();
}, false);
this.dom = dom;
this.setValue(text);
return this;
};
Input.prototype = Object.create(Element.prototype);
Input.prototype.constructor = Input;
Input.prototype.getValue = function () {
return this.dom.value;
};
Input.prototype.setValue = function (value) {
this.dom.value = value;
return this;
};
export default Input;

164
src/ui/Integer.js Normal file
View File

@ -0,0 +1,164 @@
import Element from './Element';
// Integer
function Integer(number) {
Element.call(this);
var scope = this;
var dom = document.createElement('input');
dom.className = 'Number';
dom.value = '0';
dom.addEventListener('keydown', function (event) {
event.stopPropagation();
}, false);
this.value = 0;
this.min = - Infinity;
this.max = Infinity;
this.step = 1;
this.dom = dom;
this.setValue(number);
var changeEvent = document.createEvent('HTMLEvents');
changeEvent.initEvent('change', true, true);
var distance = 0;
var onMouseDownValue = 0;
var pointer = [0, 0];
var prevPointer = [0, 0];
function onMouseDown(event) {
event.preventDefault();
distance = 0;
onMouseDownValue = scope.value;
prevPointer = [event.clientX, event.clientY];
document.addEventListener('mousemove', onMouseMove, false);
document.addEventListener('mouseup', onMouseUp, false);
}
function onMouseMove(event) {
var currentValue = scope.value;
pointer = [event.clientX, event.clientY];
distance += (pointer[0] - prevPointer[0]) - (pointer[1] - prevPointer[1]);
var value = onMouseDownValue + (distance / (event.shiftKey ? 5 : 50)) * scope.step;
value = Math.min(scope.max, Math.max(scope.min, value)) | 0;
if (currentValue !== value) {
scope.setValue(value);
dom.dispatchEvent(changeEvent);
}
prevPointer = [event.clientX, event.clientY];
}
function onMouseUp(event) {
document.removeEventListener('mousemove', onMouseMove, false);
document.removeEventListener('mouseup', onMouseUp, false);
if (Math.abs(distance) < 2) {
dom.focus();
dom.select();
}
}
function onChange(event) {
scope.setValue(dom.value);
}
function onFocus(event) {
dom.style.backgroundColor = '';
dom.style.cursor = '';
}
function onBlur(event) {
dom.style.backgroundColor = 'transparent';
dom.style.cursor = 'col-resize';
}
onBlur();
dom.addEventListener('mousedown', onMouseDown, false);
dom.addEventListener('change', onChange, false);
dom.addEventListener('focus', onFocus, false);
dom.addEventListener('blur', onBlur, false);
return this;
};
Integer.prototype = Object.create(Element.prototype);
Integer.prototype.constructor = Integer;
Integer.prototype.getValue = function () {
return this.value;
};
Integer.prototype.setValue = function (value) {
if (value !== undefined) {
value = parseInt(value);
this.value = value;
this.dom.value = value;
}
return this;
};
Integer.prototype.setStep = function (step) {
this.step = parseInt(step);
return this;
};
Integer.prototype.setRange = function (min, max) {
this.min = min;
this.max = max;
return this;
};
export default Integer;

61
src/ui/Modal.js Normal file
View File

@ -0,0 +1,61 @@
import Element from './Element';
import Panel from './Panel';
// Modal
function Modal(value) {
var scope = this;
var dom = document.createElement('div');
dom.style.position = 'absolute';
dom.style.width = '100%';
dom.style.height = '100%';
dom.style.backgroundColor = 'rgba(0,0,0,0.5)';
dom.style.display = 'none';
dom.style.alignItems = 'center';
dom.style.justifyContent = 'center';
dom.addEventListener('click', function (event) {
scope.hide();
});
this.dom = dom;
this.container = new Panel();
this.container.dom.style.width = '200px';
this.container.dom.style.padding = '20px';
this.container.dom.style.backgroundColor = '#ffffff';
this.container.dom.style.boxShadow = '0px 5px 10px rgba(0,0,0,0.5)';
this.add(this.container);
return this;
};
Modal.prototype = Object.create(Element.prototype);
Modal.prototype.constructor = Modal;
Modal.prototype.show = function (content) {
this.container.clear();
this.container.add(content);
this.dom.style.display = 'flex';
return this;
};
Modal.prototype.hide = function () {
this.dom.style.display = 'none';
return this;
};
export default Modal;

189
src/ui/Number.js Normal file
View File

@ -0,0 +1,189 @@
import Element from './Element';
// Number
function Number(number) {
Element.call(this);
var scope = this;
var dom = document.createElement('input');
dom.className = 'Number';
dom.value = '0.00';
dom.addEventListener('keydown', function (event) {
event.stopPropagation();
if (event.keyCode === 13) dom.blur();
}, false);
this.value = 0;
this.min = - Infinity;
this.max = Infinity;
this.precision = 2;
this.step = 1;
this.unit = '';
this.dom = dom;
this.setValue(number);
var changeEvent = document.createEvent('HTMLEvents');
changeEvent.initEvent('change', true, true);
var distance = 0;
var onMouseDownValue = 0;
var pointer = [0, 0];
var prevPointer = [0, 0];
function onMouseDown(event) {
event.preventDefault();
distance = 0;
onMouseDownValue = scope.value;
prevPointer = [event.clientX, event.clientY];
document.addEventListener('mousemove', onMouseMove, false);
document.addEventListener('mouseup', onMouseUp, false);
}
function onMouseMove(event) {
var currentValue = scope.value;
pointer = [event.clientX, event.clientY];
distance += (pointer[0] - prevPointer[0]) - (pointer[1] - prevPointer[1]);
var value = onMouseDownValue + (distance / (event.shiftKey ? 5 : 50)) * scope.step;
value = Math.min(scope.max, Math.max(scope.min, value));
if (currentValue !== value) {
scope.setValue(value);
dom.dispatchEvent(changeEvent);
}
prevPointer = [event.clientX, event.clientY];
}
function onMouseUp(event) {
document.removeEventListener('mousemove', onMouseMove, false);
document.removeEventListener('mouseup', onMouseUp, false);
if (Math.abs(distance) < 2) {
dom.focus();
dom.select();
}
}
function onChange(event) {
scope.setValue(dom.value);
}
function onFocus(event) {
dom.style.backgroundColor = '';
dom.style.cursor = '';
}
function onBlur(event) {
dom.style.backgroundColor = 'transparent';
dom.style.cursor = 'col-resize';
}
onBlur();
dom.addEventListener('mousedown', onMouseDown, false);
dom.addEventListener('change', onChange, false);
dom.addEventListener('focus', onFocus, false);
dom.addEventListener('blur', onBlur, false);
return this;
};
Number.prototype = Object.create(Element.prototype);
Number.prototype.constructor = Number;
Number.prototype.getValue = function () {
return this.value;
};
Number.prototype.setValue = function (value) {
if (value !== undefined) {
value = parseFloat(value);
if (value < this.min) value = this.min;
if (value > this.max) value = this.max;
this.value = value;
this.dom.value = value.toFixed(this.precision);
if (this.unit !== '') this.dom.value += ' ' + this.unit;
}
return this;
};
Number.prototype.setPrecision = function (precision) {
this.precision = precision;
return this;
};
Number.prototype.setStep = function (step) {
this.step = step;
return this;
};
Number.prototype.setRange = function (min, max) {
this.min = min;
this.max = max;
return this;
};
Number.prototype.setUnit = function (unit) {
this.unit = unit;
return this;
};
export default Number;

270
src/ui/Outliner.js Normal file
View File

@ -0,0 +1,270 @@
import Element from './Element';
// Outliner
function Outliner(editor) {
Element.call(this);
var scope = this;
var dom = document.createElement('div');
dom.className = 'Outliner';
dom.tabIndex = 0; // keyup event is ignored without setting tabIndex
// hack
this.scene = editor.scene;
// Prevent native scroll behavior
dom.addEventListener('keydown', function (event) {
switch (event.keyCode) {
case 38: // up
case 40: // down
event.preventDefault();
event.stopPropagation();
break;
}
}, false);
// Keybindings to support arrow navigation
dom.addEventListener('keyup', function (event) {
switch (event.keyCode) {
case 38: // up
scope.selectIndex(scope.selectedIndex - 1);
break;
case 40: // down
scope.selectIndex(scope.selectedIndex + 1);
break;
}
}, false);
this.dom = dom;
this.options = [];
this.selectedIndex = - 1;
this.selectedValue = null;
return this;
};
Outliner.prototype = Object.create(Element.prototype);
Outliner.prototype.constructor = Outliner;
Outliner.prototype.selectIndex = function (index) {
if (index >= 0 && index < this.options.length) {
this.setValue(this.options[index].value);
var changeEvent = document.createEvent('HTMLEvents');
changeEvent.initEvent('change', true, true);
this.dom.dispatchEvent(changeEvent);
}
};
Outliner.prototype.setOptions = function (options) {
var scope = this;
while (scope.dom.children.length > 0) {
scope.dom.removeChild(scope.dom.firstChild);
}
function onClick() {
scope.setValue(this.value);
var changeEvent = document.createEvent('HTMLEvents');
changeEvent.initEvent('change', true, true);
scope.dom.dispatchEvent(changeEvent);
}
// Drag
var currentDrag;
function onDrag(event) {
currentDrag = this;
}
function onDragStart(event) {
event.dataTransfer.setData('text', 'foo');
}
function onDragOver(event) {
if (this === currentDrag) return;
var area = event.offsetY / this.clientHeight;
if (area < 0.25) {
this.className = 'option dragTop';
} else if (area > 0.75) {
this.className = 'option dragBottom';
} else {
this.className = 'option drag';
}
}
function onDragLeave() {
if (this === currentDrag) return;
this.className = 'option';
}
function onDrop(event) {
if (this === currentDrag) return;
this.className = 'option';
var scene = scope.scene;
var object = scene.getObjectById(currentDrag.value);
var area = event.offsetY / this.clientHeight;
if (area < 0.25) {
var nextObject = scene.getObjectById(this.value);
moveObject(object, nextObject.parent, nextObject);
} else if (area > 0.75) {
var nextObject = scene.getObjectById(this.nextSibling.value);
moveObject(object, nextObject.parent, nextObject);
} else {
var parentObject = scene.getObjectById(this.value);
moveObject(object, parentObject);
}
}
function moveObject(object, newParent, nextObject) {
if (nextObject === null) nextObject = undefined;
var newParentIsChild = false;
object.traverse(function (child) {
if (child === newParent) newParentIsChild = true;
});
if (newParentIsChild) return;
editor.execute(new MoveObjectCommand(object, newParent, nextObject));
var changeEvent = document.createEvent('HTMLEvents');
changeEvent.initEvent('change', true, true);
scope.dom.dispatchEvent(changeEvent);
}
//
scope.options = [];
for (var i = 0; i < options.length; i++) {
var div = options[i];
div.className = 'option';
scope.dom.appendChild(div);
scope.options.push(div);
div.addEventListener('click', onClick, false);
if (div.draggable === true) {
div.addEventListener('drag', onDrag, false);
div.addEventListener('dragstart', onDragStart, false); // Firefox needs this
div.addEventListener('dragover', onDragOver, false);
div.addEventListener('dragleave', onDragLeave, false);
div.addEventListener('drop', onDrop, false);
}
}
return scope;
};
Outliner.prototype.getValue = function () {
return this.selectedValue;
};
Outliner.prototype.setValue = function (value) {
for (var i = 0; i < this.options.length; i++) {
var element = this.options[i];
if (element.value === value) {
element.classList.add('active');
// scroll into view
var y = element.offsetTop - this.dom.offsetTop;
var bottomY = y + element.offsetHeight;
var minScroll = bottomY - this.dom.offsetHeight;
if (this.dom.scrollTop > y) {
this.dom.scrollTop = y;
} else if (this.dom.scrollTop < minScroll) {
this.dom.scrollTop = minScroll;
}
this.selectedIndex = i;
} else {
element.classList.remove('active');
}
}
this.selectedValue = value;
return this;
};
export default Outliner;

21
src/ui/Panel.js Normal file
View File

@ -0,0 +1,21 @@
import Element from './Element';
// Panel
function Panel() {
Element.call(this);
var dom = document.createElement('div');
dom.className = 'Panel';
this.dom = dom;
return this;
};
Panel.prototype = Object.create(Element.prototype);
Panel.prototype.constructor = Panel;
export default Panel;

20
src/ui/Row.js Normal file
View File

@ -0,0 +1,20 @@
import Element from './Element';
// Row
function Row() {
Element.call(this);
var dom = document.createElement('div');
dom.className = 'Row';
this.dom = dom;
return this;
};
Row.prototype = Object.create(Element.prototype);
Row.prototype.constructor = Row;
export default Row;

77
src/ui/Select.js Normal file
View File

@ -0,0 +1,77 @@
import Element from './Element';
// Select
function Select() {
Element.call(this);
var scope = this;
var dom = document.createElement('select');
dom.className = 'Select';
dom.style.padding = '2px';
this.dom = dom;
return this;
};
Select.prototype = Object.create(Element.prototype);
Select.prototype.constructor = Select;
Select.prototype.setMultiple = function (boolean) {
this.dom.multiple = boolean;
return this;
};
Select.prototype.setOptions = function (options) {
var selected = this.dom.value;
while (this.dom.children.length > 0) {
this.dom.removeChild(this.dom.firstChild);
}
for (var key in options) {
var option = document.createElement('option');
option.value = key;
option.innerHTML = options[key];
this.dom.appendChild(option);
}
this.dom.value = selected;
return this;
};
Select.prototype.getValue = function () {
return this.dom.value;
};
Select.prototype.setValue = function (value) {
value = String(value);
if (this.dom.value !== value) {
this.dom.value = value;
}
return this;
};
export default Select;

18
src/ui/Span.js Normal file
View File

@ -0,0 +1,18 @@
import Element from './Element';
// Span
function Span() {
Element.call(this);
this.dom = document.createElement('span');
return this;
};
Span.prototype = Object.create(Element.prototype);
Span.prototype.constructor = Span;
export default Span;

43
src/ui/Text.js Normal file
View File

@ -0,0 +1,43 @@
import Element from './Element';
// Text
function Text(text) {
Element.call(this);
var dom = document.createElement('span');
dom.className = 'Text';
dom.style.cursor = 'default';
dom.style.display = 'inline-block';
dom.style.verticalAlign = 'middle';
this.dom = dom;
this.setValue(text);
return this;
};
Text.prototype = Object.create(Element.prototype);
Text.prototype.constructor = Text;
Text.prototype.getValue = function () {
return this.dom.textContent;
};
Text.prototype.setValue = function (value) {
if (value !== undefined) {
this.dom.textContent = value;
}
return this;
};
export default Text;

57
src/ui/TextArea.js Normal file
View File

@ -0,0 +1,57 @@
import Element from './Element';
// TextArea
function TextArea() {
Element.call(this);
var scope = this;
var dom = document.createElement('textarea');
dom.className = 'TextArea';
dom.style.padding = '2px';
dom.spellcheck = false;
dom.addEventListener('keydown', function (event) {
event.stopPropagation();
if (event.keyCode === 9) {
event.preventDefault();
var cursor = dom.selectionStart;
dom.value = dom.value.substring(0, cursor) + '\t' + dom.value.substring(cursor);
dom.selectionStart = cursor + 1;
dom.selectionEnd = dom.selectionStart;
}
}, false);
this.dom = dom;
return this;
};
TextArea.prototype = Object.create(Element.prototype);
TextArea.prototype.constructor = TextArea;
TextArea.prototype.getValue = function () {
return this.dom.value;
};
TextArea.prototype.setValue = function (value) {
this.dom.value = value;
return this;
};
export default TextArea;

174
src/ui/Texture.js Normal file
View File

@ -0,0 +1,174 @@
import Element from './Element';
/**
* @author mrdoob / http://mrdoob.com/
*/
function Texture(mapping) {
Element.call(this);
var scope = this;
var dom = document.createElement('span');
var form = document.createElement('form');
var input = document.createElement('input');
input.type = 'file';
input.addEventListener('change', function (event) {
loadFile(event.target.files[0]);
});
form.appendChild(input);
var canvas = document.createElement('canvas');
canvas.width = 32;
canvas.height = 16;
canvas.style.cursor = 'pointer';
canvas.style.marginRight = '5px';
canvas.style.border = '1px solid #888';
canvas.addEventListener('click', function (event) {
input.click();
}, false);
canvas.addEventListener('drop', function (event) {
event.preventDefault();
event.stopPropagation();
loadFile(event.dataTransfer.files[0]);
}, false);
dom.appendChild(canvas);
var name = document.createElement('input');
name.disabled = true;
name.style.width = '64px';
name.style.border = '1px solid #ccc';
dom.appendChild(name);
function loadFile(file) {
if (file.type.match('image.*')) {
var reader = new FileReader();
if (file.type === 'image/targa') {
reader.addEventListener('load', function (event) {
var canvas = new THREE.TGALoader().parse(event.target.result);
var texture = new THREE.CanvasTexture(canvas, mapping);
texture.sourceFile = file.name;
scope.setValue(texture);
if (scope.onChangeCallback) scope.onChangeCallback();
}, false);
reader.readAsArrayBuffer(file);
} else {
reader.addEventListener('load', function (event) {
var image = document.createElement('img');
image.addEventListener('load', function (event) {
var texture = new THREE.Texture(this, mapping);
texture.sourceFile = file.name;
texture.format = file.type === 'image/jpeg' ? THREE.RGBFormat : THREE.RGBAFormat;
texture.needsUpdate = true;
scope.setValue(texture);
if (scope.onChangeCallback) scope.onChangeCallback();
}, false);
image.src = event.target.result;
}, false);
reader.readAsDataURL(file);
}
}
form.reset();
}
this.dom = dom;
this.texture = null;
this.onChangeCallback = null;
return this;
};
Texture.prototype = Object.create(Element.prototype);
Texture.prototype.constructor = Texture;
Texture.prototype.getValue = function () {
return this.texture;
};
Texture.prototype.setValue = function (texture) {
var canvas = this.dom.children[0];
var name = this.dom.children[1];
var context = canvas.getContext('2d');
if (texture !== null) {
var image = texture.image;
if (image !== undefined && image.width > 0) {
name.value = texture.sourceFile;
var scale = canvas.width / image.width;
context.drawImage(image, 0, 0, image.width * scale, image.height * scale);
} else {
name.value = texture.sourceFile + ' (error)';
context.clearRect(0, 0, canvas.width, canvas.height);
}
} else {
name.value = '';
if (context !== null) {
// Seems like context can be null if the canvas is not visible
context.clearRect(0, 0, canvas.width, canvas.height);
}
}
this.texture = texture;
};
Texture.prototype.onChange = function (callback) {
this.onChangeCallback = callback;
return this;
};
export default Texture;

View File

@ -1,4 +1,6 @@
/**
import UI from '../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/
*/
@ -64,13 +66,13 @@ function Toolbar(editor) {
buttons.add(new UI.Text('网格:'));
buttons.add(grid);
var snap = new UI.THREE.Boolean(false, '单元').onChange(update);
var snap = new UI.Boolean(false, '单元').onChange(update);
buttons.add(snap);
var local = new UI.THREE.Boolean(false, '本地').onChange(update);
var local = new UI.Boolean(false, '本地').onChange(update);
buttons.add(local);
var showGrid = new UI.THREE.Boolean(true, '网格').onChange(update);
var showGrid = new UI.Boolean(true, '网格').onChange(update);
buttons.add(showGrid);
function update() {

51
src/ui/UI.js Normal file
View File

@ -0,0 +1,51 @@
// ui.js
import Element from './Element';
import Span from './Span';
import Div from './Div';
import Row from './Row';
import Panel from './Panel';
import Text from './Text';
import Input from './Input';
import TextArea from './TextArea';
import Select from './Select';
import Checkbox from './Checkbox';
import Color from './Color';
import Number from './Number';
import Integer from './Integer';
import Break from './Break';
import HorizontalRule from './HorizontalRule';
import Button from './Button';
import Modal from './Modal';
// ui.three.js
import Texture from './Texture';
import Outliner from './Outliner';
import Boolean from './Boolean';
const UI = {
// ui.js
Element: Element,
Span: Span,
Div: Div,
Row: Row,
Panel: Panel,
Text: Text,
Input: Input,
TextArea: TextArea,
Select: Select,
Checkbox: Checkbox,
Color: Color,
Number: Number,
Integer: Integer,
Break: Break,
HorizontalRule: HorizontalRule,
Button: Button,
Modal: Modal,
// ui.three.js
Texture: Texture,
Outliner: Outliner,
Boolean: Boolean
};
export default UI;

View File

@ -2,6 +2,7 @@
import SetPositionCommand from '../command/SetPositionCommand';
import SetRotationCommand from '../command/SetRotationCommand';
import SetScaleCommand from '../command/SetScaleCommand';
import UI from '../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/
@ -350,7 +351,7 @@ function Viewport(editor) {
container.dom.appendChild(renderer.domElement);
if ( renderer.vr.enabled ) {
if (renderer.vr.enabled) {
vrControls = new THREE.VRControls(vrCamera);
vrEffect = new THREE.VREffect(renderer);
@ -390,7 +391,7 @@ function Viewport(editor) {
if (box.isEmpty() === false) {
selectionBox.setFromObject( object );
selectionBox.setFromObject(object);
selectionBox.visible = true;
}

View File

@ -1,4 +1,6 @@
/**
import UI from '../ui/UI';
/**
* @author mrdoob / http://mrdoob.com/
*/

View File

@ -1,3 +1,4 @@
export { default as UI } from './UI';
export { default as ViewportInfo } from './ViewportInfo';
export { default as Viewport } from './Viewport';
export { default as Toolbar } from './Toolbar';