gpt4 book ai didi

javascript - Canvas 仅在 map 上绘制循环的最后一个元素

转载 作者:行者123 更新时间:2023-12-03 08:54:07 24 4
gpt4 key购买 nike

我正在使用 Icon.Canvas 在传单 map 上用 Canvas 绘制标记。我遇到了问题,我认为这与“循环闭合”有关,但由于创建普通 Canvas 及其上下文和我正在做的事情的差异,我似乎无法使用任何其他解决方案(canvas 元素和 ctx 由 Icon.Canvas 库创建)。

for (var park in parksMap) {

var circle = new L.Icon.Canvas({
iconSize: new L.Point(50, 50)
});


var item = parksMap[park];
var total = item.kpis.availability.online + item.kpis.availability.offline + item.kpis.availability.noComm;
var greenSize = item.kpis.availability.online * 2 / total;
var redSize = item.kpis.availability.offline * 2 / total;

console.log('OUTSIDE');
console.log(item);
circle.draw = function (ctx, w, h) {
console.log('INSIDE');
console.log(item);

setUpParkForStatus(item, ctx, greenSize, redSize);
parkWindConstructor(ctx);

ctxArray.push({
id: item.id,
ctx: ctx
});
} ...

(code continues on to create the actual markers)
}

setUpParksStatus 是具有绘图实际代码的函数。以下是 console.logs 的结果,以便更好地理解:

 OUTSIDE
park1

OUTSIDE
park2

INSIDE
park2

INSIDE
park2

最佳答案

您可以使用IIFE,它返回一个包含当前逻辑的函数,因此当时的值不会受到循环的影响。

编辑:当进入ES2015时,您可以使用let/const而不是 var 来使用当前代码实现,因为它的 block 范围而不是函数范围

是否可以使用库 Underscore.each也可以做这个工作,如果没有,你仍然可以使用 Object.keys()将键获取为Array,然后使用.forEach进行循环,所有这些方法都可以防止循环中获取的值随着循环的推进而变化。

失败演示和 IIFE 修复:

'use strict';
var obj = {
'a': 1,
'b': 2,
'c': 3
};
var funcArr1 = [];
var funcArr2 = [];
var k, func1, func2;
for (k in obj) {
// Way 1, all point to last.
func1 = function() {
console.log(k, obj[k]);
};

// Snapshot it
// The wrap function will be called imediately, and it'll return the function similar to func1
// But the outer function creates a scope, which stores the k(and rename it to v to avoid ambiguous)
// So all the func2s will point to each key in obj instead of last.
func2 = (function(v) {
return function() {
console.log(v, obj[v]);
};
})(k);

funcArr1.push(func1);
funcArr2.push(func2);
}

// IN ES2015, you can use let to achieve:
var funcArr3 = [];
var func3;
// The let, unlike var, is block scoped, so it can achieve what you expect in simpler form.
for (let m in obj) {
func3 = function() {
console.log(m, obj[m])
};
funcArr3.push(func3);
}

// To loop object with .forEach, which works on array.
var funcArr4 = [];
Object.keys(obj).forEach(function(key, index) {
funcArr4.push(function() {
console.log(key, obj[key]);
});
});

var i, length = funcArr1.length;
for (i = 0; i < length; ++i) {
console.log('Way1');
funcArr1[i](); // All of it will log c, 3, as k is pointing to c when exit the loop.
console.log('Way2');
funcArr2[i]() // Because we use a function to keep k, it'll log what we expect.

console.log('Way ES2015');
funcArr3[i](); // Because we use a function to keep k, it'll log what we expect.
console.log('Way forEach');
funcArr4[i](); // Because we use a function to keep k, it'll log what we expect.
}

使用 forEach 进行演示:

var obj = {
'a': 1,
'b': 2,
'c': 3
};
var funcArr = [];
Object.keys(obj).forEach(function(key, index) {
funcArr.push(function() {
console.log(key, obj[key]);
});
});

var i, length = funcArr.length;
for (i = 0; i < length; ++i) {
console.log('Way forEach');
funcArr[i](); // Because we use a function to keep k, it'll log what we expect.
}

使用 ES2015let 进行演示(这需要一些非常现代的浏览器版本才能使代码片段工作),但是有一些转译器能够将 ES2015 语法编译为 ES5 来工作在大多数浏览器上(例如: babel ):

'use strict';  // This make chrome to accept some ES2015 syntax
const obj = {
'a': 1,
'b': 2,
'c': 3
};
// IN ES2015, you can use let to achieve:
let funcArr = [];
// The let, unlike var, is block scoped, so it can achieve what you expect in simpler form.
for (let m in obj) {
funcArr.push(function() {
console.log(m, obj[m])
});
}

for (let i = 0, len = funcArr.length; i < len; ++i) {
console.log('Way ES2015');
funcArr[i](); // Because we use a function to keep k, it'll log what we expect.
}

所以你可以对你的circle.draw做类似的事情:

// Now the current value that may be used by the callback won't change as loop advanced.
circle.draw = (function(item, total, greenSize, redSize) {
return function (ctx, w, h) {
console.log('INSIDE');
console.log(item);

setUpParkForStatus(item, ctx, greenSize, redSize);
parkWindConstructor(ctx);

ctxArray.push({
id: item.id,
ctx: ctx
});
};
})(item, total, greenSize, redSize);

关于javascript - Canvas 仅在 map 上绘制循环的最后一个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32583275/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com