JSFiddle - React, Tailwind, and code Playground
by John Doe
JavaScript
/* initialize stuff */
var cvs = document.createElement('canvas')
cvs.width = 500
cvs.height = 300
var ctx = cvs.getContext('2d')
cvs.clear = function() {
ctx.fillStyle = '#afa'
ctx.fillRect(0, 0, cvs.width, cvs.height)
}
document.body.appendChild(cvs)
cvs.clear()
var mouseDownAngle = null
var angleDiff = 0
var angle = 0
function sliderule(sign = 1, offset = 0) {
var endPoint = (angle, length, radius) => [
cvs.width / 2 + Math.cos(angle + offset) * (radius + length * sign),
cvs.height / 2 + Math.sin(angle + offset) * (radius + length * sign)
]
var base = 10
var maxExp = 5
var absMax = 1e3
var upperLimit = Math.min(Math.pow(base, maxExp), absMax)
var upperLimitAngle = 2 * Math.PI * Math.min(maxExp, Math.log(absMax) / Math.log(base))
var flength = l => 50.0 * (maxExp * 1.1 - l) / maxExp //40 / (l + 1)
var radius = cvs.height / 3
//
if (sign < 0) {
ctx.beginPath()
ctx.fillStyle = '#faa'
ctx.arc(cvs.width / 2, cvs.height / 2, radius, 0, Math.PI * 2)
ctx.fill()
}
// ticks
ctx.fillStyle = '#000'
for (var k = 1; k < upperLimit; k++) {
if (k % base != 0) {
//console.log('drawing ' + k)
var log = Math.log(k) / Math.log(base)
var length = flength(log)
var angle = log * 2 * Math.PI
ctx.lineWidth = 3 / Math.sqrt(k)
// cvs.tick(angle, length, radius, width)
ctx.beginPath()
ctx.moveTo(...endPoint(angle, 0, radius))
ctx.lineTo(...endPoint(angle, length, radius))
ctx.stroke()
}
}
// spiral
var dphi = 0.02
ctx.fillStyle = '#000'
ctx.lineWidth = 1
ctx.beginPath()
var log = 0
var length = flength(log)
ctx.moveTo(...endPoint(0, length, radius))
for (var phi = 0; phi <= upperLimitAngle; phi += dphi) {
log = phi / 2 / Math.PI
length = flength(log)
ctx.lineTo(...endPoint(phi, length, radius))
}
ctx.stroke()
}
sliderule()
sliderule(-1, 0)
/* events */
cvs.onmousedown = function(e) {
var r =...