2

我正在使用 jQuery Map Hilighter插件,但我不想在每个区域上淡化一个深色补丁,而是想反转它,而是使周围区域变暗,保持悬停区域的颜色相同。

我查看了插件的代码,它似乎使用 canvas 元素(我猜是一个 MS 等效元素)来进行突出显示。然而,Firebug 对形状定义的确切位置并不是很明确——在上面的演示中它只是显示了这一点:

 <canvas style="border: 0pt none ; padding: 0pt; width: 960px; height: 593px; position: absolute; left: 0pt; top: 0pt; opacity: 1;" height="593" width="960"></canvas>

而且我看不到任何指定要悬停的元素形状的东西。这是似乎正在创建形状的 JS 部分:

add_shape_to = function(canvas, shape, coords, options) {
    var i, context = canvas.getContext('2d');
    context.beginPath();
    if(shape == 'rect') {
        context.rect(coords[0], coords[1], coords[2] - coords[0], coords[3] - coords[1]);
    } else if(shape == 'poly') {
        context.moveTo(coords[0], coords[1]);
        for(i=2; i < coords.length; i+=2) {
            context.lineTo(coords[i], coords[i+1]);
        }
    } else if(shape == 'circ') {
        context.arc(coords[0], coords[1], coords[2], 0, Math.PI * 2, false);
    }
    context.closePath();
    if(options.fill) {
        context.fillStyle = css3color(options.fillColor, options.fillOpacity);
        context.fill();
    }
    if(options.stroke) {
        context.strokeStyle = css3color(options.strokeColor, options.strokeOpacity);
        context.lineWidth = options.strokeWidth;
        context.stroke();
    }
    if(options.fade) {
        fader(canvas, 0);
    }
};
4

1 回答 1

3

元素的形状被定义为HTML 代码中<area>元素内的<map>元素。

您的问题的简单答案是添加类似这样的内容

  if (options.inverseFill) {
    context.rect(0,0, canvas.width,canvas.height);
  }

在该context.beginPath();行之后,然后是 defaults: 中的一个选项,inverseFill: true,然后确保图像映射中的所有区域都以相同的顺时针方向声明。

发生的情况是,您为定义暗斑的路径定义了一个额外的子路径,并且当您填充时,重叠区域(即原始斑块)将抵消,只要子路径的缠绕数抵消,导致你想要的倒置行为。

如果您的区域多边形定义可以双向旋转,它会变得相当复杂。例如,如果您为美国地图的原始 MapHilight 演示执行上述操作,则只有一些州的行为正确,因为它们的形状是按正确的顺时针方向定义的 - 其余的保持黑暗,因为它们的缠绕数字是错误的符号.

如果您可以完全控制图像映射定义,我的建议是保留它并确保所有区域都朝着相同的方向前进(即,只需反转每个不起作用区域的坐标列表)。

如果不是,那么在初始化时,您需要为每个形状预先计算绕组数。这很可能涉及遍历点列表并对每两个连续段之间的角度求和 - 使用 atan2 计算。然后在 add_shape_to 函数中以正确的方向遍历画布的 4 个角。

无论如何,我希望这会有所帮助

更新:

抱歉,我之前没有看到您的评论。对于圆形区域,在 add_shape_to 函数中,将 } else if(shape == 'circ') {部分替换为

  } else if(shape == 'circ') {
    context.closePath();
    context.moveTo(coords[0] + coords[2], coords[1]);
    context.arc(coords[0], coords[1], coords[2], 0, Math.PI * 2, true);
    context.closePath(); 
  }

它关闭前后的子路径,然后移动到正确的位置,以避免讨厌的红线到顶角,然后更改逆时针参数true以匹配外部矩形。根据需要修改

于 2009-11-16T17:48:47.773 回答