Create animation with css gradient and javascript - javascript

I am working on an cordova application that allows us to scan rfid tags. Based of the RSSI signal strength I need to display a bar that shows how close or far the rfid tag is. The closer I get to the tag, the higher the bar and the further I go, the smaller the bar becomes. I built the following plunkr, which I thought I could use. Unfortunately the animation is not very smooth and its slow on the mobile application. I think the issue is that I am showing/hiding the divs with a timeout to simulate the animation. I think I may need to change this to use css animations with gradients. But I am not very familiar on how to do this and I have no idea how I would hide part of the gradient if say I want to show just a small part of the bar. Any suggestions on how to do this are greatly appreciated.
Update: I have uploaded a video of what I would like to achieve. Unfortunately I am not able to upload this to SO. The animation would change as I read the tags. So I could be moving the tag back and forth and based off that it should change the bar.
https://www.dropbox.com/s/9bd421fhqvt9v5g/gradient-bar-demo.mov?dl=0

For better performance it is best to animate scale rather than height. Source (really good article on animation performance).
Here is an example of how you could do it. It's not perfect but hopefully it should give you a good starting point.
var input = document.querySelector('input');
input.addEventListener('input', function() {
var value = this.value / 100;
var bar = document.querySelector('.meter-bar');
bar.style.transform = 'scaleY(' + value + ')';
// Adjust background size to account for the scale change, there is probably a better solution
bar.style.backgroundSize = '200px ' + (300 / value) + 'px';
});
input {
width: 200px;
}
.meter {
width: 200px;
height: 300px;
margin-top: 20px;
background-color: #e5e5e5;
}
.meter-bar {
width: 100%;
height: 100%;
background-color: #333;
background-image: linear-gradient(to top, #64b572 0%, #9fc63d 50%, #f63908 100%);
background-size: 200px 0;
background-position: bottom;
transform-origin: bottom;
transform: scaleY(0);
transition: transform 1s ease, background-size 1s ease;
opacity: 0.8;
}
<input type="range" min="0" max="100" step="1" value="0">
<div class="meter">
<div class="meter-bar">
</div>
</div>

You could animate the height with javascript and the gradient with css. I am updating here on mouse over but you could have it update with every scan input and accomplish the same thing. You would just need to set up more css classes for any other gradient variations you want.
var min = 15;
var max = 100
function randPercent(){
return Math.floor(Math.random()*(max-min+1)+min);
}
$( ".statusBar" ).mouseover(function(){
var barSize = randPercent();
if (barSize > 50) {
$(this).addClass('close');
} else {
$(this).removeClass('close');
}
$(this).animate({
height: barSize+'%'
},300
);
});
.wrapper {
height:100px;
position:relative;
}
.statusBar {
width:50px;
min-height:10px;
border:1px solid black;
position:absolute;
bottom:0;
}
.bg {
-webkit-transition: background 1s ;
-moz-transition: background 1s ;
-ms-transition: background 1s ;
-o-transition: background 1s ;
transition: background 1s ;
background: rgb(71,234,46);
}
.bg.close {
background: rgb(247,247,49);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="statusBar bg"></div>
</div>

Related

How to animate CSS transition effect via a scroll?

I have an element I want to "expand" and change the background color for a page background. As the user scrolls, a dot in the center will expand to fill the page with a new background color. I see examples of how to change the background but not how to "expand" it. I have attached a jsfiddle of the CSS animation effect I'm looking for. This example shows how it will look but only works on the hover. You can see what it's supposed to look like if you scroll the example and hover the white dot.1
Preferably I'd like to accomplish this with css animation but I'm not opposed to trying it out with javascript. I've been fiddling around with that here.
Second, I've been using a fake element to get the example but is there a way I can do this effect without needing the element and just using the container's background-color?
Here's the HTML of the example of the effect I'm trying to achieve.
<div class="container">
<span class="white"></span>
</div>
And here's the CSS:
.container {height:500px;width:100%;background:#ed565d;position:relative;}
.container span {display:block;}
.white {background:#ffffff;height:10px;width:10px;margin:auto;border-radius:100%;position:absolute;top:50%;left:50%;}
.container:hover .white {
width:300%;
height:300%;
-moz-transition: all 0.5s ease-out;
-o-transition: all 0.5s ease-out;
-webkit-transition: all 0.5s ease-out;
transition:all 0.5s ease-out;
top:-100%;
left:-100%;
}
If you want the animation to correlate directly to the percentage that the user has scrolled on the page, JavaScript will be needed.
First, get the scroll percentage. Here's a great answer on how to do that: https://stackoverflow.com/a/8028584/2957677
const scrollTop = $(window).scrollTop();
const documentHeight = $(document).height();
const windowHeight = $(window).height();
const scrollPercent = (scrollTop / (documentHeight - windowHeight)) * 100;
Then you can define an animation function that takes in the percent the user has scrolled, and will set the style on the circle to be a percentage between the CSS values at the start of the animation, and the CSS values at the end of the animation.
function growAnimation($element, animationPercentage) {
const animationDecimal = animationPercentage / 100;
// Your existing .grow CSS values
const startPositionPercent = 50; // top/left at start of animation
const finishSizePercent = 300; // width/height at end of animation
const finishPositionPercent = -100; // top/left at end of animation
// The current CSS values, based on how far the user has scrolled
const currentSizePercent = getProgressFromTo(0, finishSizePercent, animationDecimal);
const currentPositionPercent = getProgressFromTo(startPositionPercent, finishPositionPercent, animationDecimal);
$element.css({
width: `${currentSizePercent}%`,
height: `${currentSizePercent}%`,
top: `${currentPositionPercent}%`,
left: `${currentPositionPercent}%`
});
}
// A util function to get the progress between two values
// e.g. 50% between 0 and 10 is 5
function getProgressFromTo(from, to, animationDecimal) {
return from + (to - from) * animationDecimal;
}
Here's a fiddle: https://jsfiddle.net/owazk8y1
Animation Curves
You can look into animation curves to make the animation look a lot smoother. Surround animationDecimal in a bezier curve function. Here's some example functions:
https://gist.github.com/gre/1650294
https://jsfiddle.net/owazk8y1/1
It's a mix of different ideas that I have sinned here and there ...
with a small part JS, to be piloted in CSS
PS :transition command must be set on element
const storeScroll=()=>{
document.documentElement.dataset.scroll = window.scrollY;
}
window.onscroll=e=>{ // called when the window is scrolled.
storeScroll()
}
storeScroll() // first attempt
.container {
position : relative;
height : 500px;
width : 100%;
background : #ed565d;
overflow : hidden; /* added */
}
.white {
display : block;
position : absolute;
background : #fff;
height : 10px;
width : 10px;
margin : auto;
border-radius : 100%;
top : 50%;
left : 50%;
-moz-transition : all 0.5s ease-out;
-o-transition : all 0.5s ease-out;
-webkit-transition : all 0.5s ease-out;
transition : all 0.5s ease-out;
}
html:not([data-scroll='0']) .white {
width : 300%;
height : 300%;
top : -100%;
left : -100%;
}
<div class="container">
<span class="white"></span>
</div>

CSS position transition not working at all when set with JavaScript

I want to do the following things:
show a div element;
move it to a an initial position;
set transition properties;
move it to the target position using CSS transition.
A minimal example:
function bla() {
/*
var obj = $('#box');
obj.css("left", "200px");
obj.css("display", "initial");
obj.addClass("trans");
obj.css("left", "500px");
*/
var elem = document.getElementById('box');
elem.style.left = "200px";
elem.style.display = "initial";
elem.className = "box trans";
elem.style.left = "500px";
}
#btn {
position: fixed;
top: 60px;
left: 0px;
width: 50px;
height: 50px;
background-color: #FEDCBA;
}
.box {
display: none;
position: fixed;
top: 0px;
left: 0px;
width: 50px;
height: 50px;
background-color: #ABCDEF;
}
.box.trans {
-webkit-transition: left 2s;
-moz-transition: left 2s;
transition: left 2s;
}
<div id="box" class="box"></div>
<div id="btn" onclick="bla()">click here</div>
JSFiddle.
It does not work at all. What is wrong?
If I set the element initially visible, I get a smooth transition starting from the origin left:0 which is totally strange because I assign elem.style.left = "200px"; before I actually add the transition properties...
You should avoid using style in javascript, just switch class years put all your animation in your css file.
You can't put transition together with display: none;, you have to use opacity: 0; instead.
function bla()
{
var obj = $('#box');
obj.toggleClass("trans");
}
#btn
{
position:fixed;
top:60px;
left:0px;
width:50px;
height:50px;
background-color:#FEDCBA;
}
.box
{
opacity: 0;
position:fixed;
top:0px;
left:0px;
width:50px;
height:50px;
background-color:#ABCDEF;
-webkit-transition: transform 2s,opacity 2s;
transition: transform 2s,opacity 2s;
}
.box.trans
{
opacity: 1;
-ms-transform: translate(500px,0); /* IE 9 */
-webkit-transform: translate(500px,0); /* Safari */
transform: translate(500px,0);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="box" class="box">
</div>
<div id="btn" onclick="bla()">
click here
</div>
DOM changes don't take effect until they can be rendered. Javascript is single-threaded (meaning you cannot run two pieces of code simultaneously), and run on the same thread as the render cycle.
Because of this, the renderer cannot fire unless you give it time to look at the new state of the DOM by deferring execution of your JS code (using setTimeout or requestAnimationFrame). So unless you give the browser time to render, only the final value before the renderer gets to look at the DOM is what matters.
This answer to a previous question goes over the exceptions to the rule.
Here's an updated version of your jsfidde that uses requestAnimationFrame to get around the issue.
I can not explain why. Maybe someone could, I'd be curious too, but with a time-out works.
setTimeout(function(){
elem.style.left = "500px";
},1);
It is probably too fast assigning properties left 500 and the transition to record the old location 200?
https://jsfiddle.net/StepBaro/s82rj48q/2/
It's because you have the div hidden, so it first need to display it and then add the transition, that is why it needs the delay.

Fade effect attribute/function in javascript custom script?

I need to add a fade effect on my javascript function
Javascript
<script type="text/javascript">
window.onload=function() {
loginBtn = document.getElementById('loginBtn');
fader = document.getElementById('login_fader');
login_box = document.getElementById('login_box');
closebtn = document.getElementById('closelogin');
loginBtn.onclick=function(){
fader.style.display = "block";
login_box.style.display = "block";
}
closebtn.onclick=function() {
fader.style.display = "none";
login_box.style.display = "none";
}
}
</script>
HTML
<div id="login_fader"> </div>
<div id="login_box">
<table class="table-login">
<th>Login or Register</th>
<th><a id="closelogin">X</a></th>
<tr>
<td>Login</td>
<td>Register</td>
</tr>
</table>
</div>
CSS
<style type="text/css">
#loginBtn {
float: right;
margin-top: -6%;
cursor:pointer;
}
#login_fader {
background: black;
opacity: .5;
-moz-opacity: .5;
-filter: alpha(opacity=50);
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
z-index: 5;
display: none;
}
#login_box {
width: 320px;
height: 200px;
border: 1px white solid:
background: #5a5a5a;
position: fixed;
top: 25%;
left: 35%;
z-index: 10;
display: none;
}
.table-login {
background: #FFF;
border-radius: 8px;
box-shadow: 0 0 5px 2px;
opacity: 0.95;
}
#closelogin {
float:right;
cursor:pointer;
}
</style>
Js fiddle
http://jsfiddle.net/U3n4j/
I have tried using the transition properties from css3 and tried applying both to login_box and login_fader.
I found some functions on the net but don't know how to link them to my already made function and i was thinking if there are any properties directly that i can link them to my function.
Proper way to fade in a static box in css3 and js 1.7 ++
This is a example using only webkit and modern javascripts classList.add
but you can add the other prefixes.-moz,-ms,-o
in this example i show only the animation.
css
.box{
width:100%;
height:100%;
position:fixed;
left:0;top:-100%;/*notice TOP -100%*/
opacity:0;
-webkit-transition:opacity 700ms ease,top 0 linear 700ms;/*notice TOP delay*/
background-color:rgba(0,0,0,0.7);
}
.box.active{
-webkit-transition:opacity 700ms ease,top 0 linear 0;
/*top transition not needed but could help to understand*/
top:0;
opacity:1;
}
js
function show(){
box.classList.add('active');
}
function hide(){
box.classList.remove('active');
}
var box=document.getElementsByClassName('box')[0],
button=document.getElementsByTagName('button')[0];
button.addEventListener('click',show,false);
box.addEventListener('click',hide,false);
DEMO
http://jsfiddle.net/RAu8Q/ not working anymore
http://jsfiddle.net/RAu8Q/17/ new syntax 10-2015
if you have any questions just ask.
I can't tell exactly what effect you're trying to achieve, but if you're going to use CSS transitions, then you need to be transitioning between numerical properties. I.e., you can't expect a fade to occur simply by transitioning from display:block to display:none. You'd want to use opacity instead.
First of all, don't try to use css transitions in conjunction with display property, that won't work! Instead, try transitioning other properties. Let's take opacity for instance (we'll simulate display: none/block functionality by setting opacity to 0/1)
Secondly, set the start value for opacity to 0 on the desired HTML element (the one you'd like to animate). Specify which property to animate (opacity in our case):
transition: opacity 1s;
-moz-transition: opacity 1s;
-webkit-transtion: opacity 1s;
When the login button is clicked, set opacity to 1:
loginBtn.onclick=function() {
fader.style.opacity = 1;
login_box.style.opacity = 1;
}
When the close button is clicked, set opacity back to 0:
closebtn.onclick=function() {
fader.style.opacity = 0;
login_box.style.opacity = 0;
}
Link to fiddle.
I believe that what you want to do needs css animations. So just create an animation class that fades out the target element and apply it after the user logs in.
#keyframes fadeOut {
from: {
opacity:1;
},
to: {
opacity:0;
}
}
then use apply it on the class
.fadeOut {
animation:fadeOut 0.25s forwards;
}
EXAMPLE
http://jsfiddle.net/zgPrc/

