【问题标题】:Is there a way to automatically generate a pseudo image map?有没有办法自动生成伪图像地图?
【发布时间】:2015-08-28 20:05:40
【问题描述】:

Hitbox Overlay IIFE 代码

//CSS Hitbox Solution 08-26-2015
//StackOverflow - https://stackoverflow.com/questions/32233084/show-an-element-without-hitbox-does-not-take-mouse-touch-input
//Detect MouseOver https://stackoverflow.com/questions/1273566/how-do-i-check-if-the-mouse-is-over-an-element-in-jquery
//Source: https://stackoverflow.com/questions/3942776/using-jquery-to-find-an-element-at-a-particular-position
//https://css-tricks.com/snippets/jquery/get-x-y-mouse-coordinates/
(function($) {
  $.mlp = {
    x: 0,
    y: 0
  }; // Mouse Last Position
  function documentHandler() {
    var $current = this === document ? $(this) : $(this).contents();
    $current.mousemove(function(e) {
      jQuery.mlp = {
        x: e.pageX,
        y: e.pageY
      };
    });
    $current.find("iframe").load(documentHandler);
  }
  $(documentHandler);
  $.fn.ismouseover = function(overThis) {
    var result = false;
    this.eq(0).each(function() {
      var $current = $(this).is("iframe") ? $(this).contents().find("body") : $(this);
      var offset = $current.offset();
      result = offset.left <= $.mlp.x && offset.left + $current.outerWidth() > $.mlp.x && offset.top <= $.mlp.y && offset.top + $current.outerHeight() > $.mlp.y;
    });
    return result;
  };
})(jQuery);
$('.notification-box').on("click", function() {
  $("button").each(function(i) {
    var iteratedButton = $('button:eq(' + i + ')');
    var buttonID = iteratedButton.attr("id");
    if (iteratedButton.ismouseover()) {
      iteratedButton.toggleClass(buttonID);
    }
  });
});

Example 01: Overlay Example for context

Example 02: Concept for auto generating content - 源自this stackoverflow 问题。

有一种方法可以在覆盖它们的覆盖层下放置多个对象。然后,如果用户在预定点单击,则有一种方法可以使指针与所述覆盖层下方的元素交互。我的问题是,请有人编写代码,将&lt;map&gt; 标签的概念与检测用户单击的参考点是否是该图像的 IIFE 结合起来,然后就好像它被单击了一样。

如果这没有意义,简单地说,我正在寻找一种偏离手动设置&lt;area&gt; 坐标或必须使用工具(非常深刻)如http://www.image-maps.com/ 的过程。相反,我们会让指针完成所有工作。

我们有以下高实用性 + 高度兼容的方法:.offset().position()elementFromPoint() 以及使用基本 CSS 将元素置于掩码后面的能力。

所以我们可以结合上面的 IIFE Overlay hitbox 方法 + ???? = 利润(再见映射坐标,通过&lt;map&gt;)。

我只是知道 ????是。我确实知道无论解决方案是什么,我都希望它适用于所有浏览器(包括 IE 5)。

最后,该过程在设计、设置和实施方面应该是相当自动化的。

无论是谁创建的,请将其命名为 autoMapperJs(因为它不仅限于图像)。

更新:
???? 的核心功能组件正如@Alex 在 cmets 中所指出的那样,已经实现了。 CreateJs 会在指针悬停在图像的非透明区域上时发出通知。这是强大的,应该是创建的工具的标准。它似乎也使用了.mousemove()z-index。请继续发表评论,总的来说,我觉得可以找到解决方案。

