style full color javascript jquery html css screen-resolution

javascript - full - background-size responsive



Elemento de escala proporcional a Background Cover con jQuery (6)

A continuación se muestra una solución jQuery, el complemento bgCoverTool reposiciona un elemento basado en la escala de la imagen de fondo del padre.

//bgCoverTool Properties $(''.hot-spot'').bgCoverTool({ parent: $(''#container''), top: ''100px'', left: ''100px'', height: ''100px'', width: ''100px''})

Manifestación:

$(function() { $(''.hot-spot'').bgCoverTool(); });

html, body { height: 100%; padding: 0; margin: 0; } #container { height: 100%; width: 100%; background: url(''https://upload.wikimedia.org/wikipedia/commons/thumb/0/08/Alexanderplatz_Stadtmodell_1.jpg/1920px-Alexanderplatz_Stadtmodell_1.jpg''); background-size: cover; background-repeat: no-repeat; position: relative; } .hot-spot { position: absolute; z-index: 1; background: red; left: 980px; top: 400px; height: 40px; width: 40px; opacity: 0.7; }

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>BG Cover Tool</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script type="text/javascript" charset="utf-8"> //bgCoverTool jQuery plugin (function($) { $.bgCoverTool = function(element, options) { var $element = $(element), imgsize = {}; var defaults = { parent: $element.parent(), top: $element.css(''top''), left: $element.css(''left''), height: $element.css(''height''), width: $element.css(''width'') }; var plugin = this; plugin.settings = {}; plugin.init = function() { plugin.settings = $.extend({}, defaults, options); var tempurl = plugin.settings.parent.css(''background-image'').slice(4, -1) .replace(''"'', '''').replace(''"'', ''''); var tempimg = new Image(); var console = console || { error: function() {} }; if (plugin.settings.parent.css(''background-size'') != "cover") { return false; } if (typeof tempurl !== "string") { return false; } if (plugin.settings.top == "auto" || plugin.settings.left == "auto") { console.error("#" + $element.attr(''id'') + " needs CSS values for ''top'' and ''left''"); return false; } $(tempimg).on(''load'', function() { imgsize.width = this.width; imgsize.height = this.height; imageSizeDetected(imgsize.width, imgsize.height); }); $(window).on(''resize'', function() { if (''width'' in imgsize && imgsize.width != 0) { imageSizeDetected(imgsize.width, imgsize.height); } }); tempimg.src = tempurl; }; var imageSizeDetected = function(w, h) { var scale_h = plugin.settings.parent.width() / w, scale_v = plugin.settings.parent.height() / h, scale = scale_h > scale_v ? scale_h : scale_v; $element.css({ top: parseInt(plugin.settings.top, 10) * scale, left: parseInt(plugin.settings.left, 10) * scale, height: parseInt(plugin.settings.height, 10) * scale, width: parseInt(plugin.settings.width, 10) * scale }); }; plugin.init(); }; /** * @param {options} object Three optional properties are parent, top and left. */ $.fn.bgCoverTool = function(options) { return this.each(function() { if (undefined == $(this).data(''bgCoverTool'')) { var plugin = new $.bgCoverTool(this, options); $(this).data(''bgCoverTool'', plugin); } }); } })(jQuery); </script> </head> <body> <div id="container"> <div class="hot-spot"></div> </div> </body> </html>

Tengo una pregunta difícil: tengo un fondo completo sobre el sitio en el que estoy trabajando. Ahora quiero adjuntar un div a cierta posición en la imagen y también que el div se escala de la misma manera que la imagen de fondo con la propiedad "background-size: cover". Entonces en este ejemplo, tengo una imagen de una ciudad, que cubre la ventana del navegador y quiero que mi div se superponga a un edificio en particular, sin importar el tamaño de la ventana.

Ya logré hacer que el div se quedara en una posición, pero no puedo ajustar el tamaño correctamente. Lo que hice hasta ahora

http://codepen.io/EmmieBln/pen/YqWaYZ

