提交 20dc92f3 编写于 作者: M Mr.doob

Editor: Reworked scripting UI. Implemented CodeMirror.

上级 88cde75a
......@@ -37,6 +37,15 @@ input.Number {
text-shadow: 1px 1px 0px rgba(0,0,0,0.25);
}
#script {
position: absolute;
top: 32px;
left: 0px;
right: 300px;
bottom: 32px;
opacity: 0.9;
}
#player {
position: absolute;
top: 32px;
......@@ -80,7 +89,7 @@ input.Number {
display: none;
padding: 5px 0px;
background: #111;
width: 140px;
width: 150px;
}
#menubar .menu:hover .options {
......
......@@ -38,6 +38,15 @@ input.Number {
text-shadow: 1px 1px 0px rgba(0,0,0,0.25);
}
#script {
position: absolute;
top: 32px;
left: 0px;
right: 300px;
bottom: 32px;
opacity: 0.9;
}
#player {
position: absolute;
top: 32px;
......@@ -81,7 +90,7 @@ input.Number {
display: none;
padding: 5px 0px;
background: #eee;
width: 140px;
width: 150px;
}
#menubar .menu:hover .options {
......
......@@ -71,6 +71,14 @@ textarea, input { outline: none; } /* osx */
display: none;
}
.CodeMirror {
position: absolute !important;
top: 37px;
width: 100% !important;
height: calc(100% - 37px) !important;
}
/* scene types */
.type {
......
{
"camera": {
"metadata": {
"version": 4.3,
"type": "Object",
"generator": "ObjectExporter"
},
"object": {
"uuid": "F0D8434F-4603-415B-8024-792FE97B9600",
"type": "PerspectiveCamera",
"name": "Camera",
"fov": 50,
"aspect": 1.2252042007001167,
"near": 0.1,
"far": 100000,
"matrix": [0.9700406789779663,-5.500052080442686e-10,-0.24294254183769226,0,-0.04822639003396034,0.9800989627838135,-0.19256223738193512,0,0.23810774087905884,0.19850945472717285,0.950735867023468,0,159.0158233642578,132.5708465576172,634.9312744140625,1]
}
},
"scene": {
"metadata": {
"version": 4.3,
"type": "Object",
"generator": "ObjectExporter"
},
"geometries": [
{
"uuid": "D8E200D3-27BC-49F8-A5C5-7384206E70FE",
"type": "BoxGeometry",
"width": 100,
"height": 100,
"depth": 100,
"widthSegments": 1,
"heightSegments": 1,
"depthSegments": 1
},
{
"uuid": "25BA32DB-8B02-4ABA-A77C-69868C464A1A",
"type": "CylinderGeometry",
"radiusTop": 0,
"radiusBottom": 40,
"height": 75,
"radialSegments": 4,
"heightSegments": 1,
"openEnded": false
},
{
"uuid": "51BB3E54-D2DF-4576-9953-FB8E940588B5",
"type": "PlaneGeometry",
"width": 1000,
"height": 1000,
"widthSegments": 1,
"heightSegments": 1
},
{
"uuid": "4DECFAB5-6FD1-4D84-9A29-565807B074EA",
"type": "IcosahedronGeometry",
"radius": 40,
"detail": 2
}],
"materials": [
{
"uuid": "B5943856-E404-45D9-A427-4774202C2CD0",
"type": "MeshPhongMaterial",
"color": 37119,
"ambient": 16777215,
"emissive": 0,
"specular": 1118481,
"shininess": 30
},
{
"uuid": "3F872310-2067-4BE4-9250-5B3F4E43797E",
"type": "MeshPhongMaterial",
"color": 15859456,
"ambient": 16777215,
"emissive": 0,
"specular": 1118481,
"shininess": 30
},
{
"uuid": "4AE8130E-B6A8-47BC-ACCF-060973C74044",
"type": "MeshPhongMaterial",
"color": 16777215,
"ambient": 16777215,
"emissive": 0,
"specular": 1118481,
"shininess": 30
},
{
"uuid": "E1826901-7922-4584-A25D-6D487E2C9BBD",
"type": "MeshPhongMaterial",
"color": 16711680,
"ambient": 16777215,
"emissive": 0,
"specular": 1118481,
"shininess": 30
}],
"object": {
"uuid": "3741222A-BD8F-401C-A5D2-5A907E891896",
"type": "Scene",
"name": "Scene",
"matrix": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],
"children": [
{
"uuid": "60B69C58-4201-43FD-815E-AD2EDFBBD0CE",
"type": "PerspectiveCamera",
"name": "PerspectiveCamera 1",
"fov": 50,
"aspect": 1,
"near": 100,
"far": 10000,
"matrix": [1,0,0,0,0,1,0,0,0,0,1,0,0,100,400,1]
},
{
"uuid": "26DAAD69-725D-43B7-AF9D-990A99DEF8C5",
"type": "Mesh",
"name": "Box 1",
"geometry": "D8E200D3-27BC-49F8-A5C5-7384206E70FE",
"material": "B5943856-E404-45D9-A427-4774202C2CD0",
"matrix": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]
},
{
"uuid": "AAAFF2D6-4725-4AFC-A9FE-26419B11011F",
"type": "Mesh",
"name": "Cylinder 3",
"geometry": "25BA32DB-8B02-4ABA-A77C-69868C464A1A",
"material": "3F872310-2067-4BE4-9250-5B3F4E43797E",
"matrix": [1,0,0,0,0,1,0,0,0,0,1,0,-130,-15,0,1]
},
{
"uuid": "A460C230-DC88-4A8F-A3FB-AA0FE735F3ED",
"type": "Mesh",
"name": "Plane 4",
"geometry": "51BB3E54-D2DF-4576-9953-FB8E940588B5",
"material": "4AE8130E-B6A8-47BC-ACCF-060973C74044",
"matrix": [1,0,0,0,0,0.040785059332847595,-0.9991679191589355,0,0,0.9991679191589355,0.040785059332847595,0,0,-50,0,1]
},
{
"uuid": "3412781E-27CC-43C3-A5DB-54C0C8E42ED6",
"type": "PointLight",
"name": "PointLight 2",
"color": 12773063,
"intensity": 1,
"distance": 0,
"matrix": [1,0,0,0,0,1,0,0,0,0,1,0,88.12999725341797,8.3100004196167,125.44999694824219,1]
},
{
"uuid": "E2939A7B-5E40-438A-8C1B-32126FBC6892",
"type": "PointLight",
"name": "PointLight 1",
"color": 9474221,
"intensity": 0.75,
"distance": 0,
"matrix": [1,0,0,0,0,1,0,0,0,0,1,0,-93.86000061035156,127.12999725341797,-114.30000305175781,1]
},
{
"uuid": "B855E267-A266-4098-ACD6-6A1FDE7B88BA",
"type": "Mesh",
"name": "Icosahedron 1",
"geometry": "4DECFAB5-6FD1-4D84-9A29-565807B074EA",
"material": "E1826901-7922-4584-A25D-6D487E2C9BBD",
"matrix": [1,0,0,0,0,1,0,0,0,0,1,0,130,-10,0,1]
}]
}
},
"scripts": {
"60B69C58-4201-43FD-815E-AD2EDFBBD0CE": [
{
"name": "Camera Orbit",
"source": "player.setCamera( this );\n\nfunction update( event ) {\n\n\tvar time = event.time * 0.001;\n\n\tthis.position.x = Math.sin( time ) * 400;\n\tthis.position.z = Math.cos( time ) * 400;\n\tthis.lookAt( scene.position );\n\n}"
}]
}
}
......@@ -93,7 +93,7 @@
"3741222A-BD8F-401C-A5D2-5A907E891896": [
{
"name": "Particle Fountain",
"source": "/**\n * @author mrdoob / http://mrdoob.com/\n */\n\nvar original = scene.getObjectByName( 'Particle' );\n\nvar particles = [];\n\nfunction update( event ) {\n\n\tif ( particles.length < 200 ) {\n\n\t\tvar velocity = new THREE.Vector3();\n\t\tvelocity.x = Math.random() * 10 - 5;\n\t\tvelocity.y = Math.random() * 10 + 10;\n\t\tvelocity.z = Math.random() * 10 - 5;\n\n\t\tvar particle = original.clone();\n\t\tparticle.userData.velocity = velocity;\n\t\tparticles.push( particle );\n\n\t\tscene.add( particle );\n\n\t}\n\n\tfor ( var i = 0; i < particles.length; i ++ ) {\n\n\t\tvar particle = particles[ i ];\n\n\t\tvar velocity = particle.userData.velocity;\n\n\t\tvelocity.y -= 0.98;\n\n\t\tparticle.position.add( velocity );\n\n\t\tif ( particle.position.y < 0 ) {\n\n\t\t\tparticle.position.y = 0;\n\n\t\t\tvelocity.y = - velocity.y;\n\t\t\tvelocity.multiplyScalar( 0.6 );\n\n\t\t}\n\n\t}\n\n}"
"source": "var original = this.getObjectByName( 'Particle' );\n\nvar particles = [];\n\nfunction update( event ) {\n\n\tif ( particles.length < 200 ) {\n\n\t\tvar velocity = new THREE.Vector3();\n\t\tvelocity.x = Math.random() * 10 - 5;\n\t\tvelocity.y = Math.random() * 10 + 10;\n\t\tvelocity.z = Math.random() * 10 - 5;\n\n\t\tvar particle = original.clone();\n\t\tparticle.userData.velocity = velocity;\n\t\tparticles.push( particle );\n\n\t\tthis.add( particle );\n\n\t}\n\n\tfor ( var i = 0; i < particles.length; i ++ ) {\n\n\t\tvar particle = particles[ i ];\n\n\t\tvar velocity = particle.userData.velocity;\n\n\t\tvelocity.y -= 0.98;\n\n\t\tparticle.position.add( velocity );\n\n\t\tif ( particle.position.y < 0 ) {\n\n\t\t\tparticle.position.y = 0;\n\n\t\t\tvelocity.y = - velocity.y;\n\t\t\tvelocity.multiplyScalar( 0.6 );\n\n\t\t}\n\n\t}\n\n}"
}]
}
}
\ No newline at end of file
}
......@@ -131,7 +131,7 @@
"31517222-A9A7-4EAF-B5F6-60751C0BABA3": [
{
"name": "Game logic",
"source": "/**\n * @author mrdoob / http://mrdoob.com/\n */\n\nvar ball = scene.getObjectByName( 'Ball' );\n\nvar position = ball.position;\n\nvar direction = new THREE.Vector3();\ndirection.x = Math.random() - 0.5;\ndirection.z = Math.random() - 0.5;\ndirection.normalize();\ndirection.multiplyScalar( 8 );\n\nvar pad1 = scene.getObjectByName( 'Pad 1' );\nvar pad2 = scene.getObjectByName( 'Pad 2' );\n\n//\n\nfunction mousemove( event ) {\n\n\tpad1.position.z = ( event.clientX / window.innerWidth ) * 300 - 150;\n\tpad2.position.z = - pad1.position.z;\n\n}\n\nfunction update( event ) {\n\n\tif ( position.x < -300 || position.x > 300 )\n\t\tdirection.x = - direction.x;\n\n\tif ( position.z < -200 || position.z > 200 )\n\t\tdirection.z = - direction.z;\n\n\tposition.add( direction );\n\n}"
"source": "var ball = this.getObjectByName( 'Ball' );\n\nvar position = ball.position;\n\nvar direction = new THREE.Vector3();\ndirection.x = Math.random() - 0.5;\ndirection.z = Math.random() - 0.5;\ndirection.normalize();\ndirection.multiplyScalar( 8 );\n\nvar pad1 = this.getObjectByName( 'Pad 1' );\nvar pad2 = this.getObjectByName( 'Pad 2' );\n\n//\n\nfunction mousemove( event ) {\n\n\tpad1.position.z = ( event.clientX / window.innerWidth ) * 300 - 150;\n\tpad2.position.z = - pad1.position.z;\n\n}\n\nfunction update( event ) {\n\n\tif ( position.x < -300 || position.x > 300 )\n\t\tdirection.x = - direction.x;\n\n\tif ( position.z < -200 || position.z > 200 )\n\t\tdirection.z = - direction.z;\n\n\tposition.add( direction );\n\n}"
}]
}
}
\ No newline at end of file
}
......@@ -36,14 +36,19 @@
<script src="../examples/js/renderers/SoftwareRenderer.js"></script>
<script src="../examples/js/renderers/SVGRenderer.js"></script>
<link rel="stylesheet" href="js/libs/codemirror/codemirror.css">
<link rel="stylesheet" href="js/libs/codemirror/theme/monokai.css">
<script src="js/libs/codemirror/codemirror.js"></script>
<script src="js/libs/codemirror/mode/javascript.js"></script>
<script src="js/libs/jszip.min.js"></script>
<script src="js/libs/signals.min.js"></script>
<script src="js/libs/ui.js"></script>
<script src="js/libs/ui.editor.js"></script>
<script src="js/libs/ui.three.js"></script>
<script src="js/libs/app.js"></script>
<script src="js/Player.js"></script>
<script src="js/Script.js"></script>
<script src="js/Storage.js"></script>
......@@ -98,6 +103,9 @@
var viewport = new Viewport( editor );
document.body.appendChild( viewport.dom );
var script = new Script( editor );
document.body.appendChild( script.dom );
var player = new Player( editor );
document.body.appendChild( player.dom );
......
......@@ -8,6 +8,10 @@ var Editor = function () {
this.signals = {
// script
editScript: new SIGNALS.Signal(),
// player
startPlayer: new SIGNALS.Signal(),
......@@ -52,7 +56,9 @@ var Editor = function () {
materialChanged: new SIGNALS.Signal(),
scriptAdded: new SIGNALS.Signal(),
scriptChanged: new SIGNALS.Signal(),
scriptRemoved: new SIGNALS.Signal(),
fogTypeChanged: new SIGNALS.Signal(),
fogColorChanged: new SIGNALS.Signal(),
......@@ -67,7 +73,7 @@ var Editor = function () {
this.storage = new Storage();
this.loader = new Loader( this );
this.camera = new THREE.PerspectiveCamera( 50, 1, 0.1, 100000 );
this.camera = new THREE.PerspectiveCamera( 50, 1, 1, 100000 );
this.camera.name = 'Camera';
this.scene = new THREE.Scene();
......@@ -281,6 +287,38 @@ Editor.prototype = {
//
addScript: function ( object, script ) {
if ( this.scripts[ object.uuid ] === undefined ) {
this.scripts[ object.uuid ] = [];
}
this.scripts[ object.uuid ].push( script );
this.signals.scriptAdded.dispatch( script );
},
removeScript: function ( object, script ) {
if ( this.scripts[ object.uuid ] === undefined ) return;
var index = this.scripts[ object.uuid ].indexOf( script );
if ( index !== - 1 ) {
this.scripts[ object.uuid ].splice( index, 1 );
}
this.signals.scriptRemoved.dispatch( script );
},
//
parent: function ( object, parent ) {
if ( parent === undefined ) {
......
......@@ -20,11 +20,13 @@ Menubar.Add = function ( editor ) {
var meshCount = 0;
var lightCount = 0;
var cameraCount = 0;
editor.signals.editorCleared.add( function () {
meshCount = 0;
lightCount = 0;
cameraCount = 0;
} );
......@@ -234,10 +236,6 @@ Menubar.Add = function ( editor ) {
} );
options.add( option );
//
options.add( new UI.HorizontalRule() );
// Sprite
var option = new UI.Panel();
......@@ -365,6 +363,26 @@ Menubar.Add = function ( editor ) {
} );
options.add( option );
//
options.add( new UI.HorizontalRule() );
// PerspectiveCamera
var option = new UI.Panel();
option.setClass( 'option' );
option.setTextContent( 'PerspectiveCamera' );
option.onClick( function() {
var camera = new THREE.PerspectiveCamera( 50, 1, 1, 10000 );
camera.name = 'PerspectiveCamera ' + ( ++ cameraCount );
editor.addObject( camera );
editor.select( camera );
} );
options.add( option );
return container;
}
......@@ -19,7 +19,8 @@ Menubar.Examples = function ( editor ) {
// Examples
var items = [
{ title: 'Particle Fountain', file: 'fountain.app.json' },
{ title: 'Camera', file: 'camera.app.json' },
{ title: 'Particles', file: 'particles.app.json' },
{ title: 'Pong', file: 'pong.app.json' }
];
......
......@@ -15,6 +15,12 @@ var Player = function ( editor ) {
var player = new APP.Player();
window.addEventListener( 'resize', function () {
player.setSize( container.dom.offsetWidth, container.dom.offsetHeight );
} );
signals.startPlayer.add( function () {
container.setDisplay( '' );
......
/**
* @author mrdoob / http://mrdoob.com/
*/
var Script = function ( editor ) {
var signals = editor.signals;
var container = new UI.Panel();
container.setId( 'script' );
container.setPosition( 'absolute' );
container.setBackgroundColor( '#272822' );
container.setDisplay( 'none' );
var header = new UI.Panel();
header.setPadding( '10px' );
container.add( header );
var title = new UI.Text().setColor( '#fff' );
header.add( title );
var buttonSVG = ( function () {
var svg = document.createElementNS( 'http://www.w3.org/2000/svg', 'svg' );
svg.setAttribute( 'width', 32 );
svg.setAttribute( 'height', 32 );
var path = document.createElementNS( 'http://www.w3.org/2000/svg', 'path' );
path.setAttribute( 'd', 'M 12,12 L 22,22 M 22,12 12,22' );
path.setAttribute( 'stroke', '#fff' );
svg.appendChild( path );
return svg;
} )();
var close = new UI.Element( buttonSVG );
close.setPosition( 'absolute' );
close.setTop( '3px' );
close.setRight( '1px' );
close.setCursor( 'pointer' );
close.onClick( function () {
container.setDisplay( 'none' );
} );
header.add( close );
var delay;
var currentScript;
var codemirror = CodeMirror( container.dom, {
value: '',
lineNumbers: true,
matchBrackets: true,
indentWithTabs: true,
tabSize: 4,
indentUnit: 4
} );
codemirror.setOption( 'theme', 'monokai' );
codemirror.on( 'change', function () {
clearTimeout( delay );
delay = setTimeout( function () {
currentScript.source = codemirror.getValue();
signals.scriptChanged.dispatch( currentScript );
}, 300 );
});
//
signals.editorCleared.add( function () {
container.setDisplay( 'none' );
} );
signals.editScript.add( function ( object, script ) {
container.setDisplay( '' );
currentScript = script;
title.setValue( object.name + ' / ' + script.name );
codemirror.setValue( script.source );
} );
return container;
};
......@@ -24,79 +24,98 @@ Sidebar.Script = function ( editor ) {
container.add( scriptsContainer );
var newScript = new UI.Button( 'New' );
newScript.setMarginLeft( '5px' );
newScript.onClick( function () {
var script = new UI.ScriptEditor( editor );
script.setValue( { name: '', source: 'return {\n\tupdate: function ( event ) {}\n};' } );
script.onChange( function () {
signals.scriptChanged.dispatch();
} );
scriptsContainer.add( script );
var script = { name: '', source: 'function update( event ) {}' };
editor.addScript( editor.selected, script );
} );
container.add( newScript );
/*
var loadScript = new UI.Button( 'Load' );
loadScript.setMarginLeft( '4px' );
container.add( loadScript );
*/
// signals
//
signals.objectSelected.add( function ( object ) {
function update() {
scriptsContainer.clear();
if ( object !== null ) {
var object = editor.selected;
var scripts = editor.scripts[ object.uuid ];
container.setDisplay( 'block' );
if ( scripts !== undefined ) {
var sources = editor.scripts[ object.uuid ];
for ( var i = 0; i < scripts.length; i ++ ) {
if ( sources !== undefined ) {
( function ( object, script ) {
for ( var i = 0; i < sources.length; i ++ ) {
var name = new UI.Input( script.name ).setWidth( '160px' ).setFontSize( '12px' );
name.onChange( function () {
var script = new UI.ScriptEditor( editor );
script.setValue( sources[ i ] );
script.onChange( function () {
script.name = this.getValue();
signals.scriptChanged.dispatch();
} );
scriptsContainer.add( script );
scriptsContainer.add( name );
}
var edit = new UI.Button( 'Edit' );
edit.setMarginLeft( '4px' );
edit.onClick( function () {
}
signals.editScript.dispatch( object, script );
} else {
} );
scriptsContainer.add( edit );
container.setDisplay( 'none' );
var remove = new UI.Button( 'Remove' );
remove.setMarginLeft( '4px' );
remove.onClick( function () {
if ( confirm( 'Are you sure?' ) ) {
editor.removeScript( editor.selected, script );
}
} );
scriptsContainer.add( remove );
scriptsContainer.add( new UI.Break() );
} )( object, scripts[ i ] )
}
}
} );
}
signals.scriptChanged.add( function () {
// signals
var array = [];
var object = editor.selected;
signals.objectSelected.add( function ( object ) {
for ( var i = 0; i < scriptsContainer.children.length; i ++ ) {
if ( object !== null ) {
var script = scriptsContainer.children[ i ];
container.setDisplay( 'block' );
array.push( script.getValue() );
update();
}
} else {
editor.scripts[ object.uuid ] = array;
container.setDisplay( 'none' );
}
} );
signals.scriptAdded.add( update );
signals.scriptRemoved.add( update );
return container;
};
......@@ -225,6 +225,12 @@ var Viewport = function ( editor ) {
// signals
signals.editorCleared.add( function () {
render();
} );
signals.themeChanged.add( function ( value ) {
switch ( value ) {
......@@ -323,11 +329,7 @@ var Viewport = function ( editor ) {
}
if ( object instanceof THREE.PerspectiveCamera === false ) {
transformControls.attach( object );
}
transformControls.attach( object );
}
......@@ -369,19 +371,21 @@ var Viewport = function ( editor ) {
transformControls.update();
if ( object !== camera ) {
if ( object.geometry !== undefined ) {
if ( object.geometry !== undefined ) {
selectionBox.update( object );
selectionBox.update( object );
}
}
if ( object instanceof THREE.PerspectiveCamera ) {
if ( editor.helpers[ object.id ] !== undefined ) {
object.updateProjectionMatrix();
editor.helpers[ object.id ].update();
}
}
if ( editor.helpers[ object.id ] !== undefined ) {
editor.helpers[ object.id ].update();
}
......
......@@ -40,7 +40,7 @@ var APP = {
var script = sources[ i ];
var events = ( new Function( 'scene', 'keydown', 'keyup', 'mousedown', 'mouseup', 'mousemove', 'update', script.source + '\nreturn { keydown: keydown, keyup: keyup, mousedown: mousedown, mouseup: mouseup, mousemove: mousemove, update: update };' ).bind( object ) )( scene );
var events = ( new Function( 'player', 'scene', 'keydown', 'keyup', 'mousedown', 'mouseup', 'mousemove', 'update', script.source + '\nreturn { keydown: keydown, keyup: keyup, mousedown: mousedown, mouseup: mouseup, mousemove: mousemove, update: update };' ).bind( object ) )( this, scene );
for ( var name in events ) {
......@@ -53,7 +53,7 @@ var APP = {
}
scripts[ name ].push( events[ name ] );
scripts[ name ].push( events[ name ].bind( object ) );
}
......@@ -65,6 +65,19 @@ var APP = {
};
this.setCamera = function ( newCamera ) {
if ( camera !== undefined ) {
newCamera.aspect = camera.aspect;
newCamera.updateProjectionMatrix();
}
camera = newCamera;
};
this.setSize = function ( width, height ) {
camera.aspect = width / height;
......
/* BASICS */
.CodeMirror {
/* Set height, width, borders, and global font properties here */
font-family: monospace;
height: 300px;
}
/* PADDING */
.CodeMirror-lines {
padding: 4px 0; /* Vertical padding around content */
}
.CodeMirror pre {
padding: 0 4px; /* Horizontal padding of content */
}
.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
background-color: white; /* The little square between H and V scrollbars */
}
/* GUTTER */
.CodeMirror-gutters {
border-right: 1px solid #ddd;
background-color: #f7f7f7;
white-space: nowrap;
}
.CodeMirror-linenumbers {}
.CodeMirror-linenumber {
padding: 0 3px 0 5px;
min-width: 20px;
text-align: right;
color: #999;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
.CodeMirror-guttermarker { color: black; }
.CodeMirror-guttermarker-subtle { color: #999; }
/* CURSOR */
.CodeMirror div.CodeMirror-cursor {
border-left: 1px solid black;
}
/* Shown when moving in bi-directional text */
.CodeMirror div.CodeMirror-secondarycursor {
border-left: 1px solid silver;
}
.CodeMirror.cm-fat-cursor div.CodeMirror-cursor {
width: auto;
border: 0;
background: #7e7;
}
.CodeMirror.cm-fat-cursor div.CodeMirror-cursors {
z-index: 1;
}
.cm-animate-fat-cursor {
width: auto;
border: 0;
-webkit-animation: blink 1.06s steps(1) infinite;
-moz-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
}
@-moz-keyframes blink {
0% { background: #7e7; }
50% { background: none; }
100% { background: #7e7; }
}
@-webkit-keyframes blink {
0% { background: #7e7; }
50% { background: none; }
100% { background: #7e7; }
}
@keyframes blink {
0% { background: #7e7; }
50% { background: none; }
100% { background: #7e7; }
}
/* Can style cursor different in overwrite (non-insert) mode */
div.CodeMirror-overwrite div.CodeMirror-cursor {}
.cm-tab { display: inline-block; text-decoration: inherit; }
.CodeMirror-ruler {
border-left: 1px solid #ccc;
position: absolute;
}
/* DEFAULT THEME */
.cm-s-default .cm-keyword {color: #708;}
.cm-s-default .cm-atom {color: #219;}
.cm-s-default .cm-number {color: #164;}
.cm-s-default .cm-def {color: #00f;}
.cm-s-default .cm-variable,
.cm-s-default .cm-punctuation,
.cm-s-default .cm-property,
.cm-s-default .cm-operator {}
.cm-s-default .cm-variable-2 {color: #05a;}
.cm-s-default .cm-variable-3 {color: #085;}
.cm-s-default .cm-comment {color: #a50;}
.cm-s-default .cm-string {color: #a11;}
.cm-s-default .cm-string-2 {color: #f50;}
.cm-s-default .cm-meta {color: #555;}
.cm-s-default .cm-qualifier {color: #555;}
.cm-s-default .cm-builtin {color: #30a;}
.cm-s-default .cm-bracket {color: #997;}
.cm-s-default .cm-tag {color: #170;}
.cm-s-default .cm-attribute {color: #00c;}
.cm-s-default .cm-header {color: blue;}
.cm-s-default .cm-quote {color: #090;}
.cm-s-default .cm-hr {color: #999;}
.cm-s-default .cm-link {color: #00c;}
.cm-negative {color: #d44;}
.cm-positive {color: #292;}
.cm-header, .cm-strong {font-weight: bold;}
.cm-em {font-style: italic;}
.cm-link {text-decoration: underline;}
.cm-strikethrough {text-decoration: line-through;}
.cm-s-default .cm-error {color: #f00;}
.cm-invalidchar {color: #f00;}
/* Default styles for common addons */
div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
.CodeMirror-activeline-background {background: #e8f2ff;}
/* STOP */
/* The rest of this file contains styles related to the mechanics of
the editor. You probably shouldn't touch them. */
.CodeMirror {
line-height: 1;
position: relative;
overflow: hidden;
background: white;
color: black;
}
.CodeMirror-scroll {
overflow: scroll !important; /* Things will break if this is overridden */
/* 30px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */
margin-bottom: -30px; margin-right: -30px;
padding-bottom: 30px;
height: 100%;
outline: none; /* Prevent dragging from highlighting the element */
position: relative;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
.CodeMirror-sizer {
position: relative;
border-right: 30px solid transparent;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
before actuall scrolling happens, thus preventing shaking and
flickering artifacts. */
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
position: absolute;
z-index: 6;
display: none;
}
.CodeMirror-vscrollbar {
right: 0; top: 0;
overflow-x: hidden;
overflow-y: scroll;
}
.CodeMirror-hscrollbar {
bottom: 0; left: 0;
overflow-y: hidden;
overflow-x: scroll;
}
.CodeMirror-scrollbar-filler {
right: 0; bottom: 0;
}
.CodeMirror-gutter-filler {
left: 0; bottom: 0;
}
.CodeMirror-gutters {
position: absolute; left: 0; top: 0;
z-index: 3;
}
.CodeMirror-gutter {
white-space: normal;
height: 100%;
-moz-box-sizing: content-box;
box-sizing: content-box;
display: inline-block;
margin-bottom: -30px;
/* Hack to make IE7 behave */
*zoom:1;
*display:inline;
}
.CodeMirror-gutter-wrapper {
position: absolute;
z-index: 4;
height: 100%;
}
.CodeMirror-gutter-elt {
position: absolute;
cursor: default;
z-index: 4;
}
.CodeMirror-lines {
cursor: text;
min-height: 1px; /* prevents collapsing before first draw */
}
.CodeMirror pre {
/* Reset some styles that the rest of the page might have set */
-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
border-width: 0;
background: transparent;
font-family: inherit;
font-size: inherit;
margin: 0;
white-space: pre;
word-wrap: normal;
line-height: inherit;
color: inherit;
z-index: 2;
position: relative;
overflow: visible;
}
.CodeMirror-wrap pre {
word-wrap: break-word;
white-space: pre-wrap;
word-break: normal;
}
.CodeMirror-linebackground {
position: absolute;
left: 0; right: 0; top: 0; bottom: 0;
z-index: 0;
}
.CodeMirror-linewidget {
position: relative;
z-index: 2;
overflow: auto;
}
.CodeMirror-widget {}
.CodeMirror-measure {
position: absolute;
width: 100%;
height: 0;
overflow: hidden;
visibility: hidden;
}
.CodeMirror-measure pre { position: static; }
.CodeMirror div.CodeMirror-cursor {
position: absolute;
border-right: none;
width: 0;
}
div.CodeMirror-cursors {
visibility: hidden;
position: relative;
z-index: 3;
}
.CodeMirror-focused div.CodeMirror-cursors {
visibility: visible;
}
.CodeMirror-selected { background: #d9d9d9; }
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
.CodeMirror-crosshair { cursor: crosshair; }
.cm-searching {
background: #ffa;
background: rgba(255, 255, 0, .4);
}
/* IE7 hack to prevent it from returning funny offsetTops on the spans */
.CodeMirror span { *vertical-align: text-bottom; }
/* Used to force a border model for a node */
.cm-force-border { padding-right: .1px; }
@media print {
/* Hide the cursor when printing */
.CodeMirror div.CodeMirror-cursors {
visibility: hidden;
}
}
/* See issue #2901 */
.cm-tab-wrap-hack:after { content: ''; }
/* Help users use markselection to safely style text background */
span.CodeMirror-selectedtext { background: none; }
此差异已折叠。
此差异已折叠。
/* Based on Sublime Text's Monokai theme */
.cm-s-monokai.CodeMirror {background: #272822; color: #f8f8f2;}
.cm-s-monokai div.CodeMirror-selected {background: #49483E !important;}
.cm-s-monokai .CodeMirror-gutters {background: #272822; border-right: 0px;}
.cm-s-monokai .CodeMirror-guttermarker { color: white; }
.cm-s-monokai .CodeMirror-guttermarker-subtle { color: #d0d0d0; }
.cm-s-monokai .CodeMirror-linenumber {color: #d0d0d0;}
.cm-s-monokai .CodeMirror-cursor {border-left: 1px solid #f8f8f0 !important;}
.cm-s-monokai span.cm-comment {color: #75715e;}
.cm-s-monokai span.cm-atom {color: #ae81ff;}
.cm-s-monokai span.cm-number {color: #ae81ff;}
.cm-s-monokai span.cm-property, .cm-s-monokai span.cm-attribute {color: #a6e22e;}
.cm-s-monokai span.cm-keyword {color: #f92672;}
.cm-s-monokai span.cm-string {color: #e6db74;}
.cm-s-monokai span.cm-variable {color: #a6e22e;}
.cm-s-monokai span.cm-variable-2 {color: #9effff;}
.cm-s-monokai span.cm-def {color: #fd971f;}
.cm-s-monokai span.cm-bracket {color: #f8f8f2;}
.cm-s-monokai span.cm-tag {color: #f92672;}
.cm-s-monokai span.cm-link {color: #ae81ff;}
.cm-s-monokai span.cm-error {background: #f92672; color: #f8f8f0;}
.cm-s-monokai .CodeMirror-activeline-background {background: #373831 !important;}
.cm-s-monokai .CodeMirror-matchingbracket {
text-decoration: underline;
color: white !important;
}
/**
* @author mrdoob / http://mrdoob.com/
*/
UI.ScriptEditor = function ( editor ) {
UI.Panel.call( this );
var scope = this;
var name = new UI.Input().setWidth( '150px' ).setFontSize( '12px' ).onChange( function () {
if ( scope.onChangeCallback !== undefined ) {
scope.onChangeCallback();
}
} );
this.add( name );
var remove = new UI.Text( 'x' );
remove.setPosition( 'absolute' );
remove.setRight( '8px' );
remove.setCursor( 'pointer' );
remove.onClick( function () {
if ( confirm( 'Are you sure?' ) ) {
scope.parent.remove( scope );
if ( scope.onChangeCallback !== undefined ) {
scope.onChangeCallback();
}
}
} );
this.add( remove );
this.add( new UI.Break() );
var object = editor.selected.clone();
var scene = editor.scene.clone();
var timeout;
var textarea = new UI.TextArea();
textarea.setWidth( '100%' );
textarea.setHeight( '150px' );
textarea.setMarginTop( '8px' );
textarea.onKeyUp( function () {
clearTimeout( timeout );
textarea.dom.classList.remove( 'success' );
textarea.dom.classList.remove( 'fail' );
timeout = setTimeout( function () {
var source = textarea.getValue();
try {
( new Function( 'scene', 'keydown', 'keyup', 'mousedown', 'mouseup', 'mousemove', 'update', source + '\nreturn { keydown: keydown, keyup: keyup, mousedown: mousedown, mouseup: mouseup, mousemove: mousemove, update: update };' ).bind( object ) )( scene );
textarea.dom.classList.add( 'success' );
textarea.dom.classList.remove( 'fail' );
} catch ( error ) {
console.error( error );
textarea.dom.classList.remove( 'success' );
textarea.dom.classList.add( 'fail' );
return;
}
if ( scope.onChangeCallback !== undefined ) {
scope.onChangeCallback();
}
}, 500 );
} );
this.add( textarea );
this.name = name;
this.textarea = textarea;
};
UI.ScriptEditor.prototype = Object.create( UI.Panel.prototype );
UI.ScriptEditor.prototype.constructor = UI.ScriptEditor;
UI.ScriptEditor.prototype.getValue = function () {
return {
name: this.name.getValue(),
source: this.textarea.getValue()
};
};
UI.ScriptEditor.prototype.setValue = function ( value ) {
this.name.setValue( value.name );
this.textarea.setValue( value.source );
return this;
};
UI.ScriptEditor.prototype.onChange = function ( callback ) {
this.onChangeCallback = callback;
return this;
};
......@@ -4,7 +4,11 @@
var UI = {};
UI.Element = function () {};
UI.Element = function ( dom ) {
this.dom = dom;
};
UI.Element.prototype = {
......@@ -56,7 +60,7 @@ UI.Element.prototype = {
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',
'backgroundColor', 'opacity', 'fontSize', 'fontWeight', 'textAlign', 'textDecoration', 'textTransform', 'cursor' ];
'backgroundColor', 'opacity', 'fontSize', 'fontWeight', 'textAlign', 'textDecoration', 'textTransform', 'cursor', 'zIndex' ];
properties.forEach( function ( property ) {
......@@ -101,9 +105,6 @@ UI.Panel = function () {
this.dom = dom;
this.parent = null;
this.children = [];
return this;
};
......@@ -119,9 +120,6 @@ UI.Panel.prototype.add = function () {
if ( argument instanceof UI.Element ) {
this.dom.appendChild( argument.dom );
this.children.push( argument );
argument.parent = this;
} else {
......@@ -146,16 +144,6 @@ UI.Panel.prototype.remove = function () {
this.dom.removeChild( argument.dom );
var index = this.children.indexOf( argument );
if ( index !== - 1 ) {
this.children.splice( index, 1 );
}
argument.parent = null;
} else {
console.error( 'UI.Panel:', argument, 'is not an instance of UI.Element.' )
......@@ -176,8 +164,6 @@ UI.Panel.prototype.clear = function () {
}
this.children = [];
};
......@@ -346,7 +332,7 @@ UI.Text.prototype.setValue = function ( value ) {
// Input
UI.Input = function () {
UI.Input = function ( text ) {
UI.Element.call( this );
......@@ -364,6 +350,7 @@ UI.Input = function () {
}, false );
this.dom = dom;
this.setValue( text );
return this;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册