There's a few ways to do it easier if you change up the data structure a bit. Upside is your code doesn't need to change or be repeated, it will all rely on the data changing which is a more maintainable approach in the long run.
Here's two different examples of what I mean, there are of course lots of ways to structure your data these are just two ways I chose for the answer. Full working code below each example (I used a test image).
First example uses an array, of arrays... of arrays. Not the most clear option representing the data just due to the fact you always have to access the initial data at the 0 index like so,
const renderGroups = [
[
[122, 235]
],
[
[69, 235],
[175, 235]
],
[
[16, 235],
[122, 235],
[228, 235]
],
[
[122, 220],
[16, 250],
[122, 250],
[228, 250]
],
[
[69, 220],
[175, 220],
[16, 250],
[122, 250],
[228, 250]
]
];
// access data group, since renderGroups is an array all data lives on the 0 index.
const renderGroup = renderGroups.filter(group => group.length === CheckedRibbons.length)[0];
Example of why this is the case, when we filter looking for the array with a length of 2 within resultsGroup
renderGroups.filter(el => el.length === 2);
this is what resultsGroup looks like.
[
[
[69, 235],
[175, 235]
]
]
That's due to filter returning an array which means to access that very first group, we need to do Array[0] which then turns into
[
[69, 235],
[175, 235]
]
Which then gives us our normal pairs we're expecting. So Array[0] for example is:
[69, 235]
Which is another array, so we need to do Array[0][0] to get 69, ect.
let RibbonsArray = Array.from(document.getElementsByClassName("Ribbons"));
let CheckedRibbons = RibbonsArray.filter(element => element.checked == true);
const renderGroups = [
[
[122, 235]
],
[
[69, 235],
[175, 235]
],
[
[16, 235],
[122, 235],
[228, 235]
],
[
[122, 220],
[16, 250],
[122, 250],
[228, 250]
],
[
[69, 220],
[175, 220],
[16, 250],
[122, 250],
[228, 250]
]
];
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
function ClearLeft() {
let clearLeft = canvas.height - 5;
ctx.fillRect(2, 2, 345, clearLeft);
};
function ReDraw() {
ClearLeft();
//RIBBONS
let CheckedRibbons = RibbonsArray.filter(element => element.checked == true);
const renderGroup = renderGroups.filter(group => group.length === CheckedRibbons.length)[0];
CheckedRibbons.forEach((Ribbon, idx) => {
let x = renderGroup[idx][0];
let y = renderGroup[idx][1];
let img = new Image();
img.src = 'https://i.picsum.photos/id/130/200/200.jpg?hmac=pMGv0FZ4yiuwOp40JbbSUg8DSKRdq2Rx70VXtqMrbjI';
img.addEventListener('load', () => {
ctx.drawImage(img, x, y);
});
});
}
// REDRAW ENDS
<canvas id="canvas" width="500px" height="500px"></canvas>
<th><input value="0001" class="Ribbons" type="checkbox" onchange="ReDraw()"></th>
<th><input value="0002" class="Ribbons" type="checkbox" onchange="ReDraw()"></th>
<th><input value="0003" class="Ribbons" type="checkbox" onchange="ReDraw()"></th>
<th><input value="0004" class="Ribbons" type="checkbox" onchange="ReDraw()"></th>
<th><input value="0005" class="Ribbons" type="checkbox" onchange="ReDraw()"></th>
The second option is an object with named group properties which hold arrays, not as generic a little more manageable and readable however. The downside is accessing the property relies on precise naming which can lead to errors if you're missing an expected property, etc.
const renderGroups = {
group1: [
[122, 235]
],
group2: [
[69, 235],
[175, 235]
],
group3: [
[16, 235],
[122, 235],
[228, 235]
],
group4: [
[122, 220],
[16, 250],
[122, 250],
[228, 250]
],
group5: [
[69, 220],
[175, 220],
[16, 250],
[122, 250],
[228, 250]
]
};
// access data group
const renderGroup = renderGroups[`group${CheckedRibbons.length}`];
let RibbonsArray = Array.from(document.getElementsByClassName("Ribbons"));
let CheckedRibbons = RibbonsArray.filter(element => element.checked == true);
const renderGroups = {
group1: [
[122, 235]
],
group2: [
[69, 235],
[175, 235]
],
group3: [
[16, 235],
[122, 235],
[228, 235]
],
group4: [
[122, 220],
[16, 250],
[122, 250],
[228, 250]
],
group5: [
[69, 220],
[175, 220],
[16, 250],
[122, 250],
[228, 250]
]
};
const CheckedRibbons = RibbonsArray.filter(element => element.checked == true);
const renderGroup = renderGroups[`group${CheckedRibbons.length}`];
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
function ClearLeft() {
let clearLeft = canvas.height - 5;
ctx.fillRect(2, 2, 345, clearLeft);
};
function ReDraw() {
ClearLeft();
//RIBBONS
const CheckedRibbons = RibbonsArray.filter(element => element.checked == true);
const renderGroup = renderGroups[`group${CheckedRibbons.length}`];
console.log(renderGroup)
CheckedRibbons.forEach((Ribbon, idx) => {
let x = renderGroup[idx][0];
let y = renderGroup[idx][1];
let img = new Image();
img.src = 'https://i.picsum.photos/id/130/200/200.jpg?hmac=pMGv0FZ4yiuwOp40JbbSUg8DSKRdq2Rx70VXtqMrbjI';
img.addEventListener('load', () => {
ctx.drawImage(img, x, y);
});
});
}
// REDRAW ENDS
<canvas id="canvas" width="500px" height="500px"></canvas>
<th><input value="0001" class="Ribbons" type="checkbox" onchange="ReDraw()"></th>
<th><input value="0002" class="Ribbons" type="checkbox" onchange="ReDraw()"></th>
<th><input value="0003" class="Ribbons" type="checkbox" onchange="ReDraw()"></th>
<th><input value="0004" class="Ribbons" type="checkbox" onchange="ReDraw()"></th>
<th><input value="0005" class="Ribbons" type="checkbox" onchange="ReDraw()"></th>