how to move a div with arrow keys - javascript

I would like to move a div with my arrow keys using jQuery.
So right, left, down and up.
Found a demo of what I want to accomplish here
I would like to be able to move a div around in another div.
How can this be done?

var pane = $('#pane'),
box = $('#box'),
w = pane.width() - box.width(),
d = {},
x = 3;
function newv(v,a,b) {
var n = parseInt(v, 10) - (d[a] ? x : 0) + (d[b] ? x : 0);
return n < 0 ? 0 : n > w ? w : n;
}
$(window).keydown(function(e) { d[e.which] = true; });
$(window).keyup(function(e) { d[e.which] = false; });
setInterval(function() {
box.css({
left: function(i,v) { return newv(v, 37, 39); },
top: function(i,v) { return newv(v, 38, 40); }
});
}, 20);
#pane {
position: relative;
width: 300px;
height: 300px;
border: 2px solid red;
}
#box {
position: absolute;
top: 140px;
left: 140px;
width: 20px;
height: 20px;
background-color: black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="pane">
<div id="box"></div>
</div>
Variable explanations:
w - the maximal left/top value that the box can have (to stay within bounds)
x - the distance (in px) that the box moves in each interval
d - this object stores the information on what key is being pressed. For instance, while the user holds down the LEFT ARROW key, d['37'] is true. Otherwise it's false. BTW, 37 is the key-code for the LEFT ARROW key and this value is stored in the e.which property of the event object. The d object is being updated on each keydown and keyup event.
An setInterval which is executed every 20ms, updates the left and top CSS properties of the box element. The new values are calculated via the newv function.
The newv function will calculate the new left/top value based on a) the old value v and b) the d object.
The expression n < 0 ? 0 : n > w ? w : n ensures that the new value is in the permitted bounds (which are 0 to w). If n is < 0, zero will be returned. If n is > w, w will be returned.
Live demo: http://jsfiddle.net/simevidas/bDMnX/1299/
Update: This code has the same functionality as the original code above. The only difference is that I used more meaningful names for my variables and arguments. As you can see, it looks awful - the original version is clearly better. :P
var pane = $('#pane'),
box = $('#box'),
maxValue = pane.width() - box.width(),
keysPressed = {},
distancePerIteration = 3;
function calculateNewValue(oldValue, keyCode1, keyCode2) {
var newValue = parseInt(oldValue, 10)
- (keysPressed[keyCode1] ? distancePerIteration : 0)
+ (keysPressed[keyCode2] ? distancePerIteration : 0);
return newValue < 0 ? 0 : newValue > maxValue ? maxValue : newValue;
}
$(window).keydown(function(event) { keysPressed[event.which] = true; });
$(window).keyup(function(event) { keysPressed[event.which] = false; });
setInterval(function() {
box.css({
left: function(index ,oldValue) {
return calculateNewValue(oldValue, 37, 39);
},
top: function(index, oldValue) {
return calculateNewValue(oldValue, 38, 40);
}
});
}, 20);

#Šime Vidas: Your first solution is simply marvelous. (i think the second one is redundant =)
May i suggest to make two different functions for the vertical and the horizontal width? Because it’s highly unlikely that you have to move around a div inside a perfect square and i believe it would be nicer to have something like this:
$(function () {
var pane = $('#pane'),
box = $('#box'),
wh = pane.width() - box.width(),
wv = pane.height() - box.height(),
d = {},
x = 5;
function newh(v,a,b) {
var n = parseInt(v, 10) - (d[a] ? x : 0) + (d[b] ? x : 0);
return n < 0 ? 0 : n > wh ? wh : n;
}
function newv(v,a,b) {
var n = parseInt(v, 10) - (d[a] ? x : 0) + (d[b] ? x : 0);
return n < 0 ? 0 : n > wv ? wv : n;
}
$(window).keydown(function(e) { d[e.which] = true; });
$(window).keyup(function(e) { d[e.which] = false; });
setInterval(function() {
box.css({
left: function(i,v) { return newh(v, 37, 39); },
top: function(i,v) { return newv(v, 38, 40); }
});
}, 20);
});
This would have been exactly what i was looking for.
If you had a responsive design based on % values it would be recommendable to adjust your setInterval like this:
setInterval(function() {
box.css({
left: function(i,v) { return newh(v, 37, 39); },
top: function(i,v) { return newv(v, 38, 40); }
});
wh = pane.width() - box.width();
wv = pane.height() - box.height();
}, 20);
if you do that it adjusts your panes height and width and the box still stops at its border.
i made a fiddle of that here http://jsfiddle.net/infidel/JkQrR/1/
Thanks a lot.

I can't see your demo, but here's a simple "move the box 1px in the direction of the arrow keys" example:
CSS:
#wrapper {
background-color: gray;
height:200px;
width: 200px;
position:absolute;
}
#mover {
background-color: white;
border: 1px solid red;
height:20px;
width: 20px;
position:relative;
}
Markup:
<div id="wrapper">
<div id="mover"></div>
</div>
JS (using jQuery):
$("#wrapper").keydown(function(event) {
var $mover = $("#mover");
//if nothing else will move "mover", then track the
//position instead of recalculating it every time:
// var moverPos = $mover.position();
// var left = moverPos.left;
// var top = moverPos.top;
var addTop = function(diff) {
$mover.css("top", ($mover.position().top + diff) + "px");
//if using tracked position:
// top += diff;
// $mover.css("top", top) + "px");
};
var addLeft = function(diff) {
$mover.css("left", ($mover.position().left + diff) + "px");
//if using tracked position:
// left += diff;
// $mover.css("left", left) + "px");
};
switch(event.keyCode) {
case 37: //left
addLeft(-1); break;
case 38: //up
addTop(-1); break;
case 39: //right
addLeft(1); break;
case 40: //down
addTop(1); break;
}
});
This is just an example, you may want to add bounds checking, larger movements, smoother animation, number pad support or any number of other things to it, but it should get you started.

try This Code
<html>
<head>
<style>
#ss{
background:#ccc;
height:100px;
width:100px;
position: absolute;
top: 0;
left: 0;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
</script>
</head>
<body>
<div id="ss"></div>
</body>
<script type="text/javascript">
var $div = $('#ss');
$(document).keydown(function(e) {
switch (e.which) {
case 37:
$div.css('left', $div.offset().left - 10);
break;
case 38:
$div.css('top', $div.offset().top - 10);
break;
case 39:
$div.css('left', $div.offset().left + 10);
break;
case 40:
$div.css('top', $div.offset().top + 10);
break;
}
})
</script>
</html>

Related

Stop moving element when he outside of parent element

So, I have an event listener keydown on arrow right, when you push the square moving on xPX but my parent element this w and h
set a 100px for example, and I would like to stop moving and I can't, I try with element.offsetWidth > 0 so them you can move.
Please look this fiddle : FIDDLE
Few errors in your code. I've commented fixes. Here is how i made it for the right arrow - you can apply same logic to the rest of the moves...
Code:
const carre = document.querySelector('.carre');
const main = document.querySelector('.main');
const w = main.offsetWidth - carre.offsetWidth; // this was wrong in your code
carre.style.left="0px"; // set start position
document.addEventListener('keyup', (event) => {
const positionLeft = parseInt(carre.style.left); //i've used style.left, rather, it gives expected numbers (10,20,30....)
if(event.keyCode == '39') {
if (positionLeft < w) { // this was fixed too
carre.style.left = (positionLeft) + 10 + 'px';
} else {
carre.style.left = '0'
}
}
})
DEmo:
const carre = document.querySelector('.carre');
const main = document.querySelector('.main');
const w = main.offsetWidth - carre.offsetWidth; // this was wrong in your code
carre.style.left="0px"; // set start position
document.addEventListener('keyup', (event) => {
const positionLeft = parseInt(carre.style.left); //i've used style.left, rather, it gives expected numbers (10,20,30....)
if(event.keyCode == '39') {
if (positionLeft < w) { // this was fixed too
carre.style.left = (positionLeft) + 10 + 'px';
} else {
carre.style.left = '0'
}
}
})
* {
box-sizing:border-box;
}
.carre {
position:absolute;
left: 0;
width: 50px;
height: 50px;
background-color: red;
}
.main {
position: relative;
width: 100px;
height: 100px;
border: 1px solid #000;
}
<main class="main">
<div class="carre"></div>
</main>
I rebuild your code:
document.addEventListener('keydown', (event) => {
const w = main.getBoundingClientRect().right - carre.getBoundingClientRect().right;
const positionLeft = carre.getBoundingClientRect().left;
if(event.keyCode == '39') {
if (w >= 0) {
carre.style.left = (positionLeft) + 10 + 'px';
} else {
carre.style.left = '0'
}
}
if (event.keyCode == '37') {
if (w >= 0) {
carre.style.left = (positionLeft) - 10 + 'px';
}else {
carre.style.left = '0'
}
}
})

JavaScript - Stop laser once its in its incrementation cycle

To see a working example simply copy code into notepad++ and run in chrome as a .html file, I have had trouble getting a working example in snippet or code pen, I would have given a link to those websites if I could get it working in them.
The QUESTION is; once I fire the laser once it behaves exactly the way I want it to. It increments with lzxR++; until it hits boarder of the game arena BUT if I hit the space bar WHILST the laser is moving the code iterates again and tries to display the laser in two places at once which looks bad and very choppy, so how can I get it to work so the if I hit the space bar a second time even whilst the laser was mid incrementation - it STOPS the incrementing and simply shoots a fresh new laser without trying to increment multiple lasers at once???
below is the Code:
<html>
<head>
<style>
#blueCanvas {
position: absolute;
background-color: black;
width: 932px;
height: 512px;
border: 1px solid black;
top: 20px;
left: 20px;
}
#blueBall {
position: relative;
background-color: white;
border: 1px solid blue;
width: 10px;
height: 10px;
border-radius: 100%;
top: 0px;
left: 0px;
}
#laser {
position: absolute;
background-color: white;
border: 1px solid blue;
width: 10px;
height: 1px;
top: 10px;
left: 10px;
}
#pixelTrackerTop {
position: absolute;
top: 530px;
left: 20px;
}
#pixelTrackerLeft {
position: absolute;
top: 550px;
left: 20px;
}
</style>
<title>Portfolio</title>
<script src="https://ajax.googleapis.com/
ajax/libs/jquery/1.12.4/jquery.min.js">
</script>
<SCRIPT LANGUAGE="JavaScript" type="text/javascript">
document.addEventListener("keydown", keyBoardInput);
var topY = 0;
var leftX = 0;
var lzrY = 0;
var lzrX = 0;
function moveUp() {
var Y = document.getElementById("blueBall");
topY = topY -= 1;
Y.style.top = topY;
masterTrack();
if (topY < 1) {
topY = 0;
Y.style.top = topY;
};
stopUp = setTimeout("moveUp()", 1)
/**allows for progression of speed with additional key strokes**/
topStop();
stopConflictYup();
console.log('moveUp');
};
function moveDown() {
var Y = document.getElementById("blueBall");
topY = topY += 1;
Y.style.top = topY;
masterTrack();
if (topY > 500) {
topY = 500;
Y.style.top = topY;
};
stopDown = setTimeout("moveDown()", 1)
/**allows for progression of speed with additional key strokes**/
topStop();
stopConflictYdown();
console.log('moveDown');
};
function moveLeft() {
var X = document.getElementById("blueBall");
leftX = leftX -= 1;
X.style.left = leftX;
masterTrack();
if (leftX < 1) {
leftX = 0;
Y.style.leftX = leftX;
};
stopLeft = setTimeout("moveLeft()", 1)
/**allows for progression of speed with additional key strokes**/
leftStop();
stopConflictXleft();
console.log('moveLeft');
};
function moveRight() {
var X = document.getElementById("blueBall");
leftX = leftX += 1;
X.style.left = leftX;
masterTrack();
if (leftX > 920) {
leftX = 920;
Y.style.leftX = leftX;
};
stopRight = setTimeout("moveRight()", 1)
/**allows for progression of speed with additional key strokes**/
leftStop();
stopConflictXright();
console.log('moveRight');
};
function masterTrack() {
var pxY = topY;
var pxX = leftX;
document.getElementById('pixelTrackerTop').innerHTML =
'Top position is ' + pxY;
document.getElementById('pixelTrackerLeft').innerHTML =
'Left position is ' + pxX;
};
function topStop() {
if (topY <= 0) {
clearTimeout(stopUp);
console.log('stopUp activated');
};
if (topY >= 500) {
clearTimeout(stopDown);
console.log('stopDown activated');
};
};
function leftStop() {
if (leftX <= 0) {
clearTimeout(stopLeft);
console.log('stopLeft activated');
};
if (leftX >= 920) {
clearTimeout(stopRight);
console.log('stopRight activated');
};
};
function stopConflictYup() {
clearTimeout(stopDown);
};
function stopConflictYdown() {
clearTimeout(stopUp);
};
function stopConflictXleft() {
clearTimeout(stopRight);
};
function stopConflictXright() {
clearTimeout(stopLeft);
};
function shootLaser() {
var l = document.getElementById("laser");
var lzrY = topY;
var lzrX = leftX;
fireLaser();
function fireLaser() {
l.style.left = lzrX; /**initial x pos **/
l.style.top = topY; /**initial y pos **/
var move = setInterval(moveLaser, 1);
/**continue to increment laser unless IF is met**/
function moveLaser() { /**CALL and start the interval**/
var bcrb = document.getElementById("blueCanvas").style.left;
if (lzrX > bcrb + 920) {
/**if the X axis of the laser goes beyond the
blueCanvas 0 point by 920 then stop incrementing the laser on its X
axis**/
clearInterval(move);
/**if statement was found true so stop increment of laser**/
} else {
lzrX++;
l.style.left = lzrX;
};
};
};
};
function keyBoardInput() {
var i = event.keyCode;
if (i == 32) {
shootLaser();
};
if (i == 38) {
if (topY > 0) {
moveUp();
};
};
if (i == 40) {
if (topY < 500) {
moveDown();
};
};
if (i == 37) {
if (leftX > 0) {
moveLeft();
};
};
if (i == 39) {
if (leftX < 920) {
moveRight();
};
};
};
/**
!! gradual progression of opacity is overall
!! being able to speed up element is best done with setTimout
!! setInterval is constant regards to visual speed
!! NEXT STEP IS ARRAYS OR CLASSES
IN ORDER TO SHOOT MULITPLE OF SAME ELEMENT? MAYBEE?
var l = document.getElementById("laser");
lzrX = lzrX += 1;
l.style.left = lzrX;
lzrY = topY += 1;
l.style.top = lzrY;
**/
</SCRIPT>
</head>
<div id="blueCanvas">
<div id="laser"></div>
<div id="blueBall">
</div>
</div>
<p id="pixelTrackerTop">Top position is 0</p>
<br>
<p id="pixelTrackerLeft">Left position is 0</p>
</body>
</html>
Solved the problem with using a variable called "g" and incrementing it once the laser is shot!
var g = 0;
function keyBoardInput() {
var i = event.keyCode;
if (i == 32) {
if (g < 1) {
shootLaser();
g++;
};
};

Overlapping range inputs. On click change input with closest value

I have two overlapping range inputs, this creates a multi range input effect.
I want it so that whenever a click is made on either of these, the input with the closest value to the newly clicked value, is changed. Not entirely sure how to go about this.
How could I do this?
(function() {
"use strict";
var supportsMultiple = self.HTMLInputElement && "valueLow" in HTMLInputElement.prototype;
var descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value");
self.multirange = function(input) {
if (supportsMultiple || input.classList.contains("multirange")) {
return;
}
var values = input.getAttribute("value").split(",");
var max = +input.max || 100;
var ghost = input.cloneNode();
input.classList.add("multirange", "original");
ghost.classList.add("multirange", "ghost");
input.value = values[0] || max / 2;
ghost.value = values[1] || max / 2;
input.parentNode.insertBefore(ghost, input.nextSibling);
Object.defineProperty(input, "originalValue", descriptor.get ? descriptor : {
// Dang you Safari >:(
get: function() {
return this.value;
},
set: function(v) {
this.value = v;
}
});
Object.defineProperties(input, {
valueLow: {
get: function() {
return Math.min(this.originalValue, ghost.value);
},
set: function(v) {
this.originalValue = v;
},
enumerable: true
},
valueHigh: {
get: function() {
return Math.max(this.originalValue, ghost.value);
},
set: function(v) {
ghost.value = v;
},
enumerable: true
}
});
if (descriptor.get) {
// Again, fuck you Safari
Object.defineProperty(input, "value", {
get: function() {
return this.valueLow + "," + this.valueHigh;
},
set: function(v) {
var values = v.split(",");
this.valueLow = values[0];
this.valueHigh = values[1];
},
enumerable: true
});
}
function update() {
ghost.style.setProperty("--low", input.valueLow * 100 / max + 1 + "%");
ghost.style.setProperty("--high", input.valueHigh * 100 / max - 1 + "%");
}
input.addEventListener("input", update);
ghost.addEventListener("input", update);
update();
}
multirange.init = function() {
Array.from(document.querySelectorAll("input[type=range][multiple]:not(.multirange)")).forEach(multirange);
}
if (document.readyState == "loading") {
document.addEventListener("DOMContentLoaded", multirange.init);
} else {
multirange.init();
}
})();
#supports (--css: variables) {
input[type="range"].multirange {
-webkit-appearance: none;
padding: 0;
margin: 0;
display: inline-block;
vertical-align: top;
width: 250px;
margin-top: 50px;
margin-left: 50px;
background: lightblue;
}
input[type="range"].multirange.original {
position: absolute;
}
input[type="range"].multirange.original::-webkit-slider-thumb {
position: relative;
z-index: 2;
}
input[type="range"].multirange.original::-moz-range-thumb {
transform: scale(1);
/* FF doesn't apply position it seems */
G z-index: 1;
}
input[type="range"].multirange::-moz-range-track {
border-color: transparent;
/* needed to switch FF to "styleable" control */
}
input[type="range"].multirange.ghost {
position: relative;
background: var(--track-background);
--track-background: linear-gradient(to right, transparent var(--low), var(--range-color) 0, var(--range-color) var(--high), transparent 0) no-repeat 0 45% / 100% 40%;
--range-color: hsl(190, 80%, 40%);
}
input[type="range"].multirange.ghost::-webkit-slider-runnable-track {
background: var(--track-background);
}
input[type="range"].multirange.ghost::-moz-range-track {
background: var(--track-background);
}
}
<input type="range" multiple value="10,80" />
You'll have to capture a mouse event on the element and calculate how close it is to the high marker vs. the low marker and decide which one to update based on that. Also, because these are two stacked input elements, you'll probably have to pass the event to the low range input manually.
Here's my go at creating such a function:
function passClick(evt) {
// Are the ghost and input elements inverted? (ghost is lower range)
var isInverted = input.valueLow == ghost.value;
// Find the horizontal position that was clicked (as a percentage of the element's width)
var clickPoint = evt.offsetX / this.offsetWidth;
// Map the percentage to a value in the range (note, assumes a min value of 0)
var clickValue = max * clickPoint;
// Get the distance to both high and low values in the range
var highDiff = Math.abs(input.valueHigh - clickValue);
var lowDiff = Math.abs(input.valueLow - clickValue);
if (lowDiff < highDiff && !isInverted || (isInverted && lowDiff > highDiff)) {
// The low value is closer to the click point than the high value
// We should update the low value input
var passEvent = new MouseEvent("mousedown", {screenX: evt.screenX, clientX: evt.clientX});
// Pass a new event to the low "input" element (which is obscured by the
// higher "ghost" element, and doesn't get mouse events outside the drag handle
input.dispatchEvent(passEvent);
// The higher "ghost" element should not respond to this event
evt.preventDefault();
return false;
}
else {
console.log("move ghost");
// The high value is closer to the click point than the low value
// The default behavior is appropriate, so do nuthin
}
}
ghost.addEventListener("mousedown", passClick);
I put this code immediately above the input.addEventListener("input", update); line in your sample, and it seems to work. See my fiddle.
Some provisos though:
I only tested in Chrome. IE might have some trouble based on how I replicated the event. It may use a mechanism other than dispatchEvent... like fireEvent or something.
Initially I coded it assuming that the "ghost" element always kept track of the high range. I've since updated things to invert the event dispatching when the ghost element has the lower value--but I sped through it.
Here's something simple you could use. Although you might want to customize the style.
I am altering the z-index of the slider element based upon its proximity to the cursor.
JSFiddle
HTML
<input id='a' type='range' />
<input id='b' type='range' />
<label role='info'></label>
JS
var a = document.getElementById('a');
var b = document.getElementById('b');
a.onmousemove = function(e) {
MouseMove.call(a, e);
};
b.onmousemove = function(e) {
MouseMove.call(b, e);
};
var MouseMove = function(eventArg)
{
var max = parseInt(a.max),
min = parseInt(a.min),
diff = max - min,
clickPoint = eventArg.offsetX / a.offsetWidth,
clickPointVal = parseInt(diff * clickPoint) + min;
/* absolute distance from respective slider values */
var da = Math.abs(a.value - clickPointVal),
db = Math.abs(b.value - clickPointVal);
// Making the two sliders appear above one another only when no mouse button is pressed, this condition may be removed at will
if (!eventArg.buttons)
{
if (da < db)
{
a.style.zIndex = 2;
b.style.zIndex = 1;
}
else if (db < da)
{
b.style.zIndex = 2;
a.style.zIndex = 1;
}
}
document.querySelector('label').innerHTML = 'Red: ' + a.value + ', Green: ' + b.value + ', X: ' + eventArg.clientX;
}
CSS
input {
margin: 0px;
position: absolute;
left: 0px;
}
label {
display: inline-block;
margin-top: 100px;
}
#a {
z-index: 2;
}
#b {
z-index: 1;
}

