Exploring some ways to provide perspective and give a faux 3D effect.
Last active
October 30, 2015 03:14
-
-
Save Brideau/e613b01862b2a586be41 to your computer and use it in GitHub Desktop.
Perspective Vibrations
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<html> | |
<head> | |
<title></title> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script> | |
</head> | |
<body> | |
<canvas width="960" height="500"></canvas> | |
<script type="text/javascript"> | |
var canvas = document.querySelector("canvas"), | |
context = canvas.getContext("2d"), | |
width = canvas.width, | |
height = canvas.height | |
planeDist = 1, // Distance from the 'eye' to the viewing plane | |
closeDepth = 4, // Distance to the close set of squares | |
farDepth = 10, // Distance to the far set of squares | |
squareSize = 23, | |
buffer = 0.2, | |
focalWidth = 1; | |
// Adjusts the size of squares based on their distance from the // viewer. Based on simple similar triangles ratio. | |
function depthAdjust(distFromAxis, minDistance, planeDist) { | |
return (planeDist * distFromAxis) / (planeDist + minDistance) * 40; | |
} | |
// Gets the size of the squares for each plane | |
var projFarSize = depthAdjust(squareSize, farDepth, planeDist); | |
var projCloseSize = depthAdjust(squareSize, closeDepth, planeDist); | |
// Used to figure out how many squares can fit on the page | |
function createGrid(objectSize, totalWidth, totalHeight) { | |
// Size of the square plus its buffer | |
var buffPixels = objectSize * buffer; | |
var bufferedSize = objectSize + buffPixels; | |
// The number that fill fit horzontally and vertically | |
var xFit = Math.ceil(totalWidth / bufferedSize); | |
var yFit = Math.ceil(totalHeight / bufferedSize); | |
// Used to align everything around the center of the screen | |
var xStart = (totalWidth - (xFit * objectSize + (xFit + 1) * buffPixels)) / 2 + buffPixels; | |
var yStart = (totalHeight - (yFit * objectSize + (yFit + 1) * buffPixels)) / 2 + buffPixels; | |
return { | |
"xFit": xFit, | |
"yFit": yFit, | |
"xStart": xStart, | |
"yStart": yStart | |
} | |
} | |
// Given a value along a sin curve and the distance the object | |
// is from the plane, return the shifted grid | |
function shiftObject(position, depth) { | |
return depthAdjust(squareSize + focalWidth * position, depth, planeDist) - depthAdjust(squareSize, depth, planeDist); | |
} | |
var counter = 0; | |
function generateGrids() { | |
context.clearRect(0, 0, width, height); | |
position = Math.sin(Math.PI * counter / 10); | |
counter = counter > 19 ? 0 : counter + 1; | |
adjFar = shiftObject(position, farDepth); | |
gridFar = createGrid(projFarSize, width, height); | |
adjClose = shiftObject(position, closeDepth); | |
gridClose = createGrid(projCloseSize, width, height); | |
for (var i = 0; i < gridFar.xFit; i++) { | |
for (var j = 0; j < gridFar.yFit; j++) { | |
// Index * width + buffer - half width | |
var xPos = gridFar.xStart + i * (projFarSize + buffer * projFarSize) + adjFar; | |
var yPos = gridFar.yStart + j * (projFarSize + buffer * projFarSize); | |
context.fillStyle = '#8ED6FF'; | |
context.globalAlpha = 1; | |
context.fill(); | |
context.fillRect(xPos, yPos, projFarSize, projFarSize); | |
} | |
} | |
for (var i = 0; i < gridClose.xFit; i++) { | |
for (var j = 0; j < gridClose.yFit; j++) { | |
// Index * width + buffer - half width | |
var xPos = gridClose.xStart + i * (projCloseSize + buffer * projCloseSize) + adjClose; | |
var yPos = gridClose.yStart + j * (projCloseSize + buffer * projCloseSize); | |
context.fillStyle = '#3AB4FC'; | |
context.globalAlpha = 0.5; | |
context.fill(); | |
context.fillRect(xPos, yPos, projCloseSize, projCloseSize); | |
} | |
} | |
} | |
setInterval("generateGrids()", 15); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment