I have a PNG image of a graph on an HTML page.
I'm hoping to include a set of superimposed x and y guide-lines that appear on mouse over, whose vertex follows the mouse pointer, in order to help users read values on the x and y axes.
For example, they use such an effect on WolframAlpha (doesn't work in IE<8 though):
http://www.wolframalpha.com/input/?i=graph+y%3D2x
Does anyone have any ideas on how to accomplish this, javascript or otherwise? I believe WolframAlpha is somehow using the HTML5 canvas if that helps (see screenshot below).
Although if there's a way to avoid using canvas in order to support IE8, that would be excellent. The gridlines could certainly also extend off the image boundary and across the whole page, if that would make it easier.
Here is a simple implementation
CSS
#imageholder div{ background-color:black;position:absolute; }
#imageholder{;position:relative;display:inline-block;overflow:hidden; }
#horizontal{width:100%;height:1px;}
#vertical{width:1px;height:100%;}
JS(use of jquery)
$('#imageholder img').on('mousemove', null, [$('#horizontal'), $('#vertical')],function(e){
e.data[1].css('left', e.offsetX==undefined?e.originalEvent.layerX:e.offsetX);
e.data[0].css('top', e.offsetY==undefined?e.originalEvent.layerY:e.offsetY);
});
$('#imageholder').on('mouseenter', null, [$('#horizontal'), $('#vertical')], function(e){
e.data[0].show();
e.data[1].show();
}).on('mouseleave', null, [$('#horizontal'), $('#vertical')], function(e){
e.data[0].hide();
e.data[1].hide();
});
HTML
<div id="imageholder">
<div id="horizontal"></div>
<div id="vertical"></div>
<img src="http://placehold.it/320x280">
</div>
DEMO
Also with lines that goes across the page DEMO
Related
I have built a WordPress theme. I came across a website that created a div to follow the user's cursor. The div was enlarged smoothly when the user hovers over a button or a link.
I want to add this nice functionality as an optional feature.
I added a div to the web page, #ambition_cursor and added some basic styling. The div now shows like a blue circle. The circle has position fixed to the top left corner of the site. The position can be changed by adding a CSS translate property.
I managed to make it work with the following code:
var ambition_cursor = document.getElementById("ambition_cursor");
function ambition_mouse(e) {
var ambition_cursor_x = e.clientX; // Get the horizontal coordinate
var ambition_cursor_y = e.clientY; // Get the vertical coordinate
var ambition_cursor_pos = `translate(${ambition_cursor_x}px, ${ambition_cursor_y}px)`;
ambition_cursor.style.transform = ambition_cursor_pos;
}
window.addEventListener('mousemove', ambition_mouse);
The big downside here is the lag (?). There's quite a big delay, especially when moving the mouse around very fast. You can try it out on this site. I also put the situation in a JSFiddle; although the delay doesn't really happen there.
I didn't apply yet much styling (the default cursor is visible, so you can get a better idea of the real position). I first want this to work better, before I spent much time on that.
How can I increase the speed of this, so that the div position follows the mouse more accurately? I'm a beginner, so I don't really know which JavaScript optimisations I should make.
Current code is JavaScript, but jQuery is also an option.
Many thanks in advance!
Update: example how it looks on my computer.
All elements on the page have a transition applied. Remove/override this style and the delay goes away (tested).
As an alternative to the great answer of Joseph Atkinson:
var ambition_cursor = document.getElementById("ambition_cursor");
function ambition_mouse(e) {
ambition_cursor.style.left = e.clientX + 'px'; // Get the horizontal coordinate
ambition_cursor.style.top = e.clientY + 'px' ; // Get the vertical coordinate
}
window.addEventListener('mousemove', ambition_mouse);
See: https://levelup.gitconnected.com/use-javascript-to-make-an-element-follow-the-cursor-3872307778b4
I visited the site example, cracked open the dev console, and found throttled(20, ambition_mouse) It is not a performance issue, and the solution is to not throttle the events. It was too smooth to be a performance issue, which gave me the first clue it had to be an accidental/deliberate effect.
This is certainly going to be an easy one but I can't get my head around what I am doing wrong...
I am trying to do a hover effect on a UL that affects a link within one of the UL LI's.
My current code looks like this:
$("ul.punchlines").hover(function () {
$(this).find("li a.light-grey-gradient").animate({'width' : '60%','top':'-65px'});
});
$("ul.punchlines").mouseleave(function () {
$(this).find("li a.light-grey-gradient").animate({'width' : '30%','top':'0px'});
});
This technically works as it gives the effect that the base of the element to be scaled remains in place and scales up from the bottom however it does it in two stages, I am trying to get this effect to happen all in one motion so it is a seamless scale and move.
I can do this easily with basic CSS3 transitions but as it is not supported in IE9 I am trying to use jQuery to allow for maximum browser support.
Can anyone offer a little support firstly about how I get the animation to happen in one motion (not staggered) and secondly if this is the right approach? I am new to jquery and only just getting my hands dirty with it :-)
Please see JQuery hover api:
http://api.jquery.com/hover/
also make sure that your "li" have absolute position.
$("ul.punchlines").hover(function () {
$(this).find("li a.light-grey-gradient").animate({'width' : '60%','top':'-65px'});
}, function () {
$(this).find("li a.light-grey-gradient").animate({'width' : '30%','top':'0px'});
});
Please see attached image:
The html (I just broke it up in 3 lines so you wouldn't have to scroll to the right):
<!-- MapServer Template -->
<area shape="circle" coords="[shpxy precision=0 proj=image yf=",7" xf=","]"
title="[name]" alt="[name]" onmouseover='displayCityInfo("[name]");
displayToolTip();' onmouseout="hideCityInfo()">
The jquery:
function displayToolTip() {
$( document ).tooltip({track: true, items: '[title]', content: getContent});
}
function getContent() {
var element = $(this);
if (element.is('[tooltip]')) {
var src = element.attr('tooltip');
return '<img src="' + src + '" width="100">';
}
if (element.is('[title]')) {
return element.attr('title');
}
}
The issue:
I am not sure why there is basically "double hovers". If I just move my mouse around the map quickly, the names get stacked on top of each other in the top left corner.
1) I do not want any tool tips in the top left corner.
2) I just want to hover over a golden point, and the tool tip appears. As you can see in the image, this is happening...somewhat.
3) Don't mind the teal-colored rectangle.
The goal:
Remove the tool tips in the top left corner, and just have tool tips when you hover over a golden point.
Any input on the matter is appreciated. I was looking through the documentation but I am not sure what I'm doing wrong.
Tooltips are one of those things that never quite works the way you expect it to and end up taking a lot more time than you expect. There a lot of factors involved but most notoriously are timing and browser type and version.
The timing issue: if the element you are hovering on has an alt or a title attribute at render time, once the hover event fires and the listener is called, it's too late, the default tooltip will show no matter what you at that point. Sometimes, you might get lucky and solve it with a event.preventDefault() or browser equivalents.
The browser issue: unsurprisingly, many versions of IE (7,8,9) once the alt or title attribute has been rendered, there is just no way to stop it from displaying the default tooltip. There are several workarounds but most include removing alt and title attributes from the html itself (i.e. before the browser has a chance to see it) and using an xhr to get the text contents of the tooltip.
Hope this helps.
I would like to do something like this: http://javascript.about.com/library/blcmarquee1.htm
The script I referenced however seems to be a bit laggy (outdated?), so I was wondering if anyone knew of a better solution. (jQuery solutions welcome.)
Just found this — jQuery-driven, and has images. I’m intending to use it for a current project.
http://logicbox.net/jquery/simplyscroll/
UPDATE: I have now used this in production code. The plugin is capable of looping 70+ 150×65px images pretty smoothly - which a number of another plugin I tried similar to this were failing on.
NOTE it reeked havoc with z-index issues in IE 6 / 7 and was not showing up etc. - But this might also have been partly due to my CSS. To anyone having trouble with it not showing up at all in IE check out the standard IE z-index fixes: http://www.google.com/search?q=ie+z+index+issues
LATEST UPDATE:
Addition things to consider when implementing plug-ins like these:
The number of items and type of content to scroll. I found a number that would start to glitch as soon as you had more than say 15 images to scroll.
I found a number of these plugins that were tied to old versions of jquery
If scrolling images ARE THEY ALL THE SAME SIZE again a number of the plug-ins I experimented with only worked if all the images were the same size but did not make this clear in the tutorials. I believe then the plugins run then set a string of li tags that are all x wide then calculate the total distance of them all chained together to manage the scrolling.
Effects - some would continuously scroll others would move one image pause for a second then move another image
I have now also found these two scroller plugins to be very good as well.
http://caroufredsel.frebsite.nl/
http://sorgalla.com/jcarousel/
The Silky-Smooth jQuery Marquee and Giva Labs' Marquee
Just a thought. Could you do something like this.
<style type="text/css">
.imgwindow{
width:500px; //or whatever
height:65px; //or whatever
position:relative;
overflow:hidden;
}
.imgholder{
min-width:2000px;
height:65px;
position:absolute;
left:-200px;
}
.inline-image{
display:inline-block;
}
</style>
<script type="text/javascript">
var img;
function imgScroll(){
img = $(".inline-image").first();
img.animate({width:0},2500,'linear',function(){
img.remove();
$(".imgholder").append(img);
imgScroll();
});
}
$(document).ready(function(){
imgScroll();
});
</script>
and the html
<div class="imgwindow">
<div class="imgholder">
<img class="inline-image" src="image1" /><img class="inline-image" src="image2" />...
</div>
</div>
Here is a link: http://www.avineon.com/
Open this link see on the top. Four images are rotating.
I need something similiar using Javascript.
Is it possible by using Javascript.
I don't think you'll have much luck if you try to do that in pure javascript. It might be possible using the emerging canvas and SVG libraries such as Raphael, but you'll still have cross-browser issues. That site used Flash, and I'd recommend using that if you wanted such an effect.
...why you'd want that on your website is another story though...
You could so something similar, but not exact.
Transparency = Supported in FF, Safari, IE7+
Changing image width = Place image in div with this Css
.class img {
display: block;
width: 100%;
height: 100%
}
This will make the image stretch to fill the .class div. You can then use JS to make this div narrower like the carousel does, and the image contained will animate within the div.
You would then need to track the mouse locations to determine how fast it spins.
You can use an equation using cosine for smooth acceleration from the far ends (IIRC)
You will not however be able to get the images in reverse, unless you create a copy in a server side language or use canvas.
Your best bet would not be to attempt to render something in actual 3D, but rather to use visual tricks to approximate a 3D effect. That is, use perspective / image deformation to make it look like a cube is rotating, similar to what is implemented at this page, which has a better explanation of the math involved.
Really, though, you're probably better off just using Flash.
That effect is possible in JavaScript simply by modifying each of the images width, height, and left styles over time. It's an involved script, but only needs to interpolate those three styles on the each of the image elements.
To get the rotation effect, decrement the width style of the image in a setInterval function while moving the left style property. There is a slight decrement on the height also.
You'll need two images for each side, a front and reverse. When the width decrements to zero, swap the image with it's flipped version and start incrementing the width.
Alternatively use Webkit's, and Firefox's transform css properties.
Or try one of these coverflow components that look similar:
Protoflow,
ImageFlow
<html>
<head>
<title></title>
</head>
<body>
<script type="text/javascript">
if (document.all || document.getElementById){ //if IE4 or NS6+
document.write('<style type="text/css">\n');
document.write('.dyncontent{display: none; width: 728px; height: 90px;}\n');
document.write('</style>');
}
var curcontentindex=0;
var messages=new Array();
function getElementByClass(classname){
var inc=0;
var alltags=document.all? document.all : document.getElementsByTagName("*");
for (i=0; i<alltags.length; i++){
if (alltags[i].className==classname)
messages[inc++]=alltags[i];
}
}
function rotatecontent(){
//get current message index (to show it):
curcontentindex=(curcontentindex<messages.length-1)? curcontentindex+1 : 0;
//get previous message index (to hide it):
prevcontentindex=(curcontentindex==0)? messages.length-1 : curcontentindex-1;
messages[prevcontentindex].style.display="none"; //hide previous message
messages[curcontentindex].style.display="block"; //show current message
}
window.onload=function(){
if (document.all || document.getElementById){
getElementByClass("dyncontent");
setInterval("rotatecontent()", 5000);
}
}
</script>
<table width="100%">
<tr align="center">
<td>
<div class="dyncontent" style="display: block">
first
</div>
<div class="dyncontent">
second
</div>
<div class="dyncontent">
Third
</div>
</td>
</tr>
</table>
</body>
</html>