I found this code here: https://stackoverflow.com/a/29017677 .
This is fadeOut function. It's working
var s = document.getElementById('thing').style;
s.opacity = 1;
(function fade(){(s.opacity-=.1)<0?s.display="none":setTimeout(fade,100)})();
var s = document.getElementById('thing').style;
s.opacity = 1;
(function fade(){(s.opacity-=.1)<0?s.display="none":setTimeout(fade,100)})();
#thing {
background: red;
line-height: 40px;
}
<div id="thing">I will fade...</div>
now I am trying to write a function for fadeIn like the fadeOut function. But this function doesn't work. I do not understand why.
var s = document.getElementById('thing').style;
s.opacity = 0;
(function fade(){(s.opacity+=.1)>0.95?s.display="block":setTimeout(fade,100)})();
var s = document.getElementById('thing').style;
s.opacity = 0;
(function fade(){(s.opacity+=.1)>0.95?s.display="block":setTimeout(fade,100)})();
#thing {
background: red;
line-height: 40px;
}
<div id="thing">I will fade...</div>
The best solution for your case would be to use more CSS instead of JS, you can add the property transition to the #thing selector and then all you need to do is set the opacity via JS code(no need to add timeouts or any other form of complicated handling)
function hide() {
document.getElementById('thing').style.opacity = 0
}
function show() {
document.getElementById('thing').style.opacity = 1
}
#thing {
transition: .4s
}
<div id="thing">I am showing up</div>
<button onclick="hide()">hide</button>
<button onclick="show()">show</button>
The += is trying to append, so keep with -= and set your .1 to negative value as -0.1 and it will works.
var s = document.getElementById('thing').style;
s.opacity = 0;
(function fade() {
(s.opacity -= -0.1) < 1 && setTimeout(fade,100);
}
)();
#thing{
background: red;
line-height: 40px;
opacity: 0;
}
<div id="thing">I will fade...</div>
Complementing my answer with Chris G's comment:
The opacity is a string, so appending 0.1 works the first time: "0" + "0.1" is "00.1" which checks out. Then it's "0.1" + 0.1 which is "0.10.1" and gets parsed back into "0.1" - Chris G
Related
I have a simple animation code, looks like a console input.
Originally from: https://codepen.io/atunnecliffe/pen/BaZyLR
I modified the splash screen intro into just a console input in my website:
Code:
<script>
//console
var textarea = $('.term');
var text = 'ping life';
var i = 0;
runner();
function runner() {
textarea.append(text.charAt(i));
i++;
setTimeout(
function () {
runner();
}, Math.floor(Math.random() * 1000) + 50);
}
</script>
Now the effect that I want is a bit complex, for me at least, as my knowledge about JQuery is limited. I wanted the code to enter ping life, then backspace completely, repeat infinitely. I looked up on how to simulate backspace in JQuery, using escape sequence of (8), but I am not sure how to use the escape sequence, nor implement the function into the existing recursive function, for it to repeat infinitely.
Any help would be wonderful :)
Like this?
Counting like this will give a zigzag like counting pattern. I added buffers for start and end of input, and a fixed timeout for deleting letters.
textarea.text(text.substr(0, i)) selects a substring of your text (treated as an array of letters - selecting everything between index 0 and i)
Easier than appending and deleting letters
var direction = 1;
var i = 0;
var textarea = $('.term');
var text = 'ping life';
// NOTE:
// I added the "#dev:~$ " as css:before elem, easier to write the code
function count() {
i += direction;
direction *= (((i % text.length) == 0) ? -1 : 1);
textarea.text(text.substr(0, i));
clearInterval(time);
// direction is 1 if counting up
if (direction === 1) {
if (i === 0) {
// buffer for start
time = setInterval(count, 1000);
} else {
time = setInterval(count, Math.floor(Math.random() * 1000) + 50);
}
} else {
// direction is -1 if counting down
if (i === text.length) {
time = setInterval(count, 1500);
} else {
// buffer for end
time = setInterval(count, 100);
}
}
}
// inital interval
// setTimeout doesn't work well here
var time = setInterval(count, 1000)
html,
body {
margin: 0 auto;
height: 100%;
}
pre {
padding: 0;
margin: 0;
}
pre::before {
content: "#dev:~$ ";
color: white;
}
.load {
margin: 0 auto;
min-height: 100%;
width: 100%;
background: black;
}
.term {
font-family: monospace;
color: #fff;
opacity: 0.8;
font-size: 2em;
overflow-y: auto;
overflow-x: hidden;
padding-top: 10px;
padding-left: 20px;
}
.term:after {
content: "_";
opacity: 1;
animation: cursor 1s infinite;
}
#keyframes cursor {
0% {
opacity: 0;
}
40% {
opacity: 0;
}
50% {
opacity: 1;
}
90% {
opacity: 1;
}
100% {
opacity: 0;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="load">
<pre class="term"></pre>
</div>
I have a series of images I want to transition from 0 opacity to 1 opacity when they come into the view port. I have the viewport check part done and the adding classes, however I would like them to be on an interval, so once the first 3 images come into the view port they appear 1, 2, 3 every .5seconds or so. Instead of all 3 at the same time.
here's a JS fiddle of how it works currently
reveal();
function reveal() {
var reveal = document.querySelectorAll(".reveal");
window.onscroll = function() {
for(var i = 0; i < reveal.length; i++) {
if(checkVisible(reveal[i]) === true) {
reveal[i].classList.add("fade");
}
}
}
};
function checkVisible(elm) {
var rect = elm.getBoundingClientRect();
var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
return !(rect.bottom < 0 || rect.top - viewHeight >= -200);
}
https://jsfiddle.net/u04sy7jb/
I've modified your code to add a transition-delay of an additional .5 seconds for each element after the first one, in each "group" that is revealed as you scroll. I left comments in the JavaScript so you can understand the changes.
Let me know if you have any questions!
Live demo:
reveal();
function reveal() {
var reveal = document.querySelectorAll(".reveal");
window.onscroll = function() {
// start a new count each time user scrolls
count = 0;
for (var i = 0; i < reveal.length; i++) {
// also check here if the element has already been faded in
if (checkVisible(reveal[i]) && !reveal[i].classList.contains("fade")) {
// add .5 seconds to the transition for each
// additional element currently being revealed
reveal[i].style.transitionDelay = count * 500 + "ms";
reveal[i].classList.add("fade");
// increment count
count++;
}
}
}
};
function checkVisible(elm) {
var rect = elm.getBoundingClientRect();
var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
return !(rect.bottom < 0 || rect.top - viewHeight >= -200);
}
.container {
width: 100%;
height: 1200px;
background-color: orange;
}
.reveal {
display: inline-block;
width: 32%;
margin: 0 auto;
height: 400px;
background-color: pink;
border: 1px solid black;
opacity: 0;
}
.fade {
opacity: 1;
transition: 1s;
}
<div class="container">
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
</div>
You could be able to stick your reveal[i].classList.add("fade"); inside of a setTimeout that executes as a function of your ith element so they show up how you're describing. Here is an example of adding short function to add the class and using it in a setTimeout to make this happen, although you could change it up to meet any additional needs.
function reveal() {
var reveal = document.querySelectorAll(".reveal");
window.onscroll = function() {
for(var i = 0; i < reveal.length; i++) {
if(checkVisible(reveal[i]) === true) {
addMyFadeClass(reveal[i], i)
}
}
}
};
function addMyFadeClass(element, i) {
setTimeout(function() {
element.classList.add("fade");
}, i * 500)
}
You can also use :nth-child CSS selectors without the need to change the JS:
.reveal:nth-child(3n+1).fade {
opacity: 1;
transition: 1s;
}
.reveal:nth-child(3n+2).fade {
opacity: 1;
transition: 1.5s;
}
.reveal:nth-child(3n).fade {
opacity: 1;
transition: 2s;
}
JSFiddle: https://jsfiddle.net/u04sy7jb/8/
well its a fairly basic code for a slideshow in html using css and javascript.
this is the javascript part how can i add a fade in and fade out to this code without jquery
<script type="text/javascript">
var step = 0
var whichimage = 0
function slideit() {
if (!document.images)
return
document.getElementById('slide').src = slideimages[step].src
whichimage = step
if (step < 3)
step++
else
step = 0
setTimeout("slideit()", 5000)
}
slideit()
</script>
The simplest way would be to use CSS to animate element opacity:
var el = document.getElementById('e');
setInterval(function(){
el.className = el.className == '' ? 'show' : '';
}, 2000);
#e {display: inline-block; width: 50px; height: 50px; background: #afa; opacity: 0; transition: opacity 1s linear}
#e.show {opacity: 1}
<div id="e"></div>
In your case you'd have to set when the previous element fades out and when the new one fades in using setTimeouts. I could write you a more accurate code, but not without seeing the markup/the whole thing. This should be enough to get you started.
I am trying to implement a sliding progrees bar. I want the progress to gradually increase.
I try:
HTML
<div id="progressKeeper">
<div id="progress"></div>
</div>
CSS
#progressKeeper {
width: 800px;
height: 25px;
border: 3px double #003366;
margin: 0px 10px;
padding: 3px;
}
JavaScript
var el = $('#progress');
var steppedIncreaseAmount = ($('#progressKeeper').width()) / 100;
for (var i = 0; i < 100; i++) {
el.width(el.width() + steppedIncreaseAmount+ 'px');
}
See this jsfiddle
But it just increases suddenly. I want a smooth effect, like a fade.
You need to set some kind of delay between the update of these values. However, because it appears that you're using jQuery, you can easily do something like this:
$(document).ready(function() {
var el = $('#progress');
el.animate({
width: "100%"
}, 1800);
});
http://jsfiddle.net/VbVBP/2/
Another way, if you really want to keep the setup you've got going now, would be do just add a setTimeout counter to your for loop like this:
var el = $('#progress');
var steppedIncreaseAmount = ($('#progressKeeper').width()) / 100;
for (var i = 0; i < 100; i++) {
setTimeout(function(){
el.width(el.width() + steppedIncreaseAmount+ 'px');
}, 1+i*20);
}
http://jsfiddle.net/VbVBP/3/
A simple for-loop is updating the values way faster than your eye can catch up....
You can use a timer function like setInterval for basic JS animation. This would work like:
var increase = setInterval(function(){
el.width(el.width() + steppedIncreaseAmount+ 'px');
}, 50); //50 is the interval in ms, i.e the function inside the interval gets called 20 times per second
When you are done with the animation (progress is at 100%) you should cancel the interval:
clearInterval(increase);
See a working fiddle and MDN docs on setInterval
If you want to dig deeper into the realms of JavaScript animation you might also want to learn about requestAnimationFrame
Try using animation:
el.animate({ width: "+=" + steppedIncreaseAmount }, 500);
Oh, don't use javascript for this. You can do it with only CSS3 animations.
#-webkit-keyframes progress {
from { }
to { width: 100% }
}
And in progress bar:
-webkit-animation: progress 2s 1 forwards;
-moz-animation: progress 2s 1 forwards;
-ms-animation: progress 2s 1 forwards;
animation: progress 2s 1 forwards;
Working example: http://jsfiddle.net/VbVBP/4/
I set up a demo of what I could figure out. http://jsfiddle.net/VbVBP/5/
I set the time of update to 300ms and the speed of that update animation to 300 also so it is constantly animating.
Instead of using the random value you would use whatever percentage complete your operation is.
<div id="progressKeeper">
<div id="progress"></div>
</div>
var randomPercentInt = 0;
function percentComplete(percent) {
var el = $('#progress');
el.animate({
width: percent
}, 300);
}
$(document).ready(function() {
percentComplete('0%');
});
function randomPercent() {
var randomNumber = Math.floor(Math.random() * 10);
randomPercentInt += randomNumber;
console.log(randomPercentInt);
if(randomPercentInt>100)
{
randomPercentInt = 100;
clearInterval(clearme);
}
percentString = randomPercentInt.toString() + '%';
percentComplete(percentString);
}
clearme = setInterval(randomPercent, 300);
I am trying to generate a random number for the css opacity.
This is what I tried so far.
CSS
.test{
position : absolute;
width : 15px;
height : 15px;
border-radius:15px;
background-color : black;
}
Script
$(function() {
for (var i = 0; i < 300; i++) {
$("<div>", {
class: "test",
css: {
opacity: randomOpacity
}
}).appendTo("body");
}
function randomOpacity() {
var opac = 0;
opac = Math.random() < 1;
console.log(opac);
}
randomize();
});
The Fiddle
There are multiple errors with your fiddle:
You are spawning 300 divs that are all absolutely positioned. They stack on top of each other and so would appear black regardless.
You aren't actually calling the function (missing parentheses)
Math.random() < 1 is going to return True instead of a number.
You aren't returning opac from your function.
You were calling randomize(), which isn't defined.
Corrected version: http://jsfiddle.net/RucKd/1/
Math.random() already generates a random number between 0 and 1, so:
$(function() {
for (var i = 0; i < 100; i++) {
$("<div>", {
class: "test"
}).css('opacity', Math.random()).appendTo("body");
}
});
Fiddle
edit: Re-inserted your loop in my answer and removed absolute pos from the fiddle. Read #ChristopheBiocca (+1)'s answer for a more complete code review.
JS
$(function() {
for (var i = 0; i < 300; i++){
$("<div>", {
class : "test",
css : {
opacity : randomOpacity
}
}).appendTo("body");
}
function randomOpacity(){
var opac = 0;
opac = (Math.random());
return opac;
}
});
CSS
remove position : absolute;, with this css all your divs at the same place
.test{
width : 15px;
height : 15px;
border-radius:15px;
background-color : black;
}
The css functions alters a css attribute, Math.random() returns 0-1 so you can just drop it in. The following code alters the opac div's opacity.
<div id="opac">
lalalalala
</div>
<script>
$(document).ready(function(){
$("#opac").css('opacity', Math.random());
});
</script>
$(document).ready calls everything inside it once the page is loaded, good idea to use for things like this.
$('#foobar').css({ opacity: Math.random() });
Math.random() always returns a value between 0 and 1 and you can put it directly in the function that creates divs. Also, the position: absolute in your CSS places every div in the same place, so you are not able to see the result correctly. Try this:
CSS
.test{
width : 15px;
height : 15px;
border-radius:15px;
background-color : black;
}
JS
$(function() {
for (var i = 0; i < 300; i++) {
$("<div>", {
class: "test",
css: {
opacity: Math.random()
}
}).appendTo("body");
}
});
Anyway, the randomize() function is not defined.