How to scale div's contents with the div? - javascript

I have a parent div that contains an image with a bunch of "holes" in it. I have a child div for each hole that defines the exact size of those holes. In the holes, I have text that I've set to position:absolute so that they fit exactly in the holes. However, when I resize the parent div, the contents don't scale at all and they stay the same size. They're also not inside the holes anymore.

User '%' as a unit instead of pixel
<div id="ParentDiv">
<img src="../610614-spring-forest.jpg">
<div class="hole1">Tree1</div>
</div>
#ParentDiv{
max-width:900px;
position: relative;
}
img{
width: 100%;
height: auto;
}
.hole1{
position: absolute;
left:2.75%;
top:23.87%;
}
You can use Viewport Hieght or Viewport Width unit for that case. Below is the example how you could use.
#ParentDiv{
max-width:100vw;
max-height:100vh;
position: relative;
}
img{
width: 100%;
height: auto;
}
.hole1{
position: absolute;
/*left:2.75%;
top:23.87%;*/
left:2.75vw;
top:23.87vh;
}
Try to use similar, hope you will get the desired result.

You could use a CSS property called transform instead of directly changing the size.
When you need to set the size of the image:
// this is the container the image and its text is in
imageContainer = document.getElementById('myDiv');
// original size of image
origX = 400;
origY = 300;
// size you need it to change to
newX = 800;
newY = 600;
/*
Tells CSS to stretch from the top-left edge of the object, so it won't stretch off the left side of the screen
Best way to change value would be percentages
Value of '0 0' sets origin to top-left
Value of '100% 100%' sets origin to bottom-right
*/
imageContainer.style.transformOrigin = '0 0';
//the following is just one string, broken into multiple lines for easy explanation
// tells CSS that the transform type is scale
imageContainer.style.transform = 'scale(' +
// tells CSS how many times normal size to widen image. in this case evaluates to 2, since 800/400 is 2, making image 2x wider
(newX / origX) + ',' +
// tells CSS how many times normal size to heighten image. in this case evaluates to 2, since 600/300 is 2, making image 2x taller
(newY / origY) + ')';
Assuming you have no major performance-sapping functions, this will work great. It's just a little slow if you have loads of stuff going on.
Uncommented:
imageContainer = document.getElementById('myDiv');
origX = 400;
origY = 300;
newX = 800;
newY = 600;
imageContainer.style.transformOrigin = '0 0';
imageContainer.style.transform = 'scale(' + (newX / origX) + ',' (newY / origY) + ')';

Related

Change element dimensions with the ratio another element changed with

In this example:
Fiddle Example
I have a Picture with dimensions 835x470, That image is added to 2 elements, A hidden <img> and as a background to a <div> width class wrapper, I set the <div> dimensions to smaller dimensions 519x220 on my screen.
There is a centered circular element on the <div> with the dimensions 100x100, I want to set these dimensions with the same ratio the image changed from 835x470 to 519x220.
So for example if the circle on the original image 835x470 was 200x200, When the <div> dimensions are set/changed to 519x220, The circle would take the same space it took on the original image, Which were 200x200.
So if the 200x200 represented 15% for example from the 835x470, Then the circle would take the same 15% from the new dimensions 519x220
What I tried to do is that I get the natural dimensions of the image 835x470 and get the new dimension of the image 519x220 and divide each dimension to get a ratio, Then check to get the smallest ratio (Not to make the circle be out of the image), Then multiply this ratio by 200 and set it as width and height of the image.
Here is the code:
//Get natural dimensions from the hidden image.
var imgNaturalHeight = document.getElementById('img').naturalHeight,
imgNaturalWidth = document.getElementById('img').naturalWidth,
//Get new dimensions from the wrapper that has the image as a background.
imgNewHeight = document.querySelector('.wrapper').height,
imgNewWidth = document.querySelector('.wrapper').width,
//Get height and width ratios.
widthRatio = imgNewWidth / imgNaturalWidth,
heightRatio = imgNewHeight / imgNaturalHeight,
//Define ratio variable.
ratio;
//Set ratio to the smallest ratio.
if ( widthRatio < heightRatio ) {
ratio = widthRatio;
}else{
ratio = heightRatio;
}
//The new value for width and height
var fixed = ratio * 200;
//Set the new width and height of the circle.
document.querySelector('.overlay').style.width = fixed;
document.querySelector('.overlay').style.height = fixed;
.wrapper{
position: relative;
background: url('https://raw.githubusercontent.com/fengyuanchen/cropperjs/master/docs/images/picture.jpg');
height:220px;
background-repeat: no-repeat;
background-size: 100%;
}
.overlay{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
background: rgba(0,0,0,0.4);
border-radius: 50%;
width: 100px;
height: 100px;
}
.image{
display:none;
}
<div class="wrapper">
<div class="overlay"></div>
</div>
<img id="img" class="image" src="https://raw.githubusercontent.com/fengyuanchen/cropperjs/master/docs/images/picture.jpg" >
I hope I made it clear.
So that it takes the same space it took on the original image, Which were 200x200.
Try to follow this steps:
calculate ratio of new to old image with and height
multiply original circle dimensions by its ratio
This should do the trick.
There is some example (maybe not exactly your case but I hope you can adapt it easily).
Example
Note: Im not so sure what you try to achieve in pure JS so I used clientHeight property, you can read about other possibilities here Height and width in JS
//Get natural dimensions from the hidden image.
var imgNaturalHeight = document.getElementById('img').naturalHeight,
imgNaturalWidth = document.getElementById('img').naturalWidth,
//Get new dimensions from the wrapper that has the image as a background.
imgNewHeight = document.querySelector('.wrapper').clientHeight,
imgNewWidth = document.querySelector('.wrapper').clientWidth,
//Get height and width ratios.
widthRatio = imgNewWidth / imgNaturalWidth,
heightRatio = imgNewHeight / imgNaturalHeight,
//Define ratio variable.
ratio;
//Set ratio to the smallest ratio.
if ( widthRatio < heightRatio ) {
ratio = widthRatio;
}else{
ratio = heightRatio;
}
//The new value for width and height
var fixed = ratio * 200;
//Set the new width and height of the circle.
document.querySelector('.overlay').style.width = fixed + "px";
document.querySelector('.overlay').style.height = fixed + "px"

Using getComputedStyle with border-box should return height sans border and padding

EDIT 3/Final: Th Computed Style problem/question is explained below but, for the benefit of others coming later, my real problem is solved with Flex Boxes and Vx measurements in conjunction with border-box. IMHO "display: flex;" is the answer to many questions and, although I'm struggling to get it to do what I want, stops you having to work against CSS!
EDIT 2: The following undoubtedly needs refactoring but if you can tell me that it does what I was asking for that'd be great. The change I had to make was to add clientTop in with offsetTop in the equation: -
function resizeContent()
{
var browserHeight = window.outerHeight;
var offesetHeight, offsetWidth;
var viewHeight = window.innerHeight;
var viewWidth = window.innerWidth;
var chromeFootPrint = browserHeight - viewHeight;
var tmpHeight = viewHeight;
if (window.matchMedia("(orientation: portrait)").matches) {
if (viewWidth > viewHeight) {
viewHeight = viewWidth - chromeFootPrint;
viewWidth = tmpHeight + chromeFootPrint;
}
} else {
if (viewWidth < viewHeight) {
viewHeight = viewWidth - chromeFootPrint;
viewWidth = tmpHeight + chromeFootPrint;
}
}
var dimTarget = logScroll;
var offsetTop = dimTarget.offsetTop + dimTarget.clientTop;
var offsetLeft = dimTarget.offsetLeft + dimTarget.clientLeft;
while (dimTarget = dimTarget.offsetParent) {
offsetTop += dimTarget.offsetTop + dimTarget.clientTop;
offsetLeft += dimTarget.offsetLeft + dimTarget.clientLeft;
}
logScrollHeight = viewHeight - (offsetTop + fireBreak);
logScroll.style.height = logScrollHeight + "px";
logScroll.style.width = getStyle(contentDiv).width;
logWindow.style.height = logScroll.style.height;
logWindow.style.width = logScroll.style.width;
logWindow.scrollTop = logWindow.scrollHeight - logScrollHeight;
contentDiv.style.visibility = "visible"; // Now we're presentable
}
and this is the fire-break calculation: -
var outerStyle = getStyle(wholeScreen);
fireBreak = Number(outerStyle.paddingBottom.match("[0-9.]*"))
+ Number(outerStyle.borderBottomWidth.match("[0-9.]*"))
;
resizeContent();
EDIT 1: Ok, let me re-phrase the question: - How to I find out the height of my DIVs content with: -
width: 250px;
border: 3px solid green;
padding: 0.5em;
box-sizing: border-box;
I am currently having to do this: -
logScrollHeight = viewHeight -
(offsetTop + Number(getStyle(headerDiv).paddingBottom.match("[0-9.]*")));
Original question: -
This is bound to be a duplicate but after nearly an hour of looking I have found many similar/identical questions but no real answer :-(
Why aren't the boundryWith and padding deducted from height?
Thankfully the boundryBottomWidth and PaddingBottom return have been converted to pixels (including the "px" string sadly) but doesn't the standard say that the usable height should be returned?
To get the height of an element, you don't use getComputedStyle.
getComputedStyle should only be used to get the parsed values that are currently applied from different style-sheets. In other words, you can see it as a live style-sheet, only targeted to a single element, with standardized units.
But in no way it should be used to get the current height or width of an element. Too many factors may interfere with the set value, and an element can even have an height without having any CSS height rule set.
So yes... when the height CSS rule is set to auto, you will get the computed value, which may coincide with the real height of the element, but it also may not be so.
So in order to get the displayed height of an element, without the border and padding, we will need to do some calculations ourself.
Element#getBoundingClientRect() will give us the real displayed dimensions of our element, transformations included. .offsetHeight will give us the untransformed height including the border-box, and .clientHeight will give us the untransformed height with the padding-box.
This means that we will first have to get all the border and padding computed values, then get the current scale of our element, and finally remove the scaled padding + border boxes from the values we get with getBoundingClientRect.
Here is an example, which will draw a new rectangle div atop the element's bounding-box without padding and border boxes.
let marker;
scale.onclick = e => {
element.classList.toggle('scaled');
drawRect();
}
boxSizing.onclick = e => {
element.classList.toggle('boxSized');
drawRect();
}
function drawRect() {
// remove previous marker if any
if (marker && marker.parentNode) {
marker.remove();
marker = null;
}
// first get the border and padding values
let computed = getComputedStyle(element);
let borderLeft = parseFloat(computed.borderLeftWidth);
let borderWidth = borderLeft + parseFloat(computed.borderRightWidth);
let borderTop = parseFloat(computed.borderTopWidth);
let borderHeight = borderTop + parseFloat(computed.borderBottomWidth);
let paddingLeft = parseFloat(computed.paddingLeft);
let paddingWidth = paddingLeft + parseFloat(computed.paddingRight)
let paddingTop = parseFloat(computed.paddingTop);
let paddingHeight = paddingTop + parseFloat(computed.paddingBottom);
// get the current bounding rect, including the border-box
let rect = element.getBoundingClientRect();
// we need to get the current scale since the computed values don't know about it...
let scale = 1 / (element.offsetHeight / rect.height);
// the real displayed height and width without border nor padding
let height = rect.height - ((borderHeight + paddingHeight) * scale);
let width = rect.width - ((borderWidth + paddingWidth) * scale);
// create our rectangle
marker = document.createElement('div');
marker.classList.add('marker');
marker.style.height = height + 'px';
marker.style.width = width + 'px';
// we need to scale border + padding again
marker.style.top = (rect.top + (borderTop + paddingTop) * scale) + 'px';
marker.style.left = (rect.left + (borderLeft + paddingLeft) * scale) + 'px';
document.body.append(marker);
}
#element {
width: 250px;
border: 0.5em solid green;
padding: 0.5em;
margin-top: 12px;
}
#element.scaled {
transform: scale(2);
transform-origin: top left;
}
#element.boxSized {
box-sizing: border-box;
}
.marker {
position: fixed;
width: 3px;
background: rgba(0, 0, 0, .3)
}
<label>scale
<input id="scale" type="checkbox">
</label>
<label>box-sizing
<input id="boxSizing" type="checkbox">
</label>
<div id="element">
Hello
<br> world
</div>
when you set box-sizing as border-box:
The width and height properties include the content, the padding and border, but not the margin
So when you use getComputedStyle to get a element's height, of course it includes the height of padding and border.
you can have a look at box-sizing property and css box model

