I want to create a 'magnifying lens' ui for a web page. Anything on the page directly below the lens should be visible, while everything else should be made semi-transparent. In other words, I want to create a semi-transparent layer (which blocks the entire page) with a transparent 'hole' (lens) in it. I should be able to move the lens around, and possibly, resize the lens as well. I have thought of a solution that involves covering the entire page with 3x3 divs, making all the divs semi-transparent except for the middle one which will host the lens and will be completely transparent. I would then handle resize & move of the lens-div (and other divs around it) in javascript. I am looking for alternate, simpler solutions to this problem.
Thanks in advance!
Nice question! Consider this simplified implementation:
var $helperLeft = $('.helper-left'),
$helperRight = $('.helper-right'),
$helperTop = $('.helper-top'),
$helperBottom = $('.helper-bottom'),
$view = $('.view').draggable({
drag: onDrag
}),
viewWidth = $view.width(),
viewHeight = $view.height();
function onDrag(event, ui) {
$helperLeft.css({width: ui.position.left});
$helperRight.css({left: ui.position.left + viewWidth});
$helperTop.css({
width: viewWidth,
left: ui.position.left,
height: ui.position.top
});
$helperBottom.css({
top: ui.position.top + viewHeight,
left: ui.position.left,
width: viewWidth
});
}
onDrag(null, {position: $view.position()});
That's it! Very short and simple. I think resizing is straightforward too.
Demo: http://jsfiddle.net/j74A9/
Related
I want to implement the following in HTML/JavaScript but don't really know where to start or even if there is already an existing function in one toolkit for this:
I have one image (e.g. a png) which is visible and a second image of the same size which is not visible. However, if I move the mouse pointer over the first image, the corresponding part from the second image shall be shown around the mouse cursor. So for example, if I move the mouse at position 100,100 on the first image, the section from 50,50 to 150,150 of the second image should be overlaid on the first image at position 50,50 to 150,150. I hope this is understandable.
Does anyone know, if there is already a library which contains this functionality? I've already searched for this on the internet but found nothing. However, I do not really know what keywords to search for. So if someone knows a keyword to search for, I would be appreciate hints as well.
Alternatively, Can you give me a cue how could I grep the part of the second image and display it at the mouse position? I was thinking that canvas might be used but I am not sure how to.
Thank you very much and best regards
Tobias
This can be done with Vanilla JS or JQuery. Basic idea behind it is to wrap the image in a container with position:relative and listen to mouse movement on it. A second <div> with position:absolute will receive the coordinates of the mouse pointer with its background position set to match the current mouse offset.
The posted code is just to give an idea how this would look like and needs to be extended to properly handle the edges of the image.
$(".hover-container").on("mousemove", function (e) {
var parentOffset = $(this).parent().offset();
//or $(this).offset(); if you really just want the current element's offset
var relX = e.pageX - parentOffset.left;
var relY = e.pageY - parentOffset.top;
var picHeight = $('.hover-image').height();
var picWidth = $('.hover-image').height();
$('.hover-image')
.css("left", relX - 50 + "px")
.css("top", relY - 50 + "px")
.css("background-position", (picWidth-relX-50) + "px "
+ (picHeight-relY-50) + "px")
});
.hover-container {
position: relative;
}
.hover-image {
position: absolute;
width: 100px;
height: 100px;
background: url(https://i.imgur.com/Hp5pUVA.jpg);
background-position: 0 0;
}
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<div class="hover-container">
<img class="hover-over" src="https://i.imgur.com/j0yhQez.jpg"/>
<div class="hover-image"></div>
</div>
I'm trying to solve an issue with css "position:fixed" property on mobile browsers. I have a fixed div:
<div id="logo">
...other content here...
</div>
with css:
#logo{
position: fixed;
-webkit-backface-visibility: hidden;
bottom: 100px;
right: 0px;
width: 32px;
height: 32px;
}
So, usually the behaviour is exactly the desired one, with the div position always on the bottom right of the window, indipendently of the scroll position.
My issue is that on mobile browsers, when the users zoom the page, after a certain zoom level the div position is wrong (sometimes the div disappear out of the window).
I know that fixed position is not well supported on mobile browsers, but I wonder if there is some workaround. I tried with this js code onScroll event:
window.addEventListener('scroll', function(e){
drag.style['-webkit-transform'] = 'scale(' +window.innerWidth/document.documentElement.clientWidth + ')';\\I want to avoid zoom on this element
var r = logo.getBoundingClientRect();
var w = window.innerWidth;
var h = window.innerHeight;
if(r.right != w){
rOff = r.right - w;
logo.style.right = rOff;
}
if(r.top+132 != h){\
tOff = r.top + 132 - h;
logo.style.bottom = tOff;
}
});
Unfortunately, the code seems to return the wrong position.
Does anyone have any tip?
Ok, that's how I solved the issue...I hope that could help anyone to simulate fixed position on iOS devices.
I switched the position from fixed to absolute;
Attach to window a listener to get the new position when the page is scrolled or zoomed,
setting window.onscroll and window.onresize events with the following function:
function position() {
drag.style.left = window.innerWidth + window.pageXOffset - 32 + 'px';
drag.style.top = window.innerHeight + window.pageYOffset - 132 + 'px';
}
Do you want to catch if zoom is active?
There's no window.onZoom listener, but you can read this thread:
Catch browser's "zoom" event in JavaScript
and this answer: https://stackoverflow.com/a/995967/3616853
There's no way to actively detect if there's a zoom. I found a good entry here on how you can attempt to implement it.
I’ve found two ways of detecting the zoom level. One way to detect zoom level changes relies on the fact that percentage values are not zoomed. A percentage value is relative to the viewport width, and thus unaffected by page zoom. If you insert two elements, one with a position in percentages, and one with the same position in pixels, they’ll move apart when the page is zoomed. Find the ratio between the positions of both elements and you’ve got the zoom level. See test case. http://web.archive.org/web/20080723161031/http://novemberborn.net/javascript/page-zoom-ff3
You could also do it using the tools of the above post. The problem is you're more or less making educated guesses on whether or not the page has zoomed. This will work better in some browsers than other.
There's no way to tell if the page is zoomed if they load your page while zoomed.
Just a theory, but you may want to try setting the bottom/right positions in % rather than px.
I think what you're seeing when using pixel measurements is just the zoom effecting the pixels. Or to put it better, when you zoom-in the pixels appear larger and that throws off the position of the element, even pushing it out of the view-port on smaller screens.
Example using pixel positioning
Notice that even on a desktop as you zoom-in and out the element appears to move up and down?
Example using percent positioning
In this example the element appears to stay in the bottom right corner, because it is always positioned at 10% from the bottom of the view-port.
#logo{
position: fixed;
-webkit-backface-visibility: hidden;
bottom:10%;
right: 0;
width: 32px;
height: 32px;
}
Having two different z-index for the logo and the rest of the page could help. Allowing zooming only to the rest of the page and not to the z-index layer where logo is included. So, this might not affect the stretching on the logo.
We can
Implement a ZOOM listener
Attach it to browser
Make the zoom listener change the zoom level of the element (modify the elements position) using z-index as a factor.
Basically I am trying to create a little image at the top corner of a webpage, which would stay in the same position even if the page is scrolled and would show the position of the mouse.
The point is to have a large webpage that would extend down and right, and navigation of this large page would be easier if I had a little image that indicated where exactly the visitor is on this page (as the browser window is smaller than the page). I wanted to to just track the browser window position on the web page, but I cannot find anything that would help me do it, so I thought I might do it with just the mouse movement. The problem is that I know about nothing about java, so does anyone know how I could track the mouse position on the page (not the browser) and display it at the same time on a small image on the upper corner of the browser?
This would work, but only in modern browsers that support css3 transforms (scale):
JsFiddle
It works by copying the whole page that should be in the .actual-page div into a .thumbnail div which is positioned on the top left of the page. Then I scale the cloned page with css transforms and use javascript to replicate mouse movements into the little box, here's the script:
var TinyNav = function() {
this.init = function() {
var clone = $('.actual-page').clone();
$('.thumbnail').append(clone);
$('.actual-page').on('mousemove', function(e) {
var posX = e.offsetX;
var posY = e.offsetY;
$('.thumbnail .cursor').css({
top: posY / 10,
left: posX / 10
});
});
}
this.init();
}
var tinyNav = new TinyNav();
Another way of doing it would be using canvas, but browser support isn't the best with that either..
Hope this helps
I have a circular background image inside a div. to start off with i need to not have the 'bubbles' to display. and after arriving on that page the bubble would grow into place like a bubble or in other words 'pop' into place. I have no idea how i would go about creating this in jquery. this also needs to work on all browsers including ie7+ any help would be grateful
jQuery show() function
jQuery animate
These should give you an idea.
You might also consider using images to illustrate what you're trying to achieve.
I recommend building the content you need, and then asking people how you can change it to get the results you want. That will be easier for people to answer.
For the popping effect you really need to animate 4 different styles, depending on your CSS preference you can animate top and left or if you're using margins (why?) margin-top and margin-left, this will give you the effect of the "bubble" expanding center outwards instead of top left to bottom right.
This is a jQuery example for top/left
var newHeight = 300;
var newWidth = 300;
jQuery('#element').animate({
"top":newHeight/2,
"left":newWidth/2,
"height":newHeight,
"width":newWidth,
"opacity":1
}, 'fast', easeInOutCirc);
You may find the easing effects here: http://gsgd.co.uk/sandbox/jquery/easing/
its worth noting you should be a little more specific with your questions, we're not mind readers :)
This is a simplified version of this fiddle where I did something very similar to what you're doing. Hope it helps.
function(){
var position = $('#bubbleposition'),
bubble = $('#bubble'),
startRadius = 200,
newRadius = 400,
startleft = 10,
starttop = 10,
endleft = 50,
endtop = 50;
position.css({left: startleft, top: starttop, 10)});
bubble.css({height: startRadius, width: startRadius});
position.animate({left: endleft, top: endtop});
bubble.animate({height: newRadius, width: newRadius}, 400);
}
<div id='bubbleposition'>
<div id='bubble'>
Hello!
</div>
</div>
The site I'm working on has a collection of navigation elements across the top ("Products", "Company", etc.). When you mouse over the Products link, an overlay appears that shows a list of products with links to each. There's a small link at the top of the container that, when clicked, closes the container. All of this works as advertised.
The client has asked that, once a user's mouse pointer is a sufficient distance from the overlay element, the overlay element would close (without them having to click the 'close' link). This element appears on multiple pages that have disparate content, so I'm afraid it won't be as simple as adding a mouseover listener to another single element within the page and have it work everywhere. My question, I suppose, is this: is there a relatively easy way to know when the mouse cursor is x pixels away from this container and trigger an event when this occurs?
My other thought is that I could just find several elements on the page that fit this criteria and add mouseover listeners to each, but I'm assuming there's a more elegant way of handling this.
Thanks in advance - and please let me know if more detail is needed.
Here's one example.
http://jsfiddle.net/CsgFk/
Calculate the bounds you want around the overlay, and set up a mousemove hanlder on the document, which tests to see if the mouse is outside the bounds.
EDIT: It may be worthwhile to unbind the mousemove from the document when the overlay is hidden, and rebind it when revealed so that the mousemove isn't constantly firing for no reason. Or at the very least, have the mousemove handler check to see if the overlay is already hidden before hiding it.
HTML
<div id='overlay'></div>
CSS
#overlay {
width: 200px;
height: 200px;
background: orange;
position: relative;
top: 123px;
left:23px;
}
jQuery
var $ovl = $('#overlay');
var offset = $ovl.offset();
var height = $ovl.height();
var width = $ovl.width();
var bounds = {top: offset.top - 100,
bottom: offset.top + height + 100,
left: offset.left - 100,
right: offset.left + width + 100
}
$ovl.mouseenter(function() {
$ovl.stop().animate({opacity:1});
});
$(document).mousemove(function(e) {
if(e.pageX < bounds.left ||
e.pageX > bounds.right ||
e.pageY < bounds.top ||
e.pageY > bounds.bottom) {
$ovl.stop().animate({opacity:.3});
}
});
EDIT:
Here's another idea (although it is heavily dependent on your layout). Place the overlay inside a container that has a large padding and remove the overlay when the pointer performs a mouseleave on the container. Again, this may not be feasible in your layout.
EDIT:
One other idea would be to set a delay on the code used to remove the overlay. Its not as precise, but may yield a sufficiently desirable effect.
Why not use a mouseout event with a timer?
var zGbl_OverlayCloseTimer = '';
OverlayElement.addEventListener ("mouseout", CloseOverlayWithDelay, false);
function CloseOverlayWithDelay (zEvent)
{
if (typeof zGbl_OverlayCloseTimer == "number")
{
clearTimeout (zGbl_OverlayCloseTimer);
zGbl_OverlayCloseTimer = '';
}
zGbl_OverlayCloseTimer = setTimeout (function() { CloseOverlay (); }, 333);
}
function CloseOverlay ()
{
...
}