So, I have programmed a simple RGB slider which shows its result on a HTML canvas. Everything works except a slice
/ substring
: for some reason, when setting it to a variable or changing the innerText of a <span>
it returns undefined
.
const $ = ele => document.querySelector(ele), numToHex = num => parseInt(num, 10).toString('16').padStart(2, '0'), c = $('#canvas').getContext('2d') var rsp = $('#rspan'), gsp = $('#gspan'), bsp = $('#bspan'), rvalue, gvalue, bvalue $('#rrange').oninput = () => { rvalue = `#${numToHex($('#rrange').value).toUpperCase()}0000` rsp.innerText = rvalue rsp.style.color = rvalue updateCanvas() } $('#grange').oninput = () => { gvalue = `#00${numToHex($('#grange').value).toUpperCase()}00` gsp.innerText = gvalue gsp.style.color = gvalue updateCanvas() } $('#brange').oninput = () => { bvalue = `#0000${numToHex($('#brange').value).toUpperCase()}` bsp.innerText = bvalue bsp.style.color = bvalue updateCanvas() } function updateCanvas(rval = rvalue, gval = gvalue, bval = bvalue) { console.log(rval.substring(0, 3)) // This works let arr = [rval.substring(0, 3), gval.substring(3, 5), bval.substring(-2)] c.fillStyle = arr.join('') // Throws error c.fillRect(0, 0, 250, 250) }
input { width: 300px; }
<!DOCTYPE html> <html> <head> <title>RGB Slider</title> </head> <body> <canvas id="canvas" width="250" height="250"></canvas> <div id="rdiv"> <input type="range" min="0" max="255" id="rrange" /> <span id="rspan"></span> </div> <div id="gdiv"> <input type="range" min="0" max="255" id="grange" /> <span id="gspan"></span> </div> <div id="bdiv"> <input type="range" min="0" max="255" id="brange" /> <span id="bspan"></span> </div> </body> </html>
Why is this happening? It also throws the same error with slice
. And why does it work in the prior console.log
statement?
You currently don't always define rvalue
, gvalue
, and bvalue
- they start out undefined
, and all 3 only become assigned to once every slider has been changed at least once. Before that point, the updateCanvas
:
function updateCanvas(rval = rvalue, gval = gvalue, bval = bvalue) {
will have at least one undefined parameter, so trying to access .substring
on those undefined parameters will throw.
Set the color values to default to the middle of the range, #808080
:
rvalue = '#808080',
gvalue = '#808080',
bvalue = '#808080';
You also need to slice the substrings properly when constructing the array - take 2 characters from each of red, green, and blue, then put them together and prefix them with #
:
const $ = ele => document.querySelector(ele), numToHex = num => parseInt(num, 10).toString('16').padStart(2, '0'), c = $('#canvas').getContext('2d') var rsp = $('#rspan'), gsp = $('#gspan'), bsp = $('#bspan'), rvalue = '#800000', gvalue = '#808080', bvalue = '#808080'; $('#rrange').oninput = () => { rvalue = `#${numToHex($('#rrange').value).toUpperCase()}0000` rsp.innerText = rvalue rsp.style.color = rvalue updateCanvas() } $('#grange').oninput = () => { gvalue = `#00${numToHex($('#grange').value).toUpperCase()}00` gsp.innerText = gvalue gsp.style.color = gvalue updateCanvas() } $('#brange').oninput = () => { bvalue = `#0000${numToHex($('#brange').value).toUpperCase()}` bsp.innerText = bvalue bsp.style.color = bvalue updateCanvas() } function updateCanvas(rval = rvalue, gval = gvalue, bval = bvalue) { let arr = [rval.substring(1, 3), gval.substring(3, 5), bval.substring(5, 7)] console.log(arr); c.fillStyle = '#' + arr.join('') // Throws error c.fillRect(0, 0, 250, 250) }
input { width: 300px; }
<!DOCTYPE html> <html> <head> <title>RGB Slider</title> </head> <body> <canvas id="canvas" width="250" height="250"></canvas> <div id="rdiv"> <input type="range" min="0" max="255" id="rrange" /> <span id="rspan"></span> </div> <div id="gdiv"> <input type="range" min="0" max="255" id="grange" /> <span id="gspan"></span> </div> <div id="bdiv"> <input type="range" min="0" max="255" id="brange" /> <span id="bspan"></span> </div> </body> </html>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.