我有一个棘手的问题:我对我正在工作的网站有一个完整的背景。现在,我希望将div附加到图像上的某个位置,并且该div的缩放方式与我的背景图像的“background size: cover”属性的缩放方式相同。所以在这个例子中,我有一个城市的图片,它覆盖了浏览器窗口,我希望我的div覆盖在一个特定的建筑上,而不管窗口的大小。
我已经设法使div粘贴到一个位置,但不能正确地调整它的大小。到目前为止,我所做的:
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);我的想法是:如果(imageWidth / windowWidth) <1,那么设置变量Scale的值= (windowWidth / imageWidth),否则设置变量Scale ( windowHeight / imageHeight ),并使用var Scale进行转换: scale (Scale,Scale),但我无法在…中执行此操作
也许你们能帮帮我…
发布于 2016-03-12 04:41:17
用于背景的解决方案-大小:cover
我正在试着给你一个解决方案(或考虑作为一个想法)。您可以查看正在运行的演示here。调整窗口大小以查看结果。
首先,我不明白你为什么要用transform,top:50%和left:50%来做热点。所以我试着用最少的用例来解决这个问题,并且为了我的方便调整了你的标记和css。
这里rImage是原始图像的纵横比。
var imageWidth = 1920;
var imageHeight = 1368;
var h = {
x: imageWidth / 2,
y: imageHeight / 2,
height: 100,
width: 50
};
var rImage= imageWidth / imageHeight;在窗口大小调整处理程序中,计算视口r的纵横比。下一步,当我们调整窗口大小时,技巧是找到图像的尺寸。但是,视区将裁剪图像以保持纵横比。因此,为了计算图像尺寸,我们需要一些公式。
当使用background-size:cover计算图像的尺寸时,使用以下公式。
if(actual_image_aspectratio <= viewport_aspectratio)
image_width = width_of_viewport
image_height = width_ofviewport / actual_image_aspectratio 和
if(actual_image_aspectratio > viewport_aspectratio)
image_width = height_of_viewport * actual_image_aspectratio
image_height = height_of_viewport在使用background-size:cover时,您可以参考this URL了解更多关于镜像尺寸计算的内容。
在获得图像的尺寸之后,我们需要绘制从实际图像到新图像尺寸的热点坐标。
为了适合视口中的图像,图像将被裁剪到图像的顶部和底部/左侧和右侧。因此,在绘制热点时,我们应该将此裁剪图像大小作为偏移量。
offset_top=(image_height-viewport_height)/2
offset_left=(image_width-viewport_width)/2将此偏移值添加到每个热点的x,y坐标中
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>
背景大小的解决方案:包含
当使用background-size:contain计算图像的尺寸时,使用以下公式。
if(actual_image_aspectratio <= viewport_aspectratio)
image_width = height_of_viewport * actual_image_aspectratio
image_height = height_of_viewport和
if(actual_image_aspectratio > viewport_aspectratio)
image_width = width_of_viewport
image_height = width_ofviewport / actual_image_aspectratio为了使图像适合视口,将在图像的顶部和底部/左侧和右侧添加额外的空间。因此,在绘制热点时,应将此空间视为偏移量。
offset_top=(viewport_height-image_height)/2
offset_left=(viewport_width-image_width)/2将此偏移值添加到每个热点的x,y坐标中
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>
背景解决方案-大小:100% 100%
这是一个解决方案,如果有人正在寻找background-size:100% 100%检查工作演示here。调整窗口大小以查看结果。
在这里,我们不需要计算图像尺寸,因为图像将始终适合div。因此,我们可以使用视口和实际图像的height和width来计算新的热点坐标。
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>
Canvas解决方案
基于@JayMee的评论,在画布上创建一个尺寸与实际图像相同的canvas和与rectangles相同的draw热点。
这种方法的一个优点是,我们不必在调整窗口大小时重新计算热点坐标,因为热点是在图像本身中绘制的。
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>
发布于 2016-03-19 11:16:42
好吧,没有多少人知道CSS单元vh和vw (指的是ViewportHeight和ViewportWidth)。我已经创建了一个脚本,它在页面加载时运行一次(不像其他一些在每次调整大小的时运行的回答)。
它计算背景图像的比例,将两个CSS规则添加到overlayContainer中,然后就完成了。
还有一个div #square,它的目的是让我们有一个比例为1:1的容器作为画布。此比例可确保在制作覆盖元素时,垂直和水平百分比距离相同。
有关background-size: cover,请参阅this Fiddle。
有关background-size: contain,请参阅this Fiddle。
HTML:
<div id="overlayContainer">
<div id="square">
<!-- Overlaying elements here -->
</div>
</div>CSS:
#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 placing overlaying elements, make them all absolutely positioned, and work with percentages only */
/* Look at my Fiddles for examples */JavaScript (jQuery):
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'})希望这能有所帮助
由更新
我没想到会找到一个只有CSS的解决方案,尽管它就在这里,隐藏在这个答案中,因此我决定将它添加到相同的解决方案中。
通过将这两行添加到#overlayContainer规则(适用于cover和contain),就可以删除该脚本。
width: calc(100vh * (1920 / 1368));
height: calc(100vw * (1368 / 1920));当然,脚本版本具有自动获取值的优势,尽管由于热点在背景中有一个特定的位置点,因此图像大小很可能是已知的。
使用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>
发布于 2016-03-14 10:07:55
好的,所以我试着使用你最初的想法,并且只在这里和那里做了一些修改。
我发现使用像素值比使用百分比更容易。所以:
$(this).css({
'margin-top': yPos + 'px',
'margin-left': xPos + 'px',
'width': xSize + 'px',
'height': ySize + 'px'
});然后,我们要做的就是检查视口的比例,看看我们必须如何修改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;工作示例:http://codepen.io/jaimerodas/pen/RaGQVm
堆栈代码段
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>
https://stackoverflow.com/questions/35942014
复制相似问题