var imageWidth = 1920, imageHeight = 1368, imageAspectRatio = imageWidth / imageHeight, $window = $(window); var hotSpots = [{ ''x'': -160, ''y'': -20, ''height'': 400, ''width'': 300 }]; function appendHotSpots() { for (var i = 0; i < hotSpots.length; i++) { var $hotSpot = $(''<div>'').addClass(''hot-spot''); $(''.container'').append($hotSpot); } positionHotSpots(); } function positionHotSpots() { var windowWidth = $window.width(), windowHeight = $window.height(), windowAspectRatio = windowWidth / windowHeight, $hotSpot = $(''.hot-spot''); $hotSpot.each(function(index) { var xPos = hotSpots[index][''x''], yPos = hotSpots[index][''y''], xSize = hotSpots[index][''width''], ySize = hotSpots[index][''height''], desiredLeft = 0, desiredTop = 0; if (windowAspectRatio > imageAspectRatio) { yPos = (yPos / imageHeight) * 100; xPos = (xPos / imageWidth) * 100; xSize = (xSize / imageWidth) * 1000; ySize = (ySize / imageHeight) * 1000; } else { yPos = ((yPos / (windowAspectRatio / imageAspectRatio)) / imageHeight) * 100; xPos = ((xPos / (windowAspectRatio / imageAspectRatio)) / imageWidth) * 100; } $(this).css({ ''margin-top'': yPos + ''%'', ''margin-left'': xPos + ''%'', ''width'': xSize + ''px'', ''height'': ySize + ''px'' }); }); } appendHotSpots(); $(window).resize(positionHotSpots);

Mi idea era: If (imageWidth / windowWidth) <1 luego establecer Valor para var Scale = (windowWidth / imageWidth) else var Scale (windowHeight / imageHeight) y usar var Scale para transform: scale (Scale, Scale) pero no pude lograr que esto funcione ...

Tal vez ustedes podrían ayudarme ...


Confiar en las transformaciones de css y aplicarlo a un solo elemento le proporciona un rendimiento mucho mejor independientemente de la cantidad de puntos de acceso (menos manipulaciones DOM y muchos menos re-flujos). La aceleración de hardware también es agradable :)

Primero, meta-código:

  1. Crea un .hot-spot--container dentro de tu imagen .container

  2. Cree .hot-spot y .hot-spot / .hot-spot--container dentro del .hot-spot--container

  3. Transformar .hot-spot--container imita el background-size: cover comportamiento de la background-size: cover

  4. Repite # 3 cada vez que hay un tamaño

Calcule su relación de imagen bg:

var bgHeight = 1368; var bgWidth = 1920; var bgRatio = bgHeight / bgWidth;

Cada vez que se vuelva a dimensionar la ventana, vuelva a calcular la proporción de contenedores:

var containerHeight = $container.height(); var containerWidth = $container.width(); var containerRatio = containerHeight / containerWidth;

Calcule los factores de escala para imitar background-size: cover comportamiento de background-size: cover ...

