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

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/

Related

web animations api, resetting 1st animation at end of chain

I'm experimenting with the web animations API for the first time, and trying to chain some values together. I'm a little confused as for this simple animation, where it will translate 200px along the X axis, then 200px down along the Y axis once the first animation is complete.
However, at the end of the animation, it resets the X value of the initial animation. I've tried playing around with 'both' | 'forwards' for the fill mode property, as well as setting translateX to 0/200 in the second transform declaration. Feel like I'm missing something quite simple here.
const box = document.getElementById('box');
const animateRight = box.animate(
[{ transform: 'translateX(0)' }, { transform: 'translateX(200px)' }],
{
fill: 'forwards',
easing: 'ease-in-out',
duration: 2000,
}
);
animateRight.finished.then(() => {
box.animate([{ transform: 'translateY(0)' }, { transform: 'translateY(100px)' }], {
composite: 'add',
fill: 'both',
duration: 1500,
});
});
#box {
width: 100px;
height: 100px;
border: 1px solid black;
}
<div id="box"></div>

How to make that animation passed linearly? without slowing down at the start and the finish?

I need to get a picture crawling smoothly without slowing down at the start and finish.
setInterval(function runIt() {
$(".bffffg").animate({
backgroundPositionX: 300
}, 8000);
$(".bffffg").animate({
backgroundPositionX: 0
}, 0);
}, 1);
.bffffg {
display: block;
position: absolute;
width: 100%;
height: 100%;
background: url(http://www.dejurka.ru/wp-content/uploads/2015/06/watercolor-patterns4.jpg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<div class="bffffg"></div>
How to apply a linear effect to the animation?
And even apply different effects to it?
If you are looking for setting easing parameter, you may pass it as a separate argument like here:
$('your-selector').animate({
'your-property': 'value'
}, 8000, 'linear');
...or with options object like here:
$('your-selector').animate({
'your-property': 'value'
}, {
duration: 8000,
easing: 'linear'
});
Here is DOC for jQuery .animate() :)

if background = url() - issue on IE

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(); }

jQuery: Image fading to another image

I have the following code in jQuery:
if (klick = true) $(this).fadeOut('fast', function(){
$(this).attr("src", "../img/daniel_effects.png").fadeIn();
});
The changing of the image now works so:
- Image1 fade-out
- No image is displayed
- Image2 fade-in
How can I fix this, that the images fading together, without a lil time with no image between them?
Here's the site where you can see what I mean:
http://anthraxbeats.com/pages/biography.html
When you're hovering on a image, theres a short empty space before the image loads in.
How can I fix it?
Use two different images. Have them cover the same space by setting their css properties "position: absolute". Fade the first one out while setting the other one to false. You may need a proper container with position: relative as position: absolute may cause them to behave...unexpectedly.
#container{
position: relative;
width: 100px;
height: 100px;
}
.img1, .img2{
position: absolute;
width: 100%;
}
Adding [queue: false] to the animation will allow for multiple animations at the same time
var $theOtherThing = $(this).attr("src", "../img/daniel_effects.png");
if(klick === true){
$(this).animate({
"opacity": "0"
}, {
duration: 200,
queue: false
});
$theOtherThing.animate({
"opacity": "1"
}, {
duration: 200,
queue: false
});
You can try preloading your image outside of the click handler. Something like this should work:
(new Image()).src = "../img/daniel_effects.png";

First anchored link after page load requires two clicks

The page I'm designing has a fixed position bar at the bottom for references, which starts on page load with a height of zero, but can be expanded up via clicking a div positioned directly on top of it. As well, the individual references are anchors to links up in the content block, and I'm using the scrollTo and localScroll jQuery plugins for navigation - if an anchored link is clicked while the reference bar is expanded, it will localScroll to it, if the bar is reduced, it will scroll to it, then call the expansion animation. The first part of the script handling all of this works great - the reference bar opens on a click to the positioned div just fine - but the first anchored link clicked after page load, whether the reference bar is closed or open, requires two clicks, not one, to do anything. Here's the script:
$(document).ready(function() {
$("#reftag").css('bottom', '0px');
$("#refblock").css('height','opx');
$("refblock").scrollTo($("#refblock h4"),0);
$("#reftag").click(
function(){
var offset = $("#refblock").offset();
if(($(document).scrollTop()+$(window).height() - offset.top) > 100)
{
$("#reftag").animate({bottom: "0px"}, {queue:false, duration: 1700, easing: 'easeOutBounce'})
$("#refblock").animate({height:"0px"},{queue:false, duration: 1700, easing: 'easeOutBounce'})
$("#refblock").scrollTo($("#refblock h4"),0);
}
else
{
$("#reftag").animate({bottom: "200px"}, {queue:false, duration: 1700, easing: 'easeOutBounce'})
$("#refblock").animate({height:"200px"},{queue:false, duration: 1700, easing: 'easeOutBounce'})
}
return false;
});
$("a.ref").click(
function () {
var offset = $("#refblock").offset();
if(($(document).scrollTop()+$(window).height() - offset.top) > 100)
{
$('#textblock').localScroll({target:'#refblock'});
}
else{
$('#textblock').localScroll({target:'#refblock',onAfter:function(){
$("#reftag").animate({bottom: "200px"}, {queue:false, duration: 1700, easing: 'easeOutBounce'})
$("#refblock").animate({height:"200px"}, {queue:false, duration: 1700, easing: 'easeOutBounce'})
}});
}
return false;
});
});
And here's the CSS for the refblock (in case it's of any value):
#refblock{
width: 100%;
height: 0px;
position: fixed;
bottom: 0px;
padding: 3px 20px 3px 0px;
background: rgb(194,1,92);
margin-left: 0%;
margin-right: auto;
text-align:center;
z-index: 100;
overflow: auto;
}
Any ideas? Is it a problem with the script, or something else? I'll post a link to the site when it goes live, if there's anything else that'd be useful for an answer let me know.
Try to prevent default action triggered by click on a.ref link:
$("a.ref").click(function (e) {
e.preventDefault();
}

Categories

Resources