Skip to content

Instantly share code, notes, and snippets.

@haadcode
Created April 10, 2017 08:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save haadcode/d15301036d3e11fb58dd7463fa9cc554 to your computer and use it in GitHub Desktop.
Save haadcode/d15301036d3e11fb58dd7463fa9cc554 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<title>Hello, WebVR! - A-Frame</title>
<meta name="description" content="Hello, WebVR! - A-Frame">
<script type="text/javascript" src="lib/aframe.min.js" charset="utf-8"></script>
<script type="text/javascript" src="lib/orbitdb.min.js" charset="utf-8"></script>
<script type="text/javascript" src="lib/ipfs-browser-daemon.min.js" charset="utf-8"></script>
</head>
<body>
<div id="output"></div>
<button id="add" type="button">Add</button>
<!-- <button id="reset" type="button">Reset</button> -->
<a-scene id="scene">
<a-entity camera="userHeight: 1.6"
wasd-controls="wsAxis: z; wsInverted: false;"
look-controls>
<a-entity cursor="fuse: true; fuseTimeout: 500"
position="0 0 -1"
geometry="primitive: ring; radiusInner: 0.02; radiusOuter: 0.03"
material="color: black; shader: flat">
</a-entity>
</a-entity>
<!--
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
<a-sky color="#ECECEC"></a-sky>
-->
<a-plane position="0 0 -4" rotation="-90 0 0" width="8" height="8" color="#7BC8A4"></a-plane>
</a-scene>
<script type="text/javascript">
let ipfs, orbit, db
let entities = {}
const output = document.getElementById("output")
const scene = document.getElementById("scene")
const addButton = document.getElementById("add")
AFRAME.registerComponent('cursor-listener', {
init: function () {
var COLORS = ['red', 'green', 'blue'];
this.el.addEventListener('click', function (evt) {
var randomIndex = Math.floor(Math.random() * COLORS.length);
this.setAttribute('material', 'color', COLORS[randomIndex]);
console.log('I was clicked at: ', evt.detail.intersection.point);
});
}
})
const addBox = (id, position = '0, 0.5, -5', color = '#4CC3D9') => {
if (entities[id])
return
const entity = document.createElement('a-box')
entity.setAttribute('id', id)
entity.setAttribute('position', position)
entity.setAttribute('color', color)
entity.setAttribute('cursor-listener')
scene.appendChild(entity)
entities[id] = entity
return entity
}
const removeBox = (entity) => {
console.log("remove dom element", entity)
if (Object.keys(scene.childNodes).map(e => scene.childNodes[e]).map(e => e.id).includes(entity.id)) {
scene.removeChild(entity)
}
}
addButton.addEventListener('click', () => {
const x = Math.random() * 8 - 4.5
const y = Math.random() * 4 + 0.5
const z = -(Math.random() * 8) - 2
const r = Math.floor(Math.random() * 256)
const g = Math.floor(Math.random() * 256)
const b = Math.floor(Math.random() * 256)
const position = `${x}, ${y}, ${z}`
const color = `rgb(${r}, ${g}, ${b})`
db.add({ position: position, color: color })
.then((hash) => {
let entity = addBox(hash, position, color)
if (entity) {
entity.addEventListener('click', () => {
console.log("Remove", entity.id)
removeBox(entity)
db.remove(hash)
.then(() => {
output.innerHTML = "Removed box at " + position
setTimeout(() => output.innerHTML = "<br>", 2000)
})
})
}
output.innerHTML = "Added a box at " + position
setTimeout(() => output.innerHTML = "<br>", 2000)
})
})
output.innerHTML = "Starting IPFS..."
ipfs = new IpfsDaemon({
IpfsDataDir: '/orbit-db-vr/examples/browser',
SignalServer: 'star-signal.cloud.ipfs.team', // IPFS dev server
})
function handleError(e) {
console.error(e.stack)
output.innerHTML = e.message
}
ipfs.on('error', (e) => handleError(e))
ipfs.on('ready', () => {
output.innerHTML = "Loading scene..."
orbit = new OrbitDB(ipfs)
db = orbit.feed("/vr/proto1/scene1", { maxHistory: -1, syncHistory: true, cachePath: '/orbit-db' })
db.events.on('ready', () => {
output.innerHTML = "<br>"
const items = db.iterator({ limit: -1 }).collect()
items.forEach((e) => {
const boxData = e.payload.value
let entity = addBox(e.hash, boxData.position, boxData.color)
if (entity) {
entity.addEventListener('click', () => {
console.log("Remove", entity.id)
removeBox(entity)
db.remove(e.hash)
.then(() => {
output.innerHTML = "Removed box at " + boxData.position
setTimeout(() => output.innerHTML = "<br>", 2000)
})
})
}
})
output.innerHTML = "Scene ready"
setTimeout(() => output.innerHTML = "<br>", 2000)
})
db.events.on('synced', () => {
const items = db.iterator({ limit: -1 }).collect()
items.forEach((e) => {
const boxData = e.payload.value
let entity = addBox(e.hash, boxData.position, boxData.color)
if (entity) {
entity.addEventListener('click', () => {
console.log("Remove", entity.id)
removeBox(entity)
db.remove(e.hash)
.then(() => {
output.innerHTML = "Removed box at " + boxData.position
setTimeout(() => output.innerHTML = "<br>", 2000)
})
})
}
})
// Remove deleted boxes
const hashes = items.map(e => e.hash)
entities = Object.keys(entities).reduce((res, val) => {
if (!hashes.includes(val)) {
removeBox(entities[val])
} else {
res[val] = entities[val]
}
return res
}, [])
output.innerHTML = "Scene replicated"
setTimeout(() => output.innerHTML = "<br>", 2000)
})
db.events.on('load.progress', () => console.log("."))
db.load()
})
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment