console API starts to work...
This commit is contained in:
@@ -0,0 +1,28 @@
|
|||||||
|
<style>
|
||||||
|
.kf-editor .inner-console .results .api-summary{ border: 1px solid white;margin: .5em;width: 90%; }
|
||||||
|
.kf-editor .inner-console .results .api-summary h1{
|
||||||
|
font-size: 1.5em;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 .5em 0 .5em;
|
||||||
|
background-color: #473;
|
||||||
|
color: white;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
.kf-editor .inner-console .results .title{
|
||||||
|
background: #DDD;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="title">Javascript Keyframe console</div>
|
||||||
|
Use any combination of Javascript and API calls to update your keyframe scene.<br>
|
||||||
|
Special commands:<br>
|
||||||
|
"\help" for help & API<br>
|
||||||
|
"\clear" to clear results<br>
|
||||||
|
<div class="api-summary">
|
||||||
|
<h1>API:</h1>
|
||||||
|
<ul>
|
||||||
|
<li>Create an agent: <b>newAgent(type, properties)</b> - returns the AID</li>
|
||||||
|
<li>Remove an agent: <b>removeAgent(aid)</b></li>
|
||||||
|
<li>Update an agent: <b>updateAgent(aid, properties)</b></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<title>Three.js + OrbitControls (importmap)</title>
|
|
||||||
<style>
|
|
||||||
body { margin: 0; overflow: hidden; }
|
|
||||||
canvas { display: block; }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<!-- Import map tells browser where "three" lives -->
|
|
||||||
<script type="importmap">
|
|
||||||
{
|
|
||||||
"imports": {
|
|
||||||
"three": "https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.module.js"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script type="module">
|
|
||||||
import * as THREE from "three"
|
|
||||||
import { OrbitControls } from "https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/controls/OrbitControls.js"
|
|
||||||
|
|
||||||
// Scene
|
|
||||||
const scene = new THREE.Scene()
|
|
||||||
scene.background = new THREE.Color(0x202080)
|
|
||||||
|
|
||||||
// Camera
|
|
||||||
const perspCam = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
|
|
||||||
perspCam.position.set(3, 3, 5)
|
|
||||||
|
|
||||||
const aspect = window.innerWidth / window.innerHeight
|
|
||||||
const frustumSize = 10
|
|
||||||
const cam2d = new THREE.OrthographicCamera(
|
|
||||||
-frustumSize * aspect / 2,
|
|
||||||
frustumSize * aspect / 2,
|
|
||||||
frustumSize / 2,
|
|
||||||
-frustumSize / 2,
|
|
||||||
0.1,
|
|
||||||
1000
|
|
||||||
)
|
|
||||||
|
|
||||||
cam2d.position.set(0, 100, 0)
|
|
||||||
|
|
||||||
cam2d.lookAt(0, 0, 0)
|
|
||||||
|
|
||||||
let activeCam = perspCam
|
|
||||||
|
|
||||||
// Renderer
|
|
||||||
const renderer = new THREE.WebGLRenderer({ antialias: true })
|
|
||||||
renderer.setSize(window.innerWidth, window.innerHeight)
|
|
||||||
document.body.appendChild(renderer.domElement)
|
|
||||||
|
|
||||||
// Cube
|
|
||||||
const geometry = new THREE.BoxGeometry()
|
|
||||||
const material = new THREE.MeshStandardMaterial({ color: 'red' })
|
|
||||||
const cube = new THREE.Mesh(geometry, material)
|
|
||||||
scene.add(cube)
|
|
||||||
cube.position.x+=2
|
|
||||||
|
|
||||||
|
|
||||||
// Light
|
|
||||||
const light = new THREE.DirectionalLight(0xffffff, 1)
|
|
||||||
light.position.set(5, 5, 5)
|
|
||||||
light.intensity = 2
|
|
||||||
scene.add(light)
|
|
||||||
this.scene.add(new THREE.AmbientLight(0xffffff, 0.4))
|
|
||||||
|
|
||||||
const snowman = new THREE.Group()
|
|
||||||
|
|
||||||
// Bottom sphere
|
|
||||||
const bottom = new THREE.Mesh(
|
|
||||||
new THREE.SphereGeometry(1, 32, 32),
|
|
||||||
new THREE.MeshStandardMaterial({ color: 'white' })
|
|
||||||
)
|
|
||||||
snowman.add(bottom)
|
|
||||||
|
|
||||||
// Middle sphere
|
|
||||||
const middle = new THREE.Mesh(
|
|
||||||
new THREE.SphereGeometry(0.7, 32, 32),
|
|
||||||
new THREE.MeshStandardMaterial({ color: 'white' })
|
|
||||||
)
|
|
||||||
middle.position.y = 1.3
|
|
||||||
snowman.add(middle)
|
|
||||||
|
|
||||||
// Head
|
|
||||||
const head = new THREE.Mesh(
|
|
||||||
new THREE.SphereGeometry(0.5, 32, 32),
|
|
||||||
new THREE.MeshStandardMaterial({ color: 'white' })
|
|
||||||
)
|
|
||||||
head.position.y = 2.3
|
|
||||||
snowman.add(head)
|
|
||||||
scene.add(new THREE.AmbientLight(0xffffff, 0.5) )
|
|
||||||
// Add the group to the scene
|
|
||||||
scene.add(snowman)
|
|
||||||
|
|
||||||
// Optional: expose to console
|
|
||||||
window.snowman = snowman
|
|
||||||
|
|
||||||
// Controls
|
|
||||||
const controls = new OrbitControls(perspCam, renderer.domElement)
|
|
||||||
|
|
||||||
// Resize handler
|
|
||||||
window.addEventListener('resize', () => {
|
|
||||||
perspCam.aspect = window.innerWidth / window.innerHeight
|
|
||||||
perspCam.updateProjectionMatrix()
|
|
||||||
renderer.setSize(window.innerWidth, window.innerHeight)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Animation loop
|
|
||||||
function animate() {
|
|
||||||
requestAnimationFrame(animate)
|
|
||||||
cube.rotation.x += 0.01
|
|
||||||
cube.rotation.y += 0.01
|
|
||||||
controls.update()
|
|
||||||
renderer.render(scene, activeCam)
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener('keydown', (e) => {
|
|
||||||
if (e.key.toLowerCase() === 'o') {
|
|
||||||
activeCam = (activeCam === perspCam ? cam2d : perspCam)
|
|
||||||
console.log('Switched to', activeCam.isPerspectiveCamera ? 'Perspective' : 'Orthographic')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
animate()
|
|
||||||
|
|
||||||
window.THREE = THREE
|
|
||||||
window.scene = scene
|
|
||||||
window.renderer = renderer
|
|
||||||
window.cube = cube
|
|
||||||
window.light = light
|
|
||||||
light.intensity = 2
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -25,7 +25,7 @@ canvas.intro3d{
|
|||||||
}
|
}
|
||||||
|
|
||||||
canvas.intro3d.ready{
|
canvas.intro3d.ready{
|
||||||
animation: logoanim 3.5s ease-out forwards;
|
animation: logoanim 1.5s ease-out forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes logoanim{
|
@keyframes logoanim{
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class DashboardsController extends WindozController {
|
|||||||
const models = {
|
const models = {
|
||||||
agents : new AgentsModel('/agents')
|
agents : new AgentsModel('/agents')
|
||||||
}
|
}
|
||||||
console.log('=============>spaceViewer 0')
|
|
||||||
const ttb = new app.LoadedModules.Threetobus({
|
const ttb = new app.LoadedModules.Threetobus({
|
||||||
eventsMapping: this.eventsMapping,
|
eventsMapping: this.eventsMapping,
|
||||||
sceneSize: this.arenaConfig.arenaSize,
|
sceneSize: this.arenaConfig.arenaSize,
|
||||||
@@ -35,7 +35,6 @@ console.log('=============>spaceViewer 0')
|
|||||||
|
|
||||||
//TODO: eventsMapping: address child by suffix in assignations
|
//TODO: eventsMapping: address child by suffix in assignations
|
||||||
|
|
||||||
console.log('=============>spaceViewer 1')
|
|
||||||
this.loadWindow(
|
this.loadWindow(
|
||||||
'visualisers/SpaceView',
|
'visualisers/SpaceView',
|
||||||
{
|
{
|
||||||
|
|||||||
Vendored
-1
@@ -142,7 +142,6 @@ bz-slidepane {
|
|||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background-color: #000A;
|
background-color: #000A;
|
||||||
padding: 0 0.5em 0 0.5em;
|
|
||||||
}
|
}
|
||||||
bz-slidepane[side="top"] { top:0; left:0; width: 100%; height:0; border-bottom: 2px solid #DDD; }
|
bz-slidepane[side="top"] { top:0; left:0; width: 100%; height:0; border-bottom: 2px solid #DDD; }
|
||||||
bz-slidepane[side="bottom"] { bottom:0; left:0; width: 100%; height:0; border-top: 2px solid #DDD;}
|
bz-slidepane[side="bottom"] { bottom:0; left:0; width: 100%; height:0; border-top: 2px solid #DDD;}
|
||||||
|
|||||||
@@ -87,6 +87,7 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: auto minmax(3em, 30%);
|
grid-template-rows: auto minmax(3em, 30%);
|
||||||
|
padding: 0.2em 0.2em 0 0.2em;
|
||||||
}
|
}
|
||||||
.kf-editor .kfArena bz-slidepane div.commandline{
|
.kf-editor .kfArena bz-slidepane div.commandline{
|
||||||
grid-template-columns: auto 3em;
|
grid-template-columns: auto 3em;
|
||||||
@@ -105,6 +106,24 @@
|
|||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
max-height: 3em;
|
max-height: 3em;
|
||||||
}
|
}
|
||||||
|
.kf-editor .kfArena .inner-console .results{
|
||||||
|
max-height: 100%;
|
||||||
|
overflow: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kf-editor .kfArena .inner-console .results h1{
|
||||||
|
font-size: 1.5em;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 .5em 0 .5em;
|
||||||
|
background-color: #473;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.kf-editor .kfArena .inner-console .results .error{
|
||||||
|
border-top: 1px solid red;
|
||||||
|
border-bottom: 1px solid red;
|
||||||
|
background-color: #FDD;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<div class="kf-editor cols-3">
|
<div class="kf-editor cols-3">
|
||||||
<article eiccard class="left-pane">
|
<article eiccard class="left-pane">
|
||||||
@@ -125,10 +144,13 @@
|
|||||||
<bz-slidepane side="bottom" data-output="console">
|
<bz-slidepane side="bottom" data-output="console">
|
||||||
<div class="inner-console">
|
<div class="inner-console">
|
||||||
<div class="results" data-output="results">
|
<div class="results" data-output="results">
|
||||||
JS 3D Console. for help, type "help"
|
<div class="title">Javascript Keyframe console</div>
|
||||||
|
Special commands:<br>
|
||||||
|
"\help" for help & API<br>
|
||||||
|
"\clear" to clear results<br>
|
||||||
</div>
|
</div>
|
||||||
<div class="cols-2 commandline">
|
<div class="cols-2 commandline">
|
||||||
<textarea type="text" data-output="commands"></textarea>
|
<textarea type="text" data-output="commands" autocorrect="off" autocomplete="off" autocapitalize="off" spellcheck="false"></textarea>
|
||||||
<button eicbutton class="icon-play" data-trigger="execCommand"></button>
|
<button eicbutton class="icon-play" data-trigger="execCommand"></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -67,13 +67,62 @@ class KeyframeView extends WindozDomContent {
|
|||||||
|
|
||||||
async execCommand(event){
|
async execCommand(event){
|
||||||
console.log('cmd:', this.outputs.commands)
|
console.log('cmd:', this.outputs.commands)
|
||||||
if(this.outputs.commands.trim()=='help'){
|
if(this.outputs.commands.value.trim()=='\\help'){
|
||||||
this.outputs.results.innerHTML = `
|
this.outputs.results.innerHTML += await app.Assets.loadHtml({ name: 'help/KFconsoleHelp.html' })
|
||||||
Type any javascript at your own risks.
|
} else if(this.outputs.commands.value.trim()=='\\clear'){
|
||||||
To create an agent : this.newAgent(type, properties)
|
this.outputs.results.innerHTML = ''
|
||||||
`
|
|
||||||
} else {
|
} else {
|
||||||
this.kfArena.evalCmd(this.outputs.commands)
|
this.outputs.results.innerHTML += await this.evalCmd(this.outputs.commands.value)
|
||||||
|
}
|
||||||
|
const lines = this.outputs.results.querySelectorAll('div.line')
|
||||||
|
if(lines.length > 100) {
|
||||||
|
for(let i=0; i<(lines.length-100); i++) lines[i].remove()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async evalCmd(code){
|
||||||
|
const api = {
|
||||||
|
newAgent: async (type, properties) => {
|
||||||
|
if(Array.from(this.outputs.agentsSelector.options).find(item => item.value==type)){
|
||||||
|
this.outputs.agentsSelector.value = type
|
||||||
|
await this.onChangeAgent()
|
||||||
|
const defaultValues = this.getFieldsValues('div[data-output="agentProperties"]')
|
||||||
|
return(this.newAgent(type, { ...defaultValues, ...properties })) //TODO: deepMerge
|
||||||
|
} else {
|
||||||
|
throw(`Invalid agent type: ${type}`)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
removeAgent: (aid) => {
|
||||||
|
|
||||||
|
},
|
||||||
|
updateAgent: (aid, properties) => {
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const fn = new Function(...Object.keys(api), `
|
||||||
|
return(
|
||||||
|
(async () => {
|
||||||
|
const logs = []
|
||||||
|
const log = (item) => { logs.push(item) }
|
||||||
|
${code}
|
||||||
|
return(logs)
|
||||||
|
})()
|
||||||
|
)
|
||||||
|
`)
|
||||||
|
|
||||||
|
const res = await fn(...Object.values(api))
|
||||||
|
return(
|
||||||
|
'<div class="line">'+
|
||||||
|
res.map(item => {
|
||||||
|
if(typeof(item) == 'object') return(JSON.stringify(item))
|
||||||
|
return(item)
|
||||||
|
}).join('</div><div class="line">')
|
||||||
|
+'</div>'
|
||||||
|
)
|
||||||
|
} catch (err) {
|
||||||
|
return(`<div class="error">${err.name}: ${err.message}</div>`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user