使HTML地图元素可见

时间:2015-10-30 05:46:21

标签: html html5-canvas imagemap

自古以来,HTML一直支持图像地图。你知道,这种事情

<img src="url/to/your/image.jpg" alt="" usemap="#Map" />
<map name="Map" id="Map">
  <area href="#" shape="poly" coords="381,90,386,64,421,32,462,19,501,32,535,62,540,83" />
  <area href="#" shape="poly" coords="509,115,511,127,492,132,483,119,487,112" />
  <area href="#" shape="poly" coords="425,113,433,108,449,118,444,128,429,128" />
</map>

我在数据库中有一些数据,用于确定图像的来源并定义命名的区域坐标集。它存储为一个JSON字符串,它解析为一个对象图,并且knockout将它全部呈现为一个网页,其中包含点击处理程序,返回每个区域的正确标识符。

所有这一切都很好,我提到它只是为了提供操作背景。

当用户点击某个区域时,我想切换其可见性。例如,想象一下,在解剖图上指出一个或多个受影响区域的伤害,或保险索赔应用程序中汽车的弯曲位,就像那样。

问题在于使区域可见。区域不呈现。所以我需要画出图像。我知道可以做到;谷歌地图做到了。

我不知道从哪里开始或搜索什么。这是我第一次需要直接绘制 - 通常我提供元素并让浏览器按原样渲染。

那么,一些搜索词,关键词甚至是视频教程的链接呢?特别是我需要覆盖图像,所以我需要在相同的坐标空间中绘制。虽然你们都在忙着讨论这个问题,但我正在研究&#34; canvas&#34;和&#34;绘制图像&#34;。

2 个答案:

答案 0 :(得分:0)

从对其他相关问题的回答看来,HTML委员会已经开始讨论帆布图像地图五年了。

简短版:你不能。

长版:使用画布,将图像设置为背景并进行自己的命中测试。

答案 1 :(得分:0)

您可以像这样“突出显示”img的映射部分:

  • 使用CSS
  • 完全覆盖相同大小的canvas元素
  • 告诉画布不要回复鼠标/触摸事件:pointer-events:none
  • 单击映射区域时,告诉画布使用路径命令在低不透明度填充中绘制该区域:

    context.beginPath();
    context.moveTo(381,90);
    context.lineTo(386,64);
    context.lineTo(421,32);
    context.lineTo(462,19);
    context.lineTo(501,32);
    context.lineTo(535,62);
    context.lineTo(540,83);
    context.closePath();
    // fill the path area with a low-opacity red (or color of you choosing)
    context.globalAlpha=0.15;
    context.fillStyle='red';
    context.fill();   // this fills the path
    context.globalAlpha=1.00;  // just resetting to default opacity
    

这使您可以保留使用img。

的现有代码

或者,如果您的设计允许重大重构,您可以在画布上绘制图像并使用context.isPointInPath来测试每条路径与鼠标单击位置的对比。然后使用低不透明度填充填充命中路径。

[添加:保存区域坐标以便以后用于命中测试]

警告:未经测试的代码,可能需要调整

为了便于重复使用每个区域坐标,您可以将每组坐标放在一个对象中,并将这些对象放在一个数组中:

var areas=[];
// first area coordinates
arrays.push([ {x:381,y:90}, {x:386,y:64}, ... etc ]);
// second area coordinates
arrays.push([ {x:509,y:115}, {x:511,y:127}, ... etc ]);
...

然后使用这些保存的区域坐标进行命中测试:

function isMouseInArea(mouseX,mouseY){

    var index;  // index of any "hit" area. leave it initially null
    for(var i=0;i<areas.length;i++){

        // create a path from this area's coordinates
        defineAreaPath(areas[i]);

        // test if the mouse is inside this area
        if(ctx.isPointInPath(mouseX,mouseY)){
            index=i;
        }

    }
    // return any "hit" index of areas[] or return null if no hits
    return(index);
}

// utility function to define a path from the supplied coordinates
function defineAreaPath(pts){
    // create a path from this area's coordinates
    ctx.beginPath();
    ctx.moveTo(pts[0].x,pts[0].y);
    for(var i=1;i<pts.length;i++){
        ctx.lineTo(pts[i].x,pts[i].y);
    }
    ctx.closePath();
}

你可以像这样使用isMouseInArea函数:

var index=isMouseInArea(mouseX,mouseY)
if( index ){
    // draw the area path that was "hit" by the mouse
    defineAreaPath(areas[index]);
    // fill that path with low-opacity fill
    ctx.globalAlpha=0.15;
    ctx.fillStyle='red';
    ctx.fill();
    ctx.globalAlpha=1.00;
}