Move Depending on Mouse State - javascript

I need my users to be able to move an element away from the mouse pointer by holding the left button down, and the element should move closer when the button is up. So far, I have this:
var divName = 'follow'; // div to follow mouse
// (must be position:absolute)
var offX = 0; // X distance from mouse
var offY = 0; // Y distance from mouse
function mouseX(evt) {
if (!evt) evt = window.event;
if (evt.pageX) return evt.pageX;
else if (evt.clientX) return evt.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
else return 0;
}
function mouseY(evt) {
if (!evt) evt = window.event;
if (evt.pageY) return evt.pageY;
else if (evt.clientY) return evt.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
else return 0;
}
function follow(evt) {
if (document.getElementById) {
var obj = document.getElementById(divName).style;
obj.visibility = 'visible';
obj.left = (parseInt(mouseX(evt)) + offX) + 'px';
obj.top = (parseInt(mouseY(evt)) + offY) + 'px';
}
}
document.onmousemove = follow;
function discharge() { //Move away
offX += 1;
offY += 1;
}
function pull() { //Come closer
if (offX > 0) {
offX -= 1;
}
if (offY > 0) {
offY -= 1;
}
}
document.onmousedown = discharge;
document.onmouseup = pull;
offX and offY are the distance the element is from the mouse. In addition, this is just one part of the script. offX and offY come into play in a different part, which works except for this push/pull.
EDIT: Updated to include whole file and here is a fiddle.
More info: My main goal was to have an image within a div follow the mouse and move closer/further depending on the mouse's state. If anyone has a different way to achieve this, it would be greatly appreciated as well.

What you want requires two offsets, those of the mouse and those of the element.
var offX = 100; // mouse X-axis
var offY = 50; // mouse Y-axis
var elemOffX = 950; // elem X-axis
var elemOffY = 600; // elem Y-axis
// Now get the distance from the elem to the mouse:
var diffX = offX - elemOffX; // get the diff X
var diffY = offY - elemOffY; // get the diff Y
// Depending on your interval you might want to change the factor,
// this will move it in steps of 10%
var newOffX = offX + (diffX * 0.1); // set this as new result for the element's X
var newOffY = offY + (diffY * 0.1); // set this as new result for the element's Y
Please note, I havent tested this for bugs, this is to show a principle. Might be that you need to change the newOff's + to a -
In you example you do this: offY-1, you need to change that to offY=offY-1 or offY-=1

Here's a complete example using JQuery:
var divName = 'follow'; // div to follow mouse
// (must be position:absolute)
var offX = 0; // X distance from mouse
var offY = 0; // Y distance from mouse
var mouseX;
var mouseY;
var mouseState = 0;
var _this = this;
function follow(evt) {
if(_this.mouseState === 1) {
discharge();
} else {
pull();
}
if (document.getElementById) {
var obj = document.getElementById(divName).style;
obj.visibility = 'visible';
obj.left = evt.pageX + _this.offX + 'px';
obj.top = evt.pageY + _this.offY + 'px';
}
}
document.onmousemove = follow;
function discharge() { //Move away
_this.offX += 1;
_this.offY += 1;
}
function pull() { //Come closer
if (_this.offX > 0) {
_this.offX -= 1;
}
if (_this.offY > 0) {
_this.offY -= 1;
}
}
$(document).mousedown(function(e){_this.mouseState = 1;});
$(document).mouseup(function(e){_this.mouseState = 0; });

Related

drag and drop with accurate drop position

I am using this W3school drag and drop API but i want it to drop on the specific position the cursor left of, instead it is always going to the top right. I have tried this code but i dont know if i am doing it right
var dragObj, count=0;
function set_drag_drop(obj)
{
if(count>0){
obj.adx = 10;
obj.ady = 10 + (count*100)
}else{
obj.adx = 0;
obj.ady = 0;
}
count++;
obj.onmousedown = function(e)
{
var rect = obj.getBoundingClientRect();
obj.dx = rect.left - e.clientX;
obj.dy = rect.top - e.clientY;
obj.isDown = true;
dragObj = this;
}
obj.onmouseup = function(e)
{
obj.isDown = false;
}
document.onmousemove = function(e)
{
if(dragObj && dragObj.isDown)
{
dragObj.style.left = e.pageX -dragObj.adx+ dragObj.dx +"px";
dragObj.style.top = e.pageY -dragObj.ady+ dragObj.dy + "px";
}
}
}
set_drag_drop(document.getElementById("obj1"));
check it out here

Mouse coordinate based perspective rotation with centered div [Javascript]

Second question I've asked, so if I need to add anything else, let me know please!
Been looking everywhere to try and understand concepts, but I feel like I am over thinking it. What I am trying to do is base "transform: rotateX("x"deg)" off of the x location of the users cursor proportionately from the size of the window. Here is a gif that does what I want, but they use matrix3D instead of just transform's rotate.
http://i.imgur.com/tUZSLXA.gif
Here is a js fiddle of what I have so far.
https://jsfiddle.net/z7bet2sw/
JS:
function rotate() {
var x = event.clientX;
var w = window.innerWidth;
var midpoint = w / 2;
// restrictions for rotation
if (x > -20 && x < 20) {
document.getElementsById("logo").style.transform = "perspective(550px)" + "rotateY(" + x + "deg)";
} else {
}
}
document.addEventListener("mousemove", rotate);
Thanks!
You need to pass the event parameter to rotate function from addEventListener, and also you need to calculate a relative position from the x coordinates to get a value between -20 and 20:
function rotate (event)
{
var x = event.clientX;
var w = window.innerWidth;
var midpoint = w / 2;
var pos = x - midpoint;
var val = (pos / midpoint) * 20;
var logo = document.getElementById ("logo");
logo.style.transform = "perspective(550px) rotateY(" + val + "deg)";
}
document.addEventListener("mousemove", function(event)
{
rotate(event)
}, false);
JSFiddle
Two issues:
you are using document.getElementsById which should actually be document.getElementById (no s)
you should subtract midpoint from x
Updated code:
function rotate() {
var x = event.clientX;
var w = window.innerWidth;
var midpoint = w / 2;
x -= midpoint;
if (x > -20 && x < 20) {
document.getElementById("logo").style.transform = "perspective(550px)" + "rotateY(" + x + "deg)";
} else {
}
}
fiddle: https://jsfiddle.net/jacquesc/z7bet2sw/1/

Why does my menu jump the second time I try and drag it to a new item?