How to detect object collision for this JavaScript game

Trying to put together a small game for practice and I came across a issue. The point is to catch the goblin but I don't know how to make the game detect that player has hit the goblin.
So far you can only detect touched if your position Y and X matches with the enemies axis. How can I either increase the width for both or a better way of detecting touch.
try it out here: https://jsfiddle.net/acbkk7cs/4/
Style:
#map{
margin: 0 auto;
height: 510px;
width: 510px;
background-image:url(background.png);
}
.character{
background-image:url(character.png);
z-index:1;
position: relative;
top: 150px;
left: 150px;
height: 32px;
width: 33px;
}
.monster{
background-image:url(monster.png);
position: relative;
height: 32px;
width: 30px;
}
Javascript:
$(document).ready(function(){
var char = {
player : $(".character"),
x: 150,
y: 150
};
var monster = {
npc : $(".monster"),
x: 100,
y: 100
};
var keypush = {};
$(document).on("keydown keyup", function(e){
var keyN = e.which;
keypush[keyN] = e.type === "keydown";
});
function moveCharacter(){
if (keypush[37]) char.x -=2;
if (keypush[38]) char.y -=2;
if (keypush[39]) char.x +=2;
if (keypush[40]) char.y +=2;
char.player.css({transform:"translate3D("+ char.x +"px, "+ char.y +"px, 0)"});
monster.npc.css({transform:"translate3D("+ monster.x +"px, "+ monster.y +"px, 0)"});
var playerPosX = char.player.position().top;
var monsterPosX = monster.npc.position().top;
var playerPosY = char.player.position().left;
var monsterPosY = monster.npc.position().left;
if ( playerPosX === monsterPosX
&& playerPosY === monsterPosY
){
document.getElementById("pos").innerHTML="Touched";
} else {
document.getElementById("pos").innerHTML="Off";
}
//backend logs
console.log(char.x);
}
(function engine(){
moveCharacter();
window.requestAnimationFrame(engine);
}());
});
HTML:
<div id = "map">
<div class = "character">
</div>
<div class = "monster">
<p id = "pos" style = "color:yellow;font- weight:bold;position:relative;left:5px;font-size:20px;">Position: </p>
</div>
</div>
The easiest and fastest way is to calculate the distance between the character and the monster: fiddle using circle collision.
var dx = playerPosX - monsterPosX,
dy = playerPosY - monsterPosY,
touchDistance = 30;
if ( Math.sqrt( dx * dx + dy * dy ) < touchDistance )
document.getElementById("pos").innerHTML="Touched";
else
document.getElementById("pos").innerHTML="Off";
Here, I eyeballed the touchDistance, but it's actual value should be the sum of the radius of the player sprite and the radius of the monster sprite. This works best if they are circles:
/**
* (ax,ay) and (bx,by) are the center positions, and ar, br their radii.
*/
function circleCollision( ax, ay, ar, bx, by, br ) {
return Math.sqrt( (ax-bx)*(ax-bx) + (ay-by)*(ay-by) ) <= ar + br;
}
A second common way to determine collision is to use 'bounding boxes', or in this case, rectangles/squares: Fiddle using rectangle collision.
function rectangleCollision( pLeft, pTop, pRight, pBottom, mLeft, mTop, mRight, mBottom ) {
return
( (pLeft >= mLeft && pLeft < mRight ) || (pRight >= mLeft && pRight < mRight ) )
&& ( (pBottom >= mTop && pBottom < mBottom) || (pTop >= mTop && pTop < mBottom) )
}

