get #keyframe current value in css3 with javascript - javascript

See the demo here:
http://jsfiddle.net/hamidrezabstn/fgcPa/5/
When I click on the middle raindrop , I would like it to rotate to the current position of the spinning circle! I tried below the JS code but it doesn't work! The next thing I want to do is the raindrop rotate with spining circle!
$(function() {
$('#center').click(function() {
var pos = $('#circle').css('transform')
$(this).css('transform', 'pos')
});
});

$(function() {
$('#center').click(function() {
var obj, matrix;
obj = document.getElementById('circle');
matrix = getComputedStyle(obj).getPropertyValue('transform');
console.log(matrix);
//$(this).css('transform', matrix)
});
});
read more here http://dev.opera.com/articles/view/understanding-3d-transforms/

EDITED: I said that it is not posible to get the current status of the transform in an animation, but I was wrong. Sorry about that !
To do what you want, any way, you don't need really to get it; just use it.
I have changed slightly your HTML to put the raindrop inside the rotating div.
Then, with this CSS:
.raindrop {
background:center blue;
width:50px;
height:50px;
border-radius: 100%;
border-top-left-radius: 0;
position: absolute;
margin: auto;
left: 75px;
top: 75px;
animation: ccircle 5s infinite linear;
-webkit-animation: ccircle 5s infinite linear;
}
.raindrop:hover {
animation: none;
-webkit-animation: none;
}
.axis {
width: 200px;
height: 200px;
transform: scaleX(2);
background-color: none;
border: 1px solid black;
left: 50px;
position: absolute;
top: 50px;
border-radius: 50%;
}
.rotate {
width: 100%;
height: 100%;
top: 0px;
animation: circle 5s infinite linear;
-webkit-animation: circle 5s infinite linear;
transform-origin: 50% 50%;
-webkit-transform-origin: 50% 50%;
position: absolute;
}
.counterrotate {
width: 50px;
height: 50px;
animation: ccircle 5s infinite linear;
-webkit-animation: ccircle 5s infinite linear;
}
.planet {
width: 50px;
height: 50px;
position: absolute;
border-radius : 50px;
left: 0px;
top: 0px;
background-color: red;
display: block;
}
#keyframes circle {
from { transform: rotateZ(0deg) }
to { transform: rotateZ(360deg) }
}
#-webkit-keyframes circle {
0% { -webkit-transform: rotateZ(0deg) }
100% { -webkit-transform: rotateZ(360deg) }
}
#keyframes ccircle {
from { transform: rotateZ(360deg) }
to { transform: rotateZ(0deg) }
}
#-webkit-keyframes ccircle {
from { -webkit-transform: rotateZ(360deg) }
to { -webkit-transform: rotateZ(0deg) }
}
You got this fiddle
In it, the raindrop is always rotating with the axis div. But it is also counter-rotating, so it appears to be static.
When you hover it, the count-rotation is disabled, and it points to red circle. And will continue to do so as long as you hover it.
To do that thru a click, just asociate the :hover properties to a class, and set this class in the click.

Related

CSS rolling ball animation position

General info
I'm working on a Bingo game. Currently I'm trying to create a CSS rolling ball animation. The idea is to simulate a ball dropping from the wheel and making it roll from right to left.
The problem
The animation is working fine. But the "drop in" position is relative to the div. As a consequence of this, this position keeps moving right 75 pixels on each new ball dropping in.
Solutions I've tried
- Give the balls an absolute position. This solves the issue, but each ball will cover the previous balls due to the keyframe ending at left: 0%. This is not desirable.
- Lookup Javascript solutions to see if I can somehow change the keyframe to end with +75px on the previous ball. Unfortunately it seems impossible to manipulate animations this way, or I was unable to find a way to do it.
So now I'm hoping someone is able to help me find a solution to this problem.
Edit: I didn't tag jQuery because it's not used here, but solutions using jQuery are perfectly fine.
MCVE
const timer = setInterval(rollBall, 2000);
var ballNumber = 1;
function rollBall(){
if(document.getElementById('ball-'+(ballNumber-1))){
document.getElementById('ball-'+(ballNumber-1)).classList.remove('ball-animation');
}
let html = '<div id="ball-'+ballNumber+'" class="ball ball-animation">';
html += '<p class="ball-number">';
html += ballNumber;
html += '</p></div>';
document.getElementById('balls').innerHTML += html;
ballNumber++;
if(ballNumber > 10) {
clearInterval(timer);
document.getElementById('ball-'+(ballNumber-1)).classList.remove('ball-animation');
}
}
.ball {
display: block;
position: relative;
width: 75px;
height: 75px;
background: red;
border-radius: 50%;
background: -webkit-radial-gradient(25px 25px, circle, red, #000);
background: -moz-radial-gradient(25px 25px, circle, red, #000);
background: radial-gradient(25px 25px, circle, red, #000);
/*position: absolute;*/
float: left;
}
.ball-number {
top: -34px;
left: 25px;
font-size: 45px;
color: #fff;
position: absolute;
}
.ball-animation {
-webkit-animation: spin 1750ms linear infinite, moveRightToLeft 2s linear infinite;
-moz-animation: spin 1750ms linear infinite, moveRightToLeft 2s linear infinite;
-ms-animation: spin 1750ms linear infinite, moveRightToLeft 2s linear infinite;
animation: spin 1750ms linear infinite, moveRightToLeft 2s linear;
-webkit-transition: all 1.75s ease;
transition: all 1.75s ease;
}
#keyframes spin {
from { transform: rotate(360deg); }
to { transform: rotate(0deg); }
}
#keyframes moveRightToLeft {
0% { top: -50px; left: 200px; }
10% { top: -40px; left: 180px; }
20% { top: -25px; left: 150px; }
30% { top: 0px; left: 100px; }
100% { left: 0%; }
}
<div id="balls"></div>
This is a CSS only solution, using an intermediate div, zone to handle the ball movement .
Since this elements have varying sizes, you can set the keyframes on them to work in percentages, and adjust for a different ending point, while keeping the same origin point.
.container {
width: 600px;
height: 350px;
border: solid 1px red;
position: relative;
}
.zone {
position: absolute;
top: 0px;
right: 0px;
bottom: 40px;
left: 40px;
border: solid 1px green;
animation: move 3s linear infinite;
}
.zone:nth-child(2) {
left: calc(40px * 2);
}
.zone:nth-child(3) {
left: calc(40px * 3);
}
.zone:nth-child(4) {
left: calc(40px * 4);
}
.ball {
width: 40px;
height: 40px;
border-radius: 100%;
background-color: blue;
right: 0px;
position: absolute;
}
#keyframes move {
from {transform: translate(0px, 0px);}
50% {transform: translate(-100px, 100%);}
to {transform: translate(-100%, 100%);}
}
<div class="container">
<div class="zone">
<div class="ball">1</div>
</div>
<div class="zone">
<div class="ball">2</div>
</div>
<div class="zone">
<div class="ball">3</div>
</div>
<div class="zone">
<div class="ball">4</div>
</div>
</div>

Trying to make a CSS3 diagonal slide animation, but it's not working as expected

So I'm trying to create a diagonal scroll in CSS3, but I'm having no luck.
The original script is this: https://codepen.io/275845/pen/LoYBjg
<style>
.tech-slideshow {
height: 600px;
max-width: 800px;
margin: 0 auto;
position: relative;
overflow: hidden;
transform: translate3d(0, 0, 0);
}
.tech-slideshow > div {
height: 100px;
width: 2526px;
background: url(https://i2.wp.com/mitmark.com.br/wp-content/uploads/2016/04/circle.png?ssl=1);
position: absolute;
top: 0;
left: 0;
height: 100%;
transform: translate3d(0, 0, 0);
}
.tech-slideshow .mover-1 {
animation: moveSlideshow 12s linear infinite;
}
.tech-slideshow .mover-2 {
opacity: 0;
transition: opacity 0.5s ease-out;
background-position: 0 -200px;
animation: moveSlideshow 15s linear infinite;
}
#keyframes moveSlideshow {
100% {
transform: translateX(-66.6666%);
}
}
</style>
<div class="tech-slideshow">
<div class="mover-1"></div>
<div class="mover-2"></div>
</div>
Here's what I've tried so far, with no success: https://codepen.io/275845/pen/gJOjXY
<style>
.tech-slideshow {
height: 600px;
max-width: 800px;
margin: 0 auto;
position: relative;
overflow: hidden;
transform: translate3d(0, 0, 0);
}
.tech-slideshow > div {
height: 100px;
width: 2526px;
background: url(https://i2.wp.com/mitmark.com.br/wp-content/uploads/2016/04/circle.png?ssl=1);
position: absolute;
top: 0;
left: 0;
height: 100%;
transform: translate3d(0, 0, 0);
}
.tech-slideshow .mover-1 {
animation: moveSlideshow 2s linear infinite;
}
.tech-slideshow .mover-2 {
opacity: 0;
transition: opacity 0.5s ease-out;
background-position: 0 -200px;
animation: moveSlideshow 5s linear infinite;
}
#keyframes moveSlideshow {
0% {
transform: translatex(0px) translatey(0px)
}
100% {
transform: translatex(100px) translatey(100px);
}
}
</style>
And here's the result that I'm trying to achieve: https://streamable.com/ltsba
As you can see, I'm trying to make a diagonal slide scrolling in css3, but of course, if anyone could point me out another solution weather it's vanilla javascript, or even jQuery, I'm opened for new suggestions.
You're pretty close, just a few issues.
You don't need 2 "mover", one is enough.
Make it big! And background repeat!
Then you move the size of that background image.
.tech-slideshow > div {
height: 3000px; // BIG
width: 3000px;
background: url(https://i2.wp.com/mitmark.com.br/wp-content/uploads/2016/04/circle.png?ssl=1);
position: absolute;
bottom: 0;. // position
right: 0;
animation: moveSlideshow 5s linear infinite;
}
#keyframes moveSlideshow {
0% {
transform: translatex(0px) translatey(0px);
}
100% {
transform: translatex(255px) translatey(255px); // move size of image
}
}

Js/jQuery - This code sets a size to a variable, any way to make it responsive?

