Breaking up transformations - css

I have 48 elements and they all have the same animation which is a transformation in the Y axis but they each have a different rotation
transform:rotate(0deg) translateY(-105px);
...
#keyframes mov {
0%,65%,100% {transform:rotate(0deg) translateY(-105px);}
15%, 50% {transform:rotate(0deg) translateY(105px);}
}
and it would be horribly inefficient if I were to have that for each element - is there a way I can have transform:rotate(0deg) in one place and translateY(?px); in another place?
Current solution: element in an element, first is rotate and the second is translateY

Related

How to show fixed elements inside a web-animation-api transformed parent

I have a parent div transformed with the web-animations-api.
This makes the containing block, of any child fixed elements the parent rather than the viewport (as expected).
The parent transforms to translate3d(0, 0, 0) ... so just removing the animation/transform on complete would be perfect.
I cant find a simple* way to do this through the web-animations-api, is there one?
Previously this was done via CSS, or inlined styles & hence easy to remove on complete.
I have tried ..
amination.cancel(), inside animation.finished, but rapidly applying another animation to the
same el, breaks ... looks like fill mode flips from 'forward' to 'none'
adding an additional transform on animation.finished. This seems to work but messy.
el.animate([
{ transform: 'unset' },
{ transform: 'unset' },],
{
duration: 0,
fill: 'forwards'
}
)

Translate CSS transition-timing-function to swiping