How to create a curved slider?

i'm trying to create a curved slider with jquery like this:
with no success.
can anyone point be to the right direction?
Thanks allot
Avi
This is what you want exactly. By using the jQuery roundSlider plugin you can make any type of arc slider with custom appearance.
Please check this jsFiddle for the demo of you requirement.
Live demo:
$("#arc-slider").roundSlider({
sliderType: "min-range",
circleShape: "custom-quarter",
value: 75,
startAngle: 45,
editableTooltip: true,
radius: 350,
width: 6,
handleSize: "+32",
tooltipFormat: function (args) {
return args.value + " %";
}
});
#arc-slider {
height: 110px !important;
width: 500px !important;
overflow: hidden;
padding: 15px;
}
#arc-slider .rs-container {
margin-left: -350px; /* here 350 is the radius value */
left: 50%;
}
#arc-slider .rs-tooltip {
top: 60px;
}
#arc-slider .rs-tooltip-text {
font-size: 25px;
}
#arc-slider .rs-border{
border-width: 0px;
}
/* Appearance related changes */
.rs-control .rs-range-color {
background-color: #54BBE0;
}
.rs-control .rs-path-color {
background-color: #5f5f5f;
}
.rs-control .rs-handle {
background-color: #51c5cf;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.roundslider/1.0/roundslider.min.js"></script>
<link href="https://cdn.jsdelivr.net/jquery.roundslider/1.0/roundslider.min.css" rel="stylesheet"/>
<div id="arc-slider" class="rslider"></div>
Screenshots of the Output:
To know more about the roundSlider, please check the demos and documentation page.
Please check this LINK, you will get enough details for the slider.
'slide': function(e, ui){
var percentLeft;
var submitValue;
var Y = ui.value - 100; //Find center of Circle (We're using a max value and height of 200)
var R = 100; //Circle's radius
var skip = false;
$(this).children('.ui-slider-handle').attr('href',' UI.val = ' + ui.value);
//Show default/disabled/out of bounds state
if ( ui.value > 0 && ui.value < 201 ) { //if in the valid slide rang
$(this).children('.ui-slider-handle').addClass('is-active');
}
else {
$(this).children('.ui-slider-handle').removeClass('is-active');
}
//Calculate slider's path on circle, put it there, by setting background-position
if ( ui.value >= 0 && ui.value <= 200 ) { //if in valid range, these are one inside the min and max
var X = Math.sqrt((R*R) - (Y*Y)); //X^2 + Y^2 = R^2. Find X.
if ( X == 'NaN' ) {
percentLeft = 0;
}
else {
percentLeft = X;
}
}
else if ( ui.value == -1 || ui.value == 201 ) {
percentLeft = 0;
skip = true;
}
else {
percentLeft = 0;
}
//Move handle
if ( percentLeft > 100 ) { percentLeft = 100; }
$(this).children('.ui-slider-handle').css('background-position',percentLeft +'% 100%'); //set new css sprite, active state
//Figure out and set input value
if ( skip == true ) {
submitValue = 'fail';
$(this).children('.ui-slider-handle').css('background-position',percentLeft +'% 0%'); //reset css sprite
}
else {
submitValue = Math.round(ui.value / 2); //Clamp input value to range 0 - 100
}
$('#display-only input').val(submitValue); //display selected value, demo only
$('#slider-display').text(submitValue); //display selected value, demo only
$(this).prev('.slider-input').val(ui.value); //Set actual input field val. jQuery UI hid it for us, but it will be submitted.
}
You can also try this LINK also.
If you want any other assistance, then please add comment.
Regards D.
Alternative way you can use this plugin for a curved/360 degree slider
Reference
Here is the coding:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="js/round-slider.min.js"></script>
<div class="box dotted">
<div class="left">
<div id="degrees" class="demo"></div>
</div>
<div class="right">
<p class="name">Degrees</p>
<p id="degrees-data"></p>
</div>
</div>
Javascript
(function($){
'use strict';
var set_html = function(value, index, angle, unit){
var html = ''
,val = value;
if(unit !== ''){
val += unit;
}
html += '<b>Value: </b>' + val + '<br/>';
html += '<b>Index: </b>' + index + '<br/>';
html += '<b>Angle: </b>' + angle + '<br/>';
return html;
};
$('document').ready(function(){
var self = {
degrees: null
};
self.degrees = $('#degrees').round_slider({
min: 0,
max: 359,
unit_sign: '\u00b0',
bg: 'img/bg/degrees-theme.png',
handle_bg: 'img/handles/wheel-33-33.png',
input_bg: 'img/input/round-50.png',
points_bg: 'img/points/degress-white.png',
angle_changed_callback: function(value, index, angle, unit){
$('#degrees-data').html(set_html(value, index, angle, unit));
}
});
});
})(jQuery);
Check here for the demo
Demo

Categories