How can one make a smooth smoke trail effect with Javascript, out of the code I attached? The trail should follow an object, but have the position the object had a moment ago. The code I attached does have some sort of trail effect, but it is not smooth. Can give the trail a position using something like this: position:trail = position:object, 5 ms ago?
var left = parseInt(document.getElementById("thingy").style.left);
setInterval(fly, 10);
function fly() {
if (left > 300) {
left = 300;
};
left++;
document.getElementById("thingy").style.left = left + "px";
}
setInterval(trail, 100);
function trail() {
document.getElementById("trail").style.left = left + "px";
}
<div id="thingy" style="position:absolute; top:100px; left: 0px; width: 100px; height: 100px; background-color:#000000;"></div>
<div id="trail" style="position:absolute; top:125px; left: 0px; width: 50px; height: 50px; background-color:#CCCCCC; z-index: -10;"></div>
If it is possible I would like to stay out of jQuery.
This solution clones the element each time it moves.
CSS3 transitions are used on the cloned nodes' background to simulate a smoke trail.
The code ensures there are never more than 100 cloned nodes.
var thingy= document.getElementById('thingy'),
left = thingy.offsetLeft,
shadows= [],
delta= 4;
setInterval(fly, 10);
function fly() {
var shadow= thingy.cloneNode();
shadow.classList.add('shadow');
shadow.style.backgroundColor= 'silver';
document.body.appendChild(shadow);
setTimeout(function() {
shadow.style.backgroundColor= 'white';
},100);
shadows.push(shadow);
if(shadows.length>100) {
shadows[0].parentNode.removeChild(shadows[0]);
shadows.shift();
}
if(left+delta > document.body.offsetWidth-thingy.offsetWidth || left < 0) {
delta= -delta;
}
left+= delta;
thingy.style.left = left + 'px';
}
body {
margin: 0;
padding: 0;
}
#thingy {
position: absolute;
top: 100px;
left: 0px;
width: 100px;
height: 100px;
background-color: orange;
border-radius: 50%;
}
.shadow {
transition: all 1s;
z-index: -1;
}
<div id="thingy"></div>
Update
For a "smokier" effect, you can use random values for the cloned nodes' width, height, transition, etc., like I've done in this Snippet:
var thingy= document.getElementById('thingy'),
tleft = thingy.offsetLeft,
ttop = thingy.offsetTop,
smokes= [],
deltaX= deltaY= 2;
setInterval(fly, 10);
function fly() {
if(Math.random()>0.5) {
var smoke= thingy.cloneNode();
smoke.classList.add('smoke');
smoke.style.background= 'gray';
smoke.style.opacity= 0.2;
smoke.style.transition= Math.random()+'s';
smoke.style.width= Math.random()*thingy.offsetWidth+'px';
smoke.style.height= Math.random()*thingy.offsetHeight+'px';
smoke.style.marginTop= smoke.offsetHeight+'px';
smoke.style.borderRadius= (Math.random()*25+25)+'%';
document.body.appendChild(smoke);
setTimeout(function() {
smoke.style.opacity= 0;
},100);
smokes.push(smoke);
if(smokes.length>20) {
smokes[0].parentNode.removeChild(smokes[0]);
smokes.shift();
}
}
if(tleft+deltaX > document.body.offsetWidth-thingy.offsetWidth || tleft < 0) {
deltaX= -deltaX;
}
if(ttop +deltaY > document.body.offsetHeight-thingy.offsetHeight || ttop < 0) {
deltaY= -deltaY;
}
tleft+= deltaX;
ttop += deltaY;
thingy.style.left = tleft + 'px';
thingy.style.top = ttop + 'px';
}
body {
margin: 0;
padding: 0;
background: black;
height: 100vh;
}
#thingy {
position: absolute;
top: 100px;
left: 0px;
width: 100px;
height: 100px;
background-color: orange;
border-radius: 50%;
}
.smoke {
z-index: -1;
}
<div id="thingy"></div>
Related
In this code, I was trying to move the yellow box (the small box) to the right, bottom, left, and top respectively in the red box (the big box) and I have wanted to move the yellow box unendly. I have moved the yellow box to the right and bottom but couldn't move to the left and top. I couldn't understand what the problem is. How should I write this code in Javascript? Could you help me, please? I have used Visual Studio Code.
window.onload = function(){
var posX = 0,posY =0, posZ=0;
var smallbox = document.getElementById("smallbox");
var time = setInterval(move,10);
function move(){
if(posX>=150){
if(posY>=150){
if(posZ>=150){
clearInterval(time);
}
else{
posZ++;
smallbox.style.right = posZ + "px";
}
}
else{
posY++;
smallbox.style.top = posY + "px";
}
}
else{
posX = posX+1;
smallbox.style.left = posX + "px";
}
}
}
#bigbox{
height: 200px;
width: 200px;
background-color: red;
position: relative;
}
#smallbox{
height: 50px;
width: 50px;
background-color: yellow;
position: absolute;
}
<div id="bigbox">
<div id="smallbox">
</div>
</div>
The reason that your animation is not working is that CSS alignments for objects must use "top" or "bottom" and "left" or "right" to align themselves. What you are doing is aligning horizontally using "left" and then trying to align horizontally using "right", or the same thing but around the other way.
What I would instead suggest is using code that essentially reads:
if at top-left, move right.
if at top-right, move down.
if at bottom-right, move left.
if at bottom-left, move up.
An example of this in action:
window.onload = function() {
var posX = 0,
posY = 0,
boxW = 200,
boxH = 200,
smallboxW = 50,
smallboxH = 50;
var smallbox = document.getElementById("smallbox");
var time = setInterval(move, 10);
function move() {
if (posY <= 0 && posX < boxW) {
// go right
posX++;
smallbox.style.left = posX + "px";
}
if (posX >= boxW - smallboxW && posY < boxH) {
// go down
posY++;
smallbox.style.top = posY + "px";
}
if (posY >= boxH - smallboxH && posX > 0) {
// go left
posX--;
smallbox.style.left = posX + "px";
}
if (posX <= 0 && posY > 0) {
// go up
posY--;
smallbox.style.top = posY + "px";
}
}
}
#bigbox {
height: 200px;
width: 200px;
background-color: red;
position: relative;
}
#smallbox {
height: 50px;
width: 50px;
background-color: yellow;
position: absolute;
}
<body>
<div id="bigbox">
<div id="smallbox">
</div>
</div>
</body>
Instead of managing all calculations yourself, use the power of CSS in javascript with Element.animate().
This will also allow you to pause and play whenever needed.
const smallbox = document.querySelector('#smallbox');
smallbox.animate([
// keyframes
{
transform: 'translate(150px, 0px)'
},
{
transform: 'translate(150px, 150px)'
},
{
transform: 'translate(0px, 150px)'
},
{
transform: 'translate(0px, 0px)'
},
{
transform: 'translate(150px, 0px)'
},
], {
// timing options
duration: 2000,
iterations: Infinity
});
#bigbox {
height: 200px;
width: 200px;
background-color: red;
position: relative;
}
#smallbox {
height: 50px;
width: 50px;
background-color: yellow;
position: absolute;
}
<div id="bigbox">
<div id="smallbox">
</div>
</div>
One alternative option is to use the CSS keyframes to animate.
#bigbox {
height: 200px;
width: 200px;
background-color: red;
position: relative;
}
#smallbox {
height: 50px;
width: 50px;
background-color: yellow;
position: relative;
animation: move-around 4s infinite linear;
}
#keyframes move-around {
0% {
left: 0;
top: 0;
transform: translate(0%, 0%);
}
25% {
left: 100%;
top: 0;
transform: translate(-100%, 0%);
}
50% {
left: 100%;
top: 100%;
transform: translate(-100%, -100%);
}
75% {
left: 0;
top: 100%;
transform: translate(0%, -100%);
}
100% {
left: 0;
top: 0;
transform: translate(0%, 0%);
}
}
<body>
<div id="bigbox">
<div id="smallbox">
</div>
</div>
</body>
I'm trying to change the colors of the divs from skyblue to yellow, when a specific div appears OR goes through the middle of the window. I have been building my own logic which works fine when I scroll the page up and down slowly. But it doesn't work when I scroll the page fast. I have inserted a button which takes the page to the fourth div (Box - 5) from the 100 divs. When the fourth div appears the background color does not switch, I have the keep scrolling up and down for my logic to change the fourth background color. The button is placed at the bottom of the page.
So I need help in making a better logic to changing the div's background color when the div is at or goes through the middle of the window, no matter the page is being scrolled fast or slow OR the page being
directly shifted to a specific div. Thanks
My index.html:
window.onbeforeunload = function() {
this.scrollTo(0, 0);
}
var content = document.getElementById("content"),
current = 0;
for (var y = 0; y < 100; y++) {
var box = document.createElement("div");
box.id = "box";
box.innerHTML = "Box - " + (y + 1);
content.appendChild(box);
}
content.children[current].style.backgroundColor = "yellow";
window.onscroll = function() {
if (this.oldScroll > this.scrollY) {
if (current >= 1) {
var previous_box = content.children[current - 1];
if ((this.scrollY + this.innerHeight / 2) < previous_box.offsetTop + previous_box.clientHeight) {
content.children[current].style.backgroundColor = "skyblue";
current--;
content.children[current].style.backgroundColor = "yellow";
}
}
} else {
if (current < 99) {
var next_box = content.children[current + 1];
if ((this.scrollY + this.innerHeight / 2) > next_box.offsetTop) {
content.children[current].style.backgroundColor = "skyblue";
current++;
content.children[current].style.backgroundColor = "yellow";
}
}
}
this.oldScroll = this.scrollY;
}
document.querySelector("button").onclick = function() {
var y = content.children[4].offsetTop - (content.children[4].clientHeight / 4);
window.scrollTo(0, y);
};
body {
margin: 0;
}
#navigation {
min-width: 620px;
background-color: blue;
width: 100%;
height: 50px;
z-index: 1;
position: fixed;
top: 0;
}
#box {
position: relative;
height: 75%;
width: 100%;
margin: 15% auto 15% auto;
color: black;
background-color: skyblue;
border: black 1px solid;
font-size: 50px;
text-align: center;
}
button {
margin: 0% auto 15% auto;
left: 50%;
}
<div id="navigation"></div>
<div id="content"></div>
<button>GO TO BOX 5</button>
window.onbeforeunload = function() {
this.scrollTo(0, 0);
}
var content = document.getElementById("content"),
current = 0;
for (var y = 0; y < 100; y++) {
var box = document.createElement("div");
box.id = "box";
box.innerHTML = "Box - " + (y + 1);
content.appendChild(box);
}
content.children[current].style.backgroundColor = "yellow";
window.onscroll = function() {
for(var i=0;i<content.children.length;i++){
var top = content.children[i]. getBoundingClientRect().top;
var height = top+content.children[i].clientHeight;
var halfWindow = window.innerHeight*0.5;
if(top<halfWindow&&height>halfWindow){
content.children[i].style.backgroundColor = "skyblue";
}
else{
content.children[i].style.backgroundColor = "yellow";
}
}
}
document.querySelector("button").onclick = function() {
var y = content.children[4].offsetTop - (content.children[4].clientHeight / 4);
window.scrollTo(0, y);
};
body {
margin: 0;
}
#navigation {
min-width: 620px;
background-color: blue;
width: 100%;
height: 50px;
z-index: 1;
position: fixed;
top: 0;
}
#box {
position: relative;
height: 75%;
width: 100%;
margin: 15% auto 15% auto;
color: black;
background-color: skyblue;
border: black 1px solid;
font-size: 50px;
text-align: center;
}
button {
margin: 0% auto 15% auto;
left: 50%;
}
<div id="navigation"></div>
<div id="content"></div>
<button>GO TO BOX 5</button>
I have created the following simple image comparison slider - modified from the version on w3schools (I know my mistake to use their code).
This all works fine on a desktop but when I try to use it on a mobile, nothing happens - it doesn't even register the console.log on the mousedown/touchstart (when I press on the slider button with my finger).
I was wondering if anyone could spot anything obvious with why it isn't working on mobile devices
(() => {
$.fn.imageComparisonSlider = function() {
var returnValue = this.each((index, item) => {
var $container = $(this);
var $overlay = $container.find('.image-comparison-slider__bottom-image');
var $slider = $('<span class="image-comparison-slider__slider"></span>');
var $window = $(window);
var touchStarted = false;
var width = $container.outerWidth();
$container.prepend($slider);
$container.on('mousedown touchstart', '.image-comparison-slider__slider', event => {
event.preventDefault();
console.log('touchstart');
touchStarted = true;
});
$window.on("mousemove touchmove", windowEvent => {
if (touchStarted) {
// get the cursor's x position:
let pos = getCursorPos(windowEvent);
// prevent the slider from being positioned outside the image:
if (pos < 0) pos = 0;
if (pos > width) pos = width;
// execute a function that will resize the overlay image according to the cursor:
slide(pos);
}
});
$window.on('mouseup touchend', event => {
event.preventDefault();
touchStarted = false;
});
function getCursorPos(e) {
var thisEvent = e || window.event;
// calculate the cursor's x coordinate, relative to the image
return thisEvent.pageX - $container.offset().left;
}
function slide(x) {
// set the width of the overlay
$overlay.width(width - x);
// position the slider
$slider[0].style.left = x + 'px';
}
function resetSlider() {
$overlay.width('50%');
$slider[0].style.left = $overlay.width() + 'px'
width = $container.outerWidth();
}
});
return returnValue;
};
})($);
$('.image-comparison-slider__container').imageComparisonSlider();
.image {
display: block;
width: 100%;
}
.image-comparison-slider__title {
text-align: center;
}
.image-comparison-slider__container,
.image-comparison-slider__image-holder {
position: relative;
}
.image-comparison-slider__bottom-image {
position: absolute;
overflow: hidden;
top: 0;
right: 0;
bottom: 0;
z-index: 1;
width: 50%;
}
.image-comparison-slider__caption {
position: absolute;
padding: 1rem;
color: white;
background: rgba(0, 0, 0, 0.6);
z-index: 2;
white-space: nowrap;
}
.image-comparison-slider__top-image .image-comparison-slider__caption {
top: 0;
left: 0;
}
.image-comparison-slider__bottom-image .image-comparison-slider__caption {
bottom: 0;
right: 0;
}
.image-comparison-slider__image {
display: block;
z-index: 1;
}
.image-comparison-slider__bottom-image .image {
position: absolute;
right: 0;
top: 0;
height: 100%;
width: auto;
}
.image-comparison-slider__slider {
position: absolute;
z-index: 3;
cursor: ew-resize;
/*set the appearance of the slider:*/
width: 50px;
height: 50px;
background-color: rgba(255, 96, 38, 0.8);
border-radius: 50%;
top: 50%;
left: 50%;
display: flex;
justify-content: center;
align-items: center;
transform: translate(-50%, -50%);
}
.image-comparison-slider__slider:after {
content: "< >";
color: white;
font-weight: bold;
font-size: 25px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="image-comparison-slider__container">
<div class="image-comparison-slider__image-holder image-comparison-slider__top-image">
<img src="https://www.fillmurray.com/g/400/300" alt="A test image 1" class="image">
<div class="image-comparison-slider__caption">Left Image</div>
</div>
<div class="image-comparison-slider__image-holder image-comparison-slider__bottom-image">
<img src="https://www.fillmurray.com/400/300" alt="A test image 2" class="image">
<div class="image-comparison-slider__caption">Right Image</div>
</div>
</div>
Fiddle link for code
Ok have managed to fix this - the touch wasn't registering because of the transform so I changed that and just used negative margin as the button was a fixed size.
I then had to fix the thisEvent.pageX for android - so did a check with isNaN and then set it to e.originalEvent.touches[0].pageX if it was true.
Working version:
(() => {
$.fn.imageComparisonSlider = function() {
var returnValue = this.each((index, item) => {
var $container = $(this);
var $overlay = $container.find('.image-comparison-slider__bottom-image');
var $slider = $('<span class="image-comparison-slider__slider"></span>');
var $window = $(window);
var touchStarted = false;
var width = $container.outerWidth();
$container.prepend($slider);
$container.on('mousedown touchstart', '.image-comparison-slider__slider', event => {
event.preventDefault();
console.log('touchstart');
touchStarted = true;
});
$window.on("mousemove touchmove", windowEvent => {
if (touchStarted) {
// get the cursor's x position:
let pos = getCursorPos(windowEvent);
// prevent the slider from being positioned outside the image:
if (pos < 0) pos = 0;
if (pos > width) pos = width;
// execute a function that will resize the overlay image according to the cursor:
slide(pos);
}
});
$window.on('mouseup touchend', event => {
event.preventDefault();
touchStarted = false;
});
function getCursorPos(e) {
var thisEvent = e || window.event;
let xVal = thisEvent.pageX;
if (isNaN(xVal)) {
xVal = e.originalEvent.touches[0].pageX;
}
// calculate the cursor's x coordinate, relative to the image
return xVal - $container.offset().left;
}
function slide(x) {
// set the width of the overlay
$overlay.width(width - x);
// position the slider
$slider[0].style.left = x + 'px';
}
function resetSlider() {
$overlay.width('50%');
$slider[0].style.left = $overlay.width() + 'px'
width = $container.outerWidth();
}
});
return returnValue;
};
})($);
$('.image-comparison-slider__container').imageComparisonSlider();
.image {
display: block;
width: 100%;
}
.image-comparison-slider__title {
text-align: center;
}
.image-comparison-slider__container,
.image-comparison-slider__image-holder {
position: relative;
}
.image-comparison-slider__bottom-image {
position: absolute;
overflow: hidden;
top: 0;
right: 0;
bottom: 0;
z-index: 1;
width: 50%;
}
.image-comparison-slider__caption {
position: absolute;
padding: 1rem;
color: white;
background: rgba(0, 0, 0, 0.6);
z-index: 2;
white-space: nowrap;
}
.image-comparison-slider__top-image .image-comparison-slider__caption {
top: 0;
left: 0;
}
.image-comparison-slider__bottom-image .image-comparison-slider__caption {
bottom: 0;
right: 0;
}
.image-comparison-slider__image {
display: block;
z-index: 1;
}
.image-comparison-slider__bottom-image .image {
position: absolute;
right: 0;
top: 0;
height: 100%;
width: auto;
}
.image-comparison-slider__slider {
position: absolute;
z-index: 3;
cursor: ew-resize;
width: 50px;
height: 50px;
background-color: rgba(255, 96, 38, 0.8);
border-radius: 50%;
top: 50%;
left: 50%;
display: flex;
justify-content: center;
align-items: center;
margin: -25px 0 0 -25px;
}
.image-comparison-slider__slider:after {
content: "< >";
color: white;
font-weight: bold;
font-size: 25px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="image-comparison-slider__container">
<div class="image-comparison-slider__image-holder image-comparison-slider__top-image">
<img src="https://www.fillmurray.com/g/400/300" alt="A test image 1" class="image">
<div class="image-comparison-slider__caption">Left Image</div>
</div>
<div class="image-comparison-slider__image-holder image-comparison-slider__bottom-image">
<img src="https://www.fillmurray.com/400/300" alt="A test image 2" class="image">
<div class="image-comparison-slider__caption">Right Image</div>
</div>
</div>
I try to build a Slideshow in JS + CSS and it works pretty well except one visual glitch. The Transition to the last slides seems somehow broken.
But I couldn't figure out what the problem is. If I comment out the "offset" transition on the last slide, the error doesn't occure.
This is the codeine I am talking about: https://codepen.io/marianbreitmeyer/pen/paeYgZ
The Block of code I mentioned is this one:
const showNext = function() {
clicked = true;
for (i = 0; i <= slides.length-1; i++) {
if( parseInt(slides[i].style.zIndex) === slides.length) {
console.log(slides[i].innerHTML);
triggerAnimation(slides[i], 'offcanvas');
} else if (parseInt(slides[i].style.zIndex) === slides.length-1) {
//the line below triggers the problem
triggerAnimation(slides[i], 'offset');
}
}
};
Maybe someone with more experience could help me :)
Your code might be more simple:
const btn = document.getElementsByClassName('arrow')[0];
const slides = document.getElementsByClassName('slide');
slides[slides.length - 1].classList.add('offset', 'next');
btn.addEventListener("click", function(e) {
var o, n;
for (var i = 0; i < slides.length; i++) {
if (slides[i].classList.contains('offset')) {
slides[i].classList.remove('offset', 'next')
slides[i].classList.add('offcanvas');
o = (slides[i - 1] || slides[slides.length - 1]);
n = (slides[i - 2] || slides[slides.length + i - 2]);
}
if (slides[i].offsetLeft < -slides[i].offsetWidth) {
slides[i].classList.remove('offcanvas', 'next');
}
}
o.classList.add('offset');
n.classList.add('next');
}, false);
.container {
width: 100%;
height: 100vh;
background: brown;
position: relative;
}
body {
text-align: center;
font-size: 2rem;
}
.slide {
position: absolute;
top: 0;
left: 90%;
width: 100%;
height: 100%;
}
.slide:nth-child(1) {
background: pink;
}
.slide:nth-child(2) {
background: blue;
}
.slide:nth-child(3) {
background: green;
}
.slide:nth-child(4) {
background: grey;
}
.slide:nth-child(5) {
background: yellow;
}
.slide.next {z-index:1}
.slide.offset {
left: -10%;
z-index: 2;
transition: left .65s ease-in-out;
}
.slide.offcanvas {
left: -110%;
z-index: 2;
transition: left .65s ease-in-out;
}
.arrow {
position: absolute;
right: 5%;
top: 25px;
z-index: 9;
height: 50px;
width: 50px;
cursor: pointer;
}
.arrow:hover path {
transform: translate(16px, 0px);
}
path {
position: absolute;
top: 0;
left: 0;
transition: all .2s ease-in-out;
}
<div class="container">
<div class="slide">1 = pink</div>
<div class="slide">2 = blue</div>
<div class="slide">3 = green</div>
<div class="slide">4 = grey</div>
<div class="slide">5 = yellow</div>
<svg xmlns="http://www.w3.org/2000/svg" class="arrow"><path d="M19.443 5.17L30.138 15.5H-.095v1h30.233L19.443 26.829l.696.719L32.095 16 20.139 4.451z"/></svg>
</div>
I have been challenged with a website that requires me to make two images race at random across the screen to a finish line. I am required to make this happen using JavaScript. Unfortunately I have ran into some trouble here making this happen.
I have the script that allows a div container and an object "animate" (which is a small square) to move across the screen to the right as I am supposed to do. My question comes into play when trying to do this to two different images.
The goal is to have the animation I have created to apply to the images, I cannot figure out how to apply the functions to the images already placed on the page to make it seem as if they are racing on random intervals across the page to the finish line.
I understand the concept of the animation and the JavaScript behind it, I just dont understand how to make it apply to an image, and more than 1 image at that.
Please advise.
Here is my code that I am using: you can see that I left my demo animation on the page, and the two images I am looking to apply it to.
function myMove()
{
var elem = document.getElementById("animate");
var pos = 0;
var id = setInterval(frame, 5);
function frame()
{
if (pos == 350)
{
clearInterval(id);
}
else
{
pos++;
elem.style.left = pos + 'px';
}
}
}
<div id="traffic-light">
<div id="stopLight" class="bulb"></div>
<div id="yeildLight" class="bulb"></div>
<div id="goLight" class="bulb"></div>
</div>
<style>
body {
overflow: hidden;
}
#bluefish {
position: absolute;
top: 31pc;
width: 17pc;
left: -.5pc;
}
#turtle {
position: absolute;
width: 15pc;
top: 20pc;
}
body {
background-image: url("http://www.hpud.org/wp-content/uploads/2015/08/WaterBackground2.jpg")
}
.finishline {
position: absolute;
right: -12pc;
top: 18pc;
}
#traffic-light {
height: 10pc;
width: 4pc;
background-color: #333;
border-radius: 20pc;
position: absolute;
}
.bulb {
height: 2pc;
width: 2pc;
background-color: #111;
border-radius: 50%;
margin: 15px auto;
transition: background 500ms;
}
#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#animate {
width: 50px;
height: 50px;
position: absolute;
background: red;
}
</style>
<img id="bluefish" src="http://clipartist.net/openclipart.org/2013/July/Blue_Fish_Goldfish.png">
<img id="turtle" src="http://www.clipartkid.com/images/386/turtle-free-stock-photo-illustration-of-a-green-sea-turtle-uPgZrm-clipart.png">
<img src="https://t1.rbxcdn.com/877010da8ce131dfcb3fa6a9b07fea89" class="finishline">
<p>
<button onclick="myMove()">Click Me</button>
</p>
<div id="container">
<div id="animate"></div>
</div>
Try this one:
function myMove()
{
var elemBluefish = document.getElementById("bluefish");
var elemBluefishWin = document.getElementById("bluefishwin");
var elemTurtle = document.getElementById("turtle");
var elemTurtleWin = document.getElementById("turtlewin");
var posBluefish = 0;
var posTurtle = 0;
var hasWinner = false;
elemBluefishWin.style.display = 'none';
elemTurtleWin.style.display = 'none';
var id = setInterval(frame, 5);
function frame()
{
if(posBluefish >= 350 && posTurtle >= 350)
{
clearInterval(id);
return;
}
if(posBluefish < 350)
{
posBluefish += Math.round(Math.random()*10);
if(posBluefish >= 350)
{
posBluefish = 350;
if(!hasWinner){
hasWinner = true;
elemBluefishWin.style.display = 'unset';
}
}
elemBluefish.style.left = posBluefish + 'px';
}
if(posTurtle < 350)
{
posTurtle += Math.round(Math.random()*10);
if(posTurtle >= 350)
{
posTurtle = 350;
if(!hasWinner){
hasWinner = true;
elemTurtleWin.style.display = 'unset';
}
}
elemTurtle.style.left = posTurtle + 'px';
}
}
}
<div id="traffic-light">
<div id="stopLight" class="bulb"></div>
<div id="yeildLight" class="bulb"></div>
<div id="goLight" class="bulb"></div>
</div>
<style>
body {
overflow: hidden;
}
#bluefish {
position: absolute;
top: 31pc;
width: 17pc;
left: -.5pc;
}
#turtle {
position: absolute;
width: 15pc;
top: 20pc;
}
#bluefishwin {
position: absolute;
right: 1pc;
top: 31pc;
display: none;
}
#turtlewin {
position: absolute;
right: 1pc;
top: 20pc;
display: none;
}
body {
background-image: url("http://www.hpud.org/wp-content/uploads/2015/08/WaterBackground2.jpg")
}
.finishline {
position: absolute;
right: -12pc;
top: 18pc;
}
#traffic-light {
height: 10pc;
width: 4pc;
background-color: #333;
border-radius: 20pc;
position: absolute;
}
.bulb {
height: 2pc;
width: 2pc;
background-color: #111;
border-radius: 50%;
margin: 15px auto;
transition: background 500ms;
}
/*#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#animate {
width: 50px;
height: 50px;
position: absolute;
background: red;
}*/
</style>
<img id="bluefish" src="http://clipartist.net/openclipart.org/2013/July/Blue_Fish_Goldfish.png">
<img id="turtle" src="http://www.clipartkid.com/images/386/turtle-free-stock-photo-illustration-of-a-green-sea-turtle-uPgZrm-clipart.png">
<img src="https://t1.rbxcdn.com/877010da8ce131dfcb3fa6a9b07fea89" class="finishline">
<img id="bluefishwin" src="http://a.dryicons.com/images/icon_sets/coquette_part_3_icons_set/png/128x128/prize_winner.png">
<img id="turtlewin" src="http://a.dryicons.com/images/icon_sets/coquette_part_3_icons_set/png/128x128/prize_winner.png">
<p>
<button onclick="myMove()">Click Me</button>
</p>
<div id="container">
<div id="animate"></div>
</div>
It gets an element for each image and adds every 5ms a random amount of pixels (between 0 and 9) to each pos of image.
If both "racers" reached the target (350px) the interval is cleared and the race is over.
The winner gets an image displayed at the finish line.
an example:
function startRace() {
animateRacer("player1", true);
animateRacer("player2", true);
}
function animateRacer(playerId, reset) {
var elem = document.getElementById(playerId);
var pos = parseInt(elem.style.left, 10);
if (isNaN(pos) || reset) {
pos = 0;
}
//console.log(playerId + ': ' + pos);
if (pos < 450) {
pos += randStep(3);
elem.style.left = pos + 'px';
setTimeout('animateRacer("' + playerId + '")', randStep(5));
}
}
function randStep(max) {
var min = 1;
return Math.floor(Math.random() * (max - min)) + min;
}
body {
overflow: hidden;
}
#container {
width: 500px;
height: 160px;
position: relative;
background-color: yellow;
}
.player {
width: 50px;
height: 50px;
background-color: gray;
position: relative;
}
#player1 {
background-color: red;
top: 20px;
}
#player2 {
background-color: blue;
top: 40px;
}
<p>
<button onclick="startRace()">Start Race</button>
</p>
<div id="container">
<div id="player1" class="player"></div>
<div id="player2" class="player"></div>
</div>
function mover(obj) {
this.obj=obj;
this.pos = 0;
this.id = setInterval(this.frame, 5);
}
mover.prototype.frame=function() {
if (this.pos == 350) {
clearInterval(this.id);
} else {
this.pos++;
this.obj.style.left = this.pos + 'px';
}
}
}
Simply do:
img1=new mover(document.getElementById("pic1"));
You can repeat this with every image and you could store them into an array:
images=[];
function letsmove(){
images.push(new mover(someid));
...
}
And you can do this with all images on the site:
images=[];
function letsmove(){
domimages=document.getElementsByTagName("img");
domimages.forEach(function(img){
images.push(new mover(img));
});
}
}
See JS OOP and JS Prototyping for more explanation