I've made a rotating menu.
To select an item you rotate the menu by clicking and dragging.
http://codepen.io/PaulBunker/pen/ZGgxvY
var dragging = false;
var links = $('.menu a');
var radius = 520;
var degree = 0.262;
var angle = 0.79;
var orgX;
var orgY;
var offset = $('.menu').offset();
var newangle;
var origradians;
function setItems(angle) {
var internalangle = angle;
links.each(function() {
var y = Math.round(radius * Math.cos(internalangle));
var x = Math.round(radius * Math.sin(internalangle));
$(this).css({
left: x + 'px',
top: 0-y + 'px',
display:'block',
});
$(this).addClass(y);
if (y < 10 & x > 0) {
$(this).addClass('active');
}
if ( y < -10 || y > 0) {
$(this).removeClass('active');
}
internalangle += degree;
});
}
$(function() {
$(document).mousedown(function(evt) {
orgX = evt.pageX - offset.left;
orgY = evt.pageY - offset.top;
orgradians = Math.atan2(orgX, orgY);
dragging = true;
});
$(document).mouseup(function() {
dragging = false;
angle = newangle;
});
$(document).mousemove(function(evt) {
if (dragging) {
var x = evt.pageX - offset.left;
var y = evt.pageY - offset.top;
var radians = Math.atan2(y, x);
newangle = (orgradians + radians) - angle;
console.log (orgradians , radians, angle, newangle);
setItems(newangle);
console.log(newangle);
}
});
setItems(angle);
});
My problem is after the first drag to select an item.
At the beginning of the second drag the menu jumps into the wrong position.
on 'mouseup' I save the 'newangle' variable and override the 'angle variable'.
I suspect there is an error somewhere in the line
newangle = (orgradians + radians) - angle;
I've been tearing my hair out to try and get this to work!
Thanks in advance for any guidance!
-Paul
If you don't use trigonometry on mouse move and just use it once when the radius of the circle is defined it'll fix the issue:
Work out the rotation speed based on the radius of the circle:
var rotationSpeed = Math.atan(1/radius);
Use the rotation speed and the difference in the Y position of the cursor on mouse move:
var newangle = lastangle - (difY*rotationSpeed);
http://codepen.io/stevenarcher/pen/yNmRyP
var dragging = false;
var links = $('.menu a');
var radius = 520;
var degree = 0.262;
var lastY;
var offset = $('.menu').offset();
var lastangle = 0;
var rotationSpeed = Math.atan(1/radius);
function setItems(internalangle) {
links.each(function() {
var y = Math.round(radius * Math.cos(internalangle));
var x = Math.round(radius * Math.sin(internalangle));
$(this).css({
left: x + 'px',
top: 0 - y + 'px',
display:'block',
});
$(this).addClass(y);
if (y < 10) {
$(this).addClass('active');
}
if ( y < -10 || y > 0) {
$(this).removeClass('active');
}
internalangle += degree;
});
}
$(document).mousedown(function(evt) {
lastY = evt.pageY - offset.top;
dragging = true;
});
$(document).mouseup(function(evt) {
dragging = false;
});
$(document).mousemove(function(evt) {
if (dragging) {
var y = evt.pageY - offset.top;
var difY = lastY - y;
lastY = y;
var newangle = lastangle - (difY*rotationSpeed);
setItems(newangle);
lastangle = newangle;
}
});
setItems(0);

Pinch to zoom with Hammer.js

I want a pinch to Zoom function for an image. I want it to zoom in the area where the fingers are.
My index is only
<div id="wrapper" style="-webkit-transform: translate3d(0,0,0);overflow: hidden;">
</div>
And my script for zooming and scrolling is similar with this example. I have made a few changes to fit with my project
My problem is in
case 'transform':
rotation = last_rotation + ev.gesture.rotation;
scale = Math.max(1, Math.min(last_scale * ev.gesture.scale, 10));
break;
How can I change it so that it doesn't zoom into the center of the picture but at place where the first finger have touch the display?
Sorry for my bad english :)
This is an example with hammer.js and tap. As you tap it will zoom in at the point where you tapped. The event data is common for all gestures so switching from tap to pinch should work. It is a good example to work on. You may need to increase the scale step as you pinch. It has been tested on chrome(v30) and firefox (v24).
It is based on the solution mentioned at the thread,
Zoom in on a point (using scale and translate)
as you will see an alternative could also be to use canvas.
HTML
<div style="-webkit-transform: translate3d(0,0,0);overflow: hidden;" class="zoomable">
<img src="http://i.telegraph.co.uk/multimedia/archive/01842/landscape-rainbow_1842437i.jpg" />
</div>
JS
(function ($) {
$(document).ready(function () {
var scale = 1; // scale of the image
var xLast = 0; // last x location on the screen
var yLast = 0; // last y location on the screen
var xImage = 0; // last x location on the image
var yImage = 0; // last y location on the image
Hammer($('.zoomable img').get(0)).on("tap", function (event) {
var posX = event.gesture.center.pageX;
var posY = event.gesture.center.pageY;
// find current location on screen
var xScreen = posX; //- $(this).offset().left;
var yScreen = posY; //- $(this).offset().top;
// find current location on the image at the current scale
xImage = xImage + ((xScreen - xLast) / scale);
yImage = yImage + ((yScreen - yLast) / scale);
scale++;
// determine the location on the screen at the new scale
var xNew = (xScreen - xImage) / scale;
var yNew = (yScreen - yImage) / scale;
// save the current screen location
xLast = xScreen;
yLast = yScreen;
// redraw
$(this).css('-webkit-transform', 'scale(' + scale + ')' + 'translate(' + xNew + 'px, ' + yNew + 'px' + ')')
.css('-webkit-transform-origin', xImage + 'px ' + yImage + 'px').css('-moz-transform', 'scale(' + scale + ') translate(' + xNew + 'px, ' + yNew + 'px)').css('-moz-transform-origin', xImage + 'px ' + yImage + 'px')
.css('-o-transform', 'scale(' + scale + ') translate(' + xNew + 'px, ' + yNew + 'px)').css('-o-transform-origin', xImage + 'px ' + yImage + 'px').css('transform', 'scale(' + scale + ') translate(' + xNew + 'px, ' + yNew + 'px)');
});
});
})(jQuery);
http://jsfiddle.net/SySZL/
Check out the Pinch Zoom and Pan with HammerJS demo. This example has been tested on Android, iOS and Windows Phone.
You can find the source code at Pinch Zoom and Pan with HammerJS.
For your convenience, here is the source code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport"
content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1">
<title>Pinch Zoom</title>
</head>
<body>
<div>
<div style="height:150px;background-color:#eeeeee">
Ignore this area. Space is needed to test on the iPhone simulator as pinch simulation on the
iPhone simulator requires the target to be near the middle of the screen and we only respect
touch events in the image area. This space is not needed in production.
</div>
<style>
.pinch-zoom-container {
overflow: hidden;
height: 300px;
}
.pinch-zoom-image {
width: 100%;
}
</style>
<script src="https://hammerjs.github.io/dist/hammer.js"></script>
<script>
var MIN_SCALE = 1; // 1=scaling when first loaded
var MAX_SCALE = 64;
// HammerJS fires "pinch" and "pan" events that are cumulative in nature and not
// deltas. Therefore, we need to store the "last" values of scale, x and y so that we can
// adjust the UI accordingly. It isn't until the "pinchend" and "panend" events are received
// that we can set the "last" values.
// Our "raw" coordinates are not scaled. This allows us to only have to modify our stored
// coordinates when the UI is updated. It also simplifies our calculations as these
// coordinates are without respect to the current scale.
var imgWidth = null;
var imgHeight = null;
var viewportWidth = null;
var viewportHeight = null;
var scale = null;
var lastScale = null;
var container = null;
var img = null;
var x = 0;
var lastX = 0;
var y = 0;
var lastY = 0;
var pinchCenter = null;
// We need to disable the following event handlers so that the browser doesn't try to
// automatically handle our image drag gestures.
var disableImgEventHandlers = function () {
var events = ['onclick', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover',
'onmouseup', 'ondblclick', 'onfocus', 'onblur'];
events.forEach(function (event) {
img[event] = function () {
return false;
};
});
};
// Traverse the DOM to calculate the absolute position of an element
var absolutePosition = function (el) {
var x = 0,
y = 0;
while (el !== null) {
x += el.offsetLeft;
y += el.offsetTop;
el = el.offsetParent;
}
return { x: x, y: y };
};
var restrictScale = function (scale) {
if (scale < MIN_SCALE) {
scale = MIN_SCALE;
} else if (scale > MAX_SCALE) {
scale = MAX_SCALE;
}
return scale;
};
var restrictRawPos = function (pos, viewportDim, imgDim) {
if (pos < viewportDim/scale - imgDim) { // too far left/up?
pos = viewportDim/scale - imgDim;
} else if (pos > 0) { // too far right/down?
pos = 0;
}
return pos;
};
var updateLastPos = function (deltaX, deltaY) {
lastX = x;
lastY = y;
};
var translate = function (deltaX, deltaY) {
// We restrict to the min of the viewport width/height or current width/height as the
// current width/height may be smaller than the viewport width/height
var newX = restrictRawPos(lastX + deltaX/scale,
Math.min(viewportWidth, curWidth), imgWidth);
x = newX;
img.style.marginLeft = Math.ceil(newX*scale) + 'px';
var newY = restrictRawPos(lastY + deltaY/scale,
Math.min(viewportHeight, curHeight), imgHeight);
y = newY;
img.style.marginTop = Math.ceil(newY*scale) + 'px';
};
var zoom = function (scaleBy) {
scale = restrictScale(lastScale*scaleBy);
curWidth = imgWidth*scale;
curHeight = imgHeight*scale;
img.style.width = Math.ceil(curWidth) + 'px';
img.style.height = Math.ceil(curHeight) + 'px';
// Adjust margins to make sure that we aren't out of bounds
translate(0, 0);
};
var rawCenter = function (e) {
var pos = absolutePosition(container);
// We need to account for the scroll position
var scrollLeft = window.pageXOffset ? window.pageXOffset : document.body.scrollLeft;
var scrollTop = window.pageYOffset ? window.pageYOffset : document.body.scrollTop;
var zoomX = -x + (e.center.x - pos.x + scrollLeft)/scale;
var zoomY = -y + (e.center.y - pos.y + scrollTop)/scale;
return { x: zoomX, y: zoomY };
};
var updateLastScale = function () {
lastScale = scale;
};
var zoomAround = function (scaleBy, rawZoomX, rawZoomY, doNotUpdateLast) {
// Zoom
zoom(scaleBy);
// New raw center of viewport
var rawCenterX = -x + Math.min(viewportWidth, curWidth)/2/scale;
var rawCenterY = -y + Math.min(viewportHeight, curHeight)/2/scale;
// Delta
var deltaX = (rawCenterX - rawZoomX)*scale;
var deltaY = (rawCenterY - rawZoomY)*scale;
// Translate back to zoom center
translate(deltaX, deltaY);
if (!doNotUpdateLast) {
updateLastScale();
updateLastPos();
}
};
var zoomCenter = function (scaleBy) {
// Center of viewport
var zoomX = -x + Math.min(viewportWidth, curWidth)/2/scale;
var zoomY = -y + Math.min(viewportHeight, curHeight)/2/scale;
zoomAround(scaleBy, zoomX, zoomY);
};
var zoomIn = function () {
zoomCenter(2);
};
var zoomOut = function () {
zoomCenter(1/2);
};
var onLoad = function () {
img = document.getElementById('pinch-zoom-image-id');
container = img.parentElement;
disableImgEventHandlers();
imgWidth = img.width;
imgHeight = img.height;
viewportWidth = img.offsetWidth;
scale = viewportWidth/imgWidth;
lastScale = scale;
viewportHeight = img.parentElement.offsetHeight;
curWidth = imgWidth*scale;
curHeight = imgHeight*scale;
var hammer = new Hammer(container, {
domEvents: true
});
hammer.get('pinch').set({
enable: true
});
hammer.on('pan', function (e) {
translate(e.deltaX, e.deltaY);
});
hammer.on('panend', function (e) {
updateLastPos();
});
hammer.on('pinch', function (e) {
// We only calculate the pinch center on the first pinch event as we want the center to
// stay consistent during the entire pinch
if (pinchCenter === null) {
pinchCenter = rawCenter(e);
var offsetX = pinchCenter.x*scale - (-x*scale + Math.min(viewportWidth, curWidth)/2);
var offsetY = pinchCenter.y*scale - (-y*scale + Math.min(viewportHeight, curHeight)/2);
pinchCenterOffset = { x: offsetX, y: offsetY };
}
// When the user pinch zooms, she/he expects the pinch center to remain in the same
// relative location of the screen. To achieve this, the raw zoom center is calculated by
// first storing the pinch center and the scaled offset to the current center of the
// image. The new scale is then used to calculate the zoom center. This has the effect of
// actually translating the zoom center on each pinch zoom event.
var newScale = restrictScale(scale*e.scale);
var zoomX = pinchCenter.x*newScale - pinchCenterOffset.x;
var zoomY = pinchCenter.y*newScale - pinchCenterOffset.y;
var zoomCenter = { x: zoomX/newScale, y: zoomY/newScale };
zoomAround(e.scale, zoomCenter.x, zoomCenter.y, true);
});
hammer.on('pinchend', function (e) {
updateLastScale();
updateLastPos();
pinchCenter = null;
});
hammer.on('doubletap', function (e) {
var c = rawCenter(e);
zoomAround(2, c.x, c.y);
});
};
</script>
<button onclick="zoomIn()">Zoom In</button>
<button onclick="zoomOut()">Zoom Out</button>
<div class="pinch-zoom-container">
<img id="pinch-zoom-image-id" class="pinch-zoom-image" onload="onLoad()"
src="https://hammerjs.github.io/assets/img/pano-1.jpg">
</div>
</div>
</body>
</html>

