Text on top of image map doesn't stick on window resizing - javascript

I am doing something similar to this topic :
Text on top of image map
My problem is that the titles are not exactly at the center of the circle area and they don't stick to the area mapped on my image when the window is resized, although the areas themselves are always correctly positioned when resizing the window.
here is my code:
<div id="molecule">
<img src="./images/molecule-total.svg" alt="menu" usemap="#molecule-links">
<map name="molecule-links">
<area class="contact" shape="circle" coords="70,100,90" alt="Page1" data-name="Contact">
<area shape="circle" coords="250,350,150" href="page2.html" alt="Page2" data-name="Home">
</map>
</div>
#molecule {
height: 80vh;
width: 100vh;
padding-left: 141px;
padding-top: 15px;
position: relative;
}
.map_title {
position: absolute;
z-index: 2;
}
img {
min-height: 80%;
max-height: 100%;
}
area {
cursor: pointer;
outline-color: white;
}
function displayLinksName() {
const area = document.querySelectorAll("area");
const map = document.querySelector("map")
area.forEach(function(area){
let txt = area.getAttribute('data-name')
let coor = area.getAttribute('coords');
let coorA = coor.split(',')
let left = coorA[0];
let top = coorA[1];
let links = document.createElement('div');
links.classList.add("map-title");
links.innerHTML = txt;
links.style.top = top + 'px';
links.style.left = left + 'px';
links.style.position = 'absolute';
links.style.color = 'red';
map.append(links);
})
}
It's like the coords of the area doesn't obey to the same rules than the CSS properties top and left. Is there a workaround to make it works properly?

U can try to remake the javascript to update the position of the text based on the image position with onresize event:
window.addEventListener("resize", updateTextPosition);
function updateTextPosition() {
var img = document.querySelector("img");
var imgRect = img.getBoundingClientRect();
var areas = document.querySelectorAll("area");
areas.forEach(function(area) {
var coords = area.getAttribute("coords").split(",");
var left = coords[0];
var top = coords[1];
var text = area.nextElementSibling;
text.style.left = (imgRect.left + parseInt(left)) + "px";
text.style.top = (imgRect.top + parseInt(top)) + "px";
});
}
Adittionally you can use CSS Media queries to adjust the text, for example when the window width is less than 800:
#media (max-width: 800px) {
.map_title {
top: 50px;
left: 50px;
}
}
This adjust the position of the text.
PS:
You have an error in the javascript, it is written map-title and the css class is called map_title

I finally found the easiest way to deal with maps on any image, without using map or area tag. Just using this generator: https://imagemapper.noc.io/#/
and add tags inside the SVG code provided by the generator.
This comes from this discussion, which has lots of interesting ways to achieve this:
Responsive image map

Related

Transform dom elements to match an image regardless of its deformations

I want to have an image on page with DIVs sitting at the same place relative to the image even when the image gets stretched. Basically, I know the position the stars should take in the original picture, however I dont know how to move them such that they stand in the right place.
Here I explain with a picture :
Here is my HTML markup. The .slide-point elements are the red stars:
let points = document.querySelectorAll(".slide-point");
points.forEach(point => {
const x = point.dataset.x;
const y = point.dataset.y;
const h = point.dataset.h;
const w = point.dataset.w;
let image = point.closest(".slide").querySelector("img");
let natH = image.naturalHeight;
let natW = image.naturalWidth;
let clientH = image.clientHeight;
let clientW = image.clientWidth;
point.style.left = x * clientW / natW + "px";
point.style.top = y * clientH / natH + "px";
point.style.width = w;
point.style.height = h;
});
.slide-point {
position: absolute;
background: red;
}
.slide>img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
object-position: top left;
}
<ul data-slides>
<li class="slide" data-active>
<div class="slide-point" data-x="240" data-y="2295" data-h="165" data-w="165">★</div>
<div class="slide-point" data-x="512" data-y="2155" data-h="165" data-w="165">★</div>
<img id="slide-img" src="https://via.placeholder.com/800" alt="Photo1">
</li>
</ul>
Obviously, as soon as I resize the page, the stars don't align with the image anymore.
Thank you in advance !

Scale div inside another div with overflow scroll and center

