I made an animation on my website which moves if clicked on. The problem is that on the javascript function that manage it, I gave a series of coordinates which fits only if the browser is in full screen. Here are some example:
https://imgur.com/a/Ug6eQlp and https://imgur.com/a/bPrVg5y
This is my javascript function:
function init(){
imgObj = document.getElementById('minion');
immagine = document.getElementById('immagine_minion');
imgObj.style.position= 'absolute';
imgObj.style.top = '240px';
imgObj.style.left = '-300px';
imgObj.style.visibility='hidden';
appaer();
}
And this, for example, the method which moves it as soon as I open the page:
function appaer(){
immagine.src="../img/minion_dx.png";
if (parseInt(imgObj.style.left)<200) {
imgObj.style.left = parseInt(imgObj.style.left) + 5 + 'px';
imgObj.style.visibility='visible';
animate = setTimeout(appaer,20);
} else
stop();
}
How can I make it fit for every screen resolution?
this should get you started
var stage_number = 0
function go_to_next_stage() {
stage_number++
var stage = document.getElementById("stage" + stage_number)
me.style.left = getComputedStyle(stage).getPropertyValue("left")
me.style.top = getComputedStyle(stage).getPropertyValue("top")
if (stage_number > 3) stage_number = 0
}
img {
position: absolute;
left: -100px;
top: 0;
transition: left 2s, top 2s
}
.stage {
width: 100px;
height: 100px;
border: 1px solid black;
position: absolute;
}
#stage1 {
left: 0;
top: 0;
}
#stage2 {
right: 0;
top: 0;
}
#stage3 {
right: 0;
bottom: 0;
}
#stage4 {
left: 0;
bottom: 0;
}
div {
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
<img id="me" src="https://de.gravatar.com/userimage/95932142/195b7f5651ad2d4662c3c0e0dccd003b.png?size=100" />
<div onclick="go_to_next_stage()">click anywhere to continue</div>
<div class="stage" id="stage1">
</div>
<div class="stage" id="stage2">
</div>
<div class="stage" id="stage3">
</div>
<div class="stage" id="stage4">
</div>
Related
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 am using Skrollr librabry. In the start it works fine,but as I'm scrolling down,I am experiencing flickering and images do not load. The content of my website are just images. Works fine on firefox, but not on Chrome. Could you please help me. I am using approximately 190 images. Is that an issue?
I am using async calls to fetch the data,and every image is being loaded before the skrollr is rendered.
Here's my working example : https://jsfiddle.net/if_true/v1mLhutc/7/
html
<body>
<div id="fakeloader"></div>
<div style="transform: translate3d(0,0,0);"></div>
<div class="DESKScreen">
<div id="info" hidden="hidden">0</div>
<section id="slide">
<div class="bcg"></div>
</section>
</div>
</body>
CSS
*,:before,:after {
-moz-box-sizing:border-box;
-webkit-box-sizing:border-box;
box-sizing:border-box;
-webkit-backface-visibility:hidden;
backface-visibility: hidden;
}
#info{
position: fixed;
top: 20px;
left: 20px;
background-color: rgba(0, 0, 0, 0.5);
color: #fff;
padding: 20px;
z-index: 9999;
}
body {
margin: 0;
width: 100%;
height: 100%;
}
html{
width: 100%;
height: 100%;
}
section {
width: 100%;
max-width: 100%;
height: 100%;
position: fixed;
left: 0;
right: 0;
margin: auto;
}
#slide .bcg {
height: 100%;
width: 100%;
background-size: 100%;
background-position: center top;
background-attachment: fixed;
position: absolute;
transform:translateZ(0)
}
.img{
background-size: cover;
background-repeat: no-repeat;
background-position: center;
display: table;
margin: auto;
max-height: 100vh !important;
height: 100% !important;
}
.item {
width: 100%;
position: absolute;
opacity: 1;
}
`Js`
$(document).ready(function() {
DivImage("sup");
var s = skrollr.init({
render: function(data) {
console.log(data.curTop);
}
});
//Check the screen size.
(function() {
if (screen.width < 768) {
$("#fullpage").fullpage({
//scrollingSpeed: 0,
});
$(".DESKScreen").css("display", "none");
} else if (screen.width > 768) {
$(".MObileScreen").css("display", "none");
}
})();
//Fakeloader for the loadtime
function loader() {
$("#fakeloader").fakeLoader({
timeToHide: 4000,
bgColor: "#e74c3c",
spinner: "spinner2"
});
}
loader();
});
function DivImage(name) {
//console.log(name);
//a counter to set for div id
let counter = 0;
//create the urls based on a nr
var Images = makeUrls();
//first create the div and pass the counter to it
CreateDiv(Images);
}
function makeUrls() {
let base = "images/";
let rest = ".jpg";
let result = [];
for (let i = 0; i < 191; i++) {
let baseNr = 1 + i;
if (baseNr === 2000) {
console.log("base");
} else {
result.push(base + baseNr + rest);
}
}
return result;
}
function CreateDiv(images) {
// debugger;
var from = 0,
to = 0;
let result = [];
for (let i of images) {
var newDiv = $('<div class="img-div"></div>');
newDiv.css({
backgroundImage: `url(${i})`
});
newDiv.attr("data--" + from + "-top", "opacity: 0;");
from += 125;
newDiv.attr("data--" + from + "-top", "opacity: 0;");
from += 125;
newDiv.attr("data--" + from + "-top", "opacity: 1;");
newDiv.attr("data-anchor-target", "#slide");
newDiv.attr("data-skrollr-decks-speed", "300");
$("#slide").append($(newDiv));
}
}
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
I have made this scrolling effect that comes into action when page is scrolled. Now, i want to show a scrollbar on the page which when present at the starting position, all the divs are at 100% width and when at bottom, all divs are at 0% width.
EDIT - Basically I want to control whatever animation I have made, not with wheel event but by using a scrollbar, controlling the div widths using scrollTop etc.
var leftDiv = document.querySelectorAll(".lcurtain");
var rightDiv = document.querySelectorAll(".rcurtain");
var locker = document.getElementById("locker");
document.addEventListener("wheel", change);
var per = 100;
var angle = 0;
function change(e) {
if (e.deltaY > 0 && per > 0) {
for (var i = 0; i < 4; i++) {
leftDiv[i].style.width = per - 1 + "%";
rightDiv[i].style.width = per - 1 + "%";
}
per -= 1;
} else if (e.deltaY < 0 && per < 100) {
for (var i = 0; i < 4; i++) {
leftDiv[i].style.width = per + 1 + "%";
rightDiv[i].style.width = per + 1 + "%";
}
per += 1;
}
}
html {
width: 100%;
height: 100%;
}
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
position: relative;
}
.lcurtain,
.rcurtain {
width: 100%;
height: 12.5%;
position: absolute;
}
#div1 {
top: 0;
left: 0;
background-color: blue;
}
#div2 {
top: 12.5%;
right: 0;
background-color: red;
}
#div3 {
top: 25%;
left: 0;
background-color: green;
}
#div4 {
top: 37.5%;
right: 0;
background-color: purple;
}
#div5 {
top: 50%;
left: 0;
background-color: orange;
}
#div6 {
top: 62.5%;
right: 0;
background-color: cyan;
}
#div7 {
top: 75%;
left: 0;
background-color: brown;
}
#div8 {
top: 87.5%;
right: 0;
background-color: pink;
}
<div id="div1" class="lcurtain"></div>
<div id="div2" class="rcurtain"></div>
<div id="div3" class="lcurtain"></div>
<div id="div4" class="rcurtain"></div>
<div id="div5" class="lcurtain"></div>
<div id="div6" class="rcurtain"></div>
<div id="div7" class="lcurtain"></div>
<div id="div8" class="rcurtain"></div>
<script src="script.js"></script>
Here's the solution using CSS vh units and scroll event handler.
When a scroll events is handled it calculates the relative current scroll position in percents:
100 - (scrollTop / (scrollHeight - clientHeight) * 100)
thus 100% means the very top scroll position, otherwise 0% means we're at the very bottom.
Reference: Cross-Browser Method to Determine Vertical Scroll Percentage in Javascript.
Then we just apply this calculated value to the divs style.width parameters.
var leftDiv = document.querySelectorAll(".lcurtain");
var rightDiv = document.querySelectorAll(".rcurtain");
document.addEventListener("scroll", change);
function change(e) {
var h = document.documentElement;
var b = document.body;
var st = 'scrollTop';
var sh = 'scrollHeight';
var percent = 100 - (h[st] || b[st] / ((h[sh] || b[sh]) - h.clientHeight) * 100) + "%";
for (var i = 0; i < 4; i++) {
leftDiv[i].style.width = percent;
rightDiv[i].style.width = percent;
}
}
html {
width: 100%;
height: 1000vh;
}
body {
width: 100%;
height: 100vh;
margin: 0;
padding: 0;
position: fixed;
}
.lcurtain,
.rcurtain {
width: 100%;
height: 12.5%;
position: absolute;
}
#div1 {
top: 0;
left: 0;
background-color: blue;
}
#div2 {
top: 12.5%;
right: 0;
background-color: red;
}
#div3 {
top: 25%;
left: 0;
background-color: green;
}
#div4 {
top: 37.5%;
right: 0;
background-color: purple;
}
#div5 {
top: 50%;
left: 0;
background-color: orange;
}
#div6 {
top: 62.5%;
right: 0;
background-color: cyan;
}
#div7 {
top: 75%;
left: 0;
background-color: brown;
}
#div8 {
top: 87.5%;
right: 0;
background-color: pink;
}
<div id="div1" class="lcurtain"></div>
<div id="div2" class="rcurtain"></div>
<div id="div3" class="lcurtain"></div>
<div id="div4" class="rcurtain"></div>
<div id="div5" class="lcurtain"></div>
<div id="div6" class="rcurtain"></div>
<div id="div7" class="lcurtain"></div>
<div id="div8" class="rcurtain"></div>
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>