How do I make an object change it's direction smoothly?

I have a simple Javascript program that displays a small rectangle in a canvas. The rectangle moves towards the mouse position. When it changes direction, it does so with sharp corners. As in, if the rectangle left a line behind, when I move my mouse in a circle, the rectangle would draw a tilted square.
What I'd want to happen, is that it would draw a circle. No sharp corners.
Here's the code I am using for changing the direction:
function changeDir()
{
if(mouseXCoord-5<x && x<mouseXCoord+5)
{
xDirection = 0;//stop moving if close to mouse
}
else if(x>mouseXCoord)
{
xDirection = -1;
}
else if(x<mouseXCoord)
{
xDirection = 1;
}
if(mouseYCoord-5<y && y<mouseYCoord+5)
{
yDirection = 0;//stop moving if close to mouse
}
else if(y>mouseYCoord)
{
yDirection = -1;
}
else if(y<mouseYCoord)
{
yDirection = 1;
}
}
The draw function:
function draw()
{
context2D.clearRect(0, 0, canvas.width, canvas.height);
fillwith = context2D.fillStyle='red';
context2D.fillRect(x,y,10,10);
changeDir();
x = x + (thrust * xDirection);
y = y + (thrust * yDirection);
console.log(x,y,xDirection, yDirection,mouseXCoord,mouseYCoord);
}
So, how do I do that?
Update:
I changed the changeDir() function so that it makes the corners of the tilted square rounded.
function changeDir()
{
if(mouseXCoord-5<x && x<mouseXCoord+5)
{
xstop = true;//stop moving if close to mouse
}
else if(x>mouseXCoord)
{
if(Math.abs(xthrust)==mainThrust)
{
xthrust = -1*mainThrust;
}
else
{
xthrust--;
}
xstop = false;//make sure it moves
}
else if(x<mouseXCoord)
{
if(xthrust==mainThrust)
{
xthrust = mainThrust;
}
else
{
xthrust++;
}
xstop = false;//make sure it moves
}
if(mouseYCoord-5<y && y<mouseYCoord+5)
{
ystop = true;//stop moving if close to mouse
}
else if(y>mouseYCoord)
{
if(Math.abs(ythrust)==mainThrust)
{
ythrust = -1*mainThrust;
}
else
{
ythrust--;
}
ystop = false;//make sure it moves
}
else if(y<mouseYCoord)
{
if(ythrust==mainThrust)
{
ythrust = mainThrust;
}
else
{
ythrust++;
}
ystop = false;//make sure it moves
}
}
Here's the variables I declare:
const FPS = 5;
var x = 300;
var y = 200;
var xDirection = 1;
var yDirection = 1;
var image = new Image();
var canvas = null;
var context2D = null;
var mouseXCoord = 0;
var mouseYCoord = 0;
var mainThrust = 5;
var xthrust = mainThrust;
var ythrust = mainThrust;
var xstop = false;
var ystop = false;
Where it actualy moves:
changeDir();
if(!xstop)
x = x + (xthrust);
if(!ystop)
y = y + (ythrust);
Ok, here's my new code thanks to cape1232. I actually started over entirely. I get smooth turning, but the speed the block moves at changes. Demo at: http://develzone.davidreagan.net/jsMoveTesting/index.html
var gameVars = {
fps: 30
}
var object = {
name: 'default',
xpos: 200,
ypos: 200,
xVect: 1,
yVect: 1,
thrust: 15
}
ctx = null;
canvas = null;
xMousePos = 0;
yMousePos = 0;
runGame = null;
function init()
{
canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');
$('#canvas').mousemove(getMousePos);
$('#canvas').click(stop);
//setTimeout('clearInterval(runGame);',30000);
}
function start()
{
runGame = setInterval('run();',1000/gameVars.fps);
}
function run()
{
ctx.clearRect(0, 0, canvas.width, canvas.height);
moveBlock();
//ctx.translate(object.xpos,object.ypos);
drawBlock();
showMousePos = 'X: ' + xMousePos + ' Y: ' + yMousePos;
ctx.fillText(showMousePos, 215,50);
}
function stop()
{
//alert('hit stop');
console.log('clicked');
//if(e.keyCode == 113)
if(runGame)
{
clearInterval(runGame);
runGame = false;
//console.log('stop true');
}
else
start();
}
function drawBlock()
{
ctx.fillRect(object.xpos,object.ypos,10,10);
}
function moveBlock()
{
xDiff = xMousePos - object.xpos;
yDiff = yMousePos - object.ypos;
minDiff = Math.max(Math.min(xDiff, yDiff), 1);
deltaX = xDiff / minDiff;
deltaY = yDiff / minDiff;
// Scale the deltas to limit the largest to mainThrust
maxDelta = Math.max(Math.max(deltaX, deltaY), 1)
if (maxDelta>object.thrust)
{
deltaX = deltaX * object.thrust / maxDelta;
deltaY = deltaY * object.thrust / maxDelta;
}
if(object.xpos >= canvas.width)
{
object.xpos = 0;
}
else
{
object.xpos += deltaX;
//console.log('moveBlock xpos else: '+object.xpos);
}
if(object.ypos >= canvas.height)
{
object.ypos = 0;
}
else
{
object.ypos += deltaY;
//console.log('moveBlock ypos else: '+object.ypos);
}
console.log('xpos: '+object.xpos);
console.log('ypos: '+object.ypos);
console.log('xMousePos: '+xMousePos);
console.log('yMousePos: '+yMousePos);
console.log('xDiff: '+xDiff);
console.log('yDiff: '+yDiff);
console.log('minDiff: '+minDiff);
console.log('deltaX: '+xDiff+'/'+minDiff+ ' = '+ deltaX);
console.log('deltaY: '+yDiff+'/'+minDiff+ ' = '+ deltaY);
console.log('maxDelta: '+maxDelta);
}
function getMousePos(e)
{
xMousePos = e.pageX;
yMousePos = e.pageY;
//console.log('Mouse Moved');
}
window.onload = init;
You don't want your xDirection and yDirection to be only 1 or -1. They need to be proportional to the difference between the mouse and the rectangle position.
Edited to take comments into account.
function changeDir()
{
xDiff = mouseXCoord - x;
yDiff = mouseYCoord - y;
// Scale the smallest diff to be 1 (or less)
minDiff = max(min(xDiff, yDiff), 1);
deltaX = xDiff / minDiff;
deltaY = yDiff / minDiff;
// Scale the deltas to limit the largest to mainThrust
maxDelta = max(max(deltaX, deltaY), 1)
if (maxDelta>mainThrust)
{
deltaX = deltaX * mainThrust / maxDelta;
deltaY = deltaY * mainThrust / maxDelta;
}
if(mouseXCoord-5<x && x<mouseXCoord+5)
{
xDirection = 0;//stop moving if close to mouse
}
else
{
xDirection = deltaX;
}
if(mouseYCoord-5<y && y<mouseYCoord+5)
{
yDirection = 0;//stop moving if close to mouse
}
else
{
yDirection = deltaY;
}
}
Instead of having xDirection and yDirection (the sine and cosine of your direction, actually) sharply defined as 0, 1, or -1, you need to define more precisely the direction you should eventually be heading in, and recall what direction you were last moving in and how many "angular steps" you've done in changing the direction from what was to what it should be.
How many such angular steps you want to take for a change of direction, and whether each step should be of the same size or depend on how fast you're moving and/or how brusquely you're swerving, etc, is something you should adapt by trial and error, since it appears that what you're mostly after is to have things "look" right, so it's hard to give a precise prescription (for what looks right to you;-).

Categories

Resources