Skip to content

Instantly share code, notes, and snippets.

@enjalot
Created October 18, 2013 20:09
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 enjalot/7047509 to your computer and use it in GitHub Desktop.
Save enjalot/7047509 to your computer and use it in GitHub Desktop.
victor's dot cube
{"description":"victor's dot cube","endpoint":"","display":"svg","public":true,"require":[],"fileconfigs":{"inlet.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"_.md":{"default":true,"vim":false,"emacs":false,"fontSize":12},"config.json":{"default":true,"vim":false,"emacs":false,"fontSize":12},"man.svg":{"default":true,"vim":false,"emacs":false,"fontSize":12},"sticker.js":{"default":true,"vim":false,"emacs":false,"fontSize":12}},"fullscreen":false,"play":true,"loop":true,"restart":false,"autoinit":true,"pause":true,"loop_type":"pingpong","bv":false,"nclones":15,"clone_opacity":0.4,"duration":3000,"ease":"linear","dt":0.01,"thumbnail":"http://i.imgur.com/BTjK4HI.png"}
http://bl.ocks.org/vicapow/7003904
var bgColor = "#040404"
var dotColor = "#efefef"
var dotSize = 1;
var dotStyle = {
fill: dotColor,
"fill-opacity": 0.3,
stroke: "#ffffff",
"stroke-opacity": 0.5
}
var svg = d3.select("svg");
svg.append("rect").attr({ width: tributary.sw, height: tributary.sh })
.style("fill", bgColor)
var time = tributary.anim(0, 4*Math.PI);
var d = -3 // how far the box is from the camera
box = translate(generateBox(3, tributary.anim(2,3.4)), [0, 0, -3])
var sticker = d3.sticker("#man");
function generateBox(n, width){
var s = width / (n - 1), t = width / 2
var points = []
for(var x = 0; x < n; x++){
for(var y = 0; y < n; y++){
for(var z = 0; z < n; z++){
points.push([x * s - t, y * s - t, z * s - t])
}
}
}
return points
}
function generateGrid(n, width){
var s = width / n, t = width / 2
var points = []
for(var x = 0; x < n; x++){
for(var y = 0; y < n; y++){
points.push([x * s - t, y * s - t, 0])
}
}
return points
}
function rotate(points, theta){
return points.slice(0).map(function(p){
return [
p[0] * Math.cos(theta) - p[2] * Math.sin(theta)
, p[1]// * Math.tan(theta)// * Math.sin(theta) + p[2] * Math.cos(theta)
, p[0] * Math.sin(theta) + p[2] * Math.cos(theta)
]
})
}
function translate(points, delta){
return points.slice(0).map(function(p){
return [p[0] + delta[0], p[1] + delta[1], p[2] + delta[2]]
})
}
// eye is located at [0, 0, 0]
// eye is pointing at [0,0,-1]
// image plane is at [0, 0, -1]
imagePlane = [0, 0, -1]
function vec_scale3d(vec, scale){
return [vec[0] * scale, vec[1] * scale, vec[2] * scale]
}
var scale = d3.scale.linear().domain([0, 1]).range([350, 450])
var circles = svg.selectAll('circle').data(box)
circles.enter().append('g')
sticker(circles)
var t = translate(box, [0, 0, -d])
t = rotate(t, time)
t = translate(t, [0, 0, d])
t = t.map(function(p){
var Ax = p[0], Ay = p[1], Az = p[2]
var Bz = imagePlane[2]
return vec_scale3d(p, Bz / Az)
})
circles.data(t).attr({
r: dotSize
, transform: function(d){ return "scale(0.915)translate(" + [50 + scale(d[0]), -50 + scale(d[1])] + ")"}
})
.style(dotStyle)
Display the source blob
Display the rendered blob
Raw
<g id="man">
<circle fill="#fff" cx="18.118" cy="8.159" r="8.159"></circle>
<path fill="#fff" id="path" d="M8.472,95.426c0,2.524,2.05,4.574,4.574,4.574c2.529,0,4.576-2.05,4.576-4.574l0.004-38.374h2.037L19.65,95.426
c0,2.524,2.048,4.574,4.574,4.574s4.573-2.05,4.573-4.574l0.02-66.158h2.006v24.38c0,4.905,6.398,4.905,6.384,0v-24.9
c0-5.418-3.184-10.728-9.523-10.728L9.396,18.012C3.619,18.012,0,22.722,0,28.599v25.05c0,4.869,6.433,4.869,6.433,0v-24.38h2.048
L8.472,95.426z"></path>
</g>
(function() {
d3.sticker = function(selector) {
var string;
var node;
var svgElement; //for deserializing svg elements
var sticker = function(selection) {
return sticker.append(selection);
}
sticker.copy = function(selector) {
node = d3.select(selector).node();
if(!node) return sticker;
//we keep track of svg element
if(d3_isSVG(node)) {
sticker.isSVG = true;
svgElement = node.ownerSVGElement;
}
node = node.cloneNode(true);
node.removeAttribute("id");
return sticker;
}
sticker.paste = function() {
if(!node) return;
return node.cloneNode(true);
}
sticker.node = function(_) {
if(!arguments.length) return node;
node = _;
if(d3_isSVG(node)) {
sticker.isSVG = true;
svgElement = node.ownerSVGElement;
}
return sticker;
}
//append a copy of the sticker to the selection
sticker.append = function(selection) {
return selection.select(function() {
return this.appendChild(sticker.paste());
});
}
//insert a copy of the sticker into a selection similar to the d3 insert API
sticker.insert = function(selection, before) {
if(!string) return selection;
return selection.select(before).select(function() {
return this.parentNode.insertBefore(sticker.paste(), this);
});
}
sticker.string = function(_) {
if(!arguments.length) return string;
string = _;
return sticker;
}
sticker.serialize = function() {
//Serialize the selected element into a string
string = new XMLSerializer().serializeToString(node);
}
sticker.deserialize = function () {
//check if our element is SVG
if(sticker.isSVG) {
node = d3_makeSVGFragment(string, svgElement);
} else {
node = d3_makeFragment(string);
}
return node;
}
sticker.toString = function() {
sticker.serialize();
return string;
}
if(selector) {
return sticker.copy(selector);
}
return sticker;
}
function d3_isSVG(el) {
if(!el) return false
return !!el.ownerSVGElement;// || el.tagName === "svg";
}
function d3_makeFragment(fragment) {
var range = document.createRange()
return range.createContextualFragment(fragment);
}
function d3_makeSVGFragment(fragment, svgElement) {
//we need to wrap our element in a temporarary intermediate svg element
//so that the browser knows to instanciate the Node properly.
//for some reason having the range select an svg element isn't enough.
// TODO: Allow optional namespace declarations
var pre = '<svg xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink>';
var post = '</svg>';
var range = document.createRange();
range.selectNode(svgElement);
var contextFragment = range.createContextualFragment(pre + fragment + post)
var intermediateSvg = contextFragment.childNodes[0]
var node = intermediateSvg.childNodes[0]
return node;
}
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment