Need help fixing Dynamic Position of Image JS - javascript

I have been working on a JS project where a sun goes around an image in a circle, and based on its position a higher index div will change opacity to make it darker or lighter. My problem is; while at one point the Sun moved in a circle, it no longer does. I have tried many things to fix this, but to no avail. My documented code is as follows:
<style>
sun{
position: absolute;
z-index: 1;
}
dark-light{
z-index: 2;
}
</style>
CSS:^ JS:v
<script>
move();
//calls move
function move(){
//set rot
var rot = 180;
var pictureToDisplay = prompt('Please insert link to picture to display','URL Necessary to function properly, but not required. Press enter to continue.');
//asks user to insert picture link for STATIONARY picture
var img = document.getElementById('img');
if (pictureToDisplay == 'URL Necessary to function properly, but not required. Press enter to continue.'){
}else{
img.src = pictureToDisplay;
}
//Sets stationary picture
window.setInterval( function() {
//Repeats every 75 milliseconds forever.
var obj = document.getElementById('sun');
// obj. is equal to id sun
var top = (Math.sin(rot)*500)+500;
var left = (Math.cos(rot)*500)+500;
//uses var rot, sine, and cosine to determine moving sun position
var toppx = top + 'px';
var leftpx = left + 'px';
//adds the px after those values
obj.style.top = toppx;
obj.style.left = leftpx;
//attempts to set position of obj (id sun)
var darkToLight = -0.5+(top/500);
//determines opacity of div using var top
//document.write(rot+' = rot : ');
var lightDiv = document.getElementById('dark-light');
// same as var obj, but with the div
lightDiv.style.opacity = darkToLight;
//sets lightDiv to opacity
//document.write(toppx,' ,',leftpx,' : ');
rot = (rot+0.01) % 360;
//moves rot up by 0.01, modulate 360
}, 75);
//back to top of setInterval
}
</script>
P.S. I know no JQuery.
Edit: The position of all is absolute, 0,0 is the top left corner of the page. I made sure not to deal with negatives. The sun should be absolute to the page, as its in nothing.

Ok, I figured out that I apparently am not too good with css, and after adding in style="position:absolute"; it now works fine.

Related

CSS/JS Top and Left are warped when placing images on top of one another

I've got an image of a basketball court and would like to place either a green or red dot on the court (green if a shot was made from that spot, red if missed).
The basketball shots are recorded by someone clicking the image of the court, and then the coordinates (represented as percentages) are saved to the database. After we are done recording, on a separate view, I am calling all of those coordinates and setting the following parameters for them:
var marker = document.createElement("IMG");
marker.src = image;
marker.style.width = '4%';
marker.style.position = 'absolute';
marker.style.left = offsetLeft + "%";
marker.style.top = offsetTop + "%";
shotChartBox.appendChild(marker);
offetLeft and Top are both just the values from the DB multiplied by 100 and given a % sign.
However, when I do this, the dots always end up just a bit off. If someone clicks in the dead center of the court image, the dot will appear just a bit above and to the right. I know that this is not a data capture problem, because when I went into the browser inspect tool and manually set a dot to have top and left values of exactly 50%, the same thing happened.
I have tried accounting for the 4% width of the dots themselves, but have not been able to find a way to do that and make it work on all browser sizes. As I resize the browser after adding or subtracting 2% here and there, it always throws things off even worse.
Let me know if you have any ideas. I feel as though there is either a positioning or JS thing that I am just not aware of.
//A couple example function calls
displayMarker(0.5, 0.5, "https://i.postimg.cc/8CLJ8Wj6/makeIcon.png");
displayMarker(0.25, 0.25, "https://i.postimg.cc/mDRcTDH6/missIcon.png");
function displayMarker(x, y, image) {
var courtImage = document.getElementById('shotChart');
var shotChartBox = document.getElementById('shotChartBox');
var offsetLeft = x * 100;
var offsetTop = y * 100;
var marker = document.createElement("IMG");
marker.src = image;
marker.style.width = '4%';
marker.style.position = 'absolute';
marker.style.left = offsetLeft + "%";
marker.style.top = offsetTop + "%";
shotChartBox.appendChild(marker);
}
<h2>Shot Chart</h2>
<div id="shotChartBox">
<img id="shotChart" src="https://i.postimg.cc/rswKtPg1/shot-Chart.png" width="100%" />
</div>
JSFiddle demo.
Assuming 0.5, 0.5 is equivalent to the center of the court here is a working solution.
<html>
<style></style>
<body>
<div id="shotChartBox" style="position: relative;">
<img style="position: relative" src="https://i.postimg.cc/rswKtPg1/shot-Chart.png" width="100%" height="auto" />
</div>
<script>
displayMarker(0.5, 0.5, "https://i.postimg.cc/8CLJ8Wj6/makeIcon.png");
displayMarker(0.25, 0.25, "https://i.postimg.cc/mDRcTDH6/missIcon.png");
function displayMarker(x, y, image) {
var shotChartBox = document.getElementById("shotChartBox");
var offsetLeft = x * 100 - 2;
var offsetTop = y * 100 - 1;
var marker = document.createElement("IMG");
marker.src = image;
marker.style.width = "4%";
marker.style.position = "absolute";
marker.style.left = offsetLeft + "%";
marker.style.top = offsetTop + "%";
shotChartBox.appendChild(marker);
}
</script>
</body>
</html>

Animate an element in Javascript on mousemove

I have two DIV's of different widths on top of each other. The top DIV displayDIV is wider than the bottom DIV captureDIV.
In the displayDIV I'm drawing a dot who's X position is proportionate to the mouse position within captureDIV.
As you move the mouse in captureDIV the dot moves proportionately in DisplayDIV.
It makes much more sense if you look at this fiddle
My code is as follows...
let capture = document.getElementById('captureDIV');
let display = document.getElementById('displayDIV');
let circle = document.getElementById('circle');
capture.addEventListener('mousemove', handleMouseMove);
function handleMouseMove(event) {
const captureRect = capture.getBoundingClientRect();
const captureWidth = captureRect.right - captureRect.left;
const relativeX = event.x - captureRect.left;
let percent = (relativeX / captureWidth) * 100;
let roundedPercent = parseFloat(Math.round(percent * 100) / 100).toFixed(2);
moveDotTo(roundedPercent);
}
function moveDotTo(percentage) {
const displayRect = display.getBoundingClientRect();
const displayWidth = displayRect.right - displayRect.left;
const circleX = displayRect.left + displayWidth * (percentage / 100);
const circleY = displayRect.top + (displayRect.height / 2);
const style = `top:${circleY}px;left:${circleX}px;`;
circle.setAttribute('style', style);
}
I also have a number of buttons that can set the position of the dot within DisplayDIV such as...
let move20 = document.getElementById('move20');
move20.addEventListener('click', function(event) {
moveDotTo(20);
});
Using Vanilla JS not CSS tricks, how can I create a function to animate (rather than move) the dot from its existing position to the new position.
function animateDotTo(percentage) {
// clever code here
}
I need to be able to call the animateDotTo(percentage) function from either a button or from the mousemove event handler.
The dot should always animate to its new position regardless of how the move is triggered. For instance if the mouse is moved out of the left side of the captureDIV round the bottom and then into the right side of the captureDIV the dot should animate across the DisplayDIV not jump as it does now. Equally pressing one of the move to x% buttons should animate the dot from its current position to the new one.
If you are drawing a circle and moving it around, I would suggest drawing to a <canvas> element instead of moving a <div> by setting its top and left properties. Even using transform: translate(x, y) might be better.
In order to smoothly transition your dot from one location to another, using JavaScript, you will want:
The dot's current position as x and y coordinates,
The dot's target position as x and y coordinates, and
The speed at which the dot moves as a scalar.
Updating the current position is done at every animation frame with window.requestAnimationFrame. With these in hand, and a way of applying the resulting calculated position to the dot, you can use a method like this one: How to move an object using X and Y coordinates in JavaScript to move your dot (the example moves a canvas, but if you know the x and y, then you can set them to top and bottom).
Answering my own question, with thanks to Billy Brown for pointing me in the right direction. Using window.requestAnimationFrame is the way to go.
var currentPercentage;
var startPercentage;
var targetPercentage;
function animateDotTo(percentage) {
targetPercentage = percentage;
startPercentage = currentPercentage;
window.requestAnimationFrame(step);
}
function step(timestamp) {
var fps = 7;
var maxStep = 30;
var distStartToTarget = Math.abs(startPercentage - targetPercentage);
var stepSize = Math.min(distStartToTarget / fps, maxStep);
if (targetPercentage < startPercentage) {
currentPercentage -= stepSize,0;
if (currentPercentage > targetPercentage) {
window.requestAnimationFrame(step);
}
} else if (targetPercentage > startPercentage) {
currentPercentage += stepSize,100;
if (currentPercentage < targetPercentage) {
window.requestAnimationFrame(step);
}
} else {
return;
}
if (currentPercentage > 100 ) { currentPercentage = 100; }
if (currentPercentage < 0 ) { currentPercentage = 0; }
moveDotTo(currentPercentage);
}
Updated fiddle
A simple trick in css transition will fix this.
Of course. You don't want it to animate when you're actually moving the mouse. So what I did is that I separate the transition css property on another class and then remove that class on mouse move, re-attaching it when we click the move buttons.
CSS
#circle {
position: absolute;
left: -100px;
top: -100px;
width: 10px;
height: 10px;
border-radius: 50%;
background-color: #000;
transition: none;
}
#circle.animate{
transition: 500ms ease;
}
JS
move20.addEventListener('click', function(event) {
moveDotTo(20); animateDotTo();
});
move60.addEventListener('click', function(event) {
moveDotTo(60);animateDotTo();
});
move80.addEventListener('click', function(event) {
moveDotTo(80);animateDotTo();
});
function moveDotTo(percentage) {
circle.classList.remove("animate");
const displayRect = display.getBoundingClientRect();
const displayWidth = displayRect.right - displayRect.left;
const circleX = displayRect.left + displayWidth * (percentage / 100);
const circleY = displayRect.top + (displayRect.height / 2);
const style = `top:${circleY}px;left:${circleX}px;`;
circle.setAttribute('style', style);
}
function animateDotTo(percentage) {
circle.classList.add("animate");
}
http://jsfiddle.net/8pm2grjd/
If you want it to animate even if you're triggering the movement using mousemove, you can disregard the class approach and just slap the transition property on the css. But this will simulate the annoying mouse delay effect similar to input delay on video games due to V-Sync.

How to make a circle grow depending on how long the user holds (Java Script)

ok here is the deal, I want a circle to grow on a canvas depending on how long you hold your mouse button. I was able to make it draw a circle of fixed width where my mouse was when I clicked, but I want to be able to determine size based on how long I hold. Ideally, you will be able to see it grow as you hold.
CODE
var c = document.getElementById("canvas");
var ctx = c.getContext('2d');
document.addEventListener("mousedown", draw);
document.addEventListener("mousedown", time1);
document.addEventListener("mouseup", time2);
//Size
function time1(event) {
var a = new Date().getTime() + 1;
return a;
}
function time2(event) {
var b = new Date().getTime() + 4;
return b;
}
var c ="Time: " + (time2 - time1);
document.getElementById("time").innerHTML = c;
function draw(event, a , b) {
//Cords
var x = event.clientX;
var y = event.clientY;
//Fill
ctx.fillStyle = "#0c67f9";
//Draw
ctx.beginPath();
ctx.arc(x ,y ,(b - a),0,Math.PI * 2, true);
ctx.fill();
}
function showCoords(event) {
var x = event.clientX;
var y = event.clientY;
var coords = "X coords: " + x + ", Y coords: " + y;
document.getElementById("demo").innerHTML = coords;
}
/*function grow(event) {
var z = event.time;
}*/
<canvas id="canvas" width="690" height="651" onclick="showCoords(event)" style ="border: 1px solid #e21313"></canvas>
<p id="demo"></p>
<p id="time"></p>
Here is your groing circle:
Here
But I don't want to give you the copy & paste solution.
So with my help I believe you can figure it out.
First of all you need to change the event listener so it doesn't get triggered if you hold down your mouse somewhere in the html area (like it is now). Set it from $("html") to $("#your-canvas").
Since you also don't want to see your circle the whole time and it can't have a static position you also want to change the CSS attributes of the .dot class. I believe display: none; and position: absolute; will do.
The last thing you want to do is to get the exact mouse position (with offset and everything) and set it as CSS attributes top and left (don't forget to set the display: none to display: block).
Boom you got your growing circle.
However I didn't really understand what you mean by:
but I want to be able to determine size based on how long I hold.

Changing Z-index Problems

I am making an old-RPG game on HTML, and I want to make a Function on Javascript
that makes the div of the player get lower than the obstacle, and when the top get higher than the obstacle, the z-index of the player go higher than the obstacle:
var top = parseInt($("#player").css("top"));
var hei = $("#player").height();
var total = top + hei;
var obTop = parseInt($("#obstacle").css("top"));
var obHei = $("#obstacle").height();
var obTotal = obHei + obTop;
if (total < obTotal) {
player.style.zIndex = 1;
$("#obstacle").css('z-index', 2);
} else {
player.style.zIndex = 2;
$("#obstacle").css('z-index', 1);
}
When top's player is higher than the obstacle (Fire)
When top is Lower
You need to compare the Y positions of the objects in question. In this case, When the fire y is lower then the player y, You want to have the player have a higher Z-index than the fire. And Vice Versa, Where when the fire y is higher than the player y, you want the fire to have a higher Z-index than the fire. You could do something like this like this:
//Define player y and fire y
player.style.zIndex = 1;
$("obstacle").css("z-index", 1);
if (playery > firey){
player.style.zIndex = 2;
} else {
$("obstacle").css("z-index", 2);
}
This hasnt been tested as there Is not a runnable example given.

Creating an effect wherever mouse goes

So I have been trying endlessly to try and do something similar too what this site is doing (http://whois.domaintools.com/). I'm trying to get a webpage, so wherever the mouse moves over the webpage, that kind of effect follows it (I'm sorry I don't know what I would call the effect).
I've read how to ask questions on here, but I don't know what too look for so it's difficult for me to attempt this. So far this link (http://p5js.org/learn/demos/Hello_P5_Drawing.php) I've used the code from this and played around with it but i'm just puzzled as too how I would go about doing this.
Thanks for any help, I've been banging my head against a brick wall for a good couple of days now.
This seems to be some kind of particle system. I would start the following way: First create a class for a particle, it should have a random x and y coordinate, and it should change it's postion periodically to a random new postion. Then create a lot of instances of the particle and distribute them over the page.
http://jsfiddle.net/aggoh0s1/3/
/* each particle will move in a 100px100px square */
var gutterWidth = 100;
/* class definition */
var Particle = function(x, y) {
var t = this;
t.x = x;
t.y = y;
t.elem = $('<div class="particle" />');
t.elem.css({ left: x+"px", top: y+"px"});
$('body').append(t.elem);
/* create a new position every 500-1000 milliseconds */
var milliSecs = 500 + Math.random() * 500;
t.ptinterval = setInterval(function() {
var dx = Math.round(Math.random() * gutterWidth);
var dy = Math.round(Math.random() * gutterWidth);
t.elem.animate({left: (t.x + dx)+"px", top: (t.y + dy) + "px"}, 600);
}, milliSecs);
};
/* create a 1000px1000px area where particles are placed each 100px */
var particles = [];
var newParticle;
for(var x = 0; x < 1000; x = x + gutterWidth) {
for(var y = 0; y < 1000; y = y + gutterWidth) {
newParticle = new Particle(x,y);
particles.push(newParticle);
}
}
CSS:
.particle {
width: 2px;
height: 2px;
background-color: black;
position: absolute;
}
Using this logic, you could also use a canvas to display the particles instead of a html div like it is done on whois.domaintools.com. The next step should be to connect the particles with lines to each other, and after that some code should hide all particles that are some distance away from the mouse position.
I've developed the following solution for the effect which you are referring. This is done using jQuery using the event mousemove(). Bind this event to your body where the content is.
Method :
Create an element with the following css on your body. You can create the element onthefly using jQuery as well.
<div class='hover'></div>
CSS
.hover{
position:absolute;
width:100px;
height:100px;
background-color:#fff;
}
The add the following code to your page.
$('body').mousemove(function(event){
$('.hover').css({
'top' : event.pageY,
'left': event.pageX
})
});
The above code will bind an event to your mouse move and I change the element position according to the mouse coordinates.
This fiddle shows a running example
I've given you the basic idea of the solution! You will have to medle with the css and jquery to add the looks and feels of the effect which you refer to.
See the simple example
<img id="imgMove" src="Images/img1.jpg" height="100" width="100" style="position: absolute;" />
JQuery
$(document).ready(function () {
$(document).mousemove(function (e) {
$("#imgMove").css({ "top": e.pageY - 50, "left": e.pageX - 50 }); // e.pageX - Half of Image height, width
})
})

Categories

Resources