Tesselation template for christmas tree decoration. Dimensions in cm
.
Last active
December 9, 2018 01:35
-
-
Save vasturiano/0c0756681a4a4b3e802942a90fbf442c to your computer and use it in GitHub Desktop.
Xmas tesselation
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
<head> | |
<style> | |
body { | |
margin: 0; | |
background: red; | |
} | |
line { | |
stroke: darkgrey; | |
stroke-width: 1px; | |
} | |
.ball { | |
stroke-width: 2; | |
stroke: black; | |
fill: green; | |
} | |
</style> | |
<script src="//unpkg.com/dat.gui"></script> | |
<script src="//unpkg.com/d3"></script> | |
</head> | |
<body> | |
<svg id="tree"></svg> | |
<script> | |
const controls = { | |
nRows: 15, | |
nCols: 15, | |
diameter: 4, // cm | |
gapH: 2.65, // cm | |
gapV: 7.05 // cm | |
}; | |
const gui = new dat.GUI(); | |
gui.add(controls, 'diameter', 1, 10).onChange(digest); | |
gui.add(controls, 'gapH', 0, 10).onChange(digest); | |
gui.add(controls, 'gapV', 0, 10).onChange(digest); | |
const svg = d3.select(document.getElementById('tree')) | |
.attr('width', window.innerWidth * 2) | |
.attr('height', window.innerHeight * 3); | |
digest(); // init run | |
function digest() { | |
const r = cm2Px(controls.diameter / 2); | |
const hGap = cm2Px(controls.gapH); | |
const vGap = cm2Px(controls.gapV); | |
const rows = [...Array(controls.nRows).keys()].map((_, i) => i); | |
const cols = [...Array(controls.nCols).keys()].map((_, i) => i); | |
const getY = rowNumber => r * 1.2 + (r * 2 + vGap) * rowNumber; | |
const getX = (colNumber, rowNumber) => r * 1.2 + (r * 2 + hGap) * (colNumber + ((rowNumber + 1)%2 * 0.5)); | |
// Balls | |
const ballRow = svg.selectAll('g.ballRow').data(rows); | |
ballRow.exit().remove(); | |
ballRow.merge(ballRow.enter().append('g').attr('class', 'ballRow')).each(function(rowNumber) { | |
const ball = d3.select(this).selectAll('.ball').data(cols); | |
ball.exit().remove(); | |
ball.merge(ball.enter().append('circle').attr('class', 'ball')) | |
.attr('cx', colNumber => getX(colNumber, rowNumber)) | |
.attr('cy', getY(rowNumber)) | |
.attr('r', r) | |
}); | |
// H lines | |
const hLine = svg.selectAll('line.h').data(cols); | |
hLine.exit().remove(); | |
hLine.merge(hLine.enter().append('line').attr('class', 'h')) | |
.attr('x1', 0) | |
.attr('x2', svg.attr('width')) | |
.attr('y1', getY) | |
.attr('y2', getY); | |
// V lines | |
const vLineOdd = svg.selectAll('line.vodd').data(rows); | |
vLineOdd.exit().remove(); | |
vLineOdd.merge(vLineOdd.enter().append('line').attr('class', 'vodd')) | |
.attr('x1', colNumber => getX(colNumber, 1)) | |
.attr('x2', colNumber => getX(colNumber, 1)) | |
.attr('y1', 0) | |
.attr('y2', svg.attr('height')); | |
const vLineEven = svg.selectAll('line.veven').data(rows); | |
vLineEven.exit().remove(); | |
vLineEven.merge(vLineEven.enter().append('line').attr('class', 'veven')) | |
.attr('x1', colNumber => getX(colNumber, 2)) | |
.attr('x2', colNumber => getX(colNumber, 2)) | |
.attr('y1', 0) | |
.attr('y2', svg.attr('height')); | |
} | |
function cm2Px(cm) { | |
return cm * 35.43307 * (4 / 2.5); | |
} | |
</script> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment