1

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

2
  • can you show a mockup of what you are trying to acheive? It't not fully clear from the description exactly how you want this animation to work. How often does it update? Does both bar size and gradient change? how do they change? do the colors change? etc... Commented Oct 28, 2015 at 22:15
  • @TinMonkey Please see the video at the dropbox location. Thanks a lot. Commented Oct 28, 2015 at 22:20

2 Answers 2

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>

Sign up to request clarification or add additional context in comments.

4 Comments

This is amazing. It works beautifully in the browser and on plunker, using the ionic framework. Unfortunately It does not work properly from the mobile device. Its not smooth. I am trying to find out if this is related to my code or ionic. Here is the plunker: embed.plnkr.co/d6rC1e/preview
I can confirm that the code does not work on ionic. It works very nice from a browser though. Here is how it looks on the device: dropbox.com/s/6v4qhgets9ni3c8/animated-bar.mov?dl=0
Hmm not sure sorry, I have never used Ionic. Oh sorry I forgot to say make sure you add browser prefixes! This might be the issue.
Ok. I will try that. Going to mark your response as the answer, since it helped me to figure out the issue and is the easiest one to use.
0

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>

5 Comments

Thank you so much. Could I achieve the same without jquery?
I have not attempted javascript animations without a framework but since the frameworks themselves are written in javascript, then yes of course it is possible. Also.. after testing this more.. It looks like maybe the gradients don't animate well.. a solid color would do a fade transition well, which would give the same effect.
an image would have the same problem as a gradient I would assume.. it would just switch out rather than animate. could animate gradient with css using animate instead of transition though.
Updated to show solid color.. if you used a different color for each 20% jump or so it would still change according to strength and look pretty cool.
You could animate the gradient using background-position. Also using transform: scale() is probably better performance wise instead of height.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.