mirror of
https://github.com/mitxela/clock4.git
synced 2025-12-05 23:20:26 -08:00
183 lines
3.8 KiB
HTML
183 lines
3.8 KiB
HTML
<!doctype html>
|
|
|
|
<canvas width=800 height=600 style='position:relative;'></canvas>
|
|
<br>
|
|
<textarea style="width:300px;height:100px" oninput='parse()'></textarea>
|
|
|
|
<script>
|
|
pre = document.querySelector('textarea')
|
|
canvas = document.querySelector('canvas')
|
|
ctx = canvas.getContext('2d')
|
|
|
|
w = canvas.width; h = canvas.height;
|
|
gw = w-50; gh = h-50
|
|
gx=25; gy=25
|
|
b={x:0,y:0}
|
|
|
|
curve = [
|
|
[0, 0],
|
|
[0.4, 0.1],
|
|
[0.7, 0.3],
|
|
[0.9, 0.6],
|
|
[1.0, 1.0]
|
|
]
|
|
|
|
function line(x1,y1,x2,y2){
|
|
ctx.beginPath()
|
|
ctx.moveTo(gx + x1*gw, gy+ gh-y1*gh)
|
|
ctx.lineTo(gx + x2*gw, gy+ gh-y2*gh)
|
|
ctx.stroke()
|
|
}
|
|
|
|
function circle(x,y) {
|
|
ctx.beginPath();
|
|
ctx.arc(gx + x*gw, gy+ gh-y*gh, 5, 0, 2 * Math.PI);
|
|
ctx.stroke();
|
|
}
|
|
ctx.font = '18px Courier, monospace';
|
|
function draw(wb){
|
|
b=canvas.getBoundingClientRect()
|
|
|
|
ctx.clearRect(0,0,w,h)
|
|
ctx.fillStyle='rgba(1,1,1,0.05)'
|
|
ctx.fillRect(gx,gy,gw,gh)
|
|
|
|
line(0,0,0,1)
|
|
line(0,0,1,0)
|
|
|
|
|
|
ctx.fillStyle='black'
|
|
ctx.textAlign='center';
|
|
ctx.fillText('Input',gx+gw/2,gy+gh+18)
|
|
ctx.save()
|
|
ctx.translate(18,gy+gh/2)
|
|
ctx.rotate(-Math.PI/2)
|
|
ctx.fillText('Output',0,0)
|
|
ctx.restore()
|
|
|
|
for (let i=0;i<curve.length;i++) {
|
|
circle( curve[i][0], curve[i][1] )
|
|
if (i) line( curve[i-1][0], curve[i-1][1], curve[i][0], curve[i][1] )
|
|
}
|
|
|
|
if (wb) return;
|
|
s=""
|
|
for (let i=0;i<curve.length;i++)
|
|
s+= "BS"+(i+1)+" = "+ Math.round(curve[i][0]*4095)+ ',' + Math.round(curve[i][1]*4095)+"\n"
|
|
pre.value = s
|
|
}
|
|
|
|
function distance(x1,y1,x2,y2){
|
|
return Math.sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) )
|
|
}
|
|
|
|
function nearestPoint(x,y){
|
|
let nearest = 0
|
|
let neardist = 999
|
|
for (let i=0;i<curve.length;i++) {
|
|
let d = distance( curve[i][0], curve[i][1], x, y )
|
|
if (d < neardist) {
|
|
nearest=i
|
|
neardist=d
|
|
}
|
|
}
|
|
return nearest
|
|
}
|
|
|
|
function clamp(x,y,i){
|
|
let step = 1/4095;
|
|
let minx = i>0? curve[i-1][0]+step:0;
|
|
let maxx = i<curve.length-1? curve[i+1][0]-step:1;
|
|
return [Math.min(maxx,Math.max(minx,x)),Math.min(1,Math.max(0,y))]
|
|
}
|
|
|
|
canvas.onmousedown=function(e){
|
|
e.preventDefault()
|
|
let x = (e.pageX-gx-b.x)/gw;
|
|
let y = 1-(e.pageY-gy-b.y)/gh;
|
|
|
|
let i = nearestPoint(x,y)
|
|
|
|
curve[i] = clamp(x,y,i)
|
|
document.onmousemove=function(e){
|
|
let x = (e.pageX-gx-b.x)/gw;
|
|
let y = 1-(e.pageY-gy-b.y)/gh;
|
|
curve[i] = clamp(x,y,i)
|
|
draw()
|
|
}
|
|
document.onmouseup=function(e){
|
|
document.onmousemove=null
|
|
document.onmouseup=null
|
|
}
|
|
draw()
|
|
}
|
|
|
|
|
|
touch={};
|
|
canvas.addEventListener("touchstart",function(e){
|
|
if (e.touches.length>1) return;
|
|
for (let t of e.changedTouches) {
|
|
let x = (t.pageX-gx-b.x)/gw
|
|
let y = 1-(t.pageY-gy-b.y)/gh
|
|
|
|
let i = nearestPoint(x,y)
|
|
curve[i] = clamp(x,y,i)
|
|
touch = {id:t.identifier,i}
|
|
}
|
|
e.preventDefault();
|
|
draw()
|
|
},true);
|
|
canvas.addEventListener("touchmove",function(e){
|
|
for (let t of e.changedTouches) {
|
|
if (touch.id == t.identifier) {
|
|
let x = (t.pageX-gx-b.x)/gw
|
|
let y = 1-(t.pageY-gy-b.y)/gh
|
|
|
|
curve[touch.i] = clamp(x,y,touch.i)
|
|
}
|
|
}
|
|
draw()
|
|
},true);
|
|
|
|
|
|
function parse(){
|
|
var lines = pre.value.split("\n");
|
|
for (let line of lines) {
|
|
let m = line.match(/^BS([1-5]) = (\d+),(\d+)$/)
|
|
if (!m || m[2]>4095 || m[3]>4095) continue;
|
|
curve[m[1]-1]=[m[2]/4095, m[3]/4095]
|
|
}
|
|
draw(1)
|
|
}
|
|
|
|
draw()
|
|
|
|
|
|
|
|
|
|
|
|
function single(inp){
|
|
|
|
|
|
inp /=4095.0
|
|
let i;
|
|
for (i=1; i< curve.length-1; i++){
|
|
if (curve[i][0] > inp) break;
|
|
}
|
|
let factor = (inp - curve[i-1][0]) / (curve[i][0] - curve[i-1][0]);
|
|
|
|
let out = curve[i-1][1]*(1.0-factor) + curve[i][1]*factor;
|
|
|
|
if (out>1.0 || isNaN(out)) out=1.0;
|
|
else if (out<0.0) out=0.0;
|
|
|
|
console.log(Math.round(out*4095,2))
|
|
|
|
}
|
|
|
|
|
|
[1500,1550,1430,3560,3470,2920,2050,2015,1980,900,580,350,450,230].forEach(single)
|
|
|
|
|
|
</script>
|