A non-programmer here, looking for help. :)
I've been searching for a way to make two circles spin inside a larger circle, in a very particular fashion, and I found some code which I managed to tweak to get exactly the effect I wanted:
However, the full width of it is 400px (I need it to be so), and the problem is that the code defines the radius and positioning values in absolute, so if the browser goes below 400px width, it can't be adjusted:
var r = 101;
var xcenter = 100;
var ycenter = 100;
var newLeft = Math.floor(xcenter + (r * Math.cos(t)));
var newTop = Math.floor(ycenter + (r * Math.sin(t)));
Now, I would be content if I could simply scale this whole thing for browsers < 400px down to
var r = 71;
var xcenter = 70;
var ycenter = 70;
var newLeft = Math.floor(xcenter + (r * Math.cos(t)));
var newTop = Math.floor(ycenter + (r * Math.sin(t)));
But I haven't the slightest clue how to go about implementing that responsiveness, or even if it's possible to do in real time (without having to refresh the browser, cos I'd like it to be resize-proof).
Here is the full fiddle of what I have: http://jsfiddle.net/29or8u76/3/
So... can someone help me out? Cos I don't really speak javascript at all :) Thanksss!
This does not directly answer your question, but here's an example using only CSS.
I've used percentages to keep everything responsive to the container width.
The inner circles rotate around their origins by using animation, which uses transform.
The pulsing of the outer circle is just for demonstration purposes, to show how the size of the inner circles are relative to their container.
#container {
position: relative;
height: 0;
border: 1px solid #000;
border-radius: 50%;
margin: 0 auto;
animation: pulse 5s 0s linear infinite;
}
.circle {
position: absolute;
width: 50%;
height: 50%;
border-radius: 50%;
animation: spin 3s 0s linear infinite;
}
#blue {
top: 0;
left: 25%;
transform-origin: center bottom;
background-color: #00f;
}
#red {
bottom: 0;
left: 25%;
transform-origin: center top;
background-color: #f00;
}
#keyframes spin {
100% {
transform: rotate(360deg);
}
}
#keyframes pulse {
0% {
width: 25%;
padding-bottom: 25%;
}
50% {
width: 10%;
padding-bottom: 10%;
}
100% {
width: 25%;
padding-bottom: 25%;
}
}
<div id="container">
<div class="circle" id="blue"></div>
<div class="circle" id="red"></div>
</div>
EDIT:
To ensure that the contents of the circles don't rotate, I've used a slightly different method that animates the circles in orbit around the container's center.
This method is based on a tutorial by Zoltan Howryluk.
#container {
position: relative;
height: 0;
border: 1px solid #000;
border-radius: 50%;
margin: 0 auto;
animation: pulse 5s 0s linear infinite;
}
.circle {
position: absolute;
width: 50%;
height: 50%;
top: 25%;
left: 25%;
border-radius: 50%;
transform-origin: center;
display: flex;
justify-content: center;
align-items: center;
}
.circle span {
font-size: 10px;
color: white;
}
#blue {
background-color: #00f;
transform: translateY(-50%);
animation: orbit1 3s 0s linear infinite;
}
#red {
background-color: #f00;
transform: translateY(50%);
animation: orbit2 3s 0s linear infinite;
}
#keyframes orbit1 {
from {
transform: rotate(0deg) translateX(50%) rotate(0deg);
}
to {
transform: rotate(360deg) translateX(50%) rotate(-360deg);
}
}
#keyframes orbit2 {
from {
transform: rotate(0deg) translateX(-50%) rotate(0deg);
}
to {
transform: rotate(360deg) translateX(-50%) rotate(-360deg);
}
}
#keyframes pulse {
0% {
width: 25%;
padding-bottom: 25%;
}
50% {
width: 10%;
padding-bottom: 10%;
}
100% {
width: 25%;
padding-bottom: 25%;
}
}
<div id="container">
<div class="circle" id="blue"><span>BLUE</span></div>
<div class="circle" id="red"><span>RED</span></div>
</div>
Before deciding on this method, I recommend considering browser compatibility and vendor prefixes for various CSS3 functionality. For simplicity, I haven't included any vendor prefixes here.

Multiple CSS animations: How to avoid re-triggering one of them?

