如何制作可重复且可点击的图像?

时间:2014-12-25 21:34:05

标签: javascript jquery css canvas svg

我正在制作一个人体模型,它具有特定的器官,需要突出显示并悬停在顶部并且可以点击。困难的部分,例如:肺部与心脏重叠,如何在不将肺部置于肺部之上的情况下使心脏可以点击?

我尝试使用透明的SVG,但无法让它们工作。

谢谢!

2 个答案:

答案 0 :(得分:3)

你需要一个"命中测试"机制。它的工作原理如下:

  1. 将形状的轮廓保存在JS结构中
  2. 在您的图形上有一个表面接收所有鼠标点击事件
  3. 单击曲面时,使用传递的坐标查找(1)
  4. 中的哪个形状

    或者,将图形切换为矢量将提供此功能out of the box,但可扩展图形的附加优势。其缺点是:旧的浏览器和增加的生成矢量的处理。

答案 1 :(得分:3)

你有心脏,肺等的轮廓路径吗?

如果是,您只需使用context.isPointInPath来测试每个器官。

如果不是,您可以将每个风琴绘制到自己的画布上,然后使用context.getImageData来测试鼠标下方的像素是否对任何特定风琴画布都不透明。

以下是使用像素数据进行命中测试的示例:

enter image description here

突出显示鼠标悬停的器官:

enter image description here enter image description here

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var $canvas=$("#canvas");
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;


var heartCanvas=document.createElement('canvas');
var heartCtx=heartCanvas.getContext('2d');
var lungsCanvas=document.createElement('canvas');
var lungsCtx=lungsCanvas.getContext('2d');
heartCanvas.width=lungsCanvas.width=canvas.width;
heartCanvas.height=lungsCanvas.height=canvas.height;
var heart={canvas:heartCanvas,x:100,y:125,alpha:0.25};
var lungs={canvas:lungsCanvas,x:65,y:105,alpha:0.25};

var imgCount=3;
var bodyImg=new Image();bodyImg.onload=start;bodyImg.src="https://dl.dropboxusercontent.com/u/139992952/multple/humanOutline.png";
var heartImg=new Image();heartImg.crossOrigin='anonymous';heartImg.onload=start;heartImg.src="https://dl.dropboxusercontent.com/u/139992952/multple/heart.png";
var lungsImg=new Image();lungsImg.crossOrigin='anonymous';lungsImg.onload=start;lungsImg.src="https://dl.dropboxusercontent.com/u/139992952/multple/lungs.png";
function start(){
  if(--imgCount>0){return;}   
  var data;
  heartCtx.drawImage(heartImg,heart.x,heart.y);
  data=heartCtx.getImageData(0,0,cw,ch).data;
  heart.pixels=[];
  for(var i=0;i<data.length;i+=4){heart.pixels.push(data[i+3]);}
  lungsCtx.drawImage(lungsImg,lungs.x,lungs.y);
  data=lungsCtx.getImageData(0,0,cw,ch).data;
  lungs.pixels=[];
  for(var i=0;i<data.length;i+=4){lungs.pixels.push(data[i+3]);}
  $("#canvas").mousemove(function(e){handleMouseMove(e);});
  draw();
}

function draw(){
  ctx.clearRect(0,0,cw,ch);
  ctx.globalAlpha=0.25;
  ctx.drawImage(bodyImg,0,0);
  ctx.globalAlpha=heart.alpha;
  ctx.drawImage(heartCanvas,0,0);
  ctx.globalAlpha=lungs.alpha;
  ctx.drawImage(lungsCanvas,0,0);
  ctx.globalAlpha=1.00;
}

function handleMouseMove(e){
  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();

  mouseX=parseInt(e.clientX-offsetX);
  mouseY=parseInt(e.clientY-offsetY);

  var heartPixelAlpha=heart.pixels[mouseY*cw+mouseX];
  heart.alpha=(heartPixelAlpha>0)?1.00:0.25;
  var lungsPixelAlpha=lungs.pixels[mouseY*cw+mouseX];
  lungs.alpha=(lungsPixelAlpha>0)?1.00:0.25;

  draw();
}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Hover mouse over 1+ organs to highlight them</h4>
<canvas id="canvas" width=300 height=330></canvas>

相关问题