Swiping effect on background Images

Hi I would like to reproduce a sort a slider effect between background images like the website http://www.moveline.com/ does on the home page.
Example section bellow the title: "Mapping out the details for your next move".
I look at the code they use jQuery, RequireJS (2.1.4)
I try to isolate the code that is producing that effect but the JavaScript code has been compressed which make it really hard to understand (plus they use backbone).
Any idea how i could reproduce this nicely probably in jQuery with the help of some plugin?
Thank you
Here's a working fiddle for almost what they're doing on their site http://jsfiddle.net/y29kR/2/
Html:
<div class="items">
<div class="menu-item" data-look-at="0 0">item1</div>
<div class="menu-item" data-look-at="-40px -70px">item2</div>
<div class="menu-item" data-look-at="-120px -30px">item3</div>
</div>
<div class="menu-content"></div>
CSS with css transitions on background-position
.items {
float:left;
}
.menu-item {
padding: 15px;
color: #333;
border-bottom: 1px solid #ccc;
width: 70px;
}
.menu-content {
height: 150px;
width: 150px;
background-repeat: no-repeat;
background-image: url("http://placehold.it/350x350");
background-position: center center;
float:left;
-webkit-transition: background-position 600ms ease;
-moz-transition: background-position 600ms ease;
-o-transition: background-position 600ms ease;
}
I'm using jQuery's .css method to detect hover event to produce the (almost) desired effect:
jQuery(document).ready(function() {
$('.menu-item').hover(function(e) {
var target = $(e.target),
newPos = target.data("look-at");
$('.menu-content').css({'background-position': newPos});
});
$('.items').mouseleave(function(e) {
$('.menu-content').css({'background-position': 'center center'});
});
});

How to change the text of a table cell while hovering using only CSS3

I was wondering if anyone in SO would be kind enough to assist me. Using only CSS (most-likely CSS3), is there a way to change the inner HTML of a table cell while hovering over the element? I have a numerical table with 49 cells (7 rows by 7 columns), and I would like the number in the first cell of the first row to change from number 1 to number 50, but only when hovering over the number 1 (i.e. - changing back to number 1 when not hovering).
I can do this with a "change innerHTML" function in JavaScript, but only when using a portion of the script inline with my HTML within the body of the document. For various reasons, I cannot use any script or CSS inline, so this method of achieving my goal is not what I want to use (this goes beyond semantic reasons). I would really rather avoid using any script at all for this effect because I think CSS3 handles effects more elegantly and selectively than JavaScript (i.e. - CSS3 Tooltips are much nicer than any script-based Tooltip).
I was just wondering if someone knew how to do this using CSS3 (maybe with the z-index, display: none; or positioning techniques somehow?}. I've played around with it, but I can't seem to figure it out. I would use JavaScript if I didn't have to mix the script in with my Markup, but there doesn't appear to be a way to do that.
Anyone have ideas on how to go about this? Thank you for your time.
Update
#ramsesoriginal
#hiphip
Thanks again. I answered "Yes" to the "Did this answer help you." I believe that is what you meant by "as accepted" ramsesoriginal; right? Thanks hiphip for your answer as well. I was playing around with styles like the code below, but it wasn't quite working out in the table cell the way I had hoped (works nice with isolated images by the way). I think I'll keep working on it though; the more options, the better.
div.up {
margin: 10px 0;
position: relative;
width: 40px;
height: 40px;
border: 1px solid rgb(170, 169, 169);
overflow: hidden;
}
div.up div {
width: 40px;
height: 40px;
font-size: 13px;
padding: 10px;
position: absolute;
top: 0;
left: 0;
text-align: center;
background: rgba(255, 255, 255, 1.000);
-moz-transition: left 1s linear;
-webkit-transition: left 1s linear;
-o-transition: left 1s linear;
transition: left 1s linear;
}
div.up div.one {
z-index: 999;
}
div.up:hover div.one {
-webkit-transition: left 1s linear;
-moz-transition: left 1s linear;
-o-transition: left 1s linear;
transition: left 1s linear;
left: -99px;
}
There are two ways, but both require some additional markup:
<td id="example1" class="hoverer"><span class="nohower">1</span><span class="hover">50</span></td>
with the styling
#example1 .hover{
display:none;
}
#example1 .nohower{
display:block;
}
#example1:hover .hover{
display:block;
}
#example1:hover .nohower{
display:none;
}
or
<td id="example2" class="hoverer"><span data-hover="50">1</span></td>
with the styling
#example2:hover span:after{
content:attr(data-hover);
}
#example2:hover span{
width:1px;
margin-left: -0.5em;/* adjust accoridng to font*/
}
You can view a working demo here: http://jsfiddle.net/ramsesoriginal/W8LQq/
This is not possible.
CSS is only used for styling HTML. It has no access to the attributes of the HTML itself.
No way to do this with only CSS
With positioning:
<style>
#outterdiv {
position: relative;
width:20px;
height:20px;
overflow:hidden;
border: 1px blue solid;
}
#innerdiv:hover {
width:20px;
height:20px;
position: absolute;
top: -20px;
}
</style>
<div id="outterdiv">
<div id="innerdiv">
<div>1</div>
<div>50</div>
</div>
</div>

Categories

Resources