Keep aware of transform and transform-origin anchor point on rotated container

I'm trying to rotate a container with javascript and css property transform and transform-origin, the idea is to rotate it around certain coordinates (For example a pinch gesture center between the two fingers), I'm using this simple code (snippet attached) right now to rotate the container and using the onclick event to capture the anchor point. It is working properly as long as you keep clicking without moving the cursor to a different position on the container. There's an issue when you change the click position once the container has been rotated, the expected behavior is to keep track of the transformation and start rotating for that new point, however right now the container is doing an odd jump. I think that some x,y translation need to be added to the container, but i can figure out what's the correct factor to add to the container.
I'm not sure if I've illustrated well the expected behavior, to make sure here's and example: Imagine you pin a note to a surface at certain position, then, you start rotating the note, having the pin as anchor point. Now, after rotating the note a little, you put out the pin (Keeping the note at the same place), then you place the pin on a different position on the note and rotate again with that new anchor point. That's the expected behavior, hope i have explained myself well.
Here's a snippet to show it better, also available on codepen, cheers.
http://codepen.io/vasilycrespo/pen/GZeYpB
var angle = 15,
scale = 1,
origin = { x: 0, y: 0};
var transform = function (e) {
var map = document.getElementById("map");
angle += 15;
map.style.transformOrigin = e.pageX + "px " + e.pageY + "px";
map.style.transform = "rotate("+angle+"deg) scale("+ scale +")";
};
.content{
position: fixed;
top: 0px;
left: 0px;
margin-top:0;
margin-left:0;
background-color: #ccc;
width: 100%;
height: 100%;
}
.square{
position: absolute;
width: 400px;
height: 400px;
background-image: url(http://www.pnas.org/site/misc/images/15-02545.500.jpg);
background-size: cover;
}
<div class="content" onclick="transform(event)">
<div class="square" id="map"></div>
</div>
The problem is that every time you click, the div changes position based on where you click. After the first click, you should save e.pageX and e.pageY, and in the next clicks you should use the saved values. You can change your transform function to this:
var transform = (function () {
var pageX, pageY;
return function(e) {
if (typeof pageX === "undefined") {
pageX = e.pageX
pageY = e.pageY
}
var map = document.getElementById("map"), xr;
angle += 15;
map.style.transformOrigin = pageX + "px " + pageY + "px";
map.style.transform = "rotate("+angle+"deg) scale("+ scale +")";
}
}())
See updated Code Pen.

Leaflet expand map to fill page on print

I have in interesting CSS/JavaScript problem. I am building a user-friendly web map that will include volunteered geographic information and needs to have the ability to print at multiple paper sizes, up to poster size. For the interface, I am working with Leaflet.js, Mapbox.js, and jQuery. The way I've approached printing is to set up a preview window that shows overlays only (no tileLayer) on a completely new L.Map with a white background, with the markers scaled proportionally to the paper size selected by the user. The idea is that the map will fill the page and the markers will always print at the same size (8 mm across for circle markers, 10 mm for icons). Here's a screenshot of the preview window in Firefox:
There is a fair bit of complex code. Suffice it to say that whenever the user changes the window size or paper orientation, the preview box and icons resize accordingly. Whenever the user changes the paper size, the icons resize but the preview box does not, so as to represent the correct size ratios. Here are the functions I'm using to do it:
function adjustPreviewBox(){
//set preview box dimensions based on print window size and paper orientation
if ($("#paperOrientation option[value=portrait]").prop("selected")){
var height = $("#printBox").height() - 61;
var width = height / Math.sqrt(2);
$("#printPreview").height(height);
$("#printPreview").width(width);
} else {
//first set by horizontal dimension
var width = $("#printBox").width() - 300;
var height = width / Math.sqrt(2);
//check for vertical overflow
if (height > $("#printBox").height() - 61){
height = $("#printBox").height() - 61;
width = height * Math.sqrt(2);
};
$("#printPreview").height(height);
$("#printPreview").width(width);
}
};
function adjustScale(){
//change symbol sizes and ratio scale according to paper size
var prevWidth = $("#printPreview").width();
var prevHeight = $("#printPreview").height();
var size = $("#paperSize select option:selected").val();
var series = size[0];
var pScale = Number(size[1]);
var longside, mmppPaper;
if (series == "A"){ //equations for long side lengths in mm, minus 10mm print margins
longside = Math.floor(1000/(Math.pow(2,(2*pScale-1)/4)) + 0.2) - 20;
} else if (series == "B"){
longside = Math.floor(1000/(Math.pow(2,(pScale-1)/2)) + 0.2) - 20;
};
//find the mm per pixel ratio
mmppPaper = prevWidth > prevHeight ? longside / prevWidth : longside / prevHeight;
var mapZoom = printPreviewMap.getZoom();
var scaleText = $("#printBox .leaflet-control-scale-line").html().split(" ");
var multiplier = scaleText[1] == "km" ? 1000000 : 1000;
var scalemm = Number(scaleText[0]) * multiplier;
var scalepx = Number($("#printBox .leaflet-control-scale-line").width());
var mmppMap = scalemm / scalepx;
var denominator = Math.round(mmppMap / mmppPaper);
$("#ratioScale span").text(denominator);
return [mmppMap, mmppPaper];
}
function resizeMarkers(markerType, init){
//scale preview marker size based on paper size and orientation
markerType == "circle" ? changeRadius(init) : changeIconSize(init);
};
function getRadius(){
//adjust ratio scale and return scale ratios
var scales = adjustScale();
var mmppPaper = scales[1];
return 4 / mmppPaper;
};
function changeRadius(init){
//each circle marker will print at 8 mm diameter regardless of map scale and page size
var radius = getRadius();
printPreviewMap.eachLayer(function(layer){
if (typeof layer._radius !== 'undefined'){
if (init == true){
layer.setStyle({
opacity: 1,
fillOpacity: 1
});
layer.unbindPopup();
};
layer.setRadius(radius);
}
});
};
function changeIconSize(init){
//each icon will print at 10 mm per side regardless of map scale and page size
var side = 2.5 * getRadius();
//need to change dimensions and offset
$("#printPreview .leaflet-marker-icon").css({
width: side + "px",
height: side + "px",
"margin-left": -(side / 2),
"margin-top": -(side / 2)
})
};
I have #media print CSS styles that seem to work well for printing the preview window:
#media print {
#page {
size: auto;
margin: 10mm;
}
#printBox, #printPreview {
position: absolute;
max-height: 100%;
bottom: 0;
left: 0;
top: 0;
right: 0;
}
#printPreview {
position: absolute !important;
width: 100% !important;
height: 100% !important;
border: none;
}
#scalegrip {
visibility: hidden;
}
#container {
visibility: hidden;
}
}
I've tested this by printing to a PDF using Adobe's driver. Here's the result:
It seems to work fine--except that the markers only fill the upper-left part of the page, whereas I would like them to expand outward to fill the entire page so that the final product is the same 'view' as the preview box. This is where I'm stumped and would welcome any advice or ideas from anyone who has tried something similar or knows their way around printing websites.
In a similar project, I had to force the map to refresh after any CSS size changes through the invalidateSize method. For example using jQuery to change map height and weight div:
$("map").css('width', '267mm');
$("map").css('height', '210mm');
map.invalidateSize();
According to leaflet help:
invalidateSize: Checks if the map container size changed and updates the map if so — call it after you've changed the map size dynamically, also animating pan by default.

