按顺序在不同 xy 坐标的数组上绘制不同图像的数组
Draw an Array of different Images on an array of different xy-coordinates, in order
我有一个 canvas:
<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>
let RibbonsArray = Array.from(document.getElementsByClassName("Ribbons"));
let CheckedRibbons = RibbonsArray.filter(element => element.checked == true);
我有几个 x/y 坐标数组:
var arr1 =[
[122, 235]
];
var arr2 =[
[69, 235],
[175, 235]
];
var arr3 =[
[16, 235],
[122, 235],
[228, 235]
];
var arr4 =[
[122, 220],
[16, 250],
[122, 250],
[228, 250]
];
var arr5 =[
[69, 220],
[175, 220],
[16, 250],
[122, 250],
[228, 250]
];
我有以下脚本:
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);
if (CheckedRibbons.length == arr1.length){
CheckedRibbons.forEach(Ribbon => {
let x = arr1[0][0];
let y = arr1[0][1];
let img = new Image();
img.src = `Ribbons/${Ribbon.value}.png`
img.addEventListener('load', () => {
ctx.drawImage(img, x, y);
});
});
} else if (CheckedRibbons.length == arr2.length){
//When 2 Ribbons are checked -> Draw Ribbon 1 at arr2[0] which is [69, 235].
// -> Draw Ribbon 2 at arr2[1] which is [175, 235].
} else if (CheckedRibbons.length == arr3.length){
//When 3 Ribbons are checked -> Draw Ribbon 1 at arr3[0] which is [16, 235].
// -> Draw Ribbon 2 at arr3[1] which is [122, 235].
// -> Draw Ribbon 3 at arr3[2] which is [228, 235].
}
};//REDRAW ENDS
正如您在选择 2 或 3 个色带的情况下看到的那样,我正在尝试找出一种方法来绘制位于“CheckedRibbons”中的每个色带......按顺序......在每个长度匹配的数组的相应索引(这是一口,嗯,我希望我没有把它搞砸)。
我尝试过在不同的配置中嵌套“forEach”,我尝试使用索引。我只是无法解决这个问题。
如果稍微更改一下数据结构,有几种方法可以更轻松地完成此操作。好处是您的代码不需要更改或重复,它将全部依赖于数据更改,这在长期 运行.
中是一种更易于维护的方法
这里有两个不同的例子来说明我的意思,当然有很多方法来构建你的数据,这只是我选择的两种回答方式。每个示例下方的完整工作代码(我使用了测试图像)。
第一个例子使用了一个数组,数组...数组。不是代表数据的最清晰的选项只是因为你总是必须像这样访问 0 索引处的初始数据,
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];
为什么会这样的例子,当我们在 resultsGroup
中过滤寻找长度为 2 的数组时
renderGroups.filter(el => el.length === 2);
这就是 resultsGroup
的样子。
[
[
[69, 235],
[175, 235]
]
]
这是由于 filter
返回一个数组,这意味着访问第一组,我们需要做 Array[0]
然后变成
[
[69, 235],
[175, 235]
]
这给了我们我们期望的正常对。所以 Array[0]
例如是:
[69, 235]
这是另一个数组,所以我们需要做Array[0][0]
得到69等。
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>
第二个选项是一个具有命名组属性的对象,它包含数组,但不是通用的,更易于管理和可读。缺点是访问 属性 依赖于精确的命名,如果您缺少预期的 属性 等,这可能会导致错误
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>
我有一个 canvas:
<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>
let RibbonsArray = Array.from(document.getElementsByClassName("Ribbons"));
let CheckedRibbons = RibbonsArray.filter(element => element.checked == true);
我有几个 x/y 坐标数组:
var arr1 =[
[122, 235]
];
var arr2 =[
[69, 235],
[175, 235]
];
var arr3 =[
[16, 235],
[122, 235],
[228, 235]
];
var arr4 =[
[122, 220],
[16, 250],
[122, 250],
[228, 250]
];
var arr5 =[
[69, 220],
[175, 220],
[16, 250],
[122, 250],
[228, 250]
];
我有以下脚本:
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);
if (CheckedRibbons.length == arr1.length){
CheckedRibbons.forEach(Ribbon => {
let x = arr1[0][0];
let y = arr1[0][1];
let img = new Image();
img.src = `Ribbons/${Ribbon.value}.png`
img.addEventListener('load', () => {
ctx.drawImage(img, x, y);
});
});
} else if (CheckedRibbons.length == arr2.length){
//When 2 Ribbons are checked -> Draw Ribbon 1 at arr2[0] which is [69, 235].
// -> Draw Ribbon 2 at arr2[1] which is [175, 235].
} else if (CheckedRibbons.length == arr3.length){
//When 3 Ribbons are checked -> Draw Ribbon 1 at arr3[0] which is [16, 235].
// -> Draw Ribbon 2 at arr3[1] which is [122, 235].
// -> Draw Ribbon 3 at arr3[2] which is [228, 235].
}
};//REDRAW ENDS
正如您在选择 2 或 3 个色带的情况下看到的那样,我正在尝试找出一种方法来绘制位于“CheckedRibbons”中的每个色带......按顺序......在每个长度匹配的数组的相应索引(这是一口,嗯,我希望我没有把它搞砸)。 我尝试过在不同的配置中嵌套“forEach”,我尝试使用索引。我只是无法解决这个问题。
如果稍微更改一下数据结构,有几种方法可以更轻松地完成此操作。好处是您的代码不需要更改或重复,它将全部依赖于数据更改,这在长期 运行.
中是一种更易于维护的方法这里有两个不同的例子来说明我的意思,当然有很多方法来构建你的数据,这只是我选择的两种回答方式。每个示例下方的完整工作代码(我使用了测试图像)。
第一个例子使用了一个数组,数组...数组。不是代表数据的最清晰的选项只是因为你总是必须像这样访问 0 索引处的初始数据,
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];
为什么会这样的例子,当我们在 resultsGroup
renderGroups.filter(el => el.length === 2);
这就是 resultsGroup
的样子。
[
[
[69, 235],
[175, 235]
]
]
这是由于 filter
返回一个数组,这意味着访问第一组,我们需要做 Array[0]
然后变成
[
[69, 235],
[175, 235]
]
这给了我们我们期望的正常对。所以 Array[0]
例如是:
[69, 235]
这是另一个数组,所以我们需要做Array[0][0]
得到69等。
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>
第二个选项是一个具有命名组属性的对象,它包含数组,但不是通用的,更易于管理和可读。缺点是访问 属性 依赖于精确的命名,如果您缺少预期的 属性 等,这可能会导致错误
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>