【问题讨论】:

  • (包括 IE 5)。 :-o
  • IE5 兼容性意味着它非常难.. :(
  • IE 5 或许可以在以后构建。至少要实现这个概念,这样我们就有了一个可以构建和改进的工作模板。
  • createjs.com/easeljs 有一个不错的功能。您可以将图像放在画布上,当您实际将鼠标悬停在非透明像素上时,指针会发出通知,如下所示:createjs.com/demos/easeljs/draganddrop。我非常怀疑 IE 5 甚至是一个互联网浏览器。
  • 您可以考虑使用 SVG 而不是 Canvas 以获得更好的元素基础操作和事件处理。顺便说一句,SVG 和 Canvas 在 IE8 及更低版本中都没有原生支持。

标签: javascript jquery html css imagemap


【解决方案1】:

这是一个开始。将图像放入画布上的一系列图层和位置,然后在鼠标悬停时通过它们进行点击。还可以在图层数组中放置图像以在命中时绘制该图像。

var can = document.getElementById('image-map');
var W = can.width;
var H = can.height;
var ctx = can.getContext('2d');
var layers = [];
var mouse = {x:0,y:0};

can.addEventListener('mousemove', function(evt) {
  mouse = getMousePos(can, evt);
  drawCanvas();
}, false);

function getMousePos(canvas, evt) {
  var rect = canvas.getBoundingClientRect();
  return {
    x: evt.clientX - rect.left,
    y: evt.clientY - rect.top
  };
}

main();

function main() {

  initLayers();
  drawCanvas();
}

function drawCanvas() {
  ctx.clearRect(0, 0, W, H);
  var hit = -1;
  for (var i =layers.length; i--;) {
    var c = layers[i];
    if(maskHit(c.img, c.x, c.y)) {
      hit = i;
      break;
    }
  }
  
  for (var i =0; i < layers.length; i++) {
    var c = layers[i];
    var img = hit === i ? c.hov : c.img;
    ctx.drawImage(img, c.x, c.y);
  }
  ctx.drawImage(circ(10,"rgba(255,200,0,.75)"), mouse.x-10/2,mouse.y-10/2);
}

// UTILITY TO DRAW SAMPLE IMAGES
function circ(size, color) {
  var can = document.createElement('canvas');
  can.width = can.height = size;
  var to_rad = Math.PI / 180;
  var ctx = can.getContext('2d');
  ctx.beginPath();
  ctx.moveTo(size, size / 2);
  ctx.arc(size / 2, size / 2, size / 2, 0, 360 * to_rad);
  ctx.fillStyle = color;
  ctx.fill();
  return can;
}

function initLayers() {
  var s = 75; // size

  // PUT YOUR IMAGES IN A LAYERS ARRAY WITH X,Y COORDS FOR CANVAS
  // PLACEMENT. X AND Y ARE TOP LEFT CORNDER OF IMAGE. STORE HOVER
  // IMAGE FOR MOUSE HIT.
  layers = [{
    img: circ(s, "#090"),
    hov: circ(s, "#C0C"),
    x: 123,
    y: 12
  }, {
    img: circ(s, "#F00"),
    hov: circ(s, "#C0C"),
    x: 63,
    y: 12
  }, {
    img: circ(s, "#00F"),
    hov: circ(s, "#C0C"),
    x: 3,
    y: 12
  }];

}

var maskCan = document.createElement("canvas");
maskCan.width=maskCan.height=1;
var maskCtx = maskCan.getContext('2d');

function maskHit(img, x, y) {
    
  // get relative coords to image upper left corner
  
  x = mouse.x - x;
  y = mouse.y - y;
  
  if (x < 0 || y < 0 || x > img.width || y > img.height) return false;

  //return 1; // square hit, no alpha check
  
  // ALPHA CHECK - draw one pixel, get and check alpha.
  //                    sx sy sw sh dx dy dw dh
  maskCtx.clearRect(0,0,1,1);
  maskCtx.drawImage(img, x, y, 1, 1, 0, 0, 1, 1);
  var imageData = maskCtx.getImageData(0,0,1,1);
  //console.log(imageData.data[3])
  return imageData.data[3] === 255;
}
#image-map {
  border: 1px solid #ACE;
}
&lt;canvas id="image-map" width="200" height="100"&gt;&lt;/canvas&gt;

【讨论】:

  • 出色的工作,感谢您主动带头开展这项工作。这种画布方法有效。您能否使用真实图像创建一个小提琴。另外,对于其他阅读者,是否也可以创建一个 SVG 替代代码?
  • 虽然这种方法并没有完全让我到达那里,但我觉得我有一个很好的框架来提出更精确的后续问题,因为我对我想要问的问题有了更多的了解。我将研究 RapahelJS + CreateJS 并形成一个更强大的问题,所以请继续关注。再次感谢!
  • @AlexanderDixon 由于跨源问题,很难在示例中显示真实的图像使用情况。当前的浏览器会将检查外部 URL 的像素数据视为安全风险,并且不允许这样做。我还没有进入图形库并在它们存在时使用本机方法。对于旧版浏览器,我会查看现代化器或一些库,它们可以为它们提供新浏览器的功能。在我看来,旧的浏览器解决方案是一个补丁,除非这是主要关注点。
猜你喜欢
  • 2013-09-03
  • 1970-01-01
  • 2017-05-07
  • 2020-11-24
  • 1970-01-01
  • 2013-08-17
  • 1970-01-01
  • 2012-03-27
  • 1970-01-01
相关资源
最近更新 更多