I'm coding a very tiny small feature, but I'm having problems with the scroll. I need to do a zoom of a div scaling with css:
transform: scale(X,Y)
But my problem is that I don't have a correct left and top scroll in the parent div. I need to know how to calculate the new left and top each time the user press the button "More zoom", I could use translate css property if it is mandatory.
I can use jQuery, but I think this is just a math problem :)
One detail: I need that the image grow from the center.
Picture:
Here is the fiddle:
Fiddle example
i believe you need to mind transform-origin too:
// get element references
var foo = document.querySelector('#foo');
var bar = document.querySelector('#bar');
// fit bar into foo
// the third options argument is optional, see the README for defaults
// https://github.com/soulwire/fit.js
var zoom = 1;
var trans = 50;
var moreZoom = document.querySelector('#moreZoom');
moreZoom.onclick = function(e){
console.log(foo);
bar.style.transform = 'scale(' + (zoom + 0.1) + ',' + (zoom + 0.1) + ')';
zoom = (zoom + 0.1);
bar.style.transformOrigin = (50 / zoom) +'px ' +(50 / zoom )+'px';
}
#foo {
background: #36D7B7;
height: 200px;
width: 400px;
padding: 50px;
overflow: auto;
}
#bar {
background-image: url('http://www.space.com/images/i/000/028/001/original/wing-small-magellanic-cloud-galaxy-1920.jpg?interpolation=lanczos-none&fit=around%7C1440:900&crop=1440:900;*,*');
background-size:cover;
height: 100%;
transform:scale(1);
width: 100%;
}
<script src="https://rawgithub.com/soulwire/fit.js/master/fit.js"></script>
<button id="moreZoom">
More Zoom
</button>
<div id="foo">
<div
http://jsfiddle.net/as20h6t4/5/

Javascript how to center an overlay when the user has zoomed in

