io3fix
Version:
toolkit for interior apps
195 lines (191 loc) • 6.55 kB
HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Scene Structure Validation</title>
<!-- vuejs -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<!-- Codemirror JS Vue -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.32.0/codemirror.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-codemirror@4.0.0/dist/vue-codemirror.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.32.0/mode/javascript/javascript.min.js"></script>
<!-- A-Frame -->
<script src="https://aframe.io/releases/0.7.1/aframe.min.js"></script>
<script src="https://rawgit.com/tizzle/aframe-orbit-controls-component/master/dist/aframe-orbit-controls-component.min.js"></script>
<!-- 3d.io -->
<script src="../../build/3dio.js"></script>
<!-- styles -->
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono:400,700" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.32.0/codemirror.min.css" rel="stylesheet">
<style>
body {
font-family: 'Roboto Mono', monospace;
padding: 10px
}
h1 {
font-size: 24px;
}
#result {
border: 1px solid transparent;
margin: 1.6em 0;
padding: 0.8em;
}
#result.success {
background: #E6EFC2;
color: #529214;
border-color: #C6D880;
}
#result.error {
background: #FBE3E4;
color: #D12F19;
border-color: #FBC2C4;
}
button {
background-color: #fff;
padding: 10px 15px;
text-decoration: none;
border: 1px solid #e1e1e1;
font-size: 14px;
outline: none;
cursor: pointer;
font-family: 'Roboto Mono', sans-serif;
font-weight: 700;
color: #333;
margin: 10px 10px 0 0;
}
button:hover {
background: #f3f3f3;
border: 1px solid #d1d1d1;
cursor: pointer;
}
a-scene {
background: #dbe4ee;
}
</style>
</head>
<body>
<div id="app">
<h1>Scene Structure Validation</h1>
<codemirror v-model="code" :options="cmOption"></codemirror>
<button @click="validate">validate</button>
<button @click="normalize">normalize</button>
<button @click="visualize">visualize</button>
<pre id="result" :class="validationState" v-if="validationState">{{validationMsg}}</pre>
</div>
<p>A-Frame view</p>
<a-scene style="height:400px;"embedded io3d-lighting>
<!-- orbit cam -->
<a-entity id="target" position="0 1 0"></a-entity>
<a-entity camera="fov: 50; zoom: 1;" position="-3 3 5" orbit-controls="invertZoom: true; autoRotate: false; target: #target; rotateSpeed: 0.2; enableDamping: true; dampingFactor: 0.1 ;minDistance:4;maxDistance:20;maxPolarAngle:1.8"></a-entity>
</a-scene>
<script>
Vue.use(VueCodemirror)
var addedItems = []
var app = new Vue({
el: '#app',
data: {
code: '{\n "type": "wall",\n "x": 0,\n "y": 0,\n "z": 0,\n "ry": 0,\n "id": "3b5ee2d1-88de-462f-bd04-c821d4fa3524",\n "w": 0.15,\n "h": 2.4,\n "l": 2\n}',
isValid: null,
validationState: null,
validationMsg: '',
visualizeScene: false,
cmOption: {
tabSize: 4,
styleActiveLine: true,
lineNumbers: true,
mode: {name: "javascript", json: true}
},
},
methods: {
validate: function() {
let _code = this.parse(this.code)
if (!_code) return
return io3d.scene.validateSceneStructure(_code)
.then(result => {
console.log(result)
this.isValid = result.isValid
this.validationState = result.isValid ? 'success' : 'error'
if (this.isValid) this.validationMsg = 'valid Scene Structure!'
else {
this.validationMsg = `ERRORS: ${result.errors.length}\nWARNINGS: ${result.warnings.length}`
if (result.errors.length) {
result.errors.forEach(err => {
this.validationMsg += `\nerror: ${err.message}`
})
}
}
return this.isValid
})
},
normalize: function() {
let _code = this.parse(this.code)
if (!_code) return
io3d.scene.normalizeSceneStructure(_code)
.then(result => {
result = result || {}
console.log(result)
this.code = JSON.stringify(result, null, ' ')
this.validate()
})
},
visualize: function() {
this.validate()
.then(isValid => {
if (!isValid) return
let _code = this.parse(this.code)
if (!_code) return
this.visualizeScene = true
const sceneEl = document.querySelector('a-scene')
addedItems.forEach(el => {
if (el && el.parentNode) el.parentNode.removeChild(el)
})
if (!sceneEl) {
console.log('no scene')
return
}
let elements = io3d.scene.getAframeElementsFromSceneStructure(_code)
if (Array.isArray(elements)) {
addedItems = elements
sceneEl.appendChild(elements[0])
} else {
addedItems = [elements]
sceneEl.appendChild(elements)
}
})
},
parse: function() {
let _code
try {
_code = JSON.parse(this.code)
} catch(err) {
try {
let _fixedCode = this.fixJson(this.code)
_code = JSON.parse(_fixedCode)
if (_code) this.code = _fixedCode
} catch(err) {
this.validationState = 'error'
this.validationMsg = 'Invalid JSON:\n' + err.message
}
}
return _code
},
// allow javascript object strings as input
fixJson: function(json) {
return json // Replace ":" with "@colon@" if it's between double-quotes
.replace(/:\s*"([^"]*)"/g, function(match, p1) {
return ': "' + p1.replace(/:/g, '@colon@') + '"';
})
// Replace ":" with "@colon@" if it's between single-quotes
.replace(/:\s*'([^']*)'/g, function(match, p1) {
return ': "' + p1.replace(/:/g, '@colon@') + '"';
})
// Add double-quotes around any tokens before the remaining ":"
.replace(/(['"])?([a-z0-9A-Z_]+)(['"])?\s*:/g, '"$2": ')
// Turn "@colon@" back into ":"
.replace(/@colon@/g, ':')
}
}
})
</script>
</body>
</html>