if background = url() - issue on IE - javascript

I am trying to achieve a situation where an animation is triggered if an element has a particular background = url(" "). I am using velocity.js as the animation plugin and am able to achieve this no problem on all browser except IE, in which it fails to recognise the background url in the if statement.
I have two examples in the code below.
The first one (the orange square) uses -
if (box.style.background == "orange")
{ run(); }
to determine whether to run the animation. IE is fine with this.
However the second (the pink triangle) uses -
if (triangle.style.background == "url(http://garyvoss.co.uk/images/triangle.svg) no-repeat")
{ runTriangle(); }
to determine whether to run the animation. IE is the only browser not to run this.
Does anyone have any idea where I'm going wrong here.
JS Fiddle example
HTML
<div id="box"></div>
<div id="triangle"></div>
CSS
#box {
width: 100px;
height: 100px;
position: absolute; }
#triangle {
width: 200px;
height: 100px;
top: 120px;
position: absolute;
z-index: 4; }
JS
window.setInterval(function runAll() {
var box = document.getElementById('box');
box.style.background = "orange";
function run() {
Velocity(box, {left: 300}, {easing: "easeInOutQuad", duration: 1000, delay: 0});
Velocity(box, {left: 10}, {easing: "easeInOutQuad", duration: 1000, delay: 0});
}
if (box.style.background == "orange")
{ run(); }
var triangle = document.getElementById('triangle');
triangle.style.background = "url(http://garyvoss.co.uk/images/triangle.svg) no-repeat";
function runTriangle() {
Velocity(triangle, {left: 300}, {easing: "easeInOutQuad", duration: 1000, delay: 200});
Velocity(triangle, {left: 10}, {easing: "easeInOutQuad", duration: 1000, delay: 0});
}
if (triangle.style.background == "url(http://garyvoss.co.uk/images/triangle.svg) no-repeat")
{ runTriangle(); }
}, 1000);
runAll();

The URLs in IE are different from webkit and/or Gecko, it is not safe to base your logic on the url paths.
if (triangle.style.background == "url(http://garyvoss.co.uk/images/triangle.svg) no-repeat" || triangle.style.background == 'url("http://garyvoss.co.uk/images/triangle.svg") no-repeat' )
{ runTriangle(); }

I've managed to find a convoluted way around the issue.
Using .match I can identify a section of the url path and apply that to the if statement so that if that section is present then the animation runs.
I've create a third example (the green circle) in this JS Fiddle that shows how it works.
var str = circle.style.background;
var res = str.match(/circle/g);
document.getElementById("check").innerHTML = res;
if (document.getElementById("check").innerHTML === "circle")
{ runCircle(); }

Related

Animating object coming in from side of screen and then back?

I'm using anime.js to animate several divs from the right side of the screen to where they are defined by the CSS styling. I'm also creating a function to do the reverse, but I'm having several issues.
I understand how to animate an object from it's location to a destination by changing translateX, but I can't figure out how to animate moving to it's original location, like with GSAP.from(). I've tried doing this to set the div off the screen while not visible so I could move them back to the original location, but instead it seems to ignore the negative value and just continues moving in one direction.
showAnswerButtons.set(answer_button_array, {translateX: offset_num})
showAnswerButtons.add({
targets: answer_button_array,
translateX: negative_offset_num,
translateY: negative_offset_num,
duration: 5000,
delay: anime.stagger(200)
});
As an alternative to the last approach, I've also tried playing an animation to move the divs off the screen, so I could reverse the animation to bring them back. I have 4 divs to animate and sometimes I need to take some of them out of the DOM (Or at least make them invisible). So my plan was to animate them off the screen, change the visibility as needed, then bring back only the ones that I want. Unfortunately using timeline.reverse() doesn't do anything and I've read several stories of people with similar issues. I've also tried setting direction: 'reverse' and then timeline.play() with no success.
Could anyone help me with this code please?
<div id="container">
<button id="answer_button_1" class="button"></button>
<button id="answer_button_2" class="button"></button>
<button id="answer_button_3" class="button"></button>
<button id="answer_button_4" class="button"></button>
</div>
.button {
display: flex;
position: relative;
top: 200px;
left: 100px;
height: 50px;
width: 400px;
background-color: black; /*Button Color*/
color: #f5f5f5;
}
#container {
position: absolute;
right: 50%;
left: 50%;
}
var hideAnswerButtons;
var showAnswerButtons;
let hidden = true;
document.addEventListener("click", () => {
hidden = !hidden;
if (hidden) {
showAnswerButtons.play();
} else {
hideAnswerButtons.play();
}
});
defineAnimations();
function defineAnimations() {
let offset_num = 1000;
let negative_offset_num = -100;
let answer_button_array = [
answer_button_4,
answer_button_3,
answer_button_2,
answer_button_1
];
hideAnswerButtons = anime.timeline({ autoplay: false });
hideAnswerButtons.add({
targets: answer_button_array,
translateX: offset_num,
translateY: offset_num,
duration: 5000,
delay: anime.stagger(200),
easing: 'linear'
});
showAnswerButtons = anime.timeline({ autoplay: false });
//showAnswerButtons.add({
//targets: answer_button_array,
//translateX: offset_num,
//translateY: offset_num,
//duration: 0,
//easing: "linear"
//});
showAnswerButtons.set(answer_button_array, {translateX: offset_num})
showAnswerButtons.add({
targets: answer_button_array,
translateX: negative_offset_num,
translateY: negative_offset_num,
duration: 5000,
delay: anime.stagger(200),
easing: 'linear'
});
}
If you want to reverse the animation and bring the div to its orginal place you can just use "direction: 'alternate'". Theres more about it in the anime.js documentation:
https://animejs.com/documentation/

How to increment the progress in javascript progress bar?

I am trying to add a simple javascript progress bar to my website, I found a few scripts, but I always encounter the same problem - I am able to intialize the loader and set it to increment to a given value, but cannot do it in steps. Here is a simple example - https://jsfiddle.net/kimmobrunfeldt/k5v2d0rr/
At the end there is:
bar.animate(1.0);
How can i have it animated in steps? Lets say first to 50% then (after 2 secs) to 75% and then 100%. I've tried
bar.animate(0.5);
bar.animate(0.75);
bar.animate(1);
as well as:
setTimeout(function(){bar.animate(0.5)}, 2000);
setTimeout(function(){bar.animate(0.75)}, 2000);
setTimeout(function(){bar.animate(1)}, 2000);
but it always chooses the last (highest) value, instead of being animated in steps. Any advice appreicated.
bar.animate(0.5);
bar.animate(0.75);
bar.animate(1);
The above code runs simultaneously, and the last one overrides the others.
setTimeout(function(){bar.animate(0.5); console.log("animate")}, 2000);
console.log('timeout 1 called');
setTimeout(function(){bar.animate(0.75); console.log("animate")}, 2000);
console.log('timeout 2 called');
setTimeout(function(){bar.animate(1); console.log("animate")}, 2000);
console.log('timeout 3 called');
Soon as the first timeout is set, it doesn't wait for the delay before setting the next. Check the logs on the console to see what happens.
The problem is that those scripts run simultaneously. Do something like this (or something better):
bar.animate(0.5); // Number from 0.0 to 1.0
setTimeout(function () {
bar.animate(0.75);
}, 2000);
setTimeout(function () {
bar.animate(1.0);
}, 4000);
If you wanted to just animate the bar in sequences for the sake of it, you can do keyframes with CSS too.
The problem is that you're, essentially, queuing up all of your steps to happen simultaneously. Instead, you want to pass a callback to the animate function so when it finishes, you can tell it to move to the next step.
// progressbar.js#1.0.0 version is used
// Docs: http://progressbarjs.readthedocs.org/en/1.0.0/
var bar = new ProgressBar.Line(container, {
strokeWidth: 4,
easing: 'easeInOut',
duration: 1400,
color: '#FFEA82',
trailColor: '#eee',
trailWidth: 1,
svgStyle: {
width: '100%',
height: '100%'
},
text: {
style: {
// Text color.
// Default: same as stroke color (options.color)
color: '#999',
position: 'absolute',
right: '0',
top: '30px',
padding: 0,
margin: 0,
transform: null
},
autoStyleContainer: false
},
from: {
color: '#FFEA82'
},
to: {
color: '#ED6A5A'
},
step: (state, bar) => {
bar.setText(Math.round(bar.value() * 100) + ' %');
}
});
// Keep track of the current value
var value = 0;
setTimeout(function increment() {
value += 0.1;
bar.animate(value, function() {
// Animation has completed, queue up another step
if (value < 1) {
setTimeout(increment, 500);
}
});
}, 1000);
#container {
margin: 20px;
width: 400px;
height: 8px;
position: relative;
}
<script src="https://rawgit.com/kimmobrunfeldt/progressbar.js/1.0.0/dist/progressbar.js"></script>
<div id="container"></div>

jQuery animating issues?

