相对于响应/缩放图像的位置元素 [英] position element relative to responsive/scaling image

查看:39
本文介绍了相对于响应/缩放图像的位置元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想相对于响应式/缩放图像定位 html 元素,因此例如,无论图像如何缩放,一个点始终位于图像上的同一位置,在此示例中,我想无论视口的大小如何,都让点始终在她的眼睛上.这甚至可能吗?

.container {宽度:100%;高度:100%;}.img {背景图片:url("https://www.esquireme.com/public/images/2019/12/18/Kendall-Jenner-Best-Model-(3).jpg");背景重复:不重复;背景尺寸:封面;宽度:100%;高度:100%;显示:块;位置:绝对;顶部:0;底部;0;左:0;右:0;}.dot {位置:绝对;最高:34%;左:40%;宽度:10px;高度:10px;背景:蓝色;边框半径:50px;}

<div class="img"><div class="dot">

由于头部非常靠近图像的中心,我们可能可以确定始终会看到眼睛,但是在这两种情况下,我们看到由封面创建的图像(图像左侧的部分,黑色矩形中勾勒出来的)与原始的纵横比不同,因此左眼或上眼的距离百分比会发生变化,而另一个与原始保持一致.

所以我们需要做一些算术来计算 HTML 元素的新 % 偏移量应该是多少.

请注意,在此代码段中,删除了 .img 元素,并将背景放入容器中,因为 .img 似乎不需要仅用于保留背景.

const originalPercentLeft = 40;//相对于原始图像 - 如问题中所述const originalPercentTop = 29;//我重新测量了 34 把点放在离脸太远的地方const imgW = 1000;//对于这个特定的图像 - 通常会加载 img 然后找到它的纵横比const imgH = 667;功能设置(){让percentLeft = originalPercentLeft;让 percentTop = originalPercentTop;const container = document.querySelector('.container');const containerW = container.offsetWidth;const containerH = container.offsetHeight;const imgAspectRatio = imgW/imgH;const containerAspectRatio = containerW/containerH;if (imgAspectRatio > containerAspectRatio ) {//如第一张图const newImgW = imgH * containerAspectRatio;percentLeft = 100 * ( (imgW * percentLeft)/100 - (imgW - newImgW)/2 )/newImgW;}else {//如第二张图const newImgH = imgW/containerAspectRatio;percentTop = 100 * ((imgH * percentTop)/100 - (imgH - newImgH)/2 )/newImgH;}//现在我们可以定位 HTML 元素;const dot = document.querySelector('.dot');dot.style.left = percentLeft + '%';dot.style.top = percentTop + '%';}window.onresize = 设置;setup();

* {box-sizing: 边框框;边距:0;填充:0;}身体 {宽度:100vw;高度:100vh;}.容器 {宽度:100%;高度:100%;边距:0;填充:0;位置:相对;背景图片:url("https://www.esquireme.com/public/images/2019/12/18/Kendall-Jenner-Best-Model-(3).jpg");背景重复:不重复;背景尺寸:封面;背景位置:居中;}.dot {位置:绝对;宽度:10px;高度:10px;背景:蓝色;边框半径:50px;}

<div class="dot">

I'd like to position a html element relative to a responsive/scaling image, so for example a point is always in the same place on the image regardless of how the image is scaled, in this example I'd like to keep the dot always on her eye regardless of the size of the viewport. Is this even possible?

.container {
  width: 100%;
  height: 100%;
}

.img {
  background-image: url("https://www.esquireme.com/public/images/2019/12/18/Kendall-Jenner-Best-Model-(3).jpg");
  background-repeat: no-repeat;
  background-size: cover;
  width: 100%;
  height: 100%;
  display: block;
  position: absolute;
  top: 0;
  bottom;
  0;
  left: 0;
  right: 0;
}

.dot {
  position: absolute;
  top: 34%;
  left: 40%;
  width: 10px;
  height: 10px;
  background: blue;
  border-radius: 50px;
}

<div class="container">
  <div class="img">
    <div class="dot">
    </div>
  </div>
</div>
</div>

https://jsfiddle.net/3knzrq4w/1/

解决方案

We need to work out the % distances of the eye from the edge of the 'new' image. The new image is the one created by the CSS cover setting. This cuts off either the top/bottom or sides of the image so that what is left completely covers the element without distortion.

As the head is fairly near to the center of the image we can probably be sure that the eye will always be seen, but looking at these two scenarios we see that the image created by cover (the part of the image left, outlined in the black rectangle) has a different aspect ratio from the original so the % distance of one of left or top of the eye will change, the other remains as on the original.

So we need to do a bit of arithmetic to calculate what the new % offsets of the HTML element should be.

Note that in this snippet the .img element is removed and the background put onto the container as .img didn't seem necessary just to hold a background.

const originalPercentLeft = 40; // relative to the original image - as given in the question
const originalPercentTop = 29; // I remeasured as 34 put the dot too far down the face
const imgW = 1000; // for this particular image - in general would load the img then find its aspect ratio
const imgH = 667;

function setup() {
let percentLeft = originalPercentLeft;
let percentTop = originalPercentTop;

const container = document.querySelector('.container');
const containerW = container.offsetWidth;
const containerH = container.offsetHeight;
const imgAspectRatio = imgW / imgH;
const containerAspectRatio = containerW / containerH;

if (imgAspectRatio > containerAspectRatio ) { //as in the first picture
  const newImgW = imgH * containerAspectRatio;
  percentLeft = 100 * ( (imgW * percentLeft)/100 - (imgW - newImgW)/2 )/newImgW;
}
else { //as in the second picture
  const newImgH = imgW / containerAspectRatio;
  percentTop = 100 * ( (imgH * percentTop)/100 - (imgH - newImgH)/2 )/newImgH;
}
// now we can position the HTML element;
const dot = document.querySelector('.dot');
dot.style.left = percentLeft + '%';
dot.style.top = percentTop + '%';
}
window.onresize = setup;
setup();

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  width: 100vw;
  height: 100vh;
}
.container {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  position: relative;
  background-image: url("https://www.esquireme.com/public/images/2019/12/18/Kendall-Jenner-Best-Model-(3).jpg");
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center center;
}

.dot {
  position: absolute;
  width: 10px;
  height: 10px;
  background: blue;
  border-radius: 50px;
}

<div class="container">
    <div class="dot">
    </div>
</div>

这篇关于相对于响应/缩放图像的位置元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