imageMapResizer.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*! Image Map Resizer
  2. * Desc: Resize HTML imageMap to scaled image.
  3. * Copyright: (c) 2014 David J. Bradshaw - dave@bradshaw.net
  4. * License: MIT
  5. */
  6. (function(){
  7. 'use strict';
  8. function scaleImageMap(){
  9. function resizeMap() {
  10. function resizeAreaTag(cachedAreaCoords){
  11. function scaleCoord(e){
  12. return e * scallingFactor[(1===(isWidth = 1-isWidth) ? 'width' : 'height')];
  13. }
  14. var isWidth = 0;
  15. return cachedAreaCoords.split(',').map(Number).map(scaleCoord).map(Math.floor).join(',');
  16. }
  17. var scallingFactor = {
  18. width : displayedImage.width / sourceImage.width,
  19. height : displayedImage.height / sourceImage.height
  20. };
  21. for (var i=0; i < areasLen ; i++) {
  22. areas[i].coords = resizeAreaTag(cachedAreaCoordsArray[i]);
  23. }
  24. }
  25. function start(){
  26. var
  27. displayedWidth = null,
  28. displayedHeight = null;
  29. //WebKit asyncs image loading, so we have to catch the load event.
  30. sourceImage.onload = function sourceImageOnLoadF(){
  31. displayedWidth = displayedImage.width;
  32. displayedHeight = displayedImage.height;
  33. if ((displayedWidth !== sourceImage.width) || (displayedHeight !== sourceImage.height)) {
  34. resizeMap();
  35. }
  36. };
  37. //IE11 can late load this image, so make sure we have the correct sizes (#10)
  38. displayedImage.onload = function() {
  39. if (null !== displayedWidth && displayedImage.width !== displayedWidth) {
  40. resizeMap();
  41. }
  42. };
  43. //Make copy of image, so we can get the actual size measurements
  44. sourceImage.src = displayedImage.src;
  45. }
  46. function listenForResize(){
  47. function debounce() {
  48. clearTimeout(timer);
  49. timer = setTimeout(resizeMap, 250);
  50. }
  51. if (window.addEventListener) { window.addEventListener('resize', debounce, false); }
  52. else if (window.attachEvent) { window.attachEvent('onresize', debounce); }
  53. }
  54. function getCoords(e){
  55. // normalize coord-string to csv format without any space chars
  56. return e.coords.replace(/ *, */g,',').replace(/ +/g,',');
  57. }
  58. var
  59. /*jshint validthis:true */
  60. map = this,
  61. areas = map.getElementsByTagName('area'),
  62. areasLen = areas.length,
  63. cachedAreaCoordsArray = Array.prototype.map.call(areas, getCoords),
  64. displayedImage = document.querySelector('img[usemap="#'+map.name+'"]'),
  65. sourceImage = new Image(),
  66. timer = null;
  67. start();
  68. listenForResize();
  69. }
  70. function factory(){
  71. function init(element){
  72. if(!element.tagName) {
  73. throw new TypeError('Object is not a valid DOM element');
  74. } else if ('MAP' !== element.tagName.toUpperCase()) {
  75. throw new TypeError('Expected <MAP> tag, found <'+element.tagName+'>.');
  76. }
  77. scaleImageMap.call(element);
  78. }
  79. return function imageMapResizeF(target){
  80. switch (typeof(target)){
  81. case 'undefined':
  82. case 'string':
  83. Array.prototype.forEach.call(document.querySelectorAll(target||'map'),init);
  84. break;
  85. case 'object':
  86. init(target);
  87. break;
  88. default:
  89. throw new TypeError('Unexpected data type ('+typeof(target)+').');
  90. }
  91. };
  92. }
  93. if (typeof define === 'function' && define.amd) {
  94. define([],factory);
  95. } else if (typeof exports === 'object') { //Node for browserfy
  96. module.exports = factory();
  97. } else {
  98. window.imageMapResize = factory();
  99. }
  100. if('jQuery' in window) {
  101. jQuery.fn.imageMapResize = function $imageMapResizeF(){
  102. return this.filter('map').each(scaleImageMap).end();
  103. };
  104. }
  105. })();