Keep div overlay relative to background image regardless of window size

I want to overlay some text over a background image with background-size: cover.
Problem here is how do I keep the overlay div at the same position, relative to the background image, regardless of the window's size?
Here's a fiddle to play around: http://jsfiddle.net/resting/2yr0b6v7/
So I want to position the word eye over the eye of the cat, regardless of window size.
CSS or JS solutions are both welcomed.
EDIT: Added js alternative
I was convinced that this could be done with css and almost gave up, but then I remembered the new(ish) css units vh and vw....
jsfiddle
CSS
html, body{
height: 100%;
width: 100%;
}
.cat {
height: 100%;
width: 100%;
position: relative;
background:url(http://placekitten.com/g/800/400) no-repeat center center / cover;
}
.place-on-eye {
position: absolute;
color: #fff;
margin:0;
}
#media (min-aspect-ratio: 2/1) {
.place-on-eye {
bottom: 50%;
left: 46.875%;
margin-bottom: 1.25vw;
}
}
#media (max-aspect-ratio: 2/1) {
.place-on-eye {
bottom: 52.5%;
left: 50%;
margin-left: -6.25vh;
}
}
Explanation
So the left eye is at approx 375, 190, and since the image is centered, we will also want to know how far off the center it is, so 25, 10. Since the image is covering, the size of the image will change based on whether the aspect ratio of the viewport is greater or less than the aspect ratio of the background image. Knowing this, we can use media queries to position the text.
The image is 2:1, so when the viewport aspect ratio is > 2:1, we know that the width of the image is the width of the viewport, so the left position of the <p> should always be 46.867% (375/800). The bottom position is going to be more difficult because the image extends beyond the viewport top and bottom. We know that the image is centered, so first move the <p> to the middle, then push it up by 2.5% (10/400) of the height of the image. We don't know the height of the image, but we do know the image aspect ratio and that the width of the image is equal to the width of the viewport, so 2.5% of the height = 1.25% width. So we have to move the bottom up by 1.25% width, which we can do by setting margin-bottom:1.25vw. Incidentally, we can do this without vw in this case because padding is always calculated relative to the width, so we could have set padding-bottom:1.25%, however this won't work in the next case where you have to position the left relative to the height.
The case when the aspect ratio is < 2:1 is analogous. The height of the image is the height of the viewport, so the bottom position should always be 52.5% (210/400) and the left is calculated similar to above. Move it over to center, then back it up by 3.125% (25/800) the width of the image, which is equal to 6.25% the height of the image, which is equal to the viewport height, so margin-left:-6.25vh.
Hopefully this is correct and helps you out!
JS Alternative
jsfiddle
Here's an alternative that uses js. It uses some features like forEach and bind that might cause problems depending on how old a browser you need it to work on, but they are easily replaceable. With js you can directly calculate the scaled dimensions of the bg image which makes the positioning easier. Not the most elegant code, but here goes:
//elem: element that has the bg image
//features: array of features to mark on the image
//bgWidth: intrinsic width of background image
//bgHeight: intrinsic height of background image
function FeatureImage(elem, features, bgWidth, bgHeight) {
this.ratio = bgWidth / bgHeight; //aspect ratio of bg image
this.element = elem;
this.features = features;
var feature, p;
for (var i = 0; i < features.length; i++) {
feature = features[i];
feature.left = feature.x / bgWidth; //percent from the left edge of bg image the feature resides
feature.bottom = (bgHeight - feature.y) / bgHeight; //percent from bottom edge of bg image that feature resides
feature.p = this.createMarker(feature.name);
}
window.addEventListener("resize", this.setFeaturePositions.bind(this));
this.setFeaturePositions(); //initialize the <p> positions
}
FeatureImage.prototype.createMarker = function(name) {
var p = document.createElement("p"); //the <p> that acts as the feature marker
p.className = "featureTag";
p.innerHTML = name;
this.element.appendChild(p);
return p
}
FeatureImage.prototype.setFeaturePositions = function () {
var eratio = this.element.clientWidth / this.element.clientHeight; //calc the current container aspect ratio
if (eratio > this.ratio) { // width of scaled bg image is equal to width of container
this.scaledHeight = this.element.clientWidth / this.ratio; // pre calc the scaled height of bg image
this.scaledDY = (this.scaledHeight - this.element.clientHeight) / 2; // pre calc the amount of the image that is outside the bottom of the container
this.features.forEach(this.setWide, this); // set the position of each feature marker
}
else { // height of scaled bg image is equal to height of container
this.scaledWidth = this.element.clientHeight * this.ratio; // pre calc the scaled width of bg image
this.scaledDX = (this.scaledWidth - this.element.clientWidth) / 2; // pre calc the amount of the image that is outside the left of the container
this.features.forEach(this.setTall, this); // set the position of each feature marker
}
}
FeatureImage.prototype.setWide = function (feature) {
feature.p.style.left = feature.left * this.element.clientWidth + "px";
feature.p.style.bottom = this.scaledHeight * feature.bottom - this.scaledDY + "px"; // calc the pixels above the bottom edge of the image - the amount below the container
}
FeatureImage.prototype.setTall = function (feature) {
feature.p.style.bottom = feature.bottom * this.element.clientHeight + "px";
feature.p.style.left = this.scaledWidth * feature.left - this.scaledDX + "px"; // calc the pixels to the right of the left edge of image - the amount left of the container
}
var features = [
{
x: 375,
y: 190,
name: "right eye"
},
{
x: 495,
y: 175,
name: "left eye"
},
{
x: 445,
y: 255,
name: "nose"
},
{
x: 260,
y: 45,
name: "right ear"
},
{
x: 540,
y: 20,
name: "left ear"
}
];
var x = new FeatureImage(document.getElementsByClassName("cat")[0], features, 800, 400);
I have done a fiddle borrowing the principles from the 2 answers. Black dot should overlay at the end of the line. But this solution drifts from actual spot a little in certain ratios.
Maybe someone can improve it?
JS:
$(function() {
function position_spot() {
w = $(window).width();
h = $(window).height();
wR = w/h;
// Point to place overlay based on 1397x1300 size
mT = 293;
mL = -195;
imgW = 1397;
imgH = 1300;
imgR = imgW/imgH;
tR = mT / imgH; // Top ratio
lR = mL / imgW; // Left ratio
wWr = w / imgW; // window width ratio to image
wHr = h / imgH; // window height ratio to image
if (wR > imgR) {
// backgroundimage size
h = imgH * wWr;
w = imgW * wWr;
} else {
h = imgH * wHr;
w = imgW * wHr;
}
$('.overlay-spot').css({
'margin-top': h * tR,
'margin-left': w * lR
});
}
$(window).resize(function() {
position_spot();
});
position_spot();
});
According to how you set your background image position and size:
background-position:center center;
background-size:cover;
the center of background image should still be in the center of your screen - that comes in handy as a constant, so just try to do the same with your p.place-on-eye
.place-on-eye {
...
top: 50%;
left: 50%;
}
Right now paragraph's left top corner is in the center of your screen, if you also add width and height properties you can actually pint elements center into the screen's center. So it's like:
.place-on-eye {
...
width:50px;
height:50px;
text-align:center /* to make sure the text is center according to elements width */
top: 50%;
left: 50%;
margin:-25px 0 0 -25px;
}
So now the center of p.place-on-eye is in the exact center of your screen, just like the center of your background image. To get it over the cat's eye just offset the left and top margin as needed.
so something like margin:-27px 0 0 -60px; should do it.
fiddle

Categories

Resources