Built with blockbuilder.org
forked from santiagogaray's block: Grid
license: mit |
Built with blockbuilder.org
forked from santiagogaray's block: Grid
{"root":[ | |
{"row": [1,1,1,0,0,0,0,0,0,0]}, | |
{"row": [1,1,0,0,0,0,0,0,0,0]}, | |
{"row": [0,0,0,1,0,0,0,0,0,0]}, | |
{"row": [0,0,0,0,0,0,0,0,1,0]}, | |
{"row": [1,0,0,1,0,0,0,0,0,0]}, | |
{"row": [1,1,0,0,0,0,0,0,0,0]}, | |
{"row": [1,1,0,0,0,0,0,0,0,0]}, | |
{"row": [1,1,0,0,0,0,0,0,0,0]}, | |
{"row": [1,1,0,0,0,0,0,0,0,0]}, | |
{"row": [1,1,0,0,0,0,0,0,0,0]}, | |
{"row": [1,1,0,0,0,0,0,0,0,0]}, | |
{"row": [1,1,0,0,0,0,0,0,0,0]}, | |
{"row": [1,1,0,0,0,0,0,0,0,0]}, | |
{"row": [1,1,0,0,0,0,0,0,0,0]}, | |
{"row": [1,1,0,0,0,0,0,0,0,0]}, | |
{"row": [1,1,0,0,0,0,0,0,0,0]}, | |
{"row": [1,1,0,0,0,0,0,0,0,0]}, | |
{"row": [1,1,0,0,0,0,0,0,0,0]}, | |
{"row": [1,1,0,0,0,0,0,0,0,0]}, | |
{"row": [1,1,0,0,0,0,0,0,0,0]}, | |
{"row": [1,1,0,0,0,0,0,0,0,0]}, | |
{"row": [1,1,0,0,0,0,0,0,0,0]}, | |
{"row": [1,1,0,0,0,0,0,0,0,0]}, | |
{"row": [1,1,0,0,0,0,0,0,0,0]}, | |
{"row": [1,1,0,0,0,0,0,0,0,0]}, | |
{"row": [0,0,0,0,0,0,0,0,0,0]}, | |
{"row": [0,0,0,1,0,0,0,0,0,0]}, | |
{"row": [1,0,0,0,0,0,0,1,1,1]}, | |
{"row": [0,1,1,0,0,0,0,0,0,1]} | |
] | |
} |
<!DOCTYPE html> | |
<head> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script> | |
<style> | |
#inputSliders { font-family:sans-serif;outline:none;padding-top:15px;width:960px;margin: 0 auto;} | |
#content { width:960px;margin: 0 auto;} | |
.inputgroup {border:none;} | |
.slider { width:210px;float:left;padding:10px;} | |
label { float:left;font-weight:bold;padding-bottom:10px;} | |
input[type=range] { float:left;clear:left;margin-right:10px;width:130px;} | |
input[type=range]::-ms-track { background: transparent;border-color: transparent;color: transparent;-webkit-appearance: none} | |
input[type=range]::-ms-track { -ms-appearance: none; height: 3px;background-color: #d5d5d5; margin-right: 0; | |
margin-top: 5px;margin-bottom: 5px; border:0; } | |
input[type=range]::-ms-thumb { background-color: #FFF; border: 3px solid rgb(150,150,150); | |
border-radius: 5px; height: 10px;width: 1px; } | |
input[type=range]::-webkit-slider-runnable-track { height: 5px;background:#7c7c7c; margin-top: -4px;} | |
input[type=range]::-webkit-slider-thumb { margin-top:-6px;} | |
#inputSliders p {padding-top:10px;} | |
</style> | |
</head> | |
<body> | |
<div id="inputSliders"> | |
<form id="sliders" autocomplete="off"> | |
<fieldset class="inputgroup"> | |
<div class="slider" id="angle_X"> | |
<label>Angle X axis(deg)</label> | |
<input type="range" name="angleX" id="angleX" value="25" min="0" max="80" step = "1"><p id="angXoutput">25°</p></div> | |
<div class="slider" id="angle_Y"> | |
<label>Angle Y axis</label> | |
<input type="range" name="angleY" id="angleY" value="25" min="0" max="80" step = "1"><p id="angYoutput">25°</p></div> | |
<div class="slider" id="grid_elev"> | |
<label>Grid elevation</label> | |
<input type="range" name="elev" id="elev" value="0" min="0" max="50" step = "1"><p id="elevoutput">0ft</p></div> | |
<div class="slider" id="grid_Size"> | |
<label>Grid Size</label> | |
<input type="range" name="gridSize" id="gridSize" value="360" min="200" max="380" step = "1"><p id="gridSizeoutput">360</p></div> | |
</fieldset> | |
</form> | |
</div> | |
<script> | |
// Get inputs from the sliders | |
var isoAngleX = $("#angleX").val().toString(); // Air tmperature in Celcius | |
var isoAngleY = $("#angleY").val().toString(); // Mean radiant tmperature in Celcius | |
var gridElevation = $("#elev").val().toString(); // Wind velocity in m/s | |
var gridSize = $("#gridSize").val().toString(); // Relative humidity in % | |
// Update inputs | |
$("#angleX").on("input", function(event) { | |
isoAngleX = $(this).val(); | |
$("#angXoutput").text(isoAngleX.toString() + "°"); | |
generateIsoGeometry("update"); | |
}); | |
$("#angleY").on("input", function(event) { | |
isoAngleY = $(this).val(); | |
$("#angYoutput").text(isoAngleY.toString() + "°"); | |
generateIsoGeometry("update"); | |
}); | |
$("#elev").on("input", function(event) { | |
gridElevation = $(this).val(); | |
$("#elevoutput").text(gridElevation.toString() + "ft"); | |
generateIsoGeometry("update"); | |
}); | |
$("#gridSize").on("input", function(event) { | |
gridSize = $(this).val(); | |
$("#gridSizeoutput").text(gridSize.toString()); | |
generateIsoGeometry("update"); | |
}); | |
//grid settings | |
var gridSizeX = gridSize; //overal grid dimensions in svg units | |
var gridSizeY = gridSize; | |
var cols = 20; | |
var rows = 20; | |
//var gridElevation = 0 | |
//var isoAngleX = 35; | |
//var isoAngleY = 35; | |
var zCoeficient = gridSize/360; | |
//grid format settings | |
var fillColorOn = "#f94200"; | |
var fillColorOff = "#cce9fe"; | |
var fillOpacity = 1 | |
var strokeColor = "white"; | |
var strokeWidth = 1; | |
var strokeOpacity = 1; | |
//facade format settings | |
var wallFormat = {} | |
wallFormat.strokeColor = "black"; | |
wallFormat.strokeOpacity = .5; | |
wallFormat.strokeWidth = 2 | |
wallFormat.fillColor = "white"; | |
wallFormat.fillOpacity = .3; | |
//window format settings | |
var windowFormat = {} | |
windowFormat.strokeColor = "black"; | |
windowFormat.strokeOpacity = .5; | |
windowFormat.strokeWidth = 1 | |
windowFormat.fillColor = "#84e4ff"; | |
windowFormat.fillOpacity = .3; | |
var canvas = d3.select("body").append("svg") | |
.attr("width", 800) | |
.attr("height", 600) | |
.append("g") | |
.attr("transform", "translate(50, 250)"); | |
generateIsoGeometry("new"); | |
function generateIsoGeometry(mode) { | |
gridSizeX = gridSize; //overal grid dimensions in svg units | |
gridSizeY = gridSize; | |
zCoeficient = gridSize/360; | |
//Facade Section | |
// temp. facade data from Chris | |
var wallSizeZ = 100;//overal grid dimensions in svg units | |
var r = {}; | |
r.wallCoords = [{x:0, y:0, z:0}, {x:gridSizeX, y:0, z:0}, | |
{x:gridSizeX, y:0, z:wallSizeZ*zCoeficient}, {x:0, y:0, z:wallSizeZ*zCoeficient}]; | |
r.glzCoords = [ | |
[{x:gridSizeX*.05, y:0, z:0}, {x:gridSizeX*.3, y:0, z:0},{x:gridSizeX*.3, y:0, z:80*zCoeficient}, {x:gridSizeX*.05, y:0, z:80*zCoeficient}], | |
[{x:gridSizeX*.35, y:0, z:0}, {x:gridSizeX*.6, y:0, z:0},{x:gridSizeX*.6, y:0, z:80*zCoeficient}, {x:gridSizeX*.35, y:0,z:80*zCoeficient}], | |
[{x:gridSizeX*.65, y:0, z:0}, {x:gridSizeX*.9, y:0, z:0},{x:gridSizeX*.9, y:0, z:80*zCoeficient}, {x:gridSizeX*.65, y:0, z:80*zCoeficient}] | |
]; | |
// Prepare wall and windows data | |
var facadeData = [prepShape(r.wallCoords, wallFormat)]; | |
for (i=0;i < r.glzCoords.length; i++) { | |
facadeData.push(prepShape(r.glzCoords[i], windowFormat)); | |
} | |
//Grid Section | |
d3.json("gridData.json", function (data) { | |
//create temp array of tile values from json file | |
//(will replace with Chris data) | |
var tileVals = []; | |
data.root.forEach(function(entry) { | |
for (i=0; i < entry.row.length; i++) { | |
tileVals.push({val:entry.row[i]}) | |
} | |
}); | |
//create array of tile origin pts and fill values | |
var tileSizeX = gridSizeX/cols; | |
var tileSizeY = gridSizeY/rows; | |
var originTiles = []; | |
for (iRow=0; iRow < rows; iRow++){ | |
for (iCol=0; iCol < cols; iCol++){ | |
var valIndex = iRow*rows+iCol; | |
var val = valIndex < tileVals.length ? tileVals[valIndex].val: 0; | |
var originX = tileSizeX*iCol; | |
var originY = tileSizeY*iRow; | |
originTiles.push({val:val, x:originX, y:originY}) | |
} | |
} | |
//convert orthogonal orign grid points to isometric points | |
originTiles.forEach(function(entry) { | |
z = -gridElevation * zCoeficient; | |
res = isoPoint(entry.x, entry.y, z, isoAngleX, isoAngleY); | |
entry.x = res[0]; | |
entry.y = res[1]; | |
}); | |
//base tile shape point loop | |
var tilePts = [{x:originTiles[0].x, y:originTiles[0].y}, | |
{x:originTiles[1].x, y:originTiles[1].y}, | |
{x:originTiles[cols+1].x, y:originTiles[cols+1].y}, | |
{x:originTiles[cols].x, y:originTiles[cols].y}, | |
{x:originTiles[0].x, y:originTiles[0].y} | |
]; | |
//create final list of tiles with five shape points each | |
//by adding the base pts to each tile's origin | |
var isoTilesPts = []; | |
for (i=0; i< originTiles.length; i++){ | |
tmpShapePts = []; | |
for (p=0; p < tilePts.length; p++){ | |
newPt = JSON.parse(JSON.stringify(tilePts[p])); | |
newPt.x = newPt.x + originTiles[i].x; | |
newPt.y = newPt.y + originTiles[i].y; | |
newPt.fc = originTiles[i].val?fillColorOn:fillColorOff; | |
newPt.fo = fillOpacity; | |
newPt.sc = strokeColor; | |
newPt.sw = strokeWidth; | |
newPt.so = strokeOpacity; | |
tmpShapePts.push(newPt); | |
} | |
isoTilesPts.push(tmpShapePts); | |
} | |
// Consolidate grid and facade data | |
var shapeData = isoTilesPts; | |
for (i=0;i < facadeData.length; i++) { | |
shapeData.push(facadeData[i]); | |
} | |
drawShapes(shapeData, mode); | |
}) | |
} | |
// Prepare Data to Isometric format | |
function prepShape(shapePts, shapeFormat){ | |
//convert orthogonal orign points to isometric points | |
shapePts.forEach(function(entry) { | |
res = isoPoint(entry.x, entry.y, -entry.z, isoAngleX, isoAngleY); | |
entry.x = res[0]; | |
entry.y = res[1]; | |
entry.fc = shapeFormat.fillColor; | |
entry.fo = shapeFormat.fillOpacity; | |
entry.sc = shapeFormat.strokeColor; | |
entry.sw = shapeFormat.strokeWidth; | |
entry.so = shapeFormat.strokeOpacity; | |
}); | |
shapePts.push(shapePts[0]); // add first point to compelte loop | |
return shapePts; | |
} | |
// Draw shapes | |
function drawShapes(shapePtLoops, mode) { | |
//line function for path shape | |
var line = d3.line() | |
.x(function(d){return d.x;}) | |
.y(function(d){return d.y;}); | |
//create shapes through path objects | |
paths = null; | |
if (mode=='new') { | |
paths = canvas.selectAll("path") | |
.data(shapePtLoops) | |
.enter().append("path"); | |
} else { | |
paths = canvas.selectAll("path") | |
.data(shapePtLoops) | |
} | |
paths.attr("d", line) | |
.attr("stroke", function(d){return d[0].sc} ) | |
.attr("stroke-width", function(d, i){return d[0].sw}) | |
.attr("stroke-opacity", function(d){return d[0].so}) | |
.attr("fill", function(d){return d[0].fc}) | |
.attr("fill-opacity", function(d){return d[0].fo}); | |
} | |
//Obtain isometric points from 2d points based on predefined angles | |
function isoPoint(x,y,z, isoAngleX, isoAngleY) { | |
var radX = (isoAngleX)*Math.PI/180; | |
var radY = (isoAngleY)*Math.PI/180; | |
var u0X = adjacentCos(radX, x); | |
var u0Y = oppositeSin(radX, x); | |
var v0X = adjacentCos(radY, y); | |
var v0Y = oppositeSin(radY, y); | |
//var locX = u0X-v0X; | |
//var locY = u0Y+v0Y; | |
var locX = u0X+v0X; | |
var locY = -u0Y+v0Y+z; | |
return [locX, locY]; | |
} | |
// Triangle math functions | |
//returns the length of the adjacent side to the angle, using the hypotenuse's length | |
function adjacentCos(angle, hypotenuse) { | |
return Math.cos(angle) * hypotenuse; | |
} | |
//returns the length of the opposite side to the angle, using the hypotenuse's length | |
function oppositeSin(angle, hypotenuse) { | |
return Math.sin(angle) * hypotenuse; | |
} | |
</script> | |
</body> | |