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> | |