D3js in 3D

Create a virtual-reality-like scene in mobile and desktop. Using D3js to do the math! Check out Live Demo now!

virtual scene

Inspired by d33d, 💣 Live Demo

Build up a local server to avoid cross-origin error

we know that using can do insert the image. Due to the cross-origin problem, in local testing, we need to use a local server to host the static file and its assets, such as images so that when used in html file, it will not cause a cross-origin error. The way we build up a temporary server is to use python. First cd to the corresponding directory, then do:

1
python -m SimpleHTTPServer 8000

Then go to the localhost:8000 can see the files. For more detailed info, check this post in stack overflow.

How to append tag in multiple nodes

references this post from stack overflow

Color palette

references this website

How to host your static page in github

references this post

The final result will be, you can access the project site from your github.io website with a branch. The procedure goes well, but it seems that gh-pages cannot host a d3 or aframe pages? Answer: YES, SURE WE CAN!!! for more info, you can just visit my website, github can host static website for free, so what kind of websites can be called as static? we called those sites as “static” as it only involves client-side scripting if it contains js file. Those who need server-side scripting are called dynamic websites.

note that in order to use gh-pages to host my project website, you need to name the html file to be index.html. Other file name will not be recognized!!

To summarize, the basic procedure is:

1
2
3
4
git clone … // from github, copy the repo’s https
cd …
git checkout - -orphan gh-pages
git rm -rf .

Then now, the gh-pages should be empty. Move the prepared index.html to here then

1
2
3
git add -A
git commit -m “First commit”
git push origin gh-pages

Then, go to www.chocoluffy.com/, you can see the project site!!

How A-frame works

1
2
3
4
5
6
7
8
9
10
<a-assets>
<a-mixin id="red" material="color: red"></a-mixin>
</a-assets>
<a-scene>
<a-entity camera look-controls wasd-controls></a-entity>
<a-entity light="type: point; color: #EEE; intensity: 0.5" position="0 3 0"></a-entity>
<a-light color="#da47da" position="0 0 0" type="ambient"></a-light>
<!-- <a-sky color="#c8f8e0"></a-sky> -->
<a-sky src="road.jpg"></a-sky>
</a-scene>

References this website for more A-frame primitives.

Then by using d3js, we can add corresponding number of to the scene from data array.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<script>
var data=[10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
var tip = -0.5;
var radius = 6;
var scene = d3.select("a-scene")
scene.append("a-camera")
.attr({
position: function(){
var x = 0;
var y = tip;
var z = 0;
return x + " " + y + " " + z
}
})
var cubes = scene.selectAll("a-entity.bar").data(data)
.enter()
.append("a-entity")
.classed("bar", true)
.attr({
// mixin: "link",
material: "color: #7BC8A4",
geometry: "primitive: box; width: 2; height: 2; depth: 2",
position: function(d, i){
var theta = (i / data.length) * (2 * Math.PI);
var x = radius * Math.cos(theta);
var y = 0;
var z = radius * Math.sin(theta);
return x + " " + y + " " + z
},
rotation: function(d, i){
var x = 0;
var y = -360 * i/data.length;
var z = -80*Math.atan(tip/radius);
return x + " " + y + " " + z
}
})
cubes.append("a-mouseenter")
.attr({
// scale: "1 2 1",
position: "0 2 0",
visible: false
})
cubes.append("a-mouseleave")
.attr({
scale: "1 1 1"
// position: "0 2 0"
// visible: true
})

Find the structure of this scene, it will like having several <a-entity> inside <a-scene>, and each of <a-entity> has multiple attributes that defines its position, rotation, material and geometry. And inside the <a-entity>, also has <a-mouseenter> and <a-mouseleave> tags which helps define the actions when hovered.

后记: 欢迎加入我的私人公众号, 和你分享我思考的观点和文章:
公众号二维码

一起加油!