Skip to content

Instantly share code, notes, and snippets.

@re-gor
Created May 14, 2017 14:36
Show Gist options
  • Save re-gor/c1c94d730bf6fef70af4b09d2cc04e55 to your computer and use it in GitHub Desktop.
Save re-gor/c1c94d730bf6fef70af4b09d2cc04e55 to your computer and use it in GitHub Desktop.
JS Bin // source https://jsbin.com/loqetu
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.0.6/rx.all.js"></script>
<title>JS Bin</title>
<style id="jsbin-css">
.log{
height: 30px;
border: 1px solid grey;
}
.border {
padding: 200px;
border: 1px solid grey;
}
.field{
width:400px;
height:400px;
border: 1px solid grey;
display: relative;
}
.draggable {
width: 50px;
height: 50px;
top: 350px;
left: 350px;
position: absolute;
border: 1px solid green;
background: rgba(0, 255, 0, 0.3);
}
</style>
</head>
<body>
<div class='log'>
</div>
<div class='border'>
<div class='field'>
<div class='draggable'>
</div>
</div>
</div>
<script id="jsbin-javascript">
'use strict';
var $body = $('body');
mousedown = Rx.Observable.fromEvent($body, 'mousedown');
var mouseup = Rx.Observable.fromEvent($body, 'mouseup');
var mousemove = Rx.Observable.fromEvent($body, 'mousemove');
var pressedMousemove = mousemove.filter(function () {
return pressed.pressed;
});
var pressed = {
$el: null,
pressed: false,
mouseOffset: {
left: 0,
top: 0
}
};
var boundaries = calcBoundaries($('.field'));
mousedown.filter(function (e) {
return $(e.target).closest('.draggable').length > 0;
}).subscribe(function (e) {
pressed.pressed = true;
pressed.$el = $(e.target);
pressed.mouseOffset = calcMouseOffset(e);
});
mouseup.subscribe(function (e) {
pressed.pressed = false;
});
pressedMousemove.map(function (e) {
var _calcWithMouseOffset = calcWithMouseOffset(e);
var top = _calcWithMouseOffset.top;
var isLowerThanTop = top >= boundaries.top;
var isUpperThanBotom = top + pressed.$el.height() <= boundaries.bottom;
if (isLowerThanTop && isUpperThanBotom) {
return top;
}
if (isUpperThanBotom) {
return boundaries.top;
}
if (isLowerThanTop) {
return boundaries.bottom - pressed.$el.height();
}
}).subscribe(function (y) {
return $(pressed.$el).css({ top: y });
});
pressedMousemove.map(function (e) {
var _calcWithMouseOffset2 = calcWithMouseOffset(e);
var left = _calcWithMouseOffset2.left;
var isRighterThanLeft = left >= boundaries.left;
var isLefterThanRight = left + pressed.$el.width() <= boundaries.right;
if (isRighterThanLeft && isLefterThanRight) {
return left;
}
if (isLefterThanRight) {
return boundaries.left;
}
if (isRighterThanLeft) {
return boundaries.right - pressed.$el.height();
}
}).subscribe(function (x) {
return $(pressed.$el).css({ left: x });
});
mousemove.subscribe(function (e) {
log({
clientY: e.clientY,
clientX: e.clientX,
pressed: pressed
});
});
function log(_ref) {
var clientX = _ref.clientX;
var clientY = _ref.clientY;
var pressed = _ref.pressed;
$('.log').text('\n x: ' + clientX + '\n y: ' + clientY + '\n pressed: ' + pressed.pressed + '\n pressedX: ' + (pressed.$el && pressed.$el.offset().left) + '\n pressedY: ' + (pressed.$el && pressed.$el.offset().top) + '\n ');
}
function calcBoundaries($el) {
var offset = $el.offset();
return {
left: offset.left,
top: offset.top,
right: offset.left + $el.width(),
bottom: offset.top + $el.height()
};
}
function calcWithMouseOffset(e) {
return {
top: e.clientY - pressed.mouseOffset.top,
left: e.clientX - pressed.mouseOffset.left
};
}
function calcMouseOffset(e) {
var $el = pressed.$el;
return {
top: e.clientY - $el.offset().top,
left: e.clientX - $el.offset().left
};
}
</script>
<script id="jsbin-source-css" type="text/css">.log{
height: 30px;
border: 1px solid grey;
}
.border {
padding: 200px;
border: 1px solid grey;
}
.field{
width:400px;
height:400px;
border: 1px solid grey;
display: relative;
}
.draggable {
width: 50px;
height: 50px;
top: 350px;
left: 350px;
position: absolute;
border: 1px solid green;
background: rgba(0, 255, 0, 0.3);
}</script>
<script id="jsbin-source-javascript" type="text/javascript">const $body = $('body')
mousedown = Rx.Observable.fromEvent($body, 'mousedown');
const mouseup = Rx.Observable.fromEvent($body, 'mouseup');
const mousemove = Rx.Observable.fromEvent($body, 'mousemove');
const pressedMousemove = mousemove.filter(() => pressed.pressed);
let pressed = {
$el: null,
pressed: false,
mouseOffset: {
left: 0,
top: 0
}
}
const boundaries = calcBoundaries($('.field'));
mousedown
.filter((e) => $(e.target).closest('.draggable').length > 0)
.subscribe(function (e) {
pressed.pressed = true;
pressed.$el = $(e.target);
pressed.mouseOffset = calcMouseOffset(e)
})
mouseup.subscribe(function (e) {
pressed.pressed = false;
})
pressedMousemove
.map((e) => {
const {top} = calcWithMouseOffset(e);
const isLowerThanTop = top >= boundaries.top
const isUpperThanBotom = top + pressed.$el.height() <= boundaries.bottom
if (isLowerThanTop && isUpperThanBotom) {
return top
}
if (isUpperThanBotom) {
return boundaries.top
}
if (isLowerThanTop) {
return boundaries.bottom - pressed.$el.height()
}
})
.subscribe((y) => $(pressed.$el).css({top: y}));
pressedMousemove
.map((e) => {
const {left} = calcWithMouseOffset(e);
const isRighterThanLeft = left >= boundaries.left;
const isLefterThanRight = left + pressed.$el.width() <= boundaries.right;
if (isRighterThanLeft && isLefterThanRight) {
return left;
}
if (isLefterThanRight) {
return boundaries.left;
}
if (isRighterThanLeft) {
return boundaries.right - pressed.$el.height();
}
})
.subscribe((x) => $(pressed.$el).css({left: x}))
mousemove.subscribe(function (e) {
log({
clientY: e.clientY,
clientX: e.clientX,
pressed
})
})
function log({clientX, clientY, pressed}) {
$('.log').text(`
x: ${clientX}
y: ${clientY}
pressed: ${pressed.pressed}
pressedX: ${pressed.$el && pressed.$el.offset().left}
pressedY: ${pressed.$el && pressed.$el.offset().top}
`)
}
function calcBoundaries($el) {
let offset = $el.offset();
return {
left: offset.left,
top: offset.top,
right: offset.left + $el.width(),
bottom: offset.top + $el.height()
}
}
function calcWithMouseOffset(e) {
return {
top: e.clientY - pressed.mouseOffset.top,
left: e.clientX - pressed.mouseOffset.left
}
}
function calcMouseOffset(e) {
let $el = pressed.$el;
return {
top: e.clientY - $el.offset().top,
left: e.clientX - $el.offset().left,
}
}
</script></body>
</html>
.log{
height: 30px;
border: 1px solid grey;
}
.border {
padding: 200px;
border: 1px solid grey;
}
.field{
width:400px;
height:400px;
border: 1px solid grey;
display: relative;
}
.draggable {
width: 50px;
height: 50px;
top: 350px;
left: 350px;
position: absolute;
border: 1px solid green;
background: rgba(0, 255, 0, 0.3);
}
'use strict';
var $body = $('body');
mousedown = Rx.Observable.fromEvent($body, 'mousedown');
var mouseup = Rx.Observable.fromEvent($body, 'mouseup');
var mousemove = Rx.Observable.fromEvent($body, 'mousemove');
var pressedMousemove = mousemove.filter(function () {
return pressed.pressed;
});
var pressed = {
$el: null,
pressed: false,
mouseOffset: {
left: 0,
top: 0
}
};
var boundaries = calcBoundaries($('.field'));
mousedown.filter(function (e) {
return $(e.target).closest('.draggable').length > 0;
}).subscribe(function (e) {
pressed.pressed = true;
pressed.$el = $(e.target);
pressed.mouseOffset = calcMouseOffset(e);
});
mouseup.subscribe(function (e) {
pressed.pressed = false;
});
pressedMousemove.map(function (e) {
var _calcWithMouseOffset = calcWithMouseOffset(e);
var top = _calcWithMouseOffset.top;
var isLowerThanTop = top >= boundaries.top;
var isUpperThanBotom = top + pressed.$el.height() <= boundaries.bottom;
if (isLowerThanTop && isUpperThanBotom) {
return top;
}
if (isUpperThanBotom) {
return boundaries.top;
}
if (isLowerThanTop) {
return boundaries.bottom - pressed.$el.height();
}
}).subscribe(function (y) {
return $(pressed.$el).css({ top: y });
});
pressedMousemove.map(function (e) {
var _calcWithMouseOffset2 = calcWithMouseOffset(e);
var left = _calcWithMouseOffset2.left;
var isRighterThanLeft = left >= boundaries.left;
var isLefterThanRight = left + pressed.$el.width() <= boundaries.right;
if (isRighterThanLeft && isLefterThanRight) {
return left;
}
if (isLefterThanRight) {
return boundaries.left;
}
if (isRighterThanLeft) {
return boundaries.right - pressed.$el.height();
}
}).subscribe(function (x) {
return $(pressed.$el).css({ left: x });
});
mousemove.subscribe(function (e) {
log({
clientY: e.clientY,
clientX: e.clientX,
pressed: pressed
});
});
function log(_ref) {
var clientX = _ref.clientX;
var clientY = _ref.clientY;
var pressed = _ref.pressed;
$('.log').text('\n x: ' + clientX + '\n y: ' + clientY + '\n pressed: ' + pressed.pressed + '\n pressedX: ' + (pressed.$el && pressed.$el.offset().left) + '\n pressedY: ' + (pressed.$el && pressed.$el.offset().top) + '\n ');
}
function calcBoundaries($el) {
var offset = $el.offset();
return {
left: offset.left,
top: offset.top,
right: offset.left + $el.width(),
bottom: offset.top + $el.height()
};
}
function calcWithMouseOffset(e) {
return {
top: e.clientY - pressed.mouseOffset.top,
left: e.clientX - pressed.mouseOffset.left
};
}
function calcMouseOffset(e) {
var $el = pressed.$el;
return {
top: e.clientY - $el.offset().top,
left: e.clientX - $el.offset().left
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment