Skip to content

Instantly share code, notes, and snippets.

@headwinds
Last active June 5, 2018 20:16
Show Gist options
  • Save headwinds/2459d99c35726d7a291ae7d9813382e0 to your computer and use it in GitHub Desktop.
Save headwinds/2459d99c35726d7a291ae7d9813382e0 to your computer and use it in GitHub Desktop.
Triangle Rect Sci Fi Targets
license: mit
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v5.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
</style>
</head>
<body>
<script>
const svg = d3.select("body").append("svg")
.attr("width", 960)
.attr("height", 500)
const drawGridLines = () => {
const gridContainer = svg.append('g')
.attr('id', 'grid');
const width = window.innerWidth;
const height = window.innerHeight;
const gap = 10;
const totalHLines = Math.floor(height / gap);
const totalVLines = Math.floor(width / gap);
let hCount = 0;
while (hCount < totalHLines) {
const y = gap * hCount;
gridContainer
.append("line")
.style("stroke", "#f1f1f1")
.attr("x1",0)
.attr("y1",y)
.attr("x2",width)
.attr("y2",y);
hCount++
}
let vCount = 0;
while (vCount < totalVLines) {
const x = gap * vCount;
gridContainer
.append("line")
.style("stroke", "#f1f1f1")
.attr("x1",x)
.attr("y1",0)
.attr("x2",x)
.attr("y2",height);
vCount++
}
}
drawGridLines()
svg.append("text")
.text("Who doesn't 🖤 sci fi reticles?!")
.attr("y", 200)
.attr("x", 120)
.attr("font-size", 36)
.attr("font-family", "monospace");
const getDestinationVector = ( originVector, angle, distance) => {
const destinationVector = {x: 0, y: 0};
destinationVector.x = Math.round(Math.cos(angle * Math.PI / 180) * distance + originVector.x);
destinationVector.y = Math.round(Math.sin(angle * Math.PI / 180) * distance + originVector.y);
return destinationVector;
}
const createDirections = (command, originVector, curAngle, distance) => {
const dV = getDestinationVector(originVector, curAngle, distance );
const X = dV.x;
const Y = dV.y;
previousVector = dV;
return `${command}${X} ${Y}`
}
const drawTriRecticle = (coordinates, id) => {
const triangleContainer = svg.append('g')
.attr('id', `triangleContainer${id}`);
triangleContainer.append('rect')
.attr("width",100)
.attr('height',90)
.style('stroke','none')
.style('fill','none');
const triangle = triangleContainer.append('g')
.attr('id',`triangle${id}`);
triangle.append("path")
.attr("fill", "none");
const symbol = d3.symbol().type(d3.symbolTriangle).size(64);
const plusX = coordinates.x + 10;
const plusY = coordinates.y + 60;
const triData = symbol();
triangleContainer
.append('g')
.attr("transform","translate(" + plusX + "," + plusY + ")")
.attr('class', 'tri')
.attr('id','target')
.append('path')
.style("fill","#CCC")
.attr("d", triData);
let pathDirections = '';
pathDirections += createDirections('M',previousVector,60,20);;
pathDirections += createDirections('L',previousVector,60,20);
pathDirections += createDirections('M',previousVector,60,40);
pathDirections += createDirections('L',previousVector,60,20);
pathDirections += createDirections('L',previousVector,180,20);
pathDirections += createDirections('M',previousVector,180,40);
pathDirections += createDirections('L',previousVector,180,20);
pathDirections += createDirections('L',previousVector,300,20);
pathDirections += createDirections('M',previousVector,300,40);
pathDirections += createDirections('L',previousVector,300,20);
const pathData = pathDirections;
triangle.select('path')
.attr('d', pathData)
.attr('stroke','#ddd')
.attr('stroke-width','1')
triangleContainer.attr('transform','translate(100,50)');
}
let previousVector = {x:40,y:-10};
drawTriRecticle(previousVector,0);
previousVector = {x:160,y:-10};
drawTriRecticle(previousVector,1);
previousVector = {x:280,y:-10};
drawTriRecticle(previousVector,2);
// need to figure out how to miter the caps!
// to add
// - animate flash
const drawSquareRecticle = (coordinates,id) => {
const squareContainer = svg.append('g')
.attr('id', `squareContainer${id}`);
squareContainer.append('rect')
.attr("width",100)
.attr('height',90)
.style('stroke','none')
.style('fill','none');
const square = squareContainer.append('g')
.attr('id',`square${id}`);
square.append("path")
.attr("fill", "none");
const symbol = d3.symbol().type(d3.symbolCross).size(40);
const plusX = coordinates.x + 50;
const plusY = coordinates.y + 50;
const plusData = symbol();
squareContainer
.append('g')
.attr("transform","translate(" + plusX + "," + plusY + ")")
.attr('class', 'plus')
.attr('id','target')
.append('path')
.style("fill","#CCC")
.attr("d", plusData);
let pathDirections = '';
pathDirections += createDirections('M',previousVector,0,0);;
pathDirections += createDirections('L',previousVector,0,20);
pathDirections += createDirections('M',previousVector,0,60);
pathDirections += createDirections('L',previousVector,0,20);
pathDirections += createDirections('L',previousVector,90,20);
pathDirections += createDirections('M',previousVector,90,60);
pathDirections += createDirections('L',previousVector,90,20);
pathDirections += createDirections('L',previousVector,180,20);
pathDirections += createDirections('M',previousVector,180,60);
pathDirections += createDirections('L',previousVector,180,20);
pathDirections += createDirections('L',previousVector,90,-20);
pathDirections += createDirections('M',previousVector,90,-60);
pathDirections += createDirections('L',previousVector,90,-20);
const pathData = pathDirections;
square.select('path')
.attr('d', pathData)
.attr('stroke','#ddd')
.attr('stroke-width','1')
squareContainer.attr('transform','translate(100,50)');
}
previousVector = {x:10,y:200};
drawSquareRecticle(previousVector,0);
previousVector = {x:150,y:200};
drawSquareRecticle(previousVector,1);
previousVector = {x:300,y:200};
drawSquareRecticle(previousVector,2);
const strobeReticle = (id, containerId) => {
const path = d3.select(`#${id}`).select('path')
const target = d3.select(`#${containerId}`).select('#target').select('path')
let repeatCount = 0;
function repeat() {
repeatCount++;
if (repeatCount < 3) {
d3
.active(this)
.style('stroke', 'white')
.transition()
.style('stroke', 'red')
.transition()
.style('stroke', 'darkred')
.transition()
.style('stroke', 'red')
.transition()
.style('stroke', '#CCC')
.transition()
.on('start', repeat);
}
}
function repeatTarget() {
repeatCount++;
if (repeatCount < 3) {
d3
.active(this)
.style('fill', 'white')
.transition()
.style('fill', 'red')
.transition()
.style('fill', 'darkred')
.transition()
.style('fill', 'red')
.transition()
.style('fill', '#CCC')
.transition()
.on('start', repeat);
}
}
path
.transition()
.duration(250)
.ease(d3.easeLinear)
.style('stroke', 'blue')
.on('start', repeat);
target
.transition()
.duration(250)
.ease(d3.easeLinear)
.style('stroke', 'none')
.style('fill', 'blue')
.on('start', repeatTarget);
}
const disco = () => {
let count = 0;
let triDelay = 200;
let squareDelay = 500;
setInterval( () => {
const targetTri = `triangle${count}`;
const targetTriContainer = `triangleContainer${count}`;
const targetSquare = `square${count}`;
const targetSquareContainerTri = `squareContainer${count}`;
strobeReticle(targetTri, targetTriContainer);
strobeReticle(targetSquare, targetSquareContainerTri);
if (count > 2) count = -1;
count++;
},2000)
}
//strobeReticle('triangle0','triangleContainer0');
disco();
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment