This is my first question, so please give me any pointers on how I could ask better ones.
Anyway, how would I make a togglable menu that displays links, that activates using a bookmarklet. I have tried to find answers, but all were fruitless. Would I need to create a new element for this?
You will need to create the pop-up menu using vanilla JS. I also implemented drag functionality. The only thing this needs is to correctly set the position when a page is scrolled.
DOM layout
The most important elements and styles below are required.
<div style="position:absolute; z-index:2147483647">
<div style="position: relative">
<div style="position:relative; display:inline-block; left:0">Bookmarklet Links</div>
<div style="position:relative; float:right">×</div>
</div>
<div>
<p>Click the links to open a new tab!</p>
<ul>
<li>
Google
</li>
<li>
Bing
</li>
<li>
DuckDuckGO
</li>
</ul>
</div>
</div>
You can save the following bookmarklet:
javascript:!function(){var c=0x1f4,d=0x12c,e='#AAA',f=0x1,g=0x20,h='#444',i='#FFF',j='Bookmarklet\x20Links',k=~~(document['documentElement']['clientWidth']/0x2-c/0x2),l=~~(document['documentElement']['clientHeight']/0x2-d/0x2),m=~~(0.8*g),n=document['createElement']('DIV');Object['assign'](n['style'],{'position':'absolute','left':k+'px','top':l+'px','zIndex':Number['MAX_SAFE_INTEGER'],'width':c+'px','height':d+'px','background':e,'border':f+'px\x20solid\x20black'});var o=document['createElement']('DIV');Object['assign'](o['style'],{'position':'relative','width':c+'px','height':g+'px','background':h,'borderBottom':f+'px\x20solid\x20black'});var p=document['createElement']('DIV');Object['assign'](p['style'],{'position':'relative','display':'inline-block','left':0x0,'width':~~(c-0x2*m)+'px','lineHeight':g+'px','color':i,'fontSize':~~(0.667*g)+'px','marginLeft':~~(m/0x3)+'px'}),p['textContent']=j;var q=document['createElement']('DIV'),r=~~((g-m)/0x2);Object['assign'](q['style'],{'position':'relative','float':'right','right':r+'px','top':r+'px','width':m+'px','height':m+'px','background':'#F00','border':f+'px\x20solid\x20black','color':'#FFF','lineHeight':m+'px','textAlign':'center','fontSize':m+'px','marginLeft':'auto','marginRight':0x0});var s=document['createElement']('DIV');Object['assign'](s['style'],{'padding':'1em'});var t=document['createElement']('P');t['textContent']='Click\x20the\x20links\x20to\x20open\x20a\x20new\x20tab!',s['appendChild'](t);var u=document['createElement']('UL');[{'name':'Google','url':'https://www.google.com'},{'name':'Bing','url':'https://www.bing.com'},{'name':'DuckDuckGO','url':'https://duckduckgo.com'}]['forEach'](c=>{var d=document['createElement']('LI'),e=document['createElement']('A');e['setAttribute']('href',c['url']),e['setAttribute']('target','_blank'),e['textContent']=c['name'],d['appendChild'](e),u['appendChild'](d);}),s['appendChild'](u),q['addEventListener']('click',function c(d){q['removeEventListener']('click',c,!0x1);o['removeChild'](q);n['removeChild'](o);n['removeChild'](s);document['body']['removeChild'](n);},!0x1),q['textContent']='×',o['appendChild'](p),o['appendChild'](q),n['appendChild'](o),n['appendChild'](s),document['body']['appendChild'](n),function(c){var d=function(c){var d=c['getBoundingClientRect'](),e=window['pageXOffset']||document['documentElement']['scrollLeft'],f=window['pageYOffset']||document['documentElement']['scrollTop'];return{'top':d['top']+f,'left':d['left']+e};}(c['parentElement']),e=!0x1,f={'x':0x0,'y':0x0},g={'x':d['left'],'y':d['top']};c['parentElement']['addEventListener']('mousedown',function(d){e=!0x0,f['x']=d['clientX'],f['y']=d['clientY'],c['parentElement']['style']['cursor']='move';}),c['parentElement']['addEventListener']('mouseup',function(d){e=!0x1,g['x']=parseInt(c['parentElement']['style']['left'])||0x0,g['y']=parseInt(c['parentElement']['style']['top'])||0x0,c['parentElement']['style']['cursor']='auto';}),document['addEventListener']('mousemove',function(d){if(!e)return;var h={'x':d['clientX']-f['x'],'y':d['clientY']-f['y']},i={'x':g['x']+h['x'],'y':g['y']+h['y']};i['x']<0x0?i['x']=0x0:i['x']+c['parentElement']['offsetWidth']>document['documentElement']['clientWidth']&&(i['x']=document['documentElement']['clientWidth']-c['parentElement']['offsetWidth']);i['y']<0x0?i['y']=0x0:i['y']+c['parentElement']['offsetHeight']>document['documentElement']['clientHeight']&&(i['y']=document['documentElement']['clientHeight']-c['parentElement']['offsetHeight']);c['parentElement']['style']['left']=i['x']+'px',c['parentElement']['style']['top']=i['y']+'px';});}(o);}(window);
Method of minification and obfuscation
I minified the code below using: https://javascript-minifier.com/
I obfuscated the resulting minified code using: https://obfuscator.io/
For the obfuscator, I set "Identifier Names Generator" to "mangled" and checked "Rename Globals".
Important: Unselect "String Array" or you cannot add new link entries.
Caveats
The script doesn't allow moving beyond the initial width and height. The following width and height methods from this post could be incorporated to fix this limitation.
Source code
(function(window) {
var links = [{
name: 'Google',
url: 'https://www.google.com'
}, {
name: 'Bing',
url: 'https://www.bing.com'
}, {
name: 'DuckDuckGO',
url: 'https://duckduckgo.com'
}];
var props = {
width: 500,
height: 300,
background: '#AAA',
borderThickness: 1,
headerHeight: 32,
headerBackground: '#444',
headerTitleColor: '#FFF',
windowTitle: 'Bookmarklet Links'
};
var windowPosition = {
left: ~~((document.documentElement.clientWidth / 2) - (props.width / 2)),
top: ~~((document.documentElement.clientHeight / 2) - (props.height / 2)),
}
var btnSize = ~~(props.headerHeight * 0.8);
var popupEl = document.createElement('DIV');
Object.assign(popupEl.style, {
position: 'absolute',
left: windowPosition.left + 'px',
top: windowPosition.top + 'px',
zIndex: Number.MAX_SAFE_INTEGER,
width: props.width + 'px',
height: props.height + 'px',
background: props.background,
border: props.borderThickness + 'px solid black'
});
var popupHeader = document.createElement('DIV');
Object.assign(popupHeader.style, {
position: 'relative',
width: (props.width) + 'px',
height: props.headerHeight + 'px',
background: props.headerBackground,
borderBottom: props.borderThickness + 'px solid black'
});
var popupHeaderTitle = document.createElement('DIV');
Object.assign(popupHeaderTitle.style, {
position: 'relative',
display: 'inline-block',
left: 0,
width: ~~(props.width - btnSize * 2) + 'px',
lineHeight: props.headerHeight + 'px',
color: props.headerTitleColor,
fontSize: ~~(props.headerHeight * 0.667) + 'px',
marginLeft: ~~(btnSize / 3) + 'px'
});
popupHeaderTitle.textContent = props.windowTitle;
var closeButton = document.createElement('DIV');
var margin = ~~((props.headerHeight - btnSize) / 2);
Object.assign(closeButton.style, {
position: 'relative',
float: 'right',
right: margin + 'px',
top: margin + 'px',
width: btnSize + 'px',
height: btnSize + 'px',
background: '#F00',
border: props.borderThickness + 'px solid black',
color: '#FFF',
lineHeight: btnSize + 'px',
textAlign: 'center',
fontSize: btnSize + 'px',
marginLeft: 'auto',
marginRight: 0
});
var popupBody = document.createElement('DIV');
Object.assign(popupBody.style, {
padding: '1em'
});
var p = document.createElement('P');
p.textContent = 'Click the links to open a new tab!';
popupBody.appendChild(p);
var listEl = document.createElement('UL');
links.forEach(link => {
var itemEl = document.createElement('LI');
var anchorEl = document.createElement('A');
anchorEl.setAttribute('href', link.url);
anchorEl.setAttribute('target', '_blank');
anchorEl.textContent = link.name;
itemEl.appendChild(anchorEl);
listEl.appendChild(itemEl);
});
popupBody.appendChild(listEl);
closeButton.addEventListener('click', destroyWindow, false);
closeButton.textContent = '×';
popupHeader.appendChild(popupHeaderTitle);
popupHeader.appendChild(closeButton);
popupEl.appendChild(popupHeader);
popupEl.appendChild(popupBody);
document.body.appendChild(popupEl);
draggable(popupHeader);
function destroyWindow(e) {
closeButton.removeEventListener('click', destroyWindow, false);
popupHeader.removeChild(closeButton);
popupEl.removeChild(popupHeader);
popupEl.removeChild(popupBody);
document.body.removeChild(popupEl);
}
/* Source: https://plainjs.com/javascript/styles/get-the-position-of-an-element-relative-to-the-document-24/ */
function offset(el) {
var rect = el.getBoundingClientRect(),
scrollLeft = window.pageXOffset || document.documentElement.scrollLeft,
scrollTop = window.pageYOffset || document.documentElement.scrollTop;
return { top: rect.top + scrollTop, left: rect.left + scrollLeft }
}
/* Source: https://gist.github.com/remarkablemark/5002d27442600510d454a5aeba370579 */
function draggable(el) {
var initialOffset = offset(el.parentElement);
var isMouseDown = false;
var currPos = { x : 0, y : 0 };
var elPos = { x : initialOffset.left, y : initialOffset.top };
el.parentElement.addEventListener('mousedown', onMouseDown);
function onMouseDown(event) {
isMouseDown = true;
currPos.x = event.clientX;
currPos.y = event.clientY;
el.parentElement.style.cursor = 'move';
}
el.parentElement.addEventListener('mouseup', onMouseUp);
function onMouseUp(event) {
isMouseDown = false;
elPos.x = parseInt(el.parentElement.style.left) || 0;
elPos.y = parseInt(el.parentElement.style.top) || 0;
el.parentElement.style.cursor = 'auto';
}
document.addEventListener('mousemove', onMouseMove);
function onMouseMove(event) {
if (!isMouseDown) return;
var delta = { x : event.clientX - currPos.x, y: event.clientY - currPos.y };
var pos = { x : elPos.x + delta.x, y : elPos.y + delta.y };
if (pos.x < 0) {
pos.x = 0;
} else if (pos.x + el.parentElement.offsetWidth > document.documentElement.clientWidth) {
pos.x = document.documentElement.clientWidth - el.parentElement.offsetWidth;
}
if (pos.y < 0) {
pos.y = 0;
} else if (pos.y + el.parentElement.offsetHeight > document.documentElement.clientHeight) {
pos.y = document.documentElement.clientHeight - el.parentElement.offsetHeight;
}
el.parentElement.style.left = pos.x + 'px';
el.parentElement.style.top = pos.y + 'px';
}
}
})(window);
Improving
You will notice that if your cursor goes off-screen while dragging (and you release the button) the window will be stuck in drag. You could detect this globally, but you will also need to figure out how re reinitialize the position to last known "good" position.
document.addEventListener('mouseup', onGlobalMouseUp);
function onGlobalMouseUp(event) {
if (
(event.clientX < 0 || event.clientX > document.documentElement.clientWidth) ||
(event.clientY < 0 || event.clientY > document.documentElement.clientHeight)
) {
if (isMouseDown) {
isMouseDown = false; // Draggged off-screen
popupEl.style.cursor = 'auto';
}
}
}
Lastly, don't spam the bookmarklet button, because it will create multiple instances of the same window. Code can be added to detect the presence of the window before creating a new one. Closing it could hide it, so it will just make the existing one visible again. Multiple windows will break the close listener.
I'm trying to draw a bunch of divs inside of a container in such a way that they are randomly positioned every time the page is loaded and that there is no overlapping. I seem to be stuck in an infinite loop and without the sources loading in Chrome before crashing the page, I can't debug properly.
Here's my code:
$(document).ready(function() {
var filledAreas = new Array();
var minX = 50;
var maxX = $("#banner").width() - 150;
var minY = 50;
var maxY = $("#banner").height() - 150;
var loops = 0;
var loopsMax = 100;
for (var i = 0; i < 15; i++) {
var color = '#' + Math.round(0xffffff * Math.random()).toString(16);
$newDiv = $("<div class='bubble-outer'></div>").css({
'width': '100px',
'height': '100px',
'background-color': color,
});
var randX = 0;
var randY = 0;
var area;
do {
randX = Math.floor(Math.random() * (maxX - minX + 1)) + minX;
randY = Math.floor(Math.random() * (maxY - minY + 1)) + minY;
var area = {
'left': randX,
'top': randY,
'right': randX + 100,
'bottom': randY + 100,
};
} while (loops < loopsMax && checkOverlap(area))
filledAreas.push(area)
$newDiv.css({
'position': 'absolute',
'left': randX + 'px',
'top': randY + 'px',
'display': 'none'
}).delay(1000).appendTo("#banner").fadeIn(300);
}
console.log("Loops: " + loops);
function checkOverlap(area) {
for (var i = 0; i < filledAreas.length; i++) {
var check = filledAreas[i];
if (area.right < check.left && area.bottom < check.top &&
check.right < area.left && check.bottom < area.top) {
loops++;
continue;
} else {
return true;
}
return false;
}
}
});
Since you used my algorithm, might as well post it as an answer!
As with many things, it is easier to cheat than to do exactly what you want to do.
Doing it the "proper" way would involve detecting collisions, which gets very tricky very fast.
However, here's a nice way to cheat at it:
Divide the area into a grid. Each grid square must be at least as big as your biggest element for this to work correctly.
For each element, pick a grid square. If that grid square hasn't been taken yet, place your element somewhere inside that grid square at random.
And... that's it! Now you are guaranteed to never have any collisions, and it looks pretty random because it is :)
I'm looking for an effect very similar to this:
http://jsfiddle.net/G5Xrz/
function rnd(max) { return Math.floor(Math.random()*(max+1)) }
function showImage(container, maxwidth, maxheight, imgsrc, imgwidth, imgheight) {
var id = "newimage" + rnd(1000000);
$(container).append(
"<img id='" + id + "' src='" + imgsrc +
"' style='display:block; float:left; position:absolute;" +
"left:" + rnd(maxwidth - imgwidth) + "px;" +
"top:" + rnd(maxheight - imgheight) + "px'>");
$('#' + id).fadeIn();
return id;
}
setInterval(
function() {
showImage("#container", 400, 600,
"http://placekitten.com/" + (90 + rnd(10)) + "/" + (90 + rnd(10)),
100, 100);
}, 700);
But i'd prefer a flexible layout, ie images not bound by a div with predefined height and width, instead responding to the dimensions of the browser.
The following piece of code seems to have a more appropriate way of generating the random positions:
http://jsfiddle.net/Xw29r/15/
function makeNewPosition(){
// Get viewport dimensions (remove the dimension of the div)
var h = $(window).height() - 50;
var w = $(window).width() - 50;
var nh = Math.floor(Math.random() * h);
var nw = Math.floor(Math.random() * w);
return [nh,nw];
}
function animateDiv(){
var newq = makeNewPosition();
var oldq = $('.a').offset();
var speed = calcSpeed([oldq.top, oldq.left], newq);
$('.a').animate({ top: newq[0], left: newq[1] }, speed, function(){
animateDiv();
});
};
However I'm very much a beginner with javascript and I don't know how to combine the two.
Can anyone help?
Thanks
Take this part from the second code:
// Get viewport dimensions (remove the dimension of the div)
var h = $(window).height() - 50;
var w = $(window).width() - 50;
and use those variables h and w with the browser height and width (minus 50) as the appropriate parameters in this part of the first code:
setInterval(
function() {
showImage("#container", 400, 600,
"http://placekitten.com/" + (90 + rnd(10)) + "/" + (90 + rnd(10)),
100, 100);
}, 700);
Also, the first code has this HTML:
<div id="container" style="width:400px; height:600px; background: green; position:relative"></div>
That hard-codes the height and width at pixel values. You can use a CSS percentage value to make the width respond to the parent container's size. However, you will need JS to set the height properly; a percentage for the height does nothing
Putting that all together (and removing the "minus 50" part), you get this:
jsFiddle demo
<div id="container" style="width:100%; height:100px; background: green; position:relative"></div>
function adjustContainerHeight(height) {
$('#container').height(height);
}
adjustContainerHeight($(window).height());
setInterval(
function() {
var h = $(window).height();
var w = $(window).width();
adjustContainerHeight(h);
showImage("#container", w, h,
"http://placekitten.com/" + (90 + rnd(10)) + "/" + (90 + rnd(10)),
100, 100);
}, 700);
This updates the height of the container when the page is first loaded, and once again whenever the random image is placed. More robust code would have a separate height-adjusting event handler that updates the height whenever the page size changes.
I have the following JavaScript; the intent is that circles will bounce on the screen, off all edges.
I went to a variable storing the window's height and width, because I thought failure to bounce off the bottom of the screen might because the node was progressively expanding, so my original check against jQuery(window).height() was pointless.
However, after having addressed this way of making a window bouncy on the edges, or tried to (it's at http://cats.stornge.com), I have not seen a ball bounce off one edge of the window, and if you watch your scrollbar, you can see that they are going well beyond the original bottom of the window as they fall.
var viewport_height = jQuery(window).height()
var viewport_width = jQuery(window).width();
var available_images = ['red.png', 'orange.png', 'yellow.png',
'green.png', 'blue.png', 'purple.png', 'brown.png', 'black.png',
'grey.png']; //, 'white.png'];
var bodies = [];
for(var i = 0; i < 3; ++i)
{
body = {id: i, velocity_y : Math.random(),
velocity_x: Math.random() * 10 - 5,
position_x: Math.random() * viewport_width - 100,
position_y: Math.random() * viewport_height - 100};
document.write('<img id="' + i + '" src="' + available_images[Math.floor(Math.random() * available_images.length)] + '" style="z-index: ' + i + '" />');
bodies[bodies.length] = body;
}
function iterate()
{
for(var index = 0; index < bodies.length; ++index)
{
bodies[index].velocity_y += .1;
bodies[index].position_x += bodies[index].velocity_x;
bodies[index].position_y += bodies[index].velocity_y;
var position = jQuery('#' + index).position();
if (position.top + 100 > viewport_height)
{
bodies[index].velocity_y = - bodies[index].velocity_y;
bodies[index].position_y = viewport_height - 100;
}
if (position.top < 0)
{
bodies[index].velocity_y = - bodies[index].velocity_y;
bodies[index].position_y = 0;
}
if (position.left > viewport_width - 100)
{
bodies[index].velocity_x = -bodies[index].velocity_x;
bodies[index].position_x = viewport_width - 100;
}
jQuery('#' + index).css('margin-top',
bodies[index].position_y + 'px');
jQuery('#' + index).css('margin-left',
bodies[index].position_x + 'px');
}
}
setInterval(iterate, 30);
I'd love to see how to make this code set bouncy walls at the boundaries of the original viewport.
When changing the margin-top and margin-left, the width and height of the window started to change as well.
I got this to work by changing the css() calls setting margin-top and margin-left to offset(). I also added another if statement to make sure the balls bounced off the left-hand side as well:
var viewport_height = jQuery(window).height()
var viewport_width = jQuery(window).width();
var available_images = ['red.png', 'orange.png', 'yellow.png',
'green.png', 'blue.png', 'purple.png', 'brown.png', 'black.png',
'grey.png']; //, 'white.png'];
var bodies = [];
for(var i = 0; i < 3; ++i)
{
body = {id: i, velocity_y : Math.random(),
velocity_x: Math.random() * 10 - 5,
position_x: Math.random() * viewport_width - 100,
position_y: Math.random() * viewport_height - 100};
document.write('<img id="' + i + '" src="http://cats.stornge.com/' + available_images[Math.floor(Math.random() * available_images.length)] + '" style="z-index: ' + i + '" />');
bodies[bodies.length] = body;
}
function iterate()
{
for(var index = 0; index < bodies.length; ++index)
{
bodies[index].velocity_y += .1;
bodies[index].position_x += bodies[index].velocity_x;
bodies[index].position_y += bodies[index].velocity_y;
var position = jQuery('#' + index).position();
if (position.top + 100 > viewport_height)
{
bodies[index].velocity_y = - bodies[index].velocity_y;
bodies[index].position_y = viewport_height - 100;
}
if (position.top < 0)
{
bodies[index].velocity_y = - bodies[index].velocity_y;
bodies[index].position_y = 0;
}
if (position.left > viewport_width - 100)
{
bodies[index].velocity_x = -bodies[index].velocity_x;
bodies[index].position_x = viewport_width - 100;
}
if (position.left < 0)
{
bodies[index].velocity_x = -bodies[index].velocity_x;
bodies[index].position_x = 0;
}
jQuery('#' + index).offset({top: bodies[index].position_y, left: bodies[index].position_x });
}
}
setInterval(iterate, 30);
How do I find out the absolute position of an element on the current visible screen (viewport) using jQuery?
I am having position:relative, so offset() will only give the offset within the parent.
I have hierarchical divs, so $("#me").parent().offset() + $("#me").offset() doesn't help either.
I need the position in the window, not the document, so when the document is scrolled, the value should change.
I know I could add up all the parent offsets, but I want a cleaner solution.
var top = $("#map").offset().top +
$("#map").parent().offset().top +
$("#map").parent().parent().offset().top +
$("#map").parent().parent().parent().offset().top;
Any ideas?
Update:
I need to get the exact gap in pixels between the top of my div and the top of the document, including padding/margins/offset?
My code:
HTML
<div id="map_frame" class="frame" hidden="hidden">
<div id="map_wrapper">
<div id="map"></div>
</div>
</div>
CSS
#map_frame{
border:1px solid #800008;
}
#map_wrapper {
position:relative;
left:2%;
top:1%;
width:95%;
max-height:80%;
display:block;
}
#map {
position:relative;
height:100%;
width:100%;
display:block;
border:3px solid #fff;
}
jQuery to resize the map to fill the screen*
var t = $("#map").offset().top +
$("#map").parent().offset().top +
$("#map").parent().parent().offset().top +
$("#map").parent().parent().parent().offset().top;
$("#map").height($(window).height() - t - ($(window).height() * 8 / 100));
Thanks...
See .offset() here in the jQuery doc. It gives the position relative to the document, not to the parent. You perhaps have .offset() and .position() confused. If you want the position in the window instead of the position in the document, you can subtract off the .scrollTop() and .scrollLeft() values to account for the scrolled position.
Here's an excerpt from the doc:
The .offset() method allows us to retrieve the current position of an
element relative to the document. Contrast this with .position(),
which retrieves the current position relative to the offset parent.
When positioning a new element on top of an existing one for global
manipulation (in particular, for implementing drag-and-drop),
.offset() is the more useful.
To combine these:
var offset = $("selector").offset();
var posY = offset.top - $(window).scrollTop();
var posX = offset.left - $(window).scrollLeft();
You can try it here (scroll to see the numbers change): http://jsfiddle.net/jfriend00/hxRPQ/
For the absolute coordinates of any jquery element I wrote this function, it probably doesnt work for all css position types but maybe its a good start for someone ..
function AbsoluteCoordinates($element) {
var sTop = $(window).scrollTop();
var sLeft = $(window).scrollLeft();
var w = $element.width();
var h = $element.height();
var offset = $element.offset();
var $p = $element;
while(typeof $p == 'object') {
var pOffset = $p.parent().offset();
if(typeof pOffset == 'undefined') break;
offset.left = offset.left + (pOffset.left);
offset.top = offset.top + (pOffset.top);
$p = $p.parent();
}
var pos = {
left: offset.left + sLeft,
right: offset.left + w + sLeft,
top: offset.top + sTop,
bottom: offset.top + h + sTop,
}
pos.tl = { x: pos.left, y: pos.top };
pos.tr = { x: pos.right, y: pos.top };
pos.bl = { x: pos.left, y: pos.bottom };
pos.br = { x: pos.right, y: pos.bottom };
//console.log( 'left: ' + pos.left + ' - right: ' + pos.right +' - top: ' + pos.top +' - bottom: ' + pos.bottom );
return pos;
}
BTW, if anyone want to get coordinates of element on screen without jQuery, please try this:
function getOffsetTop (el) {
if (el.offsetParent) return el.offsetTop + getOffsetTop(el.offsetParent)
return el.offsetTop || 0
}
function getOffsetLeft (el) {
if (el.offsetParent) return el.offsetLeft + getOffsetLeft(el.offsetParent)
return el.offsetleft || 0
}
function coordinates(el) {
var y1 = getOffsetTop(el) - window.scrollY;
var x1 = getOffsetLeft(el) - window.scrollX;
var y2 = y1 + el.offsetHeight;
var x2 = x1 + el.offsetWidth;
return {
x1: x1, x2: x2, y1: y1, y2: y2
}
}