Created
January 8, 2020 12:57
-
-
Save peacefullatom/5e5d64f1aa4fdc2090dfeb39d7ef6463 to your computer and use it in GitHub Desktop.
Gear playground
This file contains hidden or 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
:root { | |
--smokey: #f5f5f5; | |
--darky: #262625; | |
--thickness: 0.1vmin; | |
--half: 50%; | |
--border: var(--thickness) solid var(--smokey); | |
--border-radius: var(--half); | |
} | |
body, | |
html { | |
display: flex; | |
width: 100%; | |
height: 100%; | |
margin: 0; | |
background: var(--darky); | |
color: var(--smokey); | |
justify-content: center; | |
align-items: center; | |
flex-direction: column; | |
} | |
.controls { | |
display: flex; | |
width: 90vmin; | |
flex-wrap: wrap; | |
} | |
.controls .item { | |
line-height: 2rem; | |
margin-right: 1rem; | |
} | |
#container { | |
position: relative; | |
display: flex; | |
border: var(--border); | |
margin: 10vmin; | |
justify-content: center; | |
align-items: center; | |
border-radius: var(--border-radius); | |
} | |
#container .cover { | |
position: relative; | |
width: 100%; | |
height: 100%; | |
background: var(--darky); | |
border-radius: var(--border-radius); | |
z-index: 1; | |
} | |
#container .cover::before { | |
position: absolute; | |
width: var(--half); | |
height: var(--half); | |
left: var(--half); | |
top: var(--half); | |
transform: translateX(-50%) translateY(-50%); | |
background: var(--darky); | |
border-radius: var(--border-radius); | |
content: ""; | |
border: var(--border); | |
} | |
#container .tooth { | |
position: absolute; | |
box-sizing: border-box; | |
} | |
#container .tooth::before { | |
position: absolute; | |
width: 100%; | |
height: 100%; | |
border: var(--border); | |
content: ""; | |
background: var(--darky); | |
} | |
#container .tooth.circle::before { | |
border-radius: var(--border-radius); | |
} | |
#container .tooth.triangle::before { | |
transform: rotateZ(45deg); | |
} |
This file contains hidden or 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> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> | |
<title>Gear</title> | |
<link rel="stylesheet" type="text/css" href="gear.css" /> | |
</head> | |
<body> | |
<div id="container"></div> | |
<div class="controls"> | |
<div class="item"> | |
<label for="teeth">teeth:</label> | |
<input | |
id="teeth" | |
max="72" | |
min="3" | |
oninput="setTeeth(value)" | |
type="number" | |
value="3" | |
/> | |
</div> | |
<div class="item"> | |
<label for="height">height:</label> | |
<input | |
id="height" | |
max="30" | |
min="10" | |
oninput="setHeight(value)" | |
step="1" | |
type="number" | |
value="10" | |
/> | |
</div> | |
<div class="item"> | |
<label for="shape">shape:</label> | |
<select id="shape" oninput="setShape(value)"> | |
<option selected>square</option> | |
<option value="circle">circle</option> | |
<option value="triangle">triangle</option> | |
</select> | |
</div> | |
<div class="item"> | |
<label for="thickness">thickness:</label> | |
<input | |
id="thickness" | |
max="10" | |
min="1" | |
oninput="setThickness(value)" | |
step="1" | |
type="number" | |
value="1" | |
/> | |
</div> | |
<div class="item"> | |
<label for="angle">angle:</label> | |
<input | |
id="angle" | |
max="360" | |
min="0" | |
oninput="setAngle(value)" | |
step="5" | |
type="number" | |
value="0" | |
/> | |
</div> | |
</div> | |
<script src="gear.js"></script> | |
</body> | |
</html> |
This file contains hidden or 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
/** | |
* the gear container | |
* @type {HTMLDivElement} | |
*/ | |
let container = null; | |
/** | |
* the gear radius | |
* @type {number} | |
*/ | |
const radius = 10; | |
/** | |
* number of teeth | |
* @type {number} | |
*/ | |
let teeth = 3; | |
/** | |
* tooth height modifier | |
* @type {number} | |
*/ | |
let height = 10; | |
/** | |
* tooth shape name | |
* @type {string} | |
*/ | |
let shape = ""; | |
/** | |
* line thickness | |
* @type {number} | |
*/ | |
let thickness = 1; | |
/** | |
* gear angle | |
* @type {number} | |
*/ | |
let angle = 45; | |
/** | |
* set number of teeth | |
* @param {number} value number of teeth | |
*/ | |
function setTeeth(value) { | |
teeth = value; | |
update(); | |
} | |
/** | |
* set modifier for tooth height | |
* @param {number} value tooth height modifier | |
*/ | |
function setHeight(value) { | |
height = value; | |
update(); | |
} | |
/** | |
* set name of shape | |
* @param {string} value shape name | |
*/ | |
function setShape(value) { | |
shape = value; | |
update(); | |
} | |
/** | |
* set thickness | |
* @param {number} value thickness value | |
*/ | |
function setThickness(value) { | |
document.documentElement.style.setProperty( | |
"--thickness", | |
`${value / 10}vmin` | |
); | |
} | |
/** | |
* set angle value | |
* @param {number} value angle value | |
*/ | |
function setAngle(value) { | |
angle = value; | |
update(); | |
} | |
/** | |
* set a value to an input | |
* @param {string} id input id | |
* @param {number} value input value | |
*/ | |
function setupInput(id, value) { | |
const input = document.getElementById(id); | |
if (input) { | |
input.value = value; | |
} | |
} | |
/** | |
* update the gear | |
*/ | |
function update() { | |
if (container) { | |
// calculate the container dimensions | |
const size = `${radius * 3}vmin`; | |
// calculate the angle between teeth | |
const step = 360 / teeth; | |
// calculate the base dimension of the tooth | |
const side = (2 * Math.PI * radius) / (teeth * (Math.PI / 2)); | |
// calculate the tooth displacement | |
const displacement = radius * 1.5; | |
// setup container | |
container.style.width = size; | |
container.style.height = size; | |
container.style.transform = `rotate(${angle}deg)`; | |
container.innerHTML = null; | |
// draw teeth | |
for (var i = 0; i < teeth; i++) { | |
// create tooth | |
const tooth = document.createElement("div"); | |
tooth.className = `tooth ${shape}`; | |
// set size for the triangle-shaped tooth | |
if (shape === "triangle") { | |
const length = `${(side / 2) * ((height - 1) / 10)}vmin`; | |
tooth.style.height = length; | |
tooth.style.width = length; | |
} else { | |
// set size for the square and circle-shaped teeth | |
tooth.style.height = `${side}vmin`; | |
tooth.style.width = `${side * ((height - 1) / 10)}vmin`; | |
} | |
// place the tooth | |
tooth.style.transform = `rotateZ(${i * | |
step}deg) translateX(${displacement}vmin)`; | |
// append tooth to the container | |
container.appendChild(tooth); | |
} | |
// restore cover | |
const cover = document.createElement("div"); | |
cover.className = "cover"; | |
container.appendChild(cover); | |
} | |
} | |
/** | |
* perform initial values setup | |
*/ | |
function init() { | |
setupInput("teeth", teeth); | |
setupInput("height", height); | |
setupInput("thickness", thickness); | |
setupInput("angle", angle); | |
container = document.getElementById("container"); | |
update(); | |
} | |
init(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment