Use heavy (more that 400kb) svg as animated background (with css3) - javascript

I have long(more then 1500px) and heavy(more that 400kb) image, which describes environment. i'm trying to animate that left to right, but animation is not smooth, movement is quite roughly. I tried different ways, all of them are described below. So have you any idea how to solve this roughly movement?
css3:
#keyframes animatedBackground {
0% { background-position: 0 0; }
100% { background-position: 15447px 0; }
}
#-moz-keyframes animatedBackground {
0% { background-position: 0 0; }
100% { background-position: 15447px 0; }
}
#-webkit-keyframes animatedBackground {
0% { background-position: 0 0; }
100% { background-position: 15447px 0; }
}
#-ms-keyframes animatedBackground {
0% { background-position: 0 0; }
100% { background-position: 15447px 0; }
}
#-o-keyframes animatedBackground {
0% { background-position: 0 0; }
100% { background-position: 15447px 0; }
}
.animation-wrapper {
width: 15447px;
height: 100%;
background-image: url('../pictures/animation-background.svg');
background-position: 0px 0px;
background-size: 15447px 800px;
animation: animatedBackground 100s linear infinite;
-moz-animation: animatedBackground 100s linear infinite;
-webkit-animation: animatedBackground 100s linear infinite;
-ms-animation: animatedBackground 100s linear infinite;
-o-animation: animatedBackground 100s linear infinite;
}
jQuery - I split big SVG image into 20 small pieces, placed those pieces in <ul> and animated with jQuery:
$(function(){
var scroller = $('#scroller div.innerScrollArea');
var scrollerContent = scroller.children('ul');
scrollerContent.children().clone().appendTo(scrollerContent);
var curX = 0;
scrollerContent.children().each(function(){
var $this = $(this);
$this.css('left', curX);
curX += $this.outerWidth(true);
});
var fullW = curX / 2;
var viewportW = scroller.width();
// Scrolling speed management
var controller = {curSpeed:0, fullSpeed:4};
var $controller = $(controller);
var tweenToNewSpeed = function(newSpeed, duration)
{
if (duration === undefined)
duration = 600;
$controller.stop(true).animate({curSpeed:newSpeed}, duration);
};
// Scrolling management; start the automatical scrolling
var doScroll = function()
{
var curX = scroller.scrollLeft();
var newX = curX + controller.curSpeed;
if (newX > fullW*2 - viewportW)
newX -= fullW;
scroller.scrollLeft(newX);
};
setInterval(doScroll, 20);
tweenToNewSpeed(controller.fullSpeed);
});
});
gsap:
var tl = new TimelineMax({repeat:-1});
var right = $(".background").width()*20;
$(".animation-wrapper").css("left",-left+"px");
function backgroundMoveInitiate()
{
tl.to(".animation-wrapper", 50, {right: -right, ease:Linear.easeNone});
}
backgroundMoveInitiate();

Try using transit.js. The syntax is identical to jQuery animate, but it converts what would be jQuery animations into pure CSS animations. I found significant speed improvements when implementing transit.js in one of my projects using a scrolling panoramic image in my site.

On the TweenLite animation, use the properties x and y instead of left and top, and enable force3D.
Your options object should look like this:
{x: xVal, force3D: true, ease:Linear.easeNone}

Related

Why does the timing of these different animations get slower and out of order over time?

Here I have a Video that changes every few seconds with spinning animation + video getting small and big during the spinning.
But over time the timing gets out of order.
let degree = 720;
function rotateElement(){
let spin = `rotate(${degree}deg)`;
document.getElementById('myVideo').style.transform = spin;
document.getElementById('myVideo').style.transitionDuration = "1s";
degree += 720;
}
function smaller(){
document.getElementById('myVideo').style.maxWidth = "10px";
document.getElementById('myVideo').style.maxHeight = "10px";
document.getElementById('myVideo').style.transitionDuration = "1s";
}
function bigger(){
document.getElementById('myVideo').style.maxWidth = "30vw";
document.getElementById('myVideo').style.maxHeight = "19vw";
document.getElementById('myVideo').style.transitionDuration = "1s";
}
//setInterval(change, 5000);
window.onload = function () {
setInterval(change, 5000);
setInterval(rotateElement, 4900);
setInterval(smaller, 4850);
setInterval(bigger, 5050);
};
Not sure exactly what you want the animation to do with the rotate, but this is the basic idea of just doing it in CSS.
.test {
background-color: yellow;
/*animation: shrink 5s 3s ease infinite, rotate 50s steps(10, end) forwards infinite; */
animation: shrink 5s 3s ease infinite, rotate 50s forwards infinite;
transition: width 1s, height 1s;
overflow: hidden;
width: 30vw;
height: 19vh;
}
#keyframes shrink {
0%,
65%,
90%,
100% {
width: 30vw;
height: 19vh;
}
70% {
width: 14px;
height: 10px;
}
}
#keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
<img class="test" src="http://placekitten.com/200/100">

