I would like to have a div that follows the mouse coordinates the opposite direction and within a div .box. When you move your mouse the red box should move slightly to the opposite direction, so it looks like a kind of parallax effect. Now it will move on your mouse speed and that is not what I want. I would like that the box is move slightly, so you will see the box move a little bit to the opposite direction. And I would like to have align the box to the center of the mouse.
I already have code a script that let the red box follow your mouse movement, but doesn't know how to get above work.
$(document).ready(function(){
$('div.container').on('mousemove',function(e){
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
$('div.box').css({'left': x, 'top': y});
});
});
http://codepen.io/anon/pen/zBrkGa
Try to change top to bottom and left to right may solve your problem like,
$('div.box').css({'right': x, 'bottom': y});
$(document).ready(function() {
$('div.container').on('mousemove', function(e) {
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
$('div.box').css({
'right': x,
'bottom': y
});
});
});
.container {
margin: 0 auto;
width: 300px;
height: 300px;
border: 1px #000 solid;
position: relative;
}
.box {
width: 50px;
height: 50px;
border: 1px #000 solid;
position: absolute;
right: 200px;
background: red
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="container">
<div class="box"></div>
</div>
Updated, for fixing the box in 100px range with some delay
$(document).ready(function() {
$('div.container').on('mousemove', function(e) {
var x = (e.pageX - this.offsetLeft);
var y = (e.pageY - this.offsetTop);
if(x<100||x>200||y>200||y<100) return false;
setTimeout(function() {
$('div.box').css({
'right': x,
'bottom': y
}).text(x+','+y);
}, 500);
});
});
.container {
margin: 0 auto;
width: 300px;
height: 300px;
border: 1px #000 solid;
position: relative;
}
.box {
width: 50px;
height: 50px;
border: 1px #000 solid;
position: absolute;
right: 200px;
background: red
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="container">
<div class="box"></div>
</div>
$(document).ready(function(){
$('div.container').mousemove(function(e){
let mouseX = e.pageX;
let mouseY = e.pageY;
$(this).children('.box').css({
'transform': 'translate(' + mouseX / -80 + 'px ,' + mouseY / -80 + 'px)
})
});
});
The negative numbers will move the object or div (.box) the opposite way of your mouse movement
Related
I want to rotate 2 circles around each other in a circular motion by mouse drag like in this code using jQuery
When I drag the white ball it rotates correctly and makes red ball rotate also and that what I need.
My problem is that when I click on red ball it doesn't rotate and doesn't make as the white ball.
I want to make a red ball like a white ball exactly that when drag red ball the red ball and white ball rotate with mouse like in white-ball case.
https://jsfiddle.net/Sarah_Lotfy/h1ye8Ld3/4/
If there is a code that does the same thing please share it with me
var circle = document.getElementById('circle'),
picker = document.getElementById('picker'),
pickerCircle = picker.firstElementChild,
rect = circle.getBoundingClientRect(),
center = {
x: rect.left + rect.width / 2,
y: rect.top + rect.height / 2
},
transform = (function(){
var prefs = ['t', 'WebkitT', 'MozT', 'msT', 'OT'],
style = document.documentElement.style,
p;
for (var i = 0, len = prefs.length; i < len; i++){
if ( (p = prefs[i] + 'ransform') in style ) return p
}
alert('your browser doesnt support css transforms!')
})(),
rotate = function(x, y){
var deltaX = x - center.x,
deltaY = y - center.y,
angle = Math.atan2(deltaY, deltaX) * 180 / Math.PI
return angle
},
// DRAGSTART
mousedown = function(event){
event.preventDefault()
document.body.style.cursor = 'move'
mousemove(event)
document.addEventListener('mousemove', mousemove)
document.addEventListener('mouseup', mouseup)
},
// DRAG
mousemove = function(event){
picker.style[transform] = 'rotate(' + rotate(event.x, event.y) + 'deg)'
},
// DRAGEND
mouseup = function(){
document.body.style.cursor = null;
document.removeEventListener('mouseup', mouseup)
document.removeEventListener('mousemove', mousemove)
}
// DRAG START
pickerCircle.addEventListener('mousedown', mousedown)
// ENABLE STARTING THE DRAG IN THE BLACK CIRCLE
circle.addEventListener('mousedown', function(event){
if(event.target == this) mousedown(event)
})
#circle{
position: relative;
width: 300px;
height: 300px;
border-radius: 50%;
background: #000;
}
#circle-in{
position: absolute;
top: 35px;
left: 35px;
width: 230px;
height: 230px;
border-radius: 50%;
background: #fff;
}
#picker{
position: absolute;
top: 50%;
left: 50%;
height: 30px;
margin-top: -15px;
width: 50%;
transform-origin: center left;
}
#picker-circle{
width: 30px;
height: 30px;
border-radius: 50%;
background: #fff;
margin: 0 3px 0 auto;
cursor: move;
}
#picker2{
position: absolute;
top: -200%;
left: -100%;
height: 30px;
margin-top: -10px;
width: 50%;
transform-origin: center right ;
}
#picker-circle2{
width: 30px;
height: 30px;
border-radius: 50%;
background: red;
margin: 0 3px 0 auto;
cursor: move;
}
<div id="circle">
<div id="circle-in"></div>
<div id="picker">
<div id="picker-circle"></div>
</div>
<div id="picker2">
<div id="picker-circle2"></div>
</div>
</div>
I want to show a vertical line that will appear as and of my charts are hovered over and will disappear when the mouse exits the chart elements. Weirdly, the mouseleave and mouseout events seem to fire when the mouse is not moving or when it is moving up and down (rather than side-to-side), see the code snippet below. I don't want the line to disappear when the mouse pauses and I want it to track the mouse wherever it goes.
I've tried firing the code on hover, mouseenter and mouseover but mousemove (see below code) is the only event that continuously fires as the position of the cursor changes.
//$(document).ready(function() {
function showVerticalLine(e) {
var topBarHeight = 56;
var bottomHeight = 100;
var posX = $(this).offset().left;
var x = e.pageX;
var y = $(window).innerHeight();
//Change line so that it appears at the position of the cursor
$('.verticalTrackerLine').css({
'opacity': '1',
'left': x,
'top': topBarHeight,
'height': y - topBarHeight - bottomHeight + "px",
'transition': 'left 0.1s'
});
//Update string to show when the charts are being hovered over
$("#testSTRING").html('you are moving/hovering');
};
function hideVerticalLine(){
//Hide the line
$('.verticalTrackerLine').css({
'opacity': '0'
});
//Update string to show when the charts are being hovered over
$("#testSTRING").html('you have left');
}
$("#chart1").add("#chart2").mousemove(showVerticalLine);
$("#chart1").add("#chart2").mouseout(hideVerticalLine);
//})
.chart {
margin-top: 30px;
width: 100px;
height: 30px;
border: 1px solid black;
background-color: red;
}
.verticalTrackerLine {
border-left: 2px dashed RGB(68,74,79);
position: fixed;
z-index: 1;
opacity: 0;
}
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<SPAN id="testSTRING"></SPAN>
<SPAN class="verticalTrackerLine"></SPAN>
<DIV id="chart1" class="chart">Chart 1</DIV>
<DIV id="chart2" class="chart">Chart 2</DIV>
</head>
Any help/suggestions would be gratefully received.
Your guess is right, when you hover over the actual line that interferes with hovering over the buttons. So, just adding pointer-events: none; to the .verticalTrackerLine selector will fix this so that the mouse has no interaction with the line at all.
I also did some minor JS cleanup on your code, nothing too major. The CSS rule transition: left 0.1s doesn't need to be re-applied every time the mouse moves, so that has now been set in the CSS instead.
$(function() {
var topBarHeight = 56;
var bottomHeight = 100;
var $line = $('.verticalTrackerLine');
var $charts = $("#chart1, #chart2");
var $test = $("#testSTRING");
function showVerticalLine(e) {
var posX = $(this).offset().left;
var x = e.pageX;
var y = $(window).innerHeight();
//Change line so that it appears at the position of the cursor
$line.css({
'opacity': 1,
'left': x,
'top': topBarHeight,
'height': y - topBarHeight - bottomHeight + "px"
});
//Update string to show when the charts are being hovered over
$test.html('you are moving/hovering');
};
function hideVerticalLine() {
//Hide the line
$line.css('opacity', 0);
//Update string to show when the charts are being hovered over
$test.html('you have left');
}
$charts
.mousemove(showVerticalLine)
.mouseout(hideVerticalLine);
});
.chart {
margin-top: 30px;
width: 100px;
height: 30px;
border: 1px solid black;
background-color: red;
}
.verticalTrackerLine {
border-left: 2px dashed RGB(68, 74, 79);
position: fixed;
z-index: 1;
opacity: 0;
transition: left 0.1s;/* <------ this was moved from JS */
pointer-events: none; /* <------ this was added */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<output id="testSTRING">nothing has happened yet...</output>
<span class="verticalTrackerLine"></span>
<div id="chart1" class="chart">Chart 1</div>
<div id="chart2" class="chart">Chart 2</div>
You can simplify it further:
move the tracking line into an :after pseudo element inside each chart element and position it absolutely within the chart
position it 10px more to the top and bottom using:
top: -10px;
bottom: -10px;
set opacity: 0 to the tracking line and on :hover set it to one - now you'll have the line on hover - see demo below:
.chart {
margin-top: 30px;
width: 100px;
height: 30px;
border: 1px solid black;
background-color: red;
position: relative;
box-sizing: border-box;
}
.chart:after {
content: '';
border-left: 2px dashed rgb(68, 74, 79);
position: absolute;
z-index: 1;
opacity: 0;
top: -10px;
bottom: -10px;
}
.chart:hover:after {
opacity: 1;
}
<div id="chart1" class="chart">Chart 1</div>
<div id="chart2" class="chart">Chart 2</div>
Now comes the javascript part - we can modify the left property to show the line moving with the mouse:
first add a CSS variable (say --left) that can be adjusted from JS
now in a mousemove listener you can use e.pageX - this.offsetLeft to get the relative position (left value) of the mouse inside the box.
update the --left CSS variable using document.documentElement.style.setProperty('--left', ...
Note that I've made a maximum value for the left value to be on the safe side to this.offsetWidth - 2.
See demo below:
$(".chart").mousemove(function (e) {
document.documentElement.style.setProperty('--left', Math.min(e.pageX - this.offsetLeft, this.offsetWidth - 2) + 'px');
});
:root {
--left: 0;
}
.chart {
margin-top: 30px;
width: 100px;
height: 30px;
border: 1px solid black;
background-color: red;
position: relative;
box-sizing: border-box;
}
.chart:after {
content: '';
border-left: 2px dashed rgb(68, 74, 79);
position: absolute;
z-index: 1;
opacity: 0;
top: -10px;
bottom: -10px;
left: var(--left);
}
.chart:hover:after {
opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="chart1" class="chart">Chart 1</div>
<div id="chart2" class="chart">Chart 2</div>
Add pointer-events: none; to .verticalTrackerLine
//$(document).ready(function() {
function showVerticalLine(e) {
var topBarHeight = 56;
var bottomHeight = 100;
var posX = $(this).offset().left;
var x = e.pageX;
var y = $(window).innerHeight();
//Change line so that it appears at the position of the cursor
$('.verticalTrackerLine').css({
'opacity': '1',
'left': x,
'top': topBarHeight,
'height': y - topBarHeight - bottomHeight + "px",
'transition': 'left 0.1s'
});
//Update string to show when the charts are being hovered over
$("#testSTRING").html('you are moving/hovering');
};
function hideVerticalLine(){
//Hide the line
$('.verticalTrackerLine').css({
'opacity': '0'
});
//Update string to show when the charts are being hovered over
$("#testSTRING").html('you have left');
}
$("#chart1").add("#chart2").mousemove(showVerticalLine);
$("#chart1").add("#chart2").mouseout(hideVerticalLine);
//})
.chart {
margin-top: 30px;
width: 100px;
height: 30px;
border: 1px solid black;
background-color: red;
}
.verticalTrackerLine {
border-left: 2px dashed RGB(68,74,79);
position: fixed;
z-index: 1;
opacity: 0;
pointer-events: none;
}
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<SPAN id="testSTRING"></SPAN>
<SPAN class="verticalTrackerLine"></SPAN>
<DIV id="chart1" class="chart">Chart 1</DIV>
<DIV id="chart2" class="chart">Chart 2</DIV>
</head>
I tried this:
function getPosition(e) {
var rect = e.target.getBoundingClientRect();
var x = e.clientX - rect.left;
var y = e.clientY - rect.top;
return {
x,
y
}
}
window.addEventListener("click", function(event) {
document.getElementById("info").innerHTML = "ID: " + event.target.id + "<br> X: " + getPosition(event).x + " Y: " + getPosition(event).y;
});
body {
perspective: 400px;
margin: 0;
}
#test {
width: 400px;
height: 400px;
background-color: red;
transform: rotateY(45deg);
position: absolute;
left: 40%;
}
#info {
position: absolute;
right: 0;
top: 0;
box-shadow: 0px 0px 10px black;
width: 200px;
border-radius: 10px;
padding: 5px;
}
<div id="info"></div>
<div style="margin-top: 10%;">
<div id="test">
</div>
</div>
Link to jsfiddle
but it does just work without a 3D Rotation. If I click for example in the bottom right corner of the red div, then it should give me back something arround (because you never hit the corner exact) X: 300px and Y: 300px. But this works just when the element is with no rotation. So how can I get the clicked Position with 3d rotation? (if the rotation changes, then it must work too!)
Hey guys I’m trying to make simple point & click game, in background will be some nice landscape which will be moved by arrows on the left and right (same like slider works), I want object to move only within the lower div (#boxMap), I tried to build contructor to main object but together with friend who helps me, we wrote it in way below. The problem is that this object still doesn’t move how it should be, idea is that when game starts, and when I click right arrow, object appears on the left, if I click left arrow object appears on the left side of the div. When I click the mouse, object should moves to position I clicked. I’m kinda desperate as I have ideas how to make It work later but I totally cannot manage this positioning and movement of the object.
I found some nice yt tutorial about moving objects and tried to set statements to move only within the div without getting outside the edge, unfortunately now it moves only on the bottom edge of div.
So I created new object with class .hero inside the boxMap, and set it’s starting position with css properties, then with function getClickPosition I try to manage it’s movement, I try also set that if object is clicked outside the frame of div, it set it’s position on particular value. Unfortunately now it moves only through the bottom edge, right side it doesn’t exceed the edge, left side it does.
Hope I was able to more or less explain what I try to achieve and what I have already done.
Any idea how to set position and some simple movement in much simpler way?
I would be grateful for any tips
HTML
<body>
<div id="emptySpace">
<span class="left"></span>
<span class="right"></span>
</div>
<div id="boxMap">
</div>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script src="js/app.js"></script>
</body>
CSS
body {
margin: 0;
padding: 0;
background-color: antiquewhite;
#emptySpace {
width: 100%;
height: 70vh;
background-color: azure;
position: relative;
.left {
position: absolute;
left: 10px;
top: 40vh;
border-top: 40px solid transparent;
border-bottom: 40px solid transparent;
border-right:40px solid blue;
//display: none;
}
.right {
position: absolute;
right: 10px;
top: 40vh;
border-top: 40px solid transparent;
border-bottom: 40px solid transparent;
border-left: 40px solid green;
//display: none;
}
}
#boxMap {
width: 100%;
height: 30vh;
border: 1px solid black;
background-color: #d8fffa;
position: relative;
.hero {
position: absolute;
width: 50px;
height: 50px;
display: inline-block;
border: 1px solid black;
border-radius: 50%;
background-color: blue;
transform: translate3d(0px, -45px, 0);
transition: 2s linear;
}
}
}
Javascript
function Game() {
this.hero = new Hero();
this.counter = 0;
var self = this;
this.boxMap = document.querySelector("#boxMap");
// Placing hero on the map
this.showHero = function () {
var heroElement = document.createElement('div');
heroElement.classList.add('hero');
console.log(self, self.boxMap);
self.boxMap.appendChild(heroElement);
$(heroElement).css({top: 130, left: 30})
}
}
var game = new Game();
game.showHero();
var heroMovement = document.querySelector(".hero");
var boxMap = document.querySelector("#boxMap");
boxMap.addEventListener("click", getClickPosition, false);
// Set position on hero and set movement
function getClickPosition(e) {
var xPosition = e.clientX;
var maxWidth = 1350;
var minWidth = -20;
if (xPosition < minWidth) {
xPosition = minWidth;
} else if (xPosition > maxWidth) {
xPosition = maxWidth
} else {
var xPosition = e.clientX - (heroMovement.offsetWidth + 3);
}
var yPosition = e.clientY;
var maxHeight = 60;
var minHeight = -130;
if (yPosition < minHeight) {
yPosition = minHeight;
} else if (yPosition > maxHeight) {
yPosition = maxHeight
} else {
var yPosition = e.clientY - (heroMovement.offsetHeight + 558);
}
console.log(xPosition, yPosition);
var translate3dValue = "translate3d(" + xPosition + "px" + "," + yPosition + "px, 0)";
console.log(translate3dValue);
heroMovement.style.transform = translate3dValue;
}
I have a <div> that acts as a viewport for a child <div>, in which the child <div> pans by clicking and dragging the mouse around, however I would like the child <div> to be filling the viewport, so that the edge of the child <div> is never visible. Example:
var isDragging = false;
var lastMouseX;
var lastMouseY;
$("#viewport").mousedown(function(ev) {
if (ev.which == 1) {
isDragging = true;
}
});
$("html").mouseup(function(ev) {
if (ev.which == 1) {
isDragging = false;
}
});
$("#viewport").mousemove(function(e) {
var deltaX = lastMouseX - e.clientX;
var deltaY = lastMouseY - e.clientY;
lastMouseX = e.clientX;
lastMouseY = e.clientY;
if (isDragging) {
$("#view").css({
left: "-=" + deltaX,
top: "-=" + deltaY
});
};
});
body {
background-color: grey;
width: 100vw;
height: 100vh;
overflow: hidden;
}
#viewport {
display: block;
background-color: transparent;
width: 100%;
height: 100%;
overflow: hidden;
}
#view {
position: relative;
width: 100%;
height: 100%;
background-size: 24px 24px;
background-image: linear-gradient(to right, white 1px, transparent 1px), linear-gradient(to bottom, white 1px, transparent 1px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="viewport">
<div id="view"></div>
</div>
Is there a way to make it "endless", as to constantly add a piece onto the child <div> whenever the viewport gets close to the edge?
UPDATE: To clarify my question, I want the child <div> to stay un-moving, so for the user, the child div should feel like an infinite plane which they look pan around. I don't want it to act like a fixed element.
Try changing width/height of the div along with its position
if (isDragging) {
$("#view").css({
left: "-=" + deltaX,
top: "-=" + deltaY,
width: "+=" + deltaX,
height: "+=" + deltaY
});
I eventually solved this issue by creating a separate element that has the same grid background, but the background pans around with the child <div>. Snippet:
var isDragging = false;
var lastMouseX;
var lastMouseY;
$("#viewport").mousedown(function(ev) {
if (ev.which == 1) {
isDragging = true;
}
});
$("html").mouseup(function(ev) {
if (ev.which == 1) {
isDragging = false;
}
});
$("#viewport").mousemove(function(e) {
var deltaX = lastMouseX - e.clientX;
var deltaY = lastMouseY - e.clientY;
lastMouseX = e.clientX;
lastMouseY = e.clientY;
if (isDragging) {
$("#view").css({
left: "-=" + deltaX,
top: "-=" + deltaY
});
$("#grid").css({
'background-position-x': "-=" + deltaX,
'background-position-y': "-=" + deltaY,
});
};
});
body {
background-color: grey;
width: 100vw;
height: 100vh;
overflow: hidden;
}
#viewport {
display: block;
background-color: transparent;
width: 100%;
height: 100%;
overflow: hidden;
}
#view {
position: relative;
width: 100%;
height: 100%;
}
#grid {
position: fixed;
width: 100%;
height: 100%;
background-size: 24px 24px;
background-image: linear-gradient(to right, white 1px, transparent 1px), linear-gradient(to bottom, white 1px, transparent 1px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="viewport">
<div id="grid"></div>
<div id="view"></div>
</div>