I have a iframe that I create and add to the page as an overlay. I want it to be in the center of the page. However, when I am on mobile on a non mobile optimized page, and zoomed in, the iframe usually shows up off the screen.
var w = window,
d = document,
e = d.documentElement,
g = d.getElementsByTagName('body')[0],
width = w.innerWidth || e.clientWidth || g.clientWidth;
display_width = 450;
margin = (width-450) / 2;
frame.setAttribute('style','z-index: 2147483647;position:fixed;top:20px;left:'+margin+'px;width:'+display_width+'px;margin:0px;border: 1px solid; border-color:#ddd;max-width:none;overflow:visible;');
function resizeFrameWidth(){
var frame = document.getElementById('PennyPledge54DT');
var w = window,
d = document,
e = d.documentElement,
g = d.getElementsByTagName('body')[0],
width = w.innerWidth || e.clientWidth || g.clientWidth;
var margin = 20;
var display_width = width - 40;
if(!mobile){
display_width = 450;
margin = (width-450) / 2;
}
frame.style.width = display_width+"px";
frame.style.left = margin+"px";
}
if(window.attachEvent) {
window.attachEvent('onresize', resizeFrameWidth);
}
else if(window.addEventListener) {
window.addEventListener('resize', resizeFrameWidth, true);
It works when I resize the window, but not when I zoom.
edit:
here is a jsfiddle as requested. However, the problem manifests itself when you zoom in on the content. I only know how to do that via a mobile device. So I don't know how useful a fiddle will be.
https://jsfiddle.net/41y62su7/
edit
Here's a screenshot of what my iframe looks like on mobile when I zoom in on the page a little bit.
Here is a simpler method of achieving the same effect without grabbing the window.onresize event (which fires repeatedly throughout the resize event not just at the end). Using the heredoc function defined below allows for better maintainabilty and readability in your code. In this example I include the overlay which is not included in your javascript code.
This method uses margins to center the iframe within the overlay which is fixed in one position and set to the width and height of the viewport.
function heredoc(f) {
return f.toString().match(/\/\*\s*([\s\S]*?)\s*\*\//m)[1];
};
var overlay = document.createElement("div");
var iframe = document.createElement("iframe");
iframe.setAttribute("src", "https://www.google.ca");
overlay.style.cssText = heredoc(function() {/*
z-index: 2147483647;
position: fixed;
top: 0;
width: 100vw;
height: 100vw;
background: rgba(0,0,0,0.8);
*/});
iframe.style.cssText = heredoc(function() {/*
display: block;
margin-top:20px;
width: 450px;
max-width: 100vw;
height: 150px;
border: 1px solid #ddd;
overflow:visible;
margin: 0 auto;
margin-top: 20px;
*/});
overlay.appendChild(iframe);
document.getElementById('main').appendChild(overlay);
// you can also use
// document.body.appendChild(overlay);
// if you don't want to require that the user have an element with the id main
/* for example only, not required */
body {
width: 1000px;
height: 1000px;
}
<body>
<p id="main">
This is a bunch of text. Yadda yadda.
</p>
</body>

Using Zigfu (kinect) in canvas element of HTML5

I went through the initial tutorial for making a user radar on Zigfu's website. I am having trouble getting this radar to work in the canvas element.
I want to using the drawing methods in canvas, so I don't want it in the container.
Here is my code so far taken directly from the tutorial. Thanks so much for reading!
function loaded() {
var radardiv = document.getElementById('container');
var radar = {
onuserfound: function (user) {
var userdiv = document.createElement('div');
userdiv.className = 'user';
user.radarelement = userdiv;
radardiv.appendChild(user.radarelement);
},
onuserlost: function (user) {
radardiv.removeChild(user.radarelement);
},
ondataupdate: function (zigdata){
for (var userid in zigdata.users){
var user = zigdata.users[userid];
var pos = user.position;
//console.log(pos);
var el = user.radarelement;
var parentElement = el.parentNode;
var zrange = 2000;
var xrange = 700;
var pixelwidth = parentElement.offsetWidth;
var pixelheight = parentElement.offsetHeight;
var heightscale = pixelheight / zrange;
var widthscale = pixelwidth / xrange;
el.style.left = (((pos[0] / xrange) + 0.5) * pixelwidth - (el.offsetWidth / 2)) + "px";
el.style.top = ((pos[2] / zrange) * pixelheight - (el.offsetHeight / 2)) - 150 + "px";
}
}
};
zig.addListener(radar);
}
document.addEventListener('DOMContentLoaded', loaded, false);
<body>
<div id = 'container'></div>
</body>
</html>
<style>
div#container {
width: 800px;
height: 600px;
border: 1px solid black;
overflow: hidden;
}
div.user {
position: relative;
width: 10px;
height: 10px;
background-color: red;
}
It seems you are missing tags around the javascript, as well as some css for the users radar. Also - your 'container' div is missing a >
Try copying the code from the bottom of http://zigfu.com/en/zdk/tutorials/, or - check out http://zigfu.com/en/zdk/recipes/#omercy16 for a cleaner implementation of the users radar.
The radar used in the tutorial makes use of DOM div placement and positioning.
Unfortunately this can't be used inside the canvas element.
There are ways to overlay over the canvas and other workarounds. See: Placing a <div> within a <canvas>
You can also take the data directly from the plugin and draw to the canvas yourself.
Here is a demo using three.js and zigfu to draw the skeleton onto a canvas:
http://blog.kinect.tonkworks.com/post/30569123887/kinect-online-app-javascript-dev-tutorial-1

How can I animate DIVs moving from a central point to off-screen?

Is it possible to have divs located around a central point and then on hover for them to whisk off screen and return when the mouse is gone?
This what the layout:
http://pena-alcantara.com/aramael/wp-content/uploads/2010/04/Paper-Browser.8.5x11.Horizontal3.jpg
is looking like, the idea is for the green "leaves" to whisk off to show the branches and the menus. Would this be possible with JavaScript and PHP?
Any chance I could convince you to not design a site this way?
I suppose not, so the answer is to use jQuery. Here is the jQuery reference for animation, which you'll need to study carefully.
You are going to need to combine a few jQuery features.
The animation feature at: http://api.jquery.com/animate/
The mouse over feature: http://api.jquery.com/mouseover/
The mouse out feature: http://api.jquery.com/mouseout/
Have "dummy divs" where the mouse over is detected that move their ID's real div out of view using animate it, and bring it back with mouseout
I found this interesting so coded it for myself... I did it as below:
<style type="text/css">
body {
overflow:hidden;
}
.leaf {
position:relative;
background-color:#0F0;
height: 100px;
width: 100px;
}
.branch {
display:inline-block;
background-color:#F00;
height: 100px;
width: 100px;
}
</style>
<script type="text/javascript">
$(function(){
var w = $(document).width();
var h = $(document).height();
var r = 250;
$(".branch").hover(function() {
var rand = Math.random();
var x,y;
if(rand<0.25) {
x = w;
y = h*Math.random();
} else if(rand<0.5) {
x = -w;
y = h*Math.random();
} else if(rand<0.75) {
x = w*Math.random();
y = h;
} else {
x = w*Math.random();
y = -h;
}
$(this).children().animate({left: x, top: y});
}, function () {
$(this).children().animate({left: '0', top: '0'});
})
});
</script>
<div class="wrap">
<div class="branch"><div class="leaf"></div></div><!-- etc -->
</div>

Categories

Resources