CSS animation glitch when reversing the animation via JS midway

I am having an issue stopping a CSS animation at about 75% of the way complete and then reversing its order and then continuing it using JS. If you run the snippet below and you'll see that you can easily stop and reverse the animation of the cube and reverse it at 50%.
var div = document.getElementById('div');
var timer = setTimeout(function() {
div.classList.add('paused');
}, 1000)
var timer = setTimeout(function() {
div.classList.add('reverse');
div.classList.remove('paused');
}, 1700)
#keyframes animation {
0% {
margin-left: 0px;
}
100% {
margin-left: 200px;
}
}
#div {
width: 100px;
height: 100px;
background-color: red;
animation: animation 2s linear infinite;
}
.paused {
animation-play-state: paused !important;
}
.reverse {
animation-direction: reverse !important;
}
<div id="div"></div>
But, if you try to stop it at 75% and restart it backwards, it starts the paused animation at 25% (Snippet below).
var div = document.getElementById('div');
var timer = setTimeout(function() {
div.classList.add('paused');
}, 1500)
var timer = setTimeout(function() {
div.classList.add('reverse');
div.classList.remove('paused');
}, 1700)
var timer = setTimeout(function() {
div.classList.add('paused');
}, 2800)
#keyframes animation {
0% {
margin-left: 0px;
}
100% {
margin-left: 200px;
}
}
#div {
width: 100px;
height: 100px;
background-color: red;
animation: animation 2s linear infinite;
}
.paused {
animation-play-state: paused !important;
}
.reverse {
animation-direction: reverse !important;
}
<div id="div"></div>
So, my question is, is there a way around this? Some sort of CSS property. I know that this may not be considered a glitch, because at 75% complete on reverse, the box should be at 25%, even though it moves across the screen much too quickly.

CSS scroll animation restarts before all text has scrolled

I'm trying to make a list of 100 paragraphs repeatedly scroll up, but the animation is restarting before the list finishes scrolling, at about 48 paragraphs. How can I make sure that all paragraphs scroll before the animation restarts?
div = document.getElementById("titlecontent");
for (c = 0; c < 100; c++) {
str = c;
p = document.createElement("p");
p.innerText = str;
div.appendChild(p);
}
p = document.createElement("p");
p.innerText = "last p reached";
div.appendChild(p);
#titlecontent {
position: absolute;
top: 100%;
-webkit-animation: scroll 10s linear 0s infinite;
-moz-animation: scroll 10s linear 0s infinite;
-ms-animation: scroll 10s linear 0s infinite;
-o-animation: scroll 10s linear 0s infinite;
animation: scroll 10s linear 0s infinite;
}
#-webkit-keyframes scroll {
0% { top: 100%; }
100% { top: -170%; }
}
#-moz-keyframes scroll {
0% { top: 100%; }
100% { top: -170%; }
}
#-ms-keyframes scroll {
0% { top: 100%; }
100% { top: -170%; }
}
#-o-keyframes scroll {
0% { top: 100%; }
100% { top: -170%; }
}
#keyframes scroll {
0% { top: 100%; }
100% { top: -170%; }
}
<div id="titlecontent"></div>
Your problem lies with top/bottom being related to the height of the screen, since the div is longer than those dimensions, it won't work.
I think I found a good solution, using only CSS.
Animating the top/bottom values is impossible, since CSS animations require their exact counterpart to animate, however, there is a property we can use to animate based on the entire height of the element
Introducing: CSS Transforms (translateX).
div = document.getElementById("titlecontent");
for (c = 0; c < 100; c++) {
str = c;
p = document.createElement("p");
p.innerText = str;
div.appendChild(p);
}
p = document.createElement("p");
p.innerText = "last p reached";
div.appendChild(p);
body {
overflow: hidden;
}
body {
overflow: hidden;
}
#titlecontent {
animation: scroll 20s linear 0s infinite;
}
#-webkit-keyframes scroll {
0% { transform: translateY(10%); }
100% { transform: translateY(-100%); }
}
<div id="titlecontent"></div>
The magic happens in these lines:
0% { transform: translateY(10%); }
100% { transform: translateY(-100%); }
Instead of animating offset, we're animating the element's position on the X axis of the screen. Making it -100% of it's actual height, and then animating it to 100% of it's actual height, effectively animating it offscreen before it repeats.
You just need to decide where the scrolling up should start, in this example 10%

jQuery click events working only for once, but second time its not

jQuery click events working only for once, but second time its not Fiddle
$('.animateBtn').on('click', function() {
$(this).addClass('OFF');
$(this).next('div').addClass('animate');
var btnText = $(this).text('Aniamte ON');
if($(this).next('div').hasClass('animate')) {
$(this).text('Aniamte OFF')
}
$('.OFF').on('click', function() {
if($(this).hasClass('OFF')){
$(this).removeClass('OFF');
$(this).next('div').removeClass('animate');
$(this).text('Aniamte ON')
}
})
})
Use event delegation to deal with dynamically changing classes.
$(document).on('click', '.animateBtn', function () {
$(this).addClass('OFF').removeClass('animateBtn');
$(this).next('div').addClass('animate');
var btnText = $(this).text('Aniamte ON');
$(this).text('Aniamte OFF');
});
$(document).on('click', '.OFF', function () {
$(this).removeClass('OFF').addClass('animateBtn');
$(this).next('div').removeClass('animate');
$(this).text('Aniamte ON')
});
.animate {
background: url(http://lorempixel.com/100/100);
height: 100px;
width: 100px;
-webkit-animation: slide 2s linear infinite;
-moz-animation: slide 2s linear;
animation: slide 2s linear infinite;
}
#-webkit-keyframes slide {
0% {
background-position: 0 0;
}
100% {
background-position: 100px 0;
}
}
#-moz-keyframes slide {
0% {
background-position: 0 0;
}
100% {
background-position: 100px 0;
}
}
#keyframes slide {
0% {
background-position: 0 0;
}
100% {
background-position: 100px 0;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<button class="animateBtn">Animate ON</button>
<div>
</div>
</div>
use event delegation for dynamic element
$(document).on('click','.OFF', function() {

Infinite auto scroll with dynamic content e.g. append

Every 5s new content added to page(div). After 15s page start scrolling down with css animation property.
What I want is that if there is content it should scroll down till the end.
Here is the example code in snippet. In this example code animation duration is 100 seconds. It's not allowed to make it 0 or -1. Also this time will be spent between top:0% and top:-170%. I like this speed ( 270%/100s ).
100s should be forever and speed should stay the same(270%/100s).
setInterval(function() {
$("#list").append("<div id='block'>Content HERE!</div>");
}, 1000);
#list
{
position: absolute;
top: 100%;
-webkit-animation: scroll 100s linear infinite;
-moz-animation: scroll 100s linear infinite;
-ms-animation: scroll 100s linear infinite;
-o-animation: scroll 100s linear infinite;
animation: scroll 100s linear infinite;
}
/* animation */
#-webkit-keyframes scroll {
0% { top: 100%; }
100% { top: -170%; }
}
#-moz-keyframes scroll {
0% { top: 100%; }
100% { top: -170%; }
}
#-ms-keyframes scroll {
0% { top: 100%; }
100% { top: -170%; }
}
#-o-keyframes scroll {
0% { top: 100%; }
100% { top: -170%; }
}
#keyframes scroll {
0% { top: 100%; }
100% { top: -170%; }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div id="list">
</div>
Try
$(window).on("error", function(e) {
console.log(e);
clearInterval(s);
$("#list").stop(true, true)
});
$.fx.interval = 0;
var i = 0
, listScroll = function listScroll(elem, idx) {
var block = elem.find("[data-index=" + idx + "]");
block.animate({
top: "-=" + (elem.height())
}, (1000 * 100), "linear", function() {
console.log(this, idx);
listScroll($(this).parent(), idx)
});
}
, s = setInterval(function() {
var el = $("<div />", {
"data-index": i,
"html": "Content HERE!",
});
$.when($("#list").append(el), i)
.promise().done([
listScroll
, function() {
++i;
}
])
}, 1000);
#list {
position: absolute;
top: 100%;
height: calc(100% - 1%);
}
#list div {
position: relative;
padding: 6px;
height: 36px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js">
</script>
<div id="list">
</div>

Categories

Resources