These are my javascript, css, and html files for simple web page for dragging an element and putting it into the container(div) :
var xContainer;
var yContainer
var insideFirst = false;
$(window).load(
function() {
xContainer = $("#center").offset().left;
yContainer = $("#center").offset().top;
console.log("ready");
$("#center").on("click", function(event) {
console.log(event);
});
$("#center").droppable();
$("#firstID").draggable({
cursor : 'move',
revert: "invalid"
});
$("#firstID").mousedown(function() {
isDragging = false;
}).mousemove(
function() {
isDragging = true;
var x = $("#firstID").offset().left;
var y = $("#firstID").offset().top;
xContainer = $("#center").offset().left;
yContainer = $("#center").offset().top;
var xPosition = (x - xContainer).toFixed(2);
var yPosition = (y - yContainer).toFixed(2);
console.log("center:" + xContainer);
console.log("x:" + x);
console.log("difference: "+(x-xContainer));
/*
* if (x < 750 && y < 750) {
* $("#firstID").css('background','#ffffff') }
*/
if (xPosition >= 0.0 && yPosition >= 0.0
&& xPosition <= 500.0 && yPosition <= 200.0) {
$("#xPosition").val("x:" + xPosition);
$("#yPosition").val("y:" + yPosition);
$("#firstID").css('background', '#e4e4e4')
$('#firstID').draggable({containment : [xContainer,yContainer,xContainer+500,yContainer+200.0] });
} else {
//$("#xPosition").val("GO IN!!!");
//$("#yPosition").val("GO IN!!!");
$("#firstID").css('background', '#d1f1fc')
}
}).mouseup(function() {
var wasDragging = isDragging;
isDragging = false;
if (!wasDragging) {
console.log("clicked");
}
});
$("#secondID").draggable({
cursor : 'move'
});
$("#secondID").mousedown(function() {
isDragging = false;
}).mousemove(function() {
isDragging = true;
var x = $("#secondID").offset().left;
var y = $("#secondID").offset().top;
// $("#text-x").val ("x:"+x);
// $("#text-y").val ("y:"+y);
}).mouseup(function() {
var wasDragging = isDragging;
isDragging = false;
if (!wasDragging) {
console.log("clicked");
}
});
$("#secondID").dblclick(function() {
rotation += 90;
$(this).rotate(rotation);
});
});
jQuery.fn.rotate = function(degrees) {
$(this).css({
'-webkit-transform' : 'rotate(' + degrees + 'deg)',
'-moz-transform' : 'rotate(' + degrees + 'deg)',
'-ms-transform' : 'rotate(' + degrees + 'deg)',
'transform' : 'rotate(' + degrees + 'deg)'
});
return $(this);
};
var rotation = 0;
var isDragging = false;
body {
height: 100%;
background-color: #e4e4e4;
}
#firstID {
width: 100px;
height: 100px;
margin: 0 auto;
border-style: groove;
background-color: #d1f1fc;
color: black;
position: relative;
text-align: center;
z-index: 99;
}
#secondID {
width: 100px;
height: 50px;
margin: 0 auto;
color: black;
border-style: groove;
position: relative;
background-color: #d1f1fc;
text-align: center;
z-index: 99;
}
#center {
width: 600px;
height: 300px;
position: relative;
margin: 0 auto;
border-style: groove;
background-color: #c0c0c0;
}
/* If in mobile screen with maximum width 479px. The iPhone screen resolution is 320x480 px (except iPhone4, 640x960) */
#media only screen and (max-width: 479px) {
#center{
width: 50%;
height : 50%;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<html>
<head>
<link rel="stylesheet" type="text/css" href="drag.css">
</head>
<body>
<input type="text" id="xPosition" value="x:0">
<input type="text" id="yPosition" value="y:0">
<div id="firstID" >MJ</div>
<div id="secondID" >MJ</div>
<div id="center">
</div>
</body>
</html>
The code is not finished, so the logic works with only a square, not rectangle.
What i need is to drag square element into the container on the page and make it stay inside it, with no possibility to leave it. That works fine in Mozilla, but in Chrome, i have problems with dragging the square after entering container. When i click on it and try to drag it, it moves far to the right side of the page. Why is that happening only in Chrome?
Related
i was recently diving into the world of css transform and wanted to rotate a div (x and y axis), i was able to do it with 2 sliders with 0 to 360 degree range but now looking forward to do it with dragging the mouse, i have made a very sloppy effort on that looking for suggestion to fix it:
jsfiddle link to test
"use strict";
let elContainer = $('#container');
let elBox = $('#box');
$(document).ready(function() {
$('.slider-rotate').on('input', function() {
sliderRotate();
});
elContainer.mousedown(function(e) {
initDragRotate(e);
});
elContainer.mousemove(function(e) {
dragRotate(e);
});
elContainer.mouseup(function(e) {
endDragRotate();
});
});
let dragging = false;
let delta = {};
function initDragRotate(e) {
dragging = true;
delta = {
x: e.pageX,
y: e.pageY,
};
}
function dragRotate(e) {
if (!dragging) {
return;
}
delta.x = e.pageX - delta.x;
delta.y = e.pageY - delta.y;
let rotateParam = '';
rotateParam += ' rotate' + 'Y' + '(' + delta.x + 'deg)';
rotateParam += ' rotate' + 'X' + '(' + delta.y + 'deg)';
elBox.css('transform', rotateParam);
}
function endDragRotate() {
if (!dragging) {
return;
}
dragging = false;
}
function sliderRotate() {
let rotateParam = '';
$('.slider-rotate').each(function() {
rotateParam += ' ' + getRotateParamString($(this));
});
elBox.css('transform', rotateParam);
}
function getRotateParamString(elClass) {
let val = elClass.val();
let rotateType = elClass.data('rotateType');
let rotateParam = 'rotate' + rotateType + '(' + val + 'deg)';
return rotateParam;
}
#container {
background: #ccc;
padding: 10vh;
display: flex;
align-items: center;
justify-content: center;
}
#box {
width: 30vh;
height: 30vh;
border: 5px solid #000;
position: relative;
transform-style: preserve-3d;
}
#box>div {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="box">
<div style="background: #f00;"></div>
<div style="background: #0f0;"></div>
</div>
</div>
<div id="control">
<br>
<label>
x
<input type="range" class="slider-rotate" data-rotate-type="X" min="0" max="360" value="0">
</label>
<br>
<label>
y
<input type="range" class="slider-rotate" data-rotate-type="Y" min="0" max="360" value="0">
</label>
</div>
also, there's 2 div on top and bottom (green and red) with transform-style preserve-3d property, hoping that it's show the other color when flipped but no luck! please suggest, thanks!
The calulation for how much to rotate is a little odd.
I believe what you need is to have the amount of rotation dependent on the amount the mouse is placed across and down the screen. To make this proportional to the screen size you need to divide it by the screen size and then multiply it by 360 to get the full range from pageX/Y being 0 to being at the right/bottom of the screen.
"use strict";
let elContainer = $('#container');
let elBox = $('#box');
$(document).ready(function() {
$('.slider-rotate').on('input', function() {
sliderRotate();
});
elContainer.mousedown(function(e) {
initDragRotate(e);
});
elContainer.mousemove(function(e) {
dragRotate(e);
});
elContainer.mouseup(function(e) {
endDragRotate();
});
});
let dragging = false;
let delta = {};
function initDragRotate(e) {
dragging = true;
delta = {
x: e.pageX,
y: e.pageY,
};
}
function dragRotate(e) {
if (!dragging) {
return;
}
// THIS IS THE CALCULATION THAT HAS CHANGED
delta.x = e.pageX / window.innerWidth * 360; //- delta.x;
delta.y = e.pageY / window.innerHeight * 360; // - delta.y;
let rotateParam = '';
rotateParam += ' rotate' + 'Y' + '(' + delta.x + 'deg)';
rotateParam += ' rotate' + 'X' + '(' + delta.y + 'deg)';
elBox.css('transform', rotateParam);
}
function endDragRotate() {
if (!dragging) {
return;
}
dragging = false;
}
function sliderRotate() {
let rotateParam = '';
$('.slider-rotate').each(function() {
rotateParam += ' ' + getRotateParamString($(this));
});
elBox.css('transform', rotateParam);
}
function getRotateParamString(elClass) {
let val = elClass.val();
let rotateType = elClass.data('rotateType');
let rotateParam = 'rotate' + rotateType + '(' + val + 'deg)';
return rotateParam;
}
#container {
background: #ccc;
padding: 10vh;
display: flex;
align-items: center;
justify-content: center;
}
#box {
width: 30vh;
height: 30vh;
border: 5px solid #000;
position: relative;
transform-style: preserve-3d;
}
#box>div {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="box">
<div style="background: #f00;"></div>
<div style="background: #0f0;"></div>
</div>
</div>
<div id="control">
<br>
<label>
x
<input type="range" class="slider-rotate" data-rotate-type="X" min="0" max="360" value="0">
</label>
<br>
<label>
y
<input type="range" class="slider-rotate" data-rotate-type="Y" min="0" max="360" value="0">
</label>
</div>
I'm attempting to make these balls move along the border of this parent div. The parent div is a pill/discorectangle. I'm sure there must be a way to do this using some trig or equation of a circle. So the straight sides are 200px long and the radius of each semi circle is 100px. So from 0-100px and 300-400px the top style needs to be calculated for each ball. Has anyone done anything similar or have any advice?
HTML:
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css">
</head>
<button id="start_stop">Orbit</button>
<div id="oval">
<div id="ball0" class="ball"></div>
<div id="ball1" class="ball"></div>
<div id="ball2" class="ball"></div>
<div id="ball3" class="ball"></div>
</div>
<script src="orbit.js"></script>
</html>
CSS:
#oval {
position: absolute;
margin-top: 200px;
height: 200px;
width: 400px;
border: 3px solid black;
border-radius: 400px/400px;
right: 50%;
transform: translate(50%, -50%);
}
.ball {
height: 30px;
width: 30px;
border-radius: 30px;
position: absolute;
}
#ball0 {
left:270px;
top:185px;
/*right: 100px;
bottom: -15;*/
background-color: blue;
}
#ball1 {
left:100px;
/* bottom:-15px; */
top: 185px;
background-color: green;
}
#ball2 {
top:-15px;
/* right: 100px; */
left: 270px;
background-color: yellow;
}
#ball3 {
top:-15px;
left: 100px;
background-color: red;
}
JS:
var oval = document.getElementById('oval');
var balls = document.getElementsByClassName('ball');
var run_animation = false;
var req;
document.getElementById("start_stop").addEventListener("click", toggle);
function toggle() {
run_animation = !run_animation
if(run_animation) {
req = window.requestAnimationFrame(orbit);
}
}
console.log(balls.length);
var max_x = oval.clientWidth; // - 100;
var min_x = 0;
var step = 0;
var map = {
"ball0": {"top": 185, "left": 270, forward: true},
"ball1": {"top": 185, "left": 100, forward: true},
"ball2": {"top": -15, "left": 270, forward: false},
"ball3": {"top": -15, "left": 100, forward: false}
}
function get_y(x){
//some math here?
// return 100 * Math.sin(x);
// return Math.sqrt(100**2 + x**2);
}
function orbit() {
if (run_animation){
for(var i=0; i<balls.length; i++){
var curr_left = map["ball"+i].left;
if (curr_left >= max_x) map["ball"+i].forward = false;
if (curr_left <= min_x ) map["ball"+i].forward = true;
if(map["ball"+i].forward){
map["ball"+i].left += 3;
}
else {
forward = false
map["ball"+i].left -= 3;
}
//left edge - curve around semicircle
if(map["ball"+i].left <= 100) {
// map["ball"+i].top = -1 * get_y(map["ball"+i].left);
}
//right edge - curve around semicircle
if(map["ball"+i].left >= 300) {
// map["ball"+i].top = -1 * get_y(map["ball"+i].left);
}
balls[i].style.left = map["ball"+i].left + 'px';
balls[i].style.top = map["ball"+i].top + 'px';
}
req = window.requestAnimationFrame(orbit);
}
else {
console.log("cancel");
window.cancelAnimationFrame(req);
}
}
/* orbit(); */
req = window.requestAnimationFrame(orbit);
https://jsfiddle.net/gzjfxtbu/2/
Well I did it. Not sure if this is the best way to do this or not. I'd still like to figure out any other methods to accomplish this. Eventually I was going to turn the balls into actual divs containing info and images. So I'm not sure if the SVG route is the best?
Hopefully this can help someone.
JS:
var oval = document.getElementById('oval');
var balls = document.getElementsByClassName('ball');
var run_animation = false;
var req;
document.getElementById("start_stop").addEventListener("click", toggle);
function toggle() {
run_animation = !run_animation
if(run_animation) {
req = window.requestAnimationFrame(orbit);
}
}
console.log(balls.length);
var max_x = oval.clientWidth;
var min_x = 0;
var step = 0;
var map = {
"ball0": {"top": 185, "left": 270, forward: false},
"ball1": {"top": 185, "left": 100, forward: false},
"ball2": {"top": -15, "left": 270, forward: true},
"ball3": {"top": -15, "left": 100, forward: true}
}
function get_y(x){
//some math here?
// return 100 * Math.sin(x);
return 1 * (Math.sqrt(100**2 - (100-x)**2));
}
function get_y2(x) {
return 1 * (Math.sqrt(100**2 - (300-x)**2));
}
function orbit() {
if (run_animation){
for(var i=0; i<balls.length; i++){
var curr_left = map["ball"+i].left;
if (curr_left >= max_x) map["ball"+i].forward = false;
if (curr_left <= min_x ) map["ball"+i].forward = true;
if(map["ball"+i].forward){
map["ball"+i].left += 3;
}
else {
map["ball"+i].left -= 3;
}
//left edge - curve around semicircle
if(map["ball"+i].left <= 85 && !map["ball"+i].forward ) {
map["ball"+i].top = 1*get_y(map["ball"+i].left) + 85;
}
else if(map["ball"+i].left <= 85 && map["ball"+i].forward ) {
map["ball"+i].top = -1*get_y(map["ball"+i].left) + 85;
}
//right edge - curve around semicircle
if(map["ball"+i].left >= 315 && map["ball"+i].forward) {
map["ball"+i].top = -1*get_y2(map["ball"+i].left) + 85;
}
else if(map["ball"+i].left >= 315 && !map["ball"+i].forward) {
map["ball"+i].top = get_y2(map["ball"+i].left) + 85;
}
balls[i].style.left = map["ball"+i].left + 'px';
balls[i].style.top = map["ball"+i].top + 'px';
}
req = window.requestAnimationFrame(orbit);
}
else {
console.log("cancel");
window.cancelAnimationFrame(req);
}
}
/* orbit(); */
req = window.requestAnimationFrame(orbit);
HTML:
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css">
</head>
<button id="start_stop">Orbit</button>
<div id="oval">
<div id="ball0" class="ball">0</div>
<div id="ball1" class="ball">1</div>
<div id="ball2" class="ball">2</div>
<div id="ball3" class="ball">3</div>
</div>
<script src="orbit.js"></script>
</html>
CSS:
#oval {
position: absolute;
margin-top: 100px;
height: 200px;
width: 400px;
border: 3px solid black;
border-radius: 400px/400px;
right: 50%;
transform: translate(50%, -50%);
}
.ball {
height: 30px;
width: 30px;
border-radius: 30px;
position: absolute;
}
#ball0 {
left:270px;
top:185px;
/*right: 100px;
bottom: -15;*/
background-color: blue;
}
#ball1 {
left:100px;
/* bottom:-15px; */
top: 185px;
background-color: green;
}
#ball2 {
top:-15px;
/* right: 100px; */
left: 270px;
background-color: yellow;
}
#ball3 {
top:-15px;
left: 100px;
background-color: red;
}
https://jsfiddle.net/nwm3r4he/3/
I have a draggable element (see the code snippet and click on picture to add pins) which shows a tooltip on mouseover and deletes it on mouseout.
The below code throws tens of errors "TypeError: e.$element is null" in Firefox or "Uncaught TypeError: Cannot read property 'trigger' of null" in Chrome as soon as I start dragging the pin element.
I tried:
$('.tooltip').remove();
$('.tooltip').tooltip('destroy');
$('.pin').tooltip('destroy');
but none of these solve that.
How can I stop the tooltip errors when dragging the element?
var pic_wrapper = $('#pic_wrapper');
var selected_picture = $('#selected_picture');
selected_picture.on('click', function(e) {
var pin = $('<div class="pin"></div>');
x = ((e.offsetX) / $(this).width()) * 100 + "%";
y = ((e.offsetY) / $(this).height()) * 100 + "%";
pin.uniqueId();
pic_wrapper.append(pin);
pin.css({
transform: 'translate(-50%, -50%)'
});
pin.css({
left: x,
top: y
}).show();
pin.draggable({
containment: 'parent'
});
pin.on('dragstart', function() {
pin.css({
transform: 'translate(0%, 0%)'
});
});
pin.on('dragstop', function(e, ui) {
x = (ui.position.left / pic_wrapper.width()) * 100 + "%";
y = (ui.position.top / pic_wrapper.height()) * 100 + "%";
pin.css({
left: x,
top: y
});
});
});
pic_wrapper.on('mouseenter', '.pin', function(e) {
$(this).attr('title', 'tooltip text');
$(this).tooltip({
placement: function(context, source) {
return "right";
}
});
$(this).tooltip('show');
});
pic_wrapper.on('mouseout', '.pin', function(e) {
$(this).tooltip('destroy');
});
#pic_wrapper {
display: block;
position: relative;
padding: 0;
border: 1px dotted #0099ff;
}
#selected_picture {
width: 100%;
height: auto;
border: 1px solid #0099ff;
}
#selected_picture img {
width: 100%;
height: auto;
}
.pin {
display: none;
position: absolute;
padding: 0;
margin: 0;
width: 16px;
height: 16px;
border-radius: 50%;
background: #ff4100;
cursor: pointer;
box-shadow: 0 0 0 rgba(255, 65, 0, 0.4);
animation: pulse 2s infinite;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<fieldset>
<div class="col-xs-12">
<div class="form-group">
<div id="pic_wrapper">
<div id="selected_picture">
<img src="http://www.outline-world-map.com/map-images-original/blank-thin-gray-white-world-map-b9a.png" />
</div>
</div>
</div>
</div>
</fieldset>
Try with:
$('.tooltip').tooltip('destroy').remove();
it should do the trick
I think the reason why you got this error, is that when you do the $('.tooltip').tooltip('destroy') it doesn't remove also all the events linked to the tooltip.
update: It's necessary to update also
$(this).attr('title', 'tooltip text');
with
$(this).attr('data-original-title', 'tooltip text');
otherwise it display 2 tooltip!
full JS code:
var pic_wrapper = $('#pic_wrapper');
var selected_picture = $('#selected_picture');
selected_picture.on('click', function(e) {
var pin = $('<div class="pin"></div>');
x = ((e.offsetX) / $(this).width()) * 100 + "%";
y = ((e.offsetY) / $(this).height()) * 100 + "%";
pin.uniqueId();
pic_wrapper.append(pin);
pin.css({
transform: 'translate(-50%, -50%)'
});
pin.css({
left: x,
top: y
}).show();
pin.draggable({
containment: 'parent'
});
pin.on('dragstart', function() {
pin.css({
transform: 'translate(0%, 0%)'
});
});
pin.on('dragstop', function(e, ui) {
x = (ui.position.left / pic_wrapper.width()) * 100 + "%";
y = (ui.position.top / pic_wrapper.height()) * 100 + "%";
pin.css({
left: x,
top: y
});
});
});
pic_wrapper.on('mouseenter', '.pin', function(e) {
$(this).attr('data-original-title', 'tooltip text');
$(this).tooltip({
placement: function(context, source) {
return "right";
}
});
$(this).tooltip('show');
});
pic_wrapper.on('mouseout', '.pin', function(e)
{
$('.tooltip').tooltip('destroy').remove();
});
My code is forking this pen, I also include my code in the stack snippet under this post.
what I want to achieve are:
When the cursor is not inside the body, the eyeball would move randomly ( achieved ).
When the cursor enters the body, the eyeball follows the cursor ( achieved ).
When the cursor leaves the body, the eyeball starts moving randomly again ( not achieved ).
I called the function which is used to move the eyeball randomly in on("mouseleave") event, and it does move to a random position but it will immediately go back to the last cursor position, rather than staying at the new position. Can anyone point me to the right direction to fix the problem?
Thanks!
var
mouseOvering = false,
pupil = $("#pupil"),
eyeball = $("#iris"),
eyeposx = 40,
eyeposy = 20,
r = $(pupil).width()/2,
center = {
x: $(eyeball).width()/2 - r,
y: $(eyeball).height()/2 - r
},
distanceThreshold = $(eyeball).width()/2 - r,
mouseX = 0,
mouseY = 0;
$("body").ready( function(){
if ( !mouseOvering ) {
moveRandomly();
}
});
$("body").on('mouseleave', function(){
mouseOvering = false;
moveRandomly();
console.log("mouseleave");
});
$("body").on('mousemove', function(e){
mouseOvering = true;
console.log("mouseovering");
followCursor(e);
});
function moveRandomly() {
var loop = setInterval(function(){
var xp = Math.floor(Math.random()*80);
var yp = Math.floor(Math.random()*80);
pupil.animate({left:xp, top:yp});
}, 3500);
}
function followCursor(e) {
var d = {
x: e.pageX - r - eyeposx - center.x,
y: e.pageY - r - eyeposy - center.y
};
var distance = Math.sqrt(d.x*d.x + d.y*d.y);
if (distance < distanceThreshold) {
mouseX = e.pageX - eyeposx - r;
mouseY = e.pageY - eyeposy - r;
} else {
mouseX = d.x / distance * distanceThreshold + center.x;
mouseY = d.y / distance * distanceThreshold + center.y;
}
var xp = 0, yp = 0;
var loop = setInterval(function(){
// change 1 to alter damping/momentum - higher is slower
xp += (mouseX - xp) / 1;
yp += (mouseY - yp) / 1;
pupil.css({left:xp, top:yp});
}, 2);
}
body {
background-color: #D1D3CF;
}
#container {
display: inline;
height: 400px;
width: 400px;
}
#eyeball {
background: radial-gradient(circle at 100px 100px, #EEEEEE, #000);
height: 300px;
width: 300px;
border-radius: 100%;
position: relative;
}
#iris {
top: 10%;
left: 10%;
background: radial-gradient(circle at 100px 100px, #4DC9EF, #000);
height: 80%;
width: 80%;
border-radius: 100%;
position: absolute;
}
#pupil {
top: 10%;
left: 10%;
background: radial-gradient(circle at 100px 100px, #000000, #000);
height: 55%;
width: 55%;
border-radius: 100%;
position: absolute;
}
#keyframes move {
50% {
transform: translate(-50px, 50px);
}
}
#keyframes move2 {
50% {
transform: translate(-20px, 20px);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="container">
<div id="eyeball">
<div id="iris">
<div id="pupil"></div>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="script.js"></script>
</body>
</html>
With Javascript you can only track where the cursor is on the webpage. If you shift your cursor outside the body, it's not possible for your code to know where the cursor is.
This is the reason the eye tracking your cursor stops moving when you move your cursor outside the window.
The problem is that once the followcursor function was started it kept on moving back to the last known mouse position, even after the mouse had left the body. I just put a check on your mouseOvering variable inside your followcursor function:
var
mouseOvering = false,
pupil = $("#pupil"),
eyeball = $("#iris"),
eyeposx = 40,
eyeposy = 20,
r = $(pupil).width()/2,
center = {
x: $(eyeball).width()/2 - r,
y: $(eyeball).height()/2 - r
},
distanceThreshold = $(eyeball).width()/2 - r,
mouseX = 0,
mouseY = 0;
$("body").ready( function(){
if ( !mouseOvering ) {
moveRandomly();
}
});
$("body").on('mouseleave', function(){
mouseOvering = false;
console.log("mouseleave");
});
$("body").on('mousemove', function(e){
mouseOvering = true;
console.log("mouseovering");
followCursor(e);
});
function moveRandomly() {
var loop = setInterval(function(){
var xp = Math.floor(Math.random()*80);
var yp = Math.floor(Math.random()*80);
if (!mouseOvering) {
pupil.animate({left:xp, top:yp});
}
}, 3500);
}
function followCursor(e) {
var d = {
x: e.pageX - r - eyeposx - center.x,
y: e.pageY - r - eyeposy - center.y
};
var distance = Math.sqrt(d.x*d.x + d.y*d.y);
if (distance < distanceThreshold) {
mouseX = e.pageX - eyeposx - r;
mouseY = e.pageY - eyeposy - r;
} else {
mouseX = d.x / distance * distanceThreshold + center.x;
mouseY = d.y / distance * distanceThreshold + center.y;
}
var xp = 0, yp = 0;
var loop = setInterval(function(){
// change 1 to alter damping/momentum - higher is slower
xp += (mouseX - xp) / 1;
yp += (mouseY - yp) / 1;
if (mouseOvering) {
pupil.css({left:xp, top:yp});
}
}, 2);
}
body {
background-color: #D1D3CF;
}
#container {
display: inline;
height: 400px;
width: 400px;
}
#eyeball {
background: radial-gradient(circle at 100px 100px, #EEEEEE, #000);
height: 300px;
width: 300px;
border-radius: 100%;
position: relative;
}
#iris {
top: 10%;
left: 10%;
background: radial-gradient(circle at 100px 100px, #4DC9EF, #000);
height: 80%;
width: 80%;
border-radius: 100%;
position: absolute;
}
#pupil {
top: 10%;
left: 10%;
background: radial-gradient(circle at 100px 100px, #000000, #000);
height: 55%;
width: 55%;
border-radius: 100%;
position: absolute;
}
#keyframes move {
50% {
transform: translate(-50px, 50px);
}
}
#keyframes move2 {
50% {
transform: translate(-20px, 20px);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="container">
<div id="eyeball">
<div id="iris">
<div id="pupil"></div>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="script.js"></script>
</body>
</html>
When I click-drag (#cssNav) to the right, it is not moving proportionately along with the #html and #css div.
This might be something very obvious, but still am not able to figure it out, what am I missing here, please help?
Note: I don't want to use display:flex
codepen
$("#htmlNav").on("mousedown", dragStartH);
$("#cssNav").on("mousedown", dragStartH);
$("#jsNav").on("mousedown", dragStartH);
function dragStartH(e) {
e.preventDefault();
dragMeta = {};
dragMeta.pageX0 = e.pageX;
dragMeta.elem = this;
dragMeta.offset0 = $(this).offset();
dragMeta.codeWindow = "#" + $(e.target).attr("id").replace("Nav", "");
function handle_dragging(e) {
var change = e.pageX - dragMeta.pageX0;
var left = dragMeta.offset0.left + change;
$(dragMeta.elem).offset({ left: left });
$("#css").width($("#css").width() - change + "px");
$("#html").width($("#html").width() + change + "px");
}
function handle_mouseup(e) {
$("body")
.off("mousemove", handle_dragging)
.off("mouseup", handle_mouseup);
}
$("body").on("mouseup", handle_mouseup).on("mousemove", handle_dragging);
}
$(document).ready(function() {
var widthPercent = ($(window).width() - 30) / 3;
$("#html").width(widthPercent + "px");
$("#css").width(widthPercent + "px");
$("#js").width(widthPercent + "px");
});
html, body {
height: 100%;
margin: 0;
}
.container{
width:100%;
height: 100%;
background-color:#343;
display: flex;
flex-direction: column;
color: #fff;
margin: 0;
}
#preview, #code{
background-color:#433;
height: 50%;
width: 100%;
margin: 0;
}
#code{
border-bottom: #333 solid 2px;
width: 100%
}
#previewNav, #codeNav{
background-color:#bbb;
height: 10px;
width: 100%;
cursor: row-resize;
}
#html{
background-color: #BFB;
}
#css{
background-color: #FBB;
}
#js{
background-color: #BBF;
}
#html, #css, #js{
float: left;
width: 32%;
height: 100%;
}
#htmlNav, #cssNav, #jsNav{
background-color:#bbb;
float: left;
height:100%;
width: 10px;
cursor: col-resize;
z-index:10;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div id="codeNav"></div>
<div id="code">
<div id="htmlNav"></div>
<div id="html">H</div>
<div id="cssNav"></div>
<div id="css">C</div>
<div id="jsNav"></div>
<div id="js">J</div>
</div>
<div id="previewNav"></div>
<div id="preview">P</div>
</div>
This is how I would do it:
Keep track of which handle you press with navTypeand check if the user is holding its mouse down with dragging.
Then when the user moves the mouse in the document and it is holding its mouse down (dragging) it will move the #html, #css and #js accordingly
Change your javascript into this:
var mouseX, prevMouseX, navType, change;
var dragging = false;
$("#cssNav").mousedown(function () {
dragging = true;
navType = "css";
});
$("#jsNav").mousedown(function () {
dragging = true;
navType = "js";
});
$(document).mousemove(function (e) {
mouseX = e.pageX;
if(dragging){
e.preventDefault();
change = mouseX - prevMouseX;
if(navType == "css" && ($("#css").width() - (change)) > 0 && ($("#html").width() + (change)) > 0){
var hw = $("#html").width();
var cw = $("#css").width();
$("#html").width(hw + change);
$("#css").width(cw - change);
} else if(navType == "js" && ($("#css").width() + (change)) > 0 && ($("#js").width() - (change)) > 0){
var cw = $("#css").width();
var jw = $("#js").width();
$("#css").width(cw + change);
$("#js").width(jw - change);
}
}
prevMouseX = mouseX;
}).mouseup(function () {
dragging = false;
}).mouseleave(function () {
dragging = false;
});