I'm trying to get my png to move to the mouse click position when the user clicks within the container but I cant get the png to respond. I'm following this tutorial (https://www.youtube.com/watch?v=b4GwvdhrEQg), and stuck on the first test. my target doesnt respond to clicks at all.
Please help
var theGirl = document.querySelector("#girl");
var container = document.querySelector("#floor");
container.addEventListener("click", getClickPosition, false);
function getClickPosition(e) {
var xPosition = e.clientX - (theGirl.offsetWidth / 2);
var yPosition = e.clientY; - (theGirl.offsetHeight / 2)
var translate3dValue = "translate3d(" + xPosition + "px" + yPosition + "px, 0)";
theGirl.style.transform = translate3dValue;
}
#floor {
width: 700px;
height: 600px;
cursor: pointer;
overflow: visible;
border: 10px #EDEDED solid;
}
#girl {
height: 450px;
width: 200px;
border: 15px red solid;
transform: translate3d(50px, 50px, 0);
}
<body>
<div id="floor">
<div>
<img src="girl.png" id="girl"> </div>
</div>
Change #girl's position to absolute. I think it works after that.
Related
The following code always shows the coordinates of the cursor below the cursor:
function showCoords(e) {
var x = event.clientX;
var y = event.clientY;
var coor = "(" + x + ", " + y + ")";
document.getElementById("box").innerHTML = coor;
var bx = document.getElementById("box");
bx.style.left = e.pageX - 50;
bx.style.top = e.pageY + 20;
}
function clearCoords() {
document.getElementById("box").innerHTML = "";
}
div.relative {
position: relative;
width: 400px;
height: 300px;
border: 1px solid black;
}
div.abs {
position: absolute;
top: 100px;
right: 50px;
width: 200px;
height: 100px;
background-color: yellow;
}
<body onmousemove="showCoords(event)">
<div class="relative">
<div class="abs" onmousemove="showCoords(event)" onmouseout="clearCoords()"></div>
</div>
<div id="box" style="width:100px; height:30px; position:absolute"></div>
</body>
I only want the coordinates to be visible when the mouse pointer is hovering over the yellow rectangle.
If I change <body onmousemove="showCoords(event)"> to <body>, the coordinates are never visible.
How do I get the coordinates be visible only when hovering over the yellow rectangle?
Move the onmousemove listener from the body to the element you want to listen on - div.abs in this case.
I'd recommend not using the onmousemove attribute, in favour of using an entirely javascript solution - just to keep javascript-y things together. Something like (untested)
var listenOn = document.querySelector(".abs");
listenOn.addEventListener("mousemove", ShowCoords);
I can make a box that follows the mouse with the following.
document.addEventListener('mousemove', (e) => {
document.documentElement.style.setProperty('--mouse-x', e.clientX + 'px');
document.documentElement.style.setProperty('--mouse-y', e.clientY + 'px');
});
.box {
width: 50px;
height: 50px;
background-color: blue;
transform: translate(calc(var(--mouse-x) - 50%), calc(var(--mouse-y) - 50%));
}
<div class="box"></div>
but as soon as the element is not positioned at the top left, it breaks.
document.addEventListener('mousemove', (e) => {
document.documentElement.style.setProperty('--mouse-x', e.clientX + 'px');
document.documentElement.style.setProperty('--mouse-y', e.clientY + 'px');
});
.box {
width: 50px;
height: 50px;
margin-left: 150px;
background-color: blue;
transform: translate(calc(var(--mouse-x) - 50%), calc(var(--mouse-y) - 50%));
}
<div class="box"></div>
How can I use absolute coordinates with a transform? I don't want to use left/top/position: fixed/absolute because I need to preserve the position of the element in the flow.
I could use JavaScript to grab the central position and then use that infomation to get the correct center.
document.addEventListener('mousemove', (e) => {
document.documentElement.style.setProperty('--mouse-x', e.clientX + 'px');
document.documentElement.style.setProperty('--mouse-y', e.clientY + 'px');
});
window.addEventListener('load', (e) => {
const box = document.querySelector('.box');
const rect = box.getBoundingClientRect();
box.setAttribute('style', `
--center-x: ${rect.left + (rect.width / 2)}px;
--center-y: ${rect.top + (rect.height / 2)}px;
`);
});
.box {
width: 50px;
height: 50px;
margin-left: 150px;
background-color: blue;
transform: translate(calc(var(--mouse-x) - var(--center-x)), calc(var(--mouse-y) - var(--center-y)));
}
<div class="box"></div>
This works, but it's not ideal and easily broken if anything else in the page changes. It also slows down with more elements, and I'd like it to be as fast as possible. It there a better way to do this? I'm fine using CSS/Vanilla JS.
You don't have to use translate() please I would recommend you to use the left and top properties in CSS. They can help you position an element based on coordinates.
window.addEventListener('load', (e) => {
const box = document.querySelector('.box');
const rect = box.getBoundingClientRect();
document.addEventListener('mousemove', (e) => {
box.style.left = e.pageX + 'px';
box.style.top = e.pageY + 'px';
});
});
.box {
width: 50px;
height: 50px;
position:absolute;
transform:translate(-50%,-50%);
background-color: blue;
}
<div class="box"></div>
The transform: translate() property works relative to the size of the box but the left and top properties don't. It can also be much faster in some cases because in your code there was a lot of calculation going on. Whereas, this is straightforward.
Here is a solution using the requestAnimationFrame() function. The requestAnimationFrame() method tells the browser that you wish to perform an animation and requests that the browser calls a specified function to update an animation before the next repaint. For higher refresh rate monitors, this function will be run more the number of times to match the refresh rate.
More information here
Here is the working solution:
const box = document.querySelector('.box');
const rect = box.getBoundingClientRect();
let mouseX = 0;
let mouseY = 0
document.addEventListener('mousemove', (e) => {
mouseX = e.pageX + 'px';
mouseY = e.pageY + 'px';
})
function mouseMove() {
box.style.left = mouseX;
box.style.top = mouseY;
requestAnimationFrame(mouseMove)
};
mouseMove()
.box {
width: 50px;
height: 50px;
position: absolute;
transform: translate(-50%, -50%);
background-color: blue;
}
<div class="box"></div>
I have a table full of data that tends to be larger than the screen.
I put the table in a DIV and set the "overflow" to "auto" in CSS
div.scrolling-comps {
width : 970px;
height : 800px;
overflow : auto;
}
So the DIV can be scrolled up/down, left right using the browser's built-in scroll bars.
Problem is, the table can be WAAY bigger than the screen. And while the mousewheel will scroll it up/down, scrolling left/right is a pain in the hooch.
So, looking for a javascript/jquery or CSS way to scroll the div NATURALLY.
In other words, when someone viewing the huuuge table moves their mouse to the right, the DIV goes to the left (thus scrolling without using the scroll bars).
Something similar to this, but instead of following the mouse, the div would move opposite the mouse...
window.onload = function() {
var bsDiv = document.getElementById("box-shadow-div");
var x, y;
// On mousemove use event.clientX and event.clientY to set the location of the div to the location of the cursor:
window.addEventListener('mousemove', function(event) {
x = event.clientX;
y = event.clientY;
if (typeof x !== 'undefined') {
bsDiv.style.left = x + "px";
bsDiv.style.top = y + "px";
}
}, false);
}
#box-shadow-div {
position: fixed;
width: 1000px;
height: 800px;
border-radius: 0%;
background-color: black;
box-shadow: 0 0 10px 10px black;
top: 49%;
left: 48.85%;
}
<div id="box-shadow-div"></div>
The example you have about using the mouse position is interesting... But it is not what you need to achieve what you described.
In fact... What you need to know is the "ratio" between the div wrapping the table and its scrollWidth
Then, using the X position of the mouse, you can apply a scroll to the div in order to make it "move".
I used jQuery to do it using very few lines.
// Just to fake a big table
var fakeCell = $("<td>Some data</td>");
for(i=0;i<100;i++){
var fakeRow = $("<tr>");
for(k=0;k<50;k++){
fakeRow.append(fakeCell.clone().append(" "+k));
}
$("#test").append(fakeRow.clone());
}
// ---------------------------------------------------
// Calculate the "ratio" of the box-div width versus its scrollable width
var ratio = $("#box-div")[0].scrollWidth / $("#box-div").width();
console.log("Ratio: "+ratio);
// Scroll left/rigth based on mouse movement
$(window).on("mousemove", function(e){
var X = ratio * e.pageX;
// Scroll the div using the mouse position multiplyed by the ratio
$("#box-div").scrollLeft(X);
});
td{
white-space: nowrap;
border: 1px solid black;
}
#box-div{
overflow:auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div id="box-div">
<table id="test">
</table>
</div>
</body>
So while the user moves the mouse over the div's width, you apply a scroll multiplied by the ratio... The effect is the user can scroll it all from the most left to most right ends easilly.
How about this?
wrap a table in div (i.e. parent-div) which is relatively positioned
Give position absolute to the target div.
And change left & top position of target div on mousemove event.
window.onload = function() {
var bsDiv = document.getElementById("box-shadow-div");
var x, y;
// On mousemove use event.clientX and event.clientY to set the location of the div to the location of the cursor:
window.addEventListener('mousemove', function(event) {
x = event.clientX;
y = event.clientY;
if (typeof x !== 'undefined') {
bsDiv.style.left = -x + "px";
bsDiv.style.top = -y + "px";
}
}, false);
}
.parent-div {
position: relative;
}
#box-shadow-div {
position: absolute;
width: 1000px;
height: 800px;
border-radius: 0%;
background-color: black;
box-shadow: 0 0 10px 10px black;
top: 0;
left: 0;
}
<div class="parent-div">
<div id="box-shadow-div"></div>
</div>
Have you tried changing x to -x? this will technically "invert" the effect.
window.onload = function() {
var bsDiv = document.getElementById("box-shadow-div");
var x, y;
// On mousemove use event.clientX and event.clientY to set the location of the div to the location of the cursor:
window.addEventListener('mousemove', function(event) {
x = event.clientX;
y = event.clientY;
if (typeof x !== 'undefined') {
bsDiv.style.left = -x + "px";
bsDiv.style.top = -y + "px";
}
}, false);
}
#box-shadow-div {
position: fixed;
width: 1000px;
height: 800px;
border-radius: 0%;
background-color: black;
box-shadow: 0 0 10px 10px black;
top: 49%;
left: 48.85%;
}
<div id="box-shadow-div"></div>
I want to build a page to show a blown-up version of an image.
I have the smaller image and the bigger image built out. I am not sure how to build the in between portion that looks like rays coming out of the smaller image.
HTML
<div class="flex">
<div class="exp" tabindex="0">
<img class="image" src="http://via.placeholder.com/50x50">
</div>
<div class="big-image">
<img class="image" src="http://via.placeholder.com/350x550">
</div>
</div>
CSS
.exp {
margin: 5px;
width: 100px;
height: 100px;
background-color: #ded3c0;
border-radius: 100%;
line-height: 80px;
align-items: center;
display: flex;
justify-content: center;
}
.exp .image {
width: 50px;
height: 50px;
}
.big-image {
border: 1px solid #000;
padding: 20px;
border-radius: 19px;
}
.flex {
display: flex;
align-items: center;
justify-content: space-around;
}
Any pointers on how to do this is helpful.
Here is jsfiddle https://jsfiddle.net/npkeq7ut/
If you need only lines you can achieve this with JS and skew transform:
let topLine = document.getElementById('top-line');
let bottomLine = document.getElementById('bottom-line');
function updateLines()
{
let b = document.getElementById('b').getBoundingClientRect();
let a = document.getElementById('a').getBoundingClientRect();
let left = a.right;
let width = b.left - a.right;
let tHeight = a.top - b.top;
let tTop = tHeight / 2 + b.top;
let tAngle = Math.atan(tHeight / width) * 180 / Math.PI;
let bHeight = b.bottom - a.bottom;
let bTop = bHeight / 2 + a.bottom - bottomLine.offsetHeight;
let bAngle = Math.atan(bHeight / width) * 180 / Math.PI;
topLine.style.top = tTop + "px";
topLine.style.left = left + "px";
topLine.style.width = width + "px";
topLine.style.transform = "skewY("+(-tAngle)+"deg)";
bottomLine.style.top = bTop + "px";
bottomLine.style.left = left + "px";
bottomLine.style.width = width + "px";
bottomLine.style.transform = "skewY("+(bAngle)+"deg)";
}
updateLines();
Fiddle: https://jsfiddle.net/JacobDesight/f40yeuqe/2/
#EDIT
If you want trapeze with background then here is example using canvas: https://jsfiddle.net/JacobDesight/f40yeuqe/3/
This could be a starting point for you.
Code by thecodeplayer.
http://thecodeplayer.com/walkthrough/magnifying-glass-for-images-using-jquery-and-css3
$(document).ready(function() {
var native_width = 0;
var native_height = 0;
//Now the mousemove function
$(".magnify").mousemove(function(e) {
//When the user hovers on the image, the script will first calculate
//the native dimensions if they don't exist. Only after the native dimensions
//are available, the script will show the zoomed version.
if (!native_width && !native_height) {
//This will create a new image object with the same image as that in .small
//We cannot directly get the dimensions from .small because of the
//width specified to 200px in the html. To get the actual dimensions we have
//created this image object.
var image_object = new Image();
image_object.src = $(".small").attr("src");
//This code is wrapped in the .load function which is important.
//width and height of the object would return 0 if accessed before
//the image gets loaded.
native_width = image_object.width;
native_height = image_object.height;
} else {
//x/y coordinates of the mouse
//This is the position of .magnify with respect to the document.
var magnify_offset = $(this).offset();
//We will deduct the positions of .magnify from the mouse positions with
//respect to the document to get the mouse positions with respect to the
//container(.magnify)
var mx = e.pageX - magnify_offset.left;
var my = e.pageY - magnify_offset.top;
//Finally the code to fade out the glass if the mouse is outside the container
if (mx < $(this).width() && my < $(this).height() && mx > 0 && my > 0) {
$(".large").fadeIn(100);
} else {
$(".large").fadeOut(100);
}
if ($(".large").is(":visible")) {
//The background position of .large will be changed according to the position
//of the mouse over the .small image. So we will get the ratio of the pixel
//under the mouse pointer with respect to the image and use that to position the
//large image inside the magnifying glass
var rx = Math.round(mx / $(".small").width() * native_width - $(".large").width() / 2) * -1;
var ry = Math.round(my / $(".small").height() * native_height - $(".large").height() / 2) * -1;
var bgp = rx + "px " + ry + "px";
//Time to move the magnifying glass with the mouse
var px = mx - $(".large").width() / 2;
var py = my - $(".large").height() / 2;
//Now the glass moves with the mouse
//The logic is to deduct half of the glass's width and height from the
//mouse coordinates to place it with its center at the mouse coordinates
//If you hover on the image now, you should see the magnifying glass in action
$(".large").css({
left: px,
top: py,
backgroundPosition: bgp
});
}
}
})
})
/*Some CSS*/
* {
margin: 0;
padding: 0;
}
.magnify {
width: 200px;
margin: 50px auto;
position: relative;
}
/*Lets create the magnifying glass*/
.large {
width: 175px;
height: 175px;
position: absolute;
border-radius: 100%;
/*Multiple box shadows to achieve the glass effect*/
box-shadow: 0 0 0 7px rgba(255, 255, 255, 0.85), 0 0 7px 7px rgba(0, 0, 0, 0.25), inset 0 0 40px 2px rgba(0, 0, 0, 0.25);
/*Lets load up the large image first*/
background: url('http://thecodeplayer.com/uploads/media/iphone.jpg') no-repeat;
/*hide the glass by default*/
display: none;
}
/*To solve overlap bug at the edges during magnification*/
.small {
display: block;
}
<!-- Lets make a simple image magnifier -->
<div class="magnify">
<!-- This is the magnifying glass which will contain the original/large version -->
<div class="large"></div>
<!-- This is the small image -->
<img class="small" src="http://thecodeplayer.com/uploads/media/iphone.jpg" width="200"/>
</div>
<!-- Lets load up prefixfree to handle CSS3 vendor prefixes -->
<script src="http://thecodeplayer.com/uploads/js/prefixfree.js" type="text/javascript"></script>
<!-- You can download it from http://leaverou.github.com/prefixfree/ -->
<!-- Time for jquery action -->
<script src="http://thecodeplayer.com/uploads/js/jquery-1.7.1.min.js" type="text/javascript"></script>
I have this HTML that renders a simple arrow sign pointing towards the right:
<!DOCTYPE html>
<html>
<head>
<style>
div { width: 0px; height: 0px; border-left: 20px solid black; border-top: 20px solid transparent; border-bottom: 20px solid transparent; border-right: 20px solid transparent; position: absolute; left: 35px; top: 53px; cursor: pointer; }
</style>
<body>
<div></div>
</body>
</html>
If you hover of it, the cursor turns to pointer. But because it is actually a square div, the cursor turns pointer even if you are just outside the arrow within the perimeter of the div.
So I wrote this Javascript addition such that the cursor turns pointer only when the mouse is hovering over that arrow. For this purpose, I figured the coordinates of the three vertices of the triangle from Firebug ((35,53),(55,73),(35,93) clockwise from top). Then I check whether the point in question lies inside the triangle formed by these 3 vertices. This I do by checking whether the point and the opposite vertex for each edge lies on the same side of that edge or not (if they do, the product of the values obtained by substituting the coordinates of that point for x and y in that equation will be positive).
<!DOCTYPE html>
<html>
<head>
<style>
div { width: 0px; height: 0px; border-left: 20px solid black; border-top: 20px solid transparent; border-bottom: 20px solid transparent; border-right: 20px solid transparent; position: absolute; left: 35px; top: 53px; }
.hoverclass { cursor: pointer; }
</style>
<script src="jquery.js">
</script>
<script>
$(document).ready(function(){
$("div").click(function(e) { alert(e.pageX + " " + e.pageY); });
function l1(x,y) { return y - x - 18; }
function l2(x,y) { return x+y-128; }
function l3(x,y) { return x-35; }
$("div").hover(function(e) {
var x = e.pageX;
var y = e.pageY;
if (l1(x,y)*l1(35,93) >= 0 && l1(x,y)*l1(35,93) >= 0 && l1(x,y)*l1(35,93) >= 0 ) {
$(this).addClass('hoverclass');
}
else { $(this).removeClass('hoverclass'); }
},
function() {
$(this).removeClass('hoverclass');
});
});
</script>
<body>
<div></div>
</body>
</html>
However, the results are not predictable. Sometimes the cursor turns pointer within the triangle only, sometimes outside as well (just as before), and sometimes not at all. I suspect that this is probably due to the hover function working overtime, that may be temporarily hanging the script. Is there any other way to achieve this?
This could be done using HTML5 canvas. Basic idea is to check for pixel color on mousemove on canvas element. This way, your element can be of any form as you wish. Of course, you should make some optimization of following code:
SEE WORKING DEMO
function findPos(obj) {
var curleft = 0, curtop = 0;
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
return { x: curleft, y: curtop };
}
return undefined;
}
// set up triangle
var example = document.getElementById('example');
var context = example.getContext('2d');
context.fillStyle = '#000';
context.strokeStyle = '#f00';
context.lineWidth = 1;
context.beginPath();
// Start from the top-left point.
context.moveTo(10, 10); // give the (x,y) coordinates
context.lineTo(60, 60);
context.lineTo(10, 120);
context.lineTo(10, 10);
// Done! Now fill the shape, and draw the stroke.
// Note: your shape will not be visible until you call any of the two methods.
context.fill();
context.stroke();
context.closePath();
$('#example').mousemove(function(e) {
var pos = findPos(this);
var x = e.pageX - pos.x;
var y = e.pageY - pos.y;
var coord = "x=" + x + ", y=" + y;
var c = this.getContext('2d');
var p = c.getImageData(x, y, 1, 1).data;
if(p[3]!='0') $(this).css({cursor:'pointer'});
else $(this).css({cursor:'default'});
});
You'd better use CSS instead. With :before and :after pseudo classes you can do magic. Check out this Pure CSS GUI icons by Nicolas Gallagher.
If you use any CSS pre-processor, these icons can be wrapped up as a mixin, this way required properties can be assigned like this:
#icon > .close(16px, #fff, #E83921);
You can make any shape have cursor pointer with CSS only. The idea is to rotate wrapper container which has overflow: hidden (you can have several of them depending on the shape you need). In case of OP problem this code does a trick:
<div class="arrow"><i></i></div>
.arrow {
margin: 100px;
border_: 1px red solid;
width: 40px;
height: 40px;
overflow: hidden;
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
.arrow i {
height: 65px;
width: 65px;
background-color: green;
content: '';
display: block;
cursor: pointer;
margin: -35px 0 0 11px;
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
See this demo: http://cssdesk.com/PaB5n
True that this requires CSS transform support so it's not cross browser.