I am trying to build an animated menu for mobile apps similar to Pinterest's radial menu. I have managed to get the behaviour to where I want it except for one minor detail: when the menu opens, the items shoot out as I want them to, and when you hover on them, they transform as I want them to. problem is, after the cursor leaves the items, they re-trigger their original animation, instead of just returning to their previous state. I realise this is a problem to do with the class being used for the animation and I have tried a number of solutions, including deleting the class and adding a new one .onmouseover() and changing animation running state on hover/mousover. I am probably missing something simple and idiotic, but I just cannot see it. can anybody help?
The following code is just the way I had it before trying to implement solutions.
HTML:
<!--Footer-->
<div class="footer">
<!--RADIAL NAV MENU-->
<div id="navContainer">
<!--Buttons-->
<div id="workouts" class="sml smlOne">Go there</div>
<div id="home" class="sml smlTwo">Go here</div>
<div id="profile" class="sml smlThree">Go somewhere</div>
<!--Burger-->
<div class="burger-menu">
<div id="top" class="bar barTop"></div>
<div id="middle" class="bar barMid"></div>
<div id="bottom" class="bar barBot"></div>
</div>
</div>
</div>
CSS:
.footer
{
position: fixed;
bottom: 0%;
width: 100%;
height: 50px;
background-color: #d36363;
box-shadow: 0px -6px 6px #888888;
z-index: +2;
}
/* Burger menu section */
#navContainer
{
text-align: center;
font-size: 10px;
}
.burger-menu
{
position: relative;
margin: auto;
height: 100%;
width: 50px;
}
.bar
{
height: 6px;
width: 100%;
background-color: white;
}
#top
{
position: relative;
top: 5px;
}
#middle
{
position: relative;
top: 15px;
}
#bottom
{
position: relative;
top: 25px;
}
.barTop, .barMid, .barBot
{
-webkit-transition: all 0.1s ease;
-moz-transition: all 0.1s ease;
-o-transition: all 0.1s ease;
-ms-transition: all 0.1s ease;
transition: all 0.1s ease;
}
.barTopOn
{
transform: rotate(45deg) translateY(12px) translateX(11px);
}
.barMidOn
{
opacity: 0;
}
.barBotOn
{
transform: rotate(-45deg) translateY(-12px) translateX(11px);
}
/* Navigation buttons section */
#navContainer
{
position: relative;
margin: auto;
width: 50px;
}
.sml
{
border: 2px solid #58a7dd;
height: 50px;
width: 50px;
border-radius: 50%;
background-color: white;
box-shadow: 6px 6px 6px #888888;
transform: scale(0);
}
#workouts
{
position: absolute;
bottom: 10px;
left: -60px;
}
#home
{
position: absolute;
bottom: 50px;
}
#profile
{
position: absolute;
bottom: 10px;
left: 60px;
}
.smlOnOne
{
animation: pop, slideOne 0.1s ease-in;
animation-fill-mode: forwards;
}
.smlOnTwo
{
animation: pop, slideTwo 0.1s ease-in;
animation-fill-mode: forwards;
}
.smlOnThree
{
animation: pop, slideThree 0.1s ease-in;
animation-fill-mode: forwards;
}
.smlOnOne:hover
{
background-color: red;
border: none;
box-shadow: 6px 10px 18px #686868;
animation: whopL 0.2s;
animation-fill-mode: forwards;
}
.smlOnTwo:hover
{
background-color: red;
border: none;
box-shadow: 6px 10px 18px #686868;
animation: whopC 0.2s;
animation-fill-mode: forwards;
}
.smlOnThree:hover
{
background-color: red;
border: none;
box-shadow: 6px 10px 18px #686868;
animation: whopR 0.2s;
animation-fill-mode: forwards;
}
#keyframes pop
{
100%
{
transform: scale(1,1);
}
}
#keyframes slideOne
{
0%
{
bottom: -20px;
left: 0px;
}
100%
{
bottom: 10px;
left: -60px;
}
}
#keyframes slideTwo
{
0%
{
bottom: -20px;
}
100%
{
bottom: 50px;
}
}
#keyframes slideThree
{
0%
{
bottom: -20px;
left: 0px;
}
100%
{
bottom: 10px;
left: 60px;
}
}
#keyframes whopL
{
0%
{
transform: scale(1,1) translateY(0px) translateX(0px);
}
100%
{
transform: scale(1.5) translateY(-10px) translateX(-10px);
}
}
#keyframes whopC
{
0%
{
transform: scale(1,1) translateY(0px) translateX(0px);
}
100%
{
transform: scale(1.5) translateY(-10px);
}
}
#keyframes whopR
{
0%
{
transform: scale(1,1) translateY(0px) translateX(0px);
}
100%
{
transform: scale(1.5) translateY(-10px) translateX(10px);
}
}
JS/jQuery:
$(".burger-menu").click(function()
{
$(".barTop").toggleClass("barTopOn");
$(".barMid").toggleClass("barMidOn");
$(".barBot").toggleClass("barBotOn");
$(".smlOne").toggleClass("smlOnOne");
$(".smlTwo").toggleClass("smlOnTwo");
$(".smlThree").toggleClass("smlOnThree");
});
Here is a working demo:
https://codepen.io/BGGrieco/pen/NgjxXq
You have an element that is a set of #-webkit-keyframes to animate in. On hamburger-menu click, these keyframes run, and that works well.
Next, you have a second set of #-webkit-keyframes on hover, so on hover works well too.
However, the instant the mouse is away from the element, the first (intro) set of keyframes gets run again. You don't want it to run after it first runs.
Here is what I was able to accomplish:
https://codepen.io/CapySloth/pen/RgxKEb
<div id="workouts" class="sml smlOne">
<div class="test1">
Go there
</div>
</div>
Instead of stacking classes which contain keyframe animations onto the one ".sml" class, I have split the task between two elements. ".sml" now acts as a wrapper which takes care of the "hamburger-menu open" animation and "test1 a" takes care of the "whop" animation.
If you can find a way to hide/show parents of the "test1 a/test2 a/test3 a" then you will have what you want.
You can use .stop() before your .toggleClass.
$("#example").stop().toggleClass("class");

