I've got an issue with the element position properties, in particular the 'left' property. I've created a grey block shape in css and rotated it by 0.17rad in js. I want to move the block diagonally across the screen so that it moves a distance of 3px for every 20 milliseconds. If you use your good old SOHCAHTOA and pythagoras laws, that comes out to 0.5075470472px in the left direction and 2.956754301px in the upwards direction every 20ms.
html:
<html lang='en'>
<head>
<meta charset="UTF-8">
<link rel='stylesheet' href='.css'>
</head>
<body>
<div id='block'></div>
<script src='.js'></script>
</body>
</html>
css:
#block {
width: 19px;
height: 31px;
position: absolute;
background-color: grey;
}
js:
var block = document.getElementById('block');
block.style.left = '0px';
block.style.top = '500px';
block.style.transform = 'rotate(0.17rad)';
setInterval(function() {
block.style.left = (parseInt(block.style.left) + 0.5075470472) + 'px';
block.style.top = (parseInt(block.style.top) - 2.956754301) + 'px';
}, 20);
What happens in my case is the block moves correctly in the upward direction but doesn't move at all in the left direction. Any thoughts?
parseInt is rounding the numbers, what you need is to use parseFloat:
block.style.left = (parseFloat(block.style.left) + 0.5075470472) + 'px';
block.style.top = (parseFloat(block.style.top) - 2.956754301) + 'px';
Related
I'm implementing a feature on my app which make use of Snap.SVG to create rectangles which can be dragged. This is my code: (I uploaded it here: http://jsfiddle.net/u8vnL9tg/)
<!DOCTYPE html>
<html>
<head>
<title>TEST WHITEOUT FEATURE</title>
<style type="text/css">
#mySvg{
width: 700px;
height: 700px;
margin: 0 auto;
display: block;
border: 1px solid black;
}
.white-out{
cursor: move;
}
</style>
</head>
<body>
<svg id="mySvg">
</svg>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.4.1/snap.svg-min.js"></script>
<script type="text/javascript">
var s = Snap("#mySvg");
$('#mySvg').mousedown(function(e){
if (e.which === 1){
if ($(e.target).is('.white-out')){
return;
} else {
$('#mySvg').css({
'cursor' : 'cell'
});
// Calculate relative mouse position
var offset = $('#mySvg').offset();
var relativeMouseX = e.pageX - offset.left;
var relativeMouseY = e.pageY - offset.top;
// Create a rectangle
var selectionRect = s.rect(relativeMouseX, relativeMouseY, 1, 1);
selectionRect.addClass('white-out');
$('#mySvg').on('mousemove', function(e){
// Calculate relative mouse position
var offset = $('#mySvg').offset();
var newRelativeMouseX = e.pageX - offset.left;
var newRelativeMouseY = e.pageY - offset.top;
var width = Math.abs(newRelativeMouseX - relativeMouseX);
var height = Math.abs(newRelativeMouseY - relativeMouseY);
var new_x, new_y;
new_x = (newRelativeMouseX < relativeMouseX) ? (relativeMouseX - width) : relativeMouseX;
new_y = (newRelativeMouseY < relativeMouseY) ? (relativeMouseY - height) : relativeMouseY;
selectionRect.attr({
'width': width,
'height': height,
'top': new_y,
'left': new_x,
'fill': '#6699FF',
'opacity': 0.5
});
});
$('#mySvg').on('mouseup', function(e) {
// Unbind the mousemove event
$('#mySvg').off('mousemove');
// Set opacity to 1 - so it's really a whiteout
selectionRect.attr({
'opacity': 1
});
selectionRect.drag();
// Set cursor to default
$('#mySvg').css({
'cursor' : 'default'
});
});
}
}
});
</script>
</body>
</html>
At the moment, I have successfully create the rectangles and make them draggable. The problem I'm facing here is that after some attempts (more than 5 times, for example) of drag-and-drop a rectangle, the rectangle becomes MUCH slower and slower. After about 10 times of drag-and-drop, it even hardly move ! I don't know why this is happening though I'm following the examples and tutorials on the Internet, and especially the SnapSVG documentation.
Really hope that you guys could help ! Thanks so much in advanced !
I have two divs serving as two panels one to the left and one to the right.
They take 70% and 30% of the area.
I have a separator between them.
When I drag the separator to the left or right, I want that to remain as the position of the separator. i.e., I should be able to dynamically resize the left and right divs by dragging.
Here is the code I have:
http://jsbin.com/witicozi/1/edit
HTML:
<!DOCTYPE html>
<html>
<head>
<body>
<div style='height: 100px'>
<div id='left'>...</div>
<div id='separator'></div>
<div id='right'>...</div>
</div>
</body>
</html>
CSS:
#left {
float: left;
width: 70%;
height: 100%;
overflow: auto;
}
#separator {
float: left;
width: 3px;
height: 100%;
background-color: gray;
cursor: col-resize;
}
#right {
height: 100%;
overflow: auto;
}
JavaScript:
document.querySelector('#separator').addEventListener('drag', function (event) {
var newX = event.clientX;
var totalWidth = document.querySelector('#left').offsetWidth;
document.querySelector('#left').style.width = ((newX / totalWidth) * 100) + '%';
});
The problems:
The resizing happens, but the separator jumps around randomly. It even falls down many times. I have no idea what's happening.
The mouse cursor changes to a hand when the dragging begins. I want it to remain a col-resize.
It is very hard to drag.
No JQuery please.
If you use console.log(event), it shows that event.clientX doesn't return exactly what you are looking for. The following JavaScript worked for me in chrome.
document.getElementById('separator').addEventListener('drag', function(event) {
var left = document.getElementById('left');
var newX = event.offsetX + left.offsetWidth;
left.style.width = newX + 'px';
});
The event.offsetX value that it is returning is the location (in px) of the upper left hand corner of the left div. This will give you the same result but using percentages so that when the resize the window the columns adjust:
document.getElementById('separator').addEventListener('drag', function(event) {
var left = document.getElementById('left');
var newX = event.offsetX + left.offsetWidth;
left.style.width = (newX / window.innerWidth * 100) + '%';
});
Taking a bit of a different approach: rather than using the drag and drop functionality, I used some coupled mouse down and mouse up listeners. This has better cross-browser compatibility (at least as far as my testing goes) and it has the added benefit of being able to easily control the cursor.
var resize = function(event) {
var newX = event.clientX;
document.getElementById('left').style.width = (newX / window.innerWidth * 100) + '%';
};
document.getElementById('separator').addEventListener('mousedown', function(event) {
document.addEventListener('mousemove', resize);
document.body.style.cursor = 'col-resize';
});
document.addEventListener('mouseup', function(event) {
document.removeEventListener('mousemove', resize);
document.body.style.cursor = '';
});
This is what i have so far, it makes my red circle appear and then when clicked it moves from the top left of the screen to the coodinates x, y(300, 800)
<!DOCTYPE html>
<html>
<head>
<style>
body
{
background-color:#000080;
}
h1
{
</style>
<title>Mouse click game</title>
<h1 style="text-align:center;color:white;font-family:verdana;font-size:50px;">Left click on the dots!</h1>
</br>
</br>
<script type="text/javascript">
function red_circleClick()
{
var red_circle = document.getElementById('red_circle');
red_circle.hidden = true;
red_circle.style.top = 300 + "px";
red_circle.style.left = 800 + "px";
red_circle.hidden = false;
}
</script>
</head>
<body>
<img src="/Users/lorraine/Desktop/MOUSE/red_circle.png" id="red_circle" onclick="red_circleClick();" style="position:absolute; left: 400; top: 100; width: 200; height: 200;"/>
</body>
</html>
What i need it to do is move to a random spot on the screen and do that 10 times.
So I need it to appear, user clicks on it. When they click it jumps to another spot onscreen. when they click it again in its new location it jumps to an new spot onscreen, and repeat a certain amount of times(10)
Is it possible that the circle could appear in a location outside the current screen? Like x,y(1000, 1000)
Found this code, just not 100% on how/where to insert it.
<script type="text/javascript">
function changeImg()
{
var x = Math.floor(Math.random()*300);
var y = Math.floor(Math.random()*300);
var obj = document.getElementById("emotion");
obj.style.top = x + "px";
obj.style.left = y + "px";
obj.onclick= "changeImg();"
}
New enough to Javascript and html!
Thanks very much for the help in advance!
This function gets run whenever you click the dot
function red_circleClick()
{
var red_circle = document.getElementById('red_circle');
red_circle.hidden = true;
red_circle.style.top = 300 + "px";
red_circle.style.left = 800 + "px";
red_circle.hidden = false;
}
All you have to do is randomize your numbers
red_circle.style.top = 300 + "px";
red_circle.style.left = 800 + "px";
Open up a console in chrome or what have you and run Math.random() Then try Math.floor(.1433) Then maybe Math.floor(.019231*100) See what you can get. Replace 300 and 800 with whatever you come up with.
As for making it stop at 10 times, just use an if statement and a counter.
Good day! With javascript I am trying to create a function which will create a div element with a small offset from the triggering button / div. The good news is that at least as much elements are created as much as one of the effects is triggered. The bad news is that the styling of the X and Y of the div is not working properly.
The code is actually pretty short, I have posted some comments to make it more readable, I don't get any errors when running the function so I really have no idea where the error is.
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<style>
/*What will be created*/
.box {
width: 30px;
height: 30px;
background-color:red;
}
/*The positioning for the first button*/
.btm12 {
margin-left:50%;
margin-top:5%
}
/*The positioning for the second button*/
.btm1 {
margin-left:30%;
margin-top:10%
}
</style>
</head>
<body>
<button id="btn" onclick="createBox()" class="btm1">Click me</button><br />
<button id="btn2" onclick="createBox()" class="btm12">Click me</button>
</body>
</html>
<script>
document.getElementById("btn").onclick = function () { createBox(this.id); };
document.getElementById("btn2").onclick = function () { createBox(this.id); };
function createBox(IDI) {
//get reference to the element
var element = document.getElementById(IDI);
//a way we can acces the X and Y coordinates
var position = element.getBoundingClientRect();
var x = position.left;
var y = position.top;
//create, style and set the X/Y of the the div element
var box = document.createElement("div");
box.className = "box";
box.style.left = x;
box.style.top = y -10;
box.style.position = "absolute";
//Apend the element to the body
document.body.appendChild(box);
}
</script>
You need to add "px" for your style values when you set them this way. See:
box.style.left = x+"px";
box.style.top = (y -10)+"px";
Fiddle: http://jsfiddle.net/MLmCM/
I'm (still) porting an old Macintosh game to HTML5 and JavaScript. The game is a Tempest clone. (Wikipedia article on Tempest) (Shameless pimp of my project)
While it's certainly possible to implement controls using the keyboard, I'm also wondering if it's possible to make relative mouse movement work in HTML5.
The typical ways that I've seen this implemented (outside of HTML5) is to repeatedly warp the mouse to the screen's center and look for deviations, or to somehow capture raw mouse movement events. As far as I know, but I could be wrong, neither of these methods are possible in HTML5.
The odds are slim, but I figure I shouldn't completely write it off without asking the clever minds of StackOverflow. :)
I'm pretty sure that the only way to get relative mouse coords in JavaScript (HTML5 specs have no changes to this) is to calculate it from the current mouse position and the previous mouse position - or using onmousemove. As you probably are aware of, this won't work when the cursor can't physically move (eg. is touching window borders)
In the off chance that I'm wrong, you could take a search for WebGL demos. Since there's bound to be a 3D shooter demo, perhaps they have a mouse based control solution you can apply.
I don't think you need HTML5 really, but if you have an element and your game board is in the center, you could do something like this:
<html>
<head>
<title>Cursor Position Radius</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
<style type="text/css" media="screen">
#square {
height: 400px;
width: 400px;
background-color: #000;
margin: auto;
position: absolute;
overflow: hidden;
top: 10px;
left: 300px;
}
#log {
height: 100%;
width: 200px;
position: absolute;
top: 0;
left: 0;
background-color: #ccc;
color: #000;
font-size: small;
overflow: auto;
}
</style>
<!-- here's the real code, the JavaScript -->
<script type="text/javascript">
$(document).ready(function() {
var centerTop = a = $('#square').height() / 2;
var centerLeft = $('#square').width() / 2;
var squareTop = $('#square').offset().top;
var squareLeft = $('#square').offset().left;
// draw a center point
$('<div />').css({
width: '1px', height: '1px',
backgroundColor: '#fff',overflow:'hidden',
position:'absolute',
top: centerTop,left: centerLeft
}).attr('id', 'center').appendTo('#square');
$('#square').bind('mousemove', function(event) {
var mouseLeft = (event.pageX - squareLeft);
var mouseTop = (event.pageY - squareTop);
var correctTop = (centerTop - mouseTop);
var correctLeft = (mouseLeft - centerLeft);
var rawAngle = (180/Math.PI) * Math.atan2(correctTop,correctLeft);
var intAngle = parseInt(rawAngle, 10);
var msg = '';
msg += (mouseTop >= centerTop) ? ' lower ' : ' upper ';
msg += (mouseLeft >= centerLeft) ? ' right ' : ' left ';
msg += intAngle;
$('#log').prepend('<div>' + msg + '</div>');
});
/* create a dot along a radius for every degree
(not necessary for the mousemove) */
var sensitivity = (2 * Math.PI) / 360;
var radius = ($('#square').height() / 2) - 10;
var degrees = 0;
for (var t = 0; t<= (2 * Math.PI); t+=sensitivity) {
var x = radius * Math.cos(t) + a;
var y = radius * Math.sin(t) + a;
$('<div />').css({
width: '1px', height: '1px',
backgroundColor: '#ccc',overflow:'hidden',
position:'absolute',top: x,left: y
}).attr('id', 'cursor-' + t).appendTo('#square');
}
});
</script>
<!-- and the body -->
</head>
<body>
<div id="square"></div>
<div id="log"></div>
</body>
</html>
So the idea here is that you would do something with that angle around the center of the game board. If you know that the angle is 90 degrees you know that the game piece is at the far right.
I'm really interested in JavaScript for games, I'll check out your git project. Feel free to contact me and I'll do what I can. I wish I could promise real help, but I'm a newbie myself. There's probably more efficient ways to do the math I do in my sample, I did it mostly as an exercise for myself anyway. Best of luck!
Here's another tack at it, showing an avatar (really just a a bunch of points) that follow the mouse: http://gist.github.com/464974