Skip to content

Instantly share code, notes, and snippets.

@vasturiano
Last active December 9, 2018 01:35
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save vasturiano/0c0756681a4a4b3e802942a90fbf442c to your computer and use it in GitHub Desktop.
Xmas tesselation

Tesselation template for christmas tree decoration. Dimensions in cm.

<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