Why isn't this :after element working?

I have a preloader on my page which should be displaying an animation. The animation should be showing on top of the dark black background before the page has loaded... but the animation is not displaying.
http://www.samnorris.net/portfolio-ss/
The animation works if I put it's CSS into #windowloader, but because I need it to be on top of a solid background (to hide unloaded content...) I thought to put it into an :after pseudo-class to load it on top of the #windowloader div... but for some reason this is not working.
is my CSS incorrect, or something else...?
Here is the Codepen which shows the animation that should be displaying:
http://codepen.io/devilishalchemist/pen/emOVYQ
HTML:
<div id="windowloader">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
Relevant CSS from my page:
/* ==========================================================================
PAGE LOADER
========================================================================== */
.nonscroll {
overflow: hidden;
}
#windowloader {
overflow: auto;
top:0;
left: 0;
width: 100%;
height: 100%;
position: fixed;
z-index: 999998;
display: table;
background: $black;
}
#windowloader {
&:after {
content: '';
display: block;
position: absolute;
z-index: 999999;
top: 50%;
left: 50%;
width: 80px;
height: 80px;
transform: translate(-50%, -50%) rotate(45deg) translate3d(0, 0, 0);
animation: loader 1.2s infinite ease-in-out;
span {
position: absolute;
display: block;
width: 40px;
height: 40px;
background-color: #EE4040;
animation: loaderBlock 1.2s infinite ease-in-out both;
&:nth-child(1) {
top: 0;
left: 0;
}
&:nth-child(2) {
top: 0;
right: 0;
animation: loaderBlockInverse 1.2s infinite ease-in-out both;
}
&:nth-child(3) {
bottom: 0;
left: 0;
animation: loaderBlockInverse 1.2s infinite ease-in-out both;
}
&:nth-child(4) {
bottom: 0;
right: 0;
}
}
/*LOAD FINISH*/
.loaded {
top: -100%;
}
}
}
#keyframes loader {
0%, 10%, 100% {
width: 80px;
height: 80px;
}
65% {
width: 150px;
height: 150px;
}
}
#keyframes loaderBlock {
0%, 30% {
transform: rotate(0);
}
55% {
background-color: #F37272;
}
100% {
transform: rotate(90deg);
}
}
#keyframes loaderBlockInverse {
0%, 20% {
transform: rotate(0);
}
55% {
background-color: #F37272;
}
100% {
transform: rotate(-90deg);
}
}
FWIW, I have also tried:
#windowloader:after { }
Javascript:
///////////////////////////////////////////////////////////////////////////
// Window Loader
///////////////////////////////////////////////////////////////////////////
$("#windowloader").transitioncss("transitionEndOpen","loaded",{duration:2000,delay:1000});
$("#windowloader").off("transitionEndOpen").on( "transitionEndOpen", function(){
$("body").removeClass('nonscroll');
$("#windowloader").remove();
$("#portfoliogrid").isotope('layout');
$("#isotopeMembers").isotope('layout');
$(".isotopeBlog").isotope('layout');
});
Bah, nevermind - I just put the animation in a separate div inside the #windowloader div which probably works well enough I guess..

Categories

Resources