I am fading in a div (using CSS transitions) with a custom timing function (http://cubic-bezier.com/#1,0,1,1). The timing function is basically a more extreme version of 'ease-in'.
div {
opacity: 0;
transition: opacity 1s;
.in {
opacity: 1;
transition-timing-function: cubic-bezier(1, 0, 1, 1);
}
In addition to that, I want to be able to fade in the div by swiping across the screen. I am using the following Jquery to set the opacity according to how far the user has swiped:
documentWidth = $(document).width();
$(document).on('touchmove', function(e) {
// How much of the animation is completed (in %)
completion = e.changedTouches[0].pageX / documentWidth;
$('div').css('opacity', completion);
})
Nooooow, this is linear! Is there a clever Math-person out there who can figure out how to re-state that last line to represent my timing function?
So, for example, if completion is at 25%, the opacity should be around 2%. At 50%, it should be around 11% and at 75% it should be around 31%.
Start by finding a curve that approximates your cubic-bezier curve. With the given points and some online tools it's possible to draw a curve with this equation:
y = 464085.7 + (0.0174619 - 464085.7)/(1 + (x/22.88957)^4.174069)
in your case the x represents your completion variable and y the resulting opacity.
Then your code becomes
let completion = e.changedTouches[0].pageX / documentWidth;
let exponential = Math.pow((completion / 22.88957), 4.174069);
let opacity = 464085.7 + (0.0174619 - 464085.7)/(1 + exponential);
$('div').css('opacity', opacity);
(of course you may find a better equation that best fits your needs)

Resetting RotateY degrees without transformation

I use css 3D-transform rotateY to flip a div with css transition. I want the image to flip for a certain number of times : when the transition ends, I trigger it again until a certain counter value is reached.
What I would like to do : when the rotateY reaches 360 deg, I want reset it to 0 to restart the same rotation.
What happens: if I reset to 0, the div rotates backward first. I tried to disable the transform property before "rewinding', without any luck.
Is there an easy way to restore the 0 deg value without any transformation / rotation?
I did a codepen to illustrate: http://codepen.io/3MO/pen/QKogxE
It is not very graphical, but if you click on start, then reset, it will be obvious.
Here is my reset function:
$('#reset').click(function () {
deg = 0;
countRotations = 0;
$('#card').attr('transition', 'transform 0');
flipStarted = false;
flip($('#card'), 0);
});
You need to set the transition property to 0s, then change the rotation to 0 (this way it'll rotate instantly), then change the transition back to the "default" value.
Thanks to #Harry here's a working demo:
http://codepen.io/hari_shanx/pen/PGLKzN

Position a background image outside an element using percent [duplicate]

This question already has answers here:
Using percentage values with background-position on a linear-gradient
(2 answers)
Closed 3 years ago.
I don't know if it's the late hour or if I'm just being stupid, but I can't figure this out.
What I'm trying to do is position a background image just outside the element it belongs to using %. The reason I want to do is is so that I can later animate the background-position from this % to 50% having it "slide in".
If I could use pixels it's easy enough to set the background-position to [width-of-element]px 0 but as I want the element's final position to be 50% 0 I can't start with a pixel value. (I'm using the jQuery Background Position plugin btw http://keith-wood.name/backgroundPos.html).
So, my question is, knowing the width of the element and the width of the background image - how can I calculate which %:age is needed to position the image just outside the edge of the element?
Obviously setting the background position to "0 0" makes it render at the top left, "50% 0" makes it centered and "100% 0" positions it from the right edge. If I go above 100% it starts to move away from the right edge, and depending on the width of the image (and I guess, the element) any value from roughly 200 and up is needed to completely shove the background image outside the edge of the element.
If I go the other way around, from 0 and downward the image moves off to the right, again the % needed to hide it varies but is not the same as the positive % needed to push it off the other edge.
Again, maybe I'm just tired but I'm stuck here.
http://jsfiddle.net/cTeEA/
Edit: Another curious thing I noticed is that if the image is smaller than the containing element, increasing its background-position-x above 100% doesn't make it move away from the right instead it makes it move to the right. Adjust the 101% on this updated fiddle and compare with the old fiddle to see what I mean: http://jsfiddle.net/cTeEA/1/
Edit: Ok percentages seemed out of the question, or at least ten times harder than simply using pixels. Here's how I solved it (more or less):
var dir = 'left'; // || 'right' (where to slide in the image from)
var winWidth = $(document).width();
var imgWidth = $('img[src="src-of-already-added-and-loaded-img.png"]').width();
var posOutside = dir == 'right' ? '-' + imgWidth + 'px' : winWidth + 'px';
var posCenter = (imgWidth > winWidth) ? -((imgWidth - winWidth) / 2) : ((winWidth - imgWidth) / 2);
Then I just animated the background-position from posOutside to posCenter.
Thanks to those who helped in the comments as well.
Background position with percentage values is not easy.
You can see an explanation of the math involved here
In your case, the short answer is:
The background size is greater or smaller than the div by a factor of f. Then your percentage is 100 / (1 - f).
That means that:
The backgound size is the same than the div. You are out of luck, it's not posible.
The background is bigger. Say div=100 background=400, then f = 4 and the formula gives -33%. (first example in demo)
The background is narrower. Say div=400 background=100, f=0.25 and the formula gives 133% (second example in the demo)
demo
Notice that in the demo the percentages are a little bit offset to show that the background is really there
css:
div.foo {
width: 100px;
background-size: 400px 100px;
background: red url(http://placekitten.com/400/100) no-repeat 50% 0;
height: 100px;
background-position: -32% 0; /* Disappear to the left */
}
div.foo2 {
width: 400px;
background-size: 100px 100px;
background: red url(http://placekitten.com/100/100) no-repeat 50% 0;
height: 100px;
background-position: 132% 0; /* Disappear to the left */
}

Rotate more than 360 deg using css 3 matrix

I am using CSS transitions like this:
div
{
-webkit-transform: rotate(0deg);
-webkit-transition: -webkit-transform 2s;
}
div:hover
{
-webkit-transform: rotate(720deg);
}
This effectively makes the div rotate 2 times for 2 seconds. Now I want to use the matrix so that I can rotate and scale the image; however the matrix does not use degrees but cos(a) and sin(a) and as we all know cos(0) = cos(360) = cos(720) etc. So using the matrix I am unable to rotate the image more than 359deg.
So I decided to be clever and with JavaScript I took the matrix from a rotated element (720deg) and it looks like this:
-webkit-transform: matrix(1, -0.0000000000000004898587196589413, 0.0000000000000004898587196589413, 1, 0, 0);
However using this matrix I am not able to rotate the element - I will later calculate the size and apply that too.
So the question is - how do I rotate an element more than 359deg using css 3 matrix transform?
Matrices in CSS 3 define
a mathematical mapping from one coordinate system into another
(W3C reference),
which implies that 720deg is exactly equivalent to 360deg as you pointed out. So you will not be able to do this directly with a matrix.
However, this syntax should work for your need :
div:hover {
transform: scale(1.5,1.5) rotate(720deg);
transition: transform 3s;
}

Resources