So far, I have a pretty decent code to animate a center box. For some reason, when I preview this on different browsers and computer (Mac and PC) I get different results. One may show a faster animation speed, while the other is perfect. I have also noticed that when the box is being animated from left to right, there is a stutter, and the animation jerks. I can't really explain it more than that. My code is below:
$(document).ready(function(){
isAnimating = false;
$('.wrapper').on('click', '.arrow-left', function() {
if(isAnimating) return;
isAnimating = true;
var $current = $(this).parents('.signupBox');
var $next = $(this).parents('.signupBox').next();
$current.stop(true,true).animate({
left: "200%"
}, 500, 'linear', function() {
$current.css({
left: "-200%"
}).appendTo('.wrapper'); // move to end of stack
$next.css({
left: "-200%"
}).stop(true,true).animate({
left: "0%"
}, 500, 'linear', function() {
isAnimating = false;
});
});
}).on('click', '.arrow-right', function() {
if(isAnimating) return;
isAnimating = true;
var $current = $(this).parents('.signupBox');
var $next = $(this).parents('.signupBox').siblings().last();
$current.stop(true,true).animate({
left: "-200%"
}, 500, 'linear', function() {
$current.css({
left: "200%"
});
$next.prependTo('.wrapper') // move to front of stack
.css({
left: "200%"
}).stop(true,true).animate({
left: "0%"
}, 500, 'linear', function() {
isAnimating = false;
});
});
});
});
Some CSS:
.signupBox:first-child {
display: block;
}
.signupBox {
display: none;
}
.wrapper
{
overflow: hidden;
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
position: absolute;
}
Here's a JSFiddle showing what happens, hopefully you can see what's the issue from there.
Then animation from right to left (click on the < symbol and you will see a slign change in speed.
Different browsers could have different results when using JS and css transitions, it actually depends on your machine speed, browser speed as well. It could depend on how many opened tabs you have in each browser, browsers plugins could freeze animations as well. Other JS events as well.
I have tested your code in Chrome, FF (wasn't able to check it in IE11, it seems there are JS errors on jsfiddler using jQuery). Didn't mentioned something strange.
I could recommend to use Greenshock JS animating library. http://www.greensock.com/get-started-js/
They say it's x20 times faster jQuery animate. But i think actually may be in 2,3 )
That libruary is based on Flash library that was used by Action Script coders to create beauty animations in Flash.

jquery animate jerky - is there a better library for scaling images?

I noticed whenever I use jquery animate with long time and small change animation becomes incredibly jerky! The only way to fix this seems to decrease time considerably and scale more. But in some projects this is not possible...
I looked into css transitions. And it didn't provide better results. Animation itself was better, but firefox was horridly jerky and in chrome animation finishes were not quite there with smoothness.
So my question is this, is there any other library with animation engine that can provide smooth scaling of images? or is there a technique that I'm missing?
This is my animation:
$('.item a').mouseover(function(){
//
var this_img = $(this).find('.img_grayscale');
var css_w = parseInt(this_img.attr("width"), 10);
var css_h = parseInt(this_img.attr("height"), 10);
// 10% of height and width calc here
var css_p_w = css_w * 10 / 100;
var css_p_h = css_h * 10 / 100;
//
var css_top = -(css_p_h / 2);
var css_left = -(css_p_w / 2);
//
this_img.stop().animate({ opacity:1 }, 100, function(){
this_img.animate({width:css_w + css_p_w, height:css_h + css_p_h, top:css_top, left:css_left}, 1200, "linear");
});
//this_img.transitionStop().transition({ opacity:1 }, 100, function(){
// this_img.transition({ scale:1.05, rotate:0.02 }, 2500, "ease");
//});
//
}).mouseout(function(){
//
var this_img = $(this).find('.img_grayscale');
var css_w = parseInt(this_img.attr("width"), 10);
var css_h = parseInt(this_img.attr("height"), 10);
//
this_img.stop().animate({ width:css_w, height:css_h, top:"0", left:"0" }, 1200, "linear", function(){
this_img.animate({ opacity:0 }, 100);
});
//this_img.transitionStop().transition({ scale:1 }, 2500, "ease", function(){
// this_img.transition({ opacity:0, rotate:0.02 }, 100)
//});
//
});
Commented out parts are jquery.transit plugin tests, this plugin provides css3 transitions.
Live example: http://mac.idev.ge:800/test/ (hover images)
Why don't you use simple CSS transitions, here's a demo.
<img src="some-image.jpg" />
CSS
img {
width: 400px;
height: 300px;
position: absolute;
top: 100px;
left: 100px;
transition: all 0.2s linear;
}
img:hover {
width: 440px;
height: 330px;
top: 85px;
left: 80px;
}
To get the smoothest look and best performance I would definately recommend using css scale transform.
There's some gotchas to be aware of though. It seems some browsers try to be clever and optimizes transforms which only results in a size change in the image. The trick is to also apply a small rotation:
-webkit-transform: scale(1.2, 1.2) rotate(0.1deg);
transform: scale(1.2, 1.2) rotate(0.1deg);
Here's a demo: http://jsfiddle.net/g2Qrv/
It scales smoothly in Chrome, FF, IE10, Opera and Safari on iOS.

jQuery: animate to height of div

I have this function:
function fixedFeeSize(i){
var num1 = $('#num' + i);
if (num1.hasClass("extended")) {
num1.stop(true, true).animate({height: '59px'},500);
num1.removeClass("extended");
}else{
var height = 0;
num1.animate({height: '360px'},500);
num1.addClass("extended");
}
return null;
}
Which expands / contracts a div, however I am struggling to get it to expand to the height of the div as each div (there will be 10+) is going to be different heights.
I tried num1.animate({height: 'auto'},500); which has not worked.
Is this the effect you're after?
jQuery(".menu a").mouseenter(function(){
jQuery(this).stop().animate({
height: 200, opacity: 0.5
}, 1000, "linear");
});
jQuery(".menu a").mouseleave(function(){
jQuery(this).stop().animate({
height: 18, opacity: 1
}, 1000, "linear");
});
Here's a jsfiddle:
http://jsfiddle.net/kKAZx/1/
For further reading, take a look at the full documentation of the .animate function: http://api.jquery.com/animate/
You can combine effects to make all kinds of fantastic, standard-compliant effects.

Categories

Resources