if (containerRatio > bgRatio) { //fgHeight = containerHeight //fgWidth = containerHeight / bgRatio xScale = (containerHeight / bgRatio) / containerWidth } else { //fgHeight = containerWidth / bgRatio //fgWidth = containerWidth yScale = (containerWidth * bgRatio) / containerHeight }

... y aplicar la transformación al elemento contenedor de zonas activas, esencialmente redimensionándola y reposicionándola "en sincronización" con el fondo:

var transform = ''scale('' + xScale + '', '' + yScale + '')''; $hotSpotContainer.css({ ''transform'': transform });

Fiddled: https://jsfiddle.net/ovfiddle/a3pdLodm/ (puede jugar con la ventana de vista previa con bastante eficacia. Tenga en cuenta que el código se puede ajustar para tomar las dimensiones basadas en píxeles y el posicionamiento de los puntos críticos, solo tendrá que considerar tamaños de contenedor e imagen al calcular los valores de escala)

Actualización: el comportamiento background-size: contain usa el mismo cálculo, excepto cuando el containerRatio es más pequeño que el bgRatio. Actualizar el CSS de fondo y darle la vuelta al letrero es suficiente .


De acuerdo, muchas personas no conocen las medidas de CSS vh y vw (es decir, viewheight y viewwidth). Creé una secuencia de comandos que se ejecuta una vez en la carga de página (a diferencia de otras respuestas con ~ 50 líneas de código en cada cambio de tamaño ).

Calcula la proporción de la imagen de fondo, aplica dos piezas de CSS a overlayContainer , y está hecho.

También agregué un div con un square identificación. Todo lo que hace es crear un cuadrado para que trabajes con una proporción de 1: 1, en lugar de la proporción que tiene el fondo. Esto garantiza que, si desea crear un cuadrado, puede usar el mismo ancho y alto, en lugar de intentar crear uno con valores diferentes. Esto también es útil cuando modificas ligeramente el tamaño de la imagen de fondo, porque con ese cuadrado, tus divs superpuestos no perderán su relación de aspecto.

Para el background-size: cover , ver este violín .

Para el background-size: contain , ver este violín .

El HTML necesario:

<div id="overlayContainer"> <div id="square"> <!-- Create overlay divs here --> </div> </div>

El CSS necesitaba:

#overlayContainer{ position: absolute; /* Fixed if the background-image is also fixed */ min-width: 100vw; /* When cover is applied */ min-height: 100vh; /* When cover is applied */ max-width: 100vw; /* When contain is applied */ max-height: 100vh; /* When contain is applied */ top: 50%; left: 50%; transform: translate(-50%, -50%); } #square{ position: relative; padding-bottom: 100%; } /* When creating divs, make them all absolutely positioned, and work with percentages only */ /* I advise looking at my Fiddle for an example */

El JavaScript necesario:

var image = new Image() image.src = $(''body'').css(''background-image'').replace(/url/(([''"])?(.*?)/1/)/gi,''$2'').split('','')[0] /* When cover is applied, use this: */ $(''#overlayContainer'').css({''height'':100/(image.width/image.height)+''vw'',''width'':100/(image.height/image.width)+''vh''}) /* When contain is applied, use this: */ $(''#overlayContainer'').css({''height'':100*(image.height/image.width)+''vw'',''width'':100*(image.width/image.height)+''vh''})

Espero que esto ayude

Actualización por @LGSon

No esperaba encontrar una solución de CSS única , aunque aquí está, ocultándose en esta respuesta, y por lo tanto, decidí agregarla a la misma.

Al agregar estas 2 líneas a la regla #overlayContainer (funciona tanto para la cover como para contain ), la secuencia de comandos se puede descartar.

width: calc(100vh * (1920 / 1368)); height: calc(100vw * (1368 / 1920));

Por supuesto, la versión de script tiene la ventaja de obtener automáticamente los valores, aunque debido a que los puntos de acceso tienen un punto de ubicación específico en el fondo, es muy probable que se conozca el tamaño de la imagen.

Muestra con background-size: cover

html, body{ height: 100%; overflow: hidden; } body{ margin: 0; background-image: url(''https://upload.wikimedia.org/wikipedia/commons/thumb/0/08/Alexanderplatz_Stadtmodell_1.jpg/1920px-Alexanderplatz_Stadtmodell_1.jpg''); background-size: cover; background-repeat: no-repeat; background-position: center; } #overlayContainer{ position: absolute; width: calc(100vh * (1920 / 1368)); height: calc(100vw * (1368 / 1920)); min-width: 100vw; /* for cover */ min-height: 100vh; /* for cover */ /* max-width: 100vw; for contain */ /* max-height: 100vh; for contain */ top: 50%; left: 50%; transform: translate(-50%, -50%); } #square{ position: relative; padding-bottom: 100%; } #square div{ position: absolute; top: 19.75%; left: 49.75%; width: 4.75%; height: 4.75%; background-color: rgba(255,0,0,.7); border-radius: 50%; }

<div id="overlayContainer"> <div id="square"> <div></div> </div> </div>


Ok, intenté usar tu idea original y modifiqué solo algunas partes aquí y allá.

En lugar de usar porcentajes, me resultó más fácil usar valores de píxeles. Asi que:

$(this).css({ ''margin-top'': yPos + ''px'', ''margin-left'': xPos + ''px'', ''width'': xSize + ''px'', ''height'': ySize + ''px'' });

Entonces, todo lo que tenemos que hacer es verificar la proporción de la ventana gráfica para ver cómo tenemos que modificar las propiedades del div .

if (windowAspectRatio > imageAspectRatio) { var ratio = windowWidth / imageWidth; } else { var ratio = windowHeight / imageHeight; } xPos = xPos * ratio; yPos = yPos * ratio; xSize = xSize * ratio; ySize = ySize * ratio;

Ejemplo de trabajo: http://codepen.io/jaimerodas/pen/RaGQVm

Fragmento de pila

var imageWidth = 1920, imageHeight = 1368, imageAspectRatio = imageWidth / imageHeight, $window = $(window); var hotSpots = [{ x: -210, y: -150, height: 250, width: 120 }, { x: 240, y: 75, height: 85, width: 175 }]; function appendHotSpots() { for (var i = 0; i < hotSpots.length; i++) { var $hotSpot = $(''<div>'').addClass(''hot-spot''); $(''.container'').append($hotSpot); } positionHotSpots(); } function positionHotSpots() { var windowWidth = $window.width(), windowHeight = $window.height(), windowAspectRatio = windowWidth / windowHeight, $hotSpot = $(''.hot-spot''); $hotSpot.each(function(index) { var cambio = 1, xPos = hotSpots[index][''x''], yPos = hotSpots[index][''y''], xSize = hotSpots[index][''width''], ySize = hotSpots[index][''height''], desiredLeft = 0, desiredTop = 0; if (windowAspectRatio > imageAspectRatio) { var ratio = windowWidth / imageWidth; } else { var ratio = windowHeight / imageHeight; } xPos = xPos * ratio; yPos = yPos * ratio; xSize = xSize * ratio; ySize = ySize * ratio; $(this).css({ ''margin-top'': yPos + ''px'', ''margin-left'': xPos + ''px'', ''width'': xSize + ''px'', ''height'': ySize + ''px'' }); }); } appendHotSpots(); $(window).resize(positionHotSpots);

html, body { margin: 0; width: 100%; height: 100%; } .container { width: 100%; height: 100%; position: relative; background-image: url(https://upload.wikimedia.org/wikipedia/commons/thumb/0/08/Alexanderplatz_Stadtmodell_1.jpg/1920px-Alexanderplatz_Stadtmodell_1.jpg); background-size: cover; background-repeat: no-repeat; background-position: center; } .hot-spot { background-color: red; border-radius: 0; position: absolute; top: 50%; left: 50%; z-index: 1; opacity: 0.8; content: ""; }

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="container"></div>


Un enfoque mucho más simple / mejor para su problema es usar un elemento SVG, que se adapta mejor a sus necesidades. Lo bueno de SVG es que todo se escalará proporcionalmente de forma predeterminada porque es un objeto vectorial, no un objeto de flujo de documentos.

Este ejemplo demostrará la técnica

<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>SVG</title> <style type="text/css" media="screen"> body { background: #eee; margin: 0; } svg { display: block; border: 1px solid #ccc; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: #fff; } .face { stroke: #000; stroke-width: 20px; stroke-linecap: round } </style> </head> <body> <svg xmlns="http://www.w3.org/2000/svg" viewBox="-350 -250 700 500"> <circle r="200" class="face" fill="red"/> <path fill="none" class="face" transform="translate(-396,-230)" d="M487.41,282.411c-15.07,36.137-50.735,61.537-92.333,61.537 c-41.421,0-76.961-25.185-92.142-61.076"/> <circle id="leftEye" cx="-60" cy="-50" r="20" fill="#00F"/> <circle id="rightEye" cx="60" cy="-50" r="20" fill="#00F"/> </svg> <script type="text/javascript"> document.getElementById(''leftEye'').addEventListener(''mouseover'', function (e) { alert(''Left Eye''); }); document.getElementById(''rightEye'').addEventListener(''mouseover'', function (e) { alert(''Right Eye''); }); </script> </body> </html>

Puede agregar imágenes a SVG para lograr lo que necesita.

https://jsfiddle.net/tnt1/3f23amue/


Solución para el fondo de pantalla: cubierta

Estoy tratando de darte una solución (o considerarla como una idea). Puede consultar la demostración de trabajo here . Cambiar el tamaño de la ventana para ver el resultado.

En primer lugar, no entendí por qué está utilizando transform , top:50% y a la left:50% para zona activa. Así que traté de resolver esto usando un mínimo de uso y ajustando su marcado y CSS para mi conveniencia.

Aquí rImage es la relación de aspecto de la imagen original.

var imageWidth = 1920; var imageHeight = 1368; var h = { x: imageWidth / 2, y: imageHeight / 2, height: 100, width: 50 }; var rImage= imageWidth / imageHeight;

En el controlador de cambio de tamaño de ventana, calcule la relación de aspecto de la ventana gráfica r . A continuación, el truco es encontrar las dimensiones de la imagen cuando cambiamos el tamaño de la ventana. Pero, la ventana gráfica recortará la imagen para mantener la relación de aspecto. Entonces, para calcular las dimensiones de la imagen, necesitamos alguna fórmula.

Cuando se utiliza el background-size:cover para calcular las dimensiones de la imagen, a continuación se utilizan las fórmulas.

if(actual_image_aspectratio <= viewport_aspectratio) image_width = width_of_viewport image_height = width_ofviewport / actual_image_aspectratio

Y

if(actual_image_aspectratio > viewport_aspectratio) image_width = height_of_viewport * actual_image_aspectratio image_height = height_of_viewport

Puede consultar esta URL para obtener más información sobre el cálculo de las dimensiones de la imagen al usar background-size:cover .

Después de obtener las dimensiones de la imagen, debemos trazar las coordenadas del punto caliente de la imagen real a las nuevas dimensiones de la imagen.

Para ajustar la imagen en la imagen de la ventana gráfica, se recortará en la parte superior e inferior / izquierda y derecha de la imagen. Por lo tanto, debemos considerar este tamaño de imagen recortada como un desplazamiento al trazar puntos de acceso.

offset_top=(image_height-viewport_height)/2 offset_left=(image_width-viewport_width)/2

agregue estos valores de desplazamiento a las coordenadas x,y cada punto de acceso

var imageWidth = 1920; var imageHeight = 1368; var hotspots = [{ x: 100, y: 200, height: 100, width: 50 }, { x: 300, y: 500, height: 200, width: 100 }, { x: 600, y: 600, height: 150, width: 100 }, { x: 900, y: 550, height: 100, width: 25 }]; var aspectRatio = imageWidth / imageHeight; $(window).resize(function() { positionHotSpots(); }); var positionHotSpots = function() { $(''.hotspot'').remove(); var wi = 0, hi = 0; var r = $(''#image'').width() / $(''#image'').height(); if (aspectRatio <= r) { wi = $(''#image'').width(); hi = $(''#image'').width() / aspectRatio; } else { wi = $(''#image'').height() * aspectRatio; hi = $(''#image'').height(); } var offsetTop = (hi - $(''#image'').height()) / 2; var offsetLeft = (wi - $(''#image'').width()) / 2; $.each(hotspots, function(i, h) { var x = (wi * h.x) / imageWidth; var y = (hi * h.y) / imageHeight; var ww = (wi * (h.width)) / imageWidth; var hh = (hi * (h.height)) / imageHeight; var hotspot = $(''<div>'').addClass(''hotspot'').css({ top: y - offsetTop, left: x - offsetLeft, height: hh, width: ww }); $(''body'').append(hotspot); }); }; positionHotSpots();

html, body { height: 100%; padding: 0; margin: 0; } #image { height: 100%; width: 100%; background: url(''https://upload.wikimedia.org/wikipedia/commons/thumb/0/08/Alexanderplatz_Stadtmodell_1.jpg/1920px-Alexanderplatz_Stadtmodell_1.jpg''); background-size: cover; background-repeat: no-repeat; background-position: center; } .hotspot { position: absolute; z-index: 1; background: red; }

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id=''image''></div>

Solución para el fondo de pantalla: contener

Cuando se usa background-size:contain para calcular las dimensiones de la imagen, a continuación se usan las fórmulas.

if(actual_image_aspectratio <= viewport_aspectratio) image_width = height_of_viewport * actual_image_aspectratio image_height = height_of_viewport

Y

if(actual_image_aspectratio > viewport_aspectratio) image_width = width_of_viewport image_height = width_ofviewport / actual_image_aspectratio

Para ajustar la imagen en la ventana gráfica, se agregará espacio adicional en la parte superior e inferior / izquierda y derecha de la imagen. Por lo tanto, deberíamos considerar este espacio como un desplazamiento al trazar hotspots.

offset_top=(viewport_height-image_height)/2 offset_left=(viewport_width-image_width)/2

Agregue estos valores de desplazamiento a cada x,y coordina de la zona activa

var imageWidth = 1920; var imageHeight = 1368; var hotspots = [{ x: 100, y: 200, height: 100, width: 50 }, { x: 300, y: 500, height: 200, width: 100 }, { x: 600, y: 600, height: 150, width: 100 }, { x: 900, y: 550, height: 100, width: 25 }]; var aspectRatio = imageWidth / imageHeight; $(window).resize(function() { positionHotSpots(); }); var positionHotSpots = function() { $(''.hotspot'').remove(); var wi = 0, hi = 0; var r = $(''#image'').width() / $(''#image'').height(); if (aspectRatio <= r) { wi = $(''#image'').height() * aspectRatio; hi = $(''#image'').height(); } else { wi = $(''#image'').width(); hi = $(''#image'').width() / aspectRatio; } var offsetTop = ($(''#image'').height() - hi) / 2; var offsetLeft = ($(''#image'').width() - wi) / 2; $.each(hotspots, function(i, h) { var x = (wi * h.x) / imageWidth; var y = (hi * h.y) / imageHeight; var ww = (wi * (h.width)) / imageWidth; var hh = (hi * (h.height)) / imageHeight; var hotspot = $(''<div>'').addClass(''hotspot'').css({ top: y + offsetTop, left: x + offsetLeft, height: hh, width: ww }); $(''body'').append(hotspot); }); }; positionHotSpots();

html, body { height: 100%; padding: 0; margin: 0; } #image { height: 100%; width: 100%; background: url(''https://upload.wikimedia.org/wikipedia/commons/thumb/0/08/Alexanderplatz_Stadtmodell_1.jpg/1920px-Alexanderplatz_Stadtmodell_1.jpg''); background-size: contain; background-repeat: no-repeat; background-position: center; } .hotspot { position: absolute; z-index: 1; background: red; }

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id=''image''></div>

Solución para el tamaño de fondo: 100% 100%

Esta es la solución si alguien está buscando background-size:100% 100% revise la demostración de trabajo here . Cambiar el tamaño de la ventana para ver el resultado.

Aquí no es necesario que calculemos las dimensiones de la imagen ya que la imagen siempre encajará en el div. Así que podemos simplemente calcular las nuevas coordenadas del punto de acceso utilizando la height y el width de la ventana gráfica y la imagen actual.

var imageWidth = 1920; var imageHeight = 1368; var hotspots = [{ x: 100, y: 200, height: 100, width: 50 }, { x: 300, y: 500, height: 200, width: 100 }, { x: 600, y: 600, height: 150, width: 100 }, { x: 900, y: 550, height: 100, width: 25 }]; $(window).resize(function() { positionHotSpots(); }); var positionHotSpots = function() { $(''.hotspot'').remove(); $.each(hotspots, function(i, h) { var x = ($(''#image'').width() * h.x) / imageWidth; var y = ($(''#image'').height() * h.y) / imageHeight; var ww = ($(''#image'').width() * (h.width)) / imageWidth; var hh = ($(''#image'').height() * (h.height)) / imageHeight; var hotspot = $(''<div>'').addClass(''hotspot'').css({ top: y, left: x, height: hh, width: ww }); $(''body'').append(hotspot); }); }; positionHotSpots();

html, body { height: 100%; margin: 0; padding: 0; } #image { height: 100%; width: 100%; background: url(''https://upload.wikimedia.org/wikipedia/commons/thumb/0/08/Alexanderplatz_Stadtmodell_1.jpg/1920px-Alexanderplatz_Stadtmodell_1.jpg''); background-size: 100% 100%; } .hotspot { position: absolute; z-index: 1; background: red; }

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id=''image''></div>

Solución de lienzo

Según el comentario de @JayMee, cree un canvas con las mismas dimensiones que la imagen real y draw zonas interactivas como rectangles en el lienzo.

Una ventaja de este enfoque es que no tenemos que volver a calcular las coordenadas del punto de acceso en la ventana de cambio de tamaño ya que el punto de acceso se dibuja en la imagen misma.

var imageWidth = 1920; var imageHeight = 1368; var hotspots = [{ x: 100, y: 200, height: 100, width: 50 }, { x: 300, y: 500, height: 200, width: 100 }, { x: 600, y: 600, height: 150, width: 100 }, { x: 900, y: 550, height: 100, width: 25 }]; var positionHotSpots = function() { var canvas = document.createElement(''canvas''); canvas.height = imageHeight; canvas.width = imageWidth; var context = canvas.getContext(''2d''); var imageObj = new Image(); imageObj.onload = function() { context.drawImage(imageObj, 0, 0); $.each(hotspots, function(i, h) { context.rect(h.x, h.y, h.width, h.height); }); context.fillStyle = "red"; context.fill(); $(''#image'').css(''background-image'', ''url("'' + canvas.toDataURL() + ''")''); }; imageObj.setAttribute(''crossOrigin'', ''anonymous''); imageObj.src = ''https://upload.wikimedia.org/wikipedia/commons/thumb/0/08/Alexanderplatz_Stadtmodell_1.jpg/1920px-Alexanderplatz_Stadtmodell_1.jpg''; }; positionHotSpots();

html, body { height: 100%; padding: 0; margin: 0; } #image { height: 100%; width: 100%; background-size: cover; background-repeat: no-repeat; background-position: center; }

<!DOCTYPE html> <html> <head> <script src="https://code.jquery.com/jquery-2.1.4.js"></script> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>JS Bin</title> </head> <body> <div id=''image''></div> </body> </html>