function hueCanvas(f,label,max=1) {
const w = width
const tickH = 6
const gradH = 25
const unigradH = 6
const labelH = 20
const h = gradH + tickH + (label ? labelH : 0) + unigradH
const ctx = DOM.context2d(w,h)
const y = h - gradH - unigradH
ctx.font = '16px sans-serif'
if (label) {
ctx.fillStyle = '#3558'
ctx.textAlign = 'left'
ctx.textBaseline = 'top'
ctx.fillText(label, 10, 0)
}
ctx.shadowColor = '#000'
ctx.shadowBlur = 1.4
const tickRes = 4
const tickN = 6 * 2**tickRes
const tickStops = []
for (let j=0; j<tickN; j++) {
const i = j/tickN
if (i > max) break
tickStops.push([i,f(i), hue(i).hex])
}
if (max == 1) tickStops.push([1,1, hue(0).hex])
if (!cleanMode) {
for (const [i,j,color] of tickStops.slice(1,-1)) {
ctx.beginPath()
const x = j*w
ctx.moveTo(x,y-tickH)
ctx.lineTo(x,y)
ctx.strokeStyle = color; ctx.stroke()
}
}
const g = ctx.createLinearGradient(0,0,w,0)
for (const [i,j,color] of tickStops) {
g.addColorStop(j,color)
}
ctx.fillStyle = g
ctx.fillRect(0,y,w*max,gradH)
const g2 = ctx.createLinearGradient(0,0,w,0)
for (const [i,j] of tickStops) {
const h = hue(i).lchab[2]
g2.addColorStop(j, chroma.hcl(h,80,80).hex())
}
ctx.fillStyle = g2
ctx.fillRect(0,y+gradH,w*max,unigradH)
if (!cleanMode) {
ctx.textBaseline = 'middle'
for (const [label,i] of Object.entries(hueI)) {
if (max < 1 && label=='R2') break
const j = i==max ? max : f(i)
const col = hue(i).hex
ctx.beginPath()
const tx = j*w
const ty = y+gradH/2
const text = ' '+label[0]+' '
ctx.textAlign = i==0 ? 'left' : i==max ? 'right' : 'center'
ctx.lineWidth = 3
ctx.strokeStyle = '#0004'; ctx.strokeText(text,tx,ty)
ctx.fillStyle = '#fff'; ctx.fillText(text,tx,ty)
}
}
return ctx.canvas
}