webkit translateX animation is rolling back to initial position - webkit

I am trying to do a images gallery for mobile webkit,
The only way it is actually fast enough is using the hardware accelerated translateX .
My problem is that the div take back its initial position at the end of the animation. I add the slideGalLeft class cliking on the left button. to the animated div
You can see an example here, in the callback events section:
http://position-absolute.com/jqtouch/demos/main/#home
.slideGalLeft {
-webkit-animation-name: slideColis;
}
#-webkit-keyframes slideColis {
from { -webkit-transform: translateX(0%); }
to { -webkit-transform: translateX(-100%); }
}

Do not use webkit animation for this as it comes back to the default values once played.
Instead define
.slideGalleft{
-webkit-transition: -webkit-transform 1s linear;
-webkit-transform: translateX(0%);
}
and using Javascript, either set -webkit-transform: translateX(100%); or add a CSS class to your element which set the final transform value and webkit will animate it properly

Guillaume's answer is great. However, if you are looking for hardware acceleration, you must let the webkit engine know you want 3D rendering (what makes hardware acceleration active).
According to http://www.html5rocks.com/tutorials/speed/html5/#toc-hardware-accell, this is done by adding translateZ(0) to your rule, like so:
.slideGalleft{
-webkit-transition: -webkit-transform 1s linear;
-webkit-transform: translateX(0%) translateZ(0);
}
Follow Guillaume's advice beyond that.

Use:
-webkit-animation-fill-mode: none/backwards/forwards/both;
This allows you to define at what end of your animation the element remains when the animation is finished.

I was able to make it work by adding a "display:none" style on the finish of the animation. Use the following CSS:
.paused {
-webkit-animation-play-state: paused;
}
.hiddendiv {
display:none;
}
Then in your jQuery code:
$('div.sideimage').click(
function () {
$(this).removeClass("paused").delay(2000).queue(
function(next) {
$(this).addClass("hiddendiv");
next();
}
);
}
);
Should work!

Related

Safari opacity animation sometimes fails

update: I've found a workaround for this, see my own answer.
I have an animation that crossfades back and forth between two images, by changing the opacity of one image that is placed directly on top of the other.
Symptoms:
It works fine it all browsers.
It occasionally stops working after a while in Safari - typically permanently stuck on the opening image, or you see two or three frames midway through the fade with the rest skipped, occasionally you'll get a flash between the two states without any animation.
Occurs significantly more frequent on mobile. Either way always cleared by restarting the browser, but often not by reloading tabs. Sometimes fixed by navigating a new page then using the back button.
I've used will-change: opacity on both images, it doesn't help.
I didn't notice this problem when I was animating the same graphics by changing a single background image URL - but the problem with that was it's not supported in Firefox…
The images are scaled down in the browser - the full size is 1200x1200 in a frame roughly 400x400 - though that doesn't seem excessive, and they've been compressed.
They need to be within a grid because of the layout of the rest of the page (using position: absolute wouldn't give them height.)
Simplified HTML and CSS:
#keyframes crossfade {
0% {
opacity: 0;
}
33.3% {
opacity: 1;
}
66.6% {
opacity: 1;
}
100% {
opacity: 0;
}
}
<img class="start-frame" src="square-start-1200.jpg">
<img class="end-frame" src="square-end-1200.jpg">
/* within a div that has display: grid... */
img {
grid-column: 1;
grid-row: 1;
will-change: opacity;
}
img.start-frame {
z-index: 1;
}
img.end-frame {
/* placed on top of the start image, but needs to be hidden to begin with */
opacity: 0;
z-index: 2;
animation: crossfade linear 20s;
animation-iteration-count: infinite;
}
#### Affected browsers
Safari 14.1.2 on Mojave 10.14.6
iPhone 6S with iOS 14.7.1
iPad Mini 5th Gen with iOS 14.7.1
iPod Touch 7th Gen with iOS 13.7
A workaround - run the animation in reverse:
animation-direction: reverse;
As it's symmetrically in this case, it doesn't matter.
I can't explain it, but touch wood this has proved stable on Safari 14.1.2 on Mojave, and on both iOS 13 (iPod) and iOS 14 on (iPhone and iPad) in normal daily use, with backgrounding the tabs, refreshing them, sleep/wake cycles etc.
I did also try making the animation start at 5% rather than 0 (i.e. having opacity: 0 at both the 0% and 5% marks, but was only changing the direction that seemed to have an immediate effect.)
Adding animation-delay (in the hope dropped/stuttering frames might be somehow related to an image that hadn't finished loading) didn't help either.
You can try with webkit property I think It works Fine check below Ex.
img {
grid-column: 1;
grid-row: 1;
will-change: opacity;
}
img.start-frame {
z-index: 1;
}
img.end-frame {
opacity: 0;
z-index: 2;
-webkit-animation: crossfade linear 20s infinite;
animation: crossfade linear 20s infinite;
}

Vue.js animation: Enter after Leave and not simultaneously

I have two components and a fade-in/fade-out animation set up for them.
For a brief moment, both components exist on the page at different opacities, and the scrollbar shows up and disappears.
Is there a way to avoid this? A way to start the fade-in animation only after the fade-out animation is done?
The Animation:
.view-leave-active {
transition: opacity 0.5s ease-in-out, transform 0.5s ease;
}
.view-enter-active {
transition: opacity 0.5s ease-in-out, transform 0.5s ease;
transition-delay: 0.5s; /* Increasing this doesn't seem to work */
}
.view-enter, .view-leave-to {
opacity: 0.5; /* It should be 1, but setting it to 0.5 allows you to see exactly what's happening */
}
.view-enter-to, .view-leave {
opacity: 1;
}
Any help would be very much appriciated!
To further elaborate on my comment: VueJS transition components support the mode property, where you can specify the sequence of transitions when toggling between two elements.
Since you do not want both elements to appear at the same time when one is transitioning in while the other is transitioning out, you should be using:
mode="out-in"
Based on the documentation:
out-in: Current element transitions out first, then when complete, the new element transitions in.

How to disable sticky toolbar in classic editor when page is scrolled?

I want to disable sticky toolbar which appears on top of page when page is scrolled. How it can be done ?
I resolve this problem by CSS
.ck.ck-editor__top.ck-reset_all {
z-index: var(--ck-z-modal);
position: sticky;
top: 0;
}
.ck.ck-sticky-panel__placeholder {
display : none !important;
}
.ck.ck-sticky-panel .ck-sticky-panel__content_sticky {
position: unset;
}
The fact that the toolbar appears in the wrong place when the editor is in an overflowed container is a bug that we are aware of. But in this case, I'd recommend you to not use the classic editor at all. If you want to have more control over where the toolbar goes, e.g. the DecoupledEditor (demo) allow controlling the toolbar. This editor type doesn't do anything with the toolbar itself – it just creates it and it's up to you where you're gonna insert it.
Another option would be implementing your own custom editor, but that'd be necessary only if you wanted to make even more customizations
I'm having same issue with the classic-editor, the position of the .sticky_panel is changing on the event of focus in the .editor_editable.
at some point when it's not visible within the display and click inside it goes all up to first element .
CSS only:
ck.ck-sticky-panel .ck-sticky-panel__content_sticky {​​​​​​​​​​​
    position: absolute !important;
}
In my editor build, I did a hack like this:
const stickyUpdateInterval = setInterval(() => {
editor.ui.view.stickyPanel['_checkIfShouldBeSticky']();
}, 100);
editor.on('destroy', () => {
clearInterval(stickyUpdateInterval);
});
This is just a crude hack that will update sticky balloon all the time.
If you know exactly in which overflow container your editor will be mounted, you can do something more clever, like listen to scroll events and update only then (this is what CKEditor is doing for the window, BTW, that's why it's not working when you put it in a container).
I have spent some time trying to get the CKEditor Classic component "sticky toolbar" to work nicely in Angular with a scrolling pane and there are 2 issues I had to overcome.
The position of the toolbar when sticky this defaults to the top
of the browser page (view port) - so (in Angular) you need to
configure this setting in the HTML template :
[config]="{ui:{viewportOffset:{ top: 58, right: 0, bottom: 0, left:
0}}}"
Making the editor respond to scrolling. This was a more difficult
one to resolve for me. The solution I have is (thanks to panta82
above) is to catch the scroll events and call a function in the
editor to check if the toolbar should be sticky or not .. it's
called checkIfShouldBeSticky :)
Here is a working sample in StackBlitz
I faced the same issue,
if you have header then below css will also help
#media only screen and (max-width: 767px) {
.ck-sticky-panel__content {
top: 180px !important;
}
}
#media only screen and (min-width: 768px) {
.ck-sticky-panel__content {
top: 128px !important;
}
}
document.getElementById('main')?.addEventListener('scroll', () => {
setTimeout(() => {
// eslint-disable-next-line no-underscore-dangle
editor.ui.view.stickyPanel._checkIfShouldBeSticky()
}, 100)
})

bootstrap modal scale and translate

My bootstrap modal has animation with translate.
.modal.in .modal-dialog {
-webkit-transform: translate(0, 0);
-ms-transform: translate(0, 0);
-o-transform: translate(0, 0);
transform: translate(0, 0);
}
So bootstrap modal fade from top to middle. Everything works fine, but transition is reset when i want to apply scale for this modal like :
.modal.in .modal-dialog {
transform: scale(1.5)
}
so it's okay that my scale reset my translate so i apply mutliple transform conditions :
.modal.in .modal-dialog {
transform: scale(1.5) translate(0,0)
}
but in that case my modal behave like translate and scale in same time and the effect is like zoomIn.
How can i apply that modal dialog is first scale and then on scaled modal apply transition from top to middle ?
Please help !
What you are looking for are so called "keyframes" (if you want to know more, have a look here).
I created a fiddle and tested it shortly: Modal example with keyframes
The following code handles the transformations (scale and translate)
#keyframes mymove {
0% {transform: scale(1);}
50% {transform: scale(1.2);}
100% {transform: scale(1.2) translate(0, 100px);
}
Then you call "animation" instead of "transition" to make the keyframe work like this:
animation: mymove 2s ease-out;
Once the animation is finished, the state of the modal will go back to normal (no scale, no transition) - that's why we have to add the following line:
transform: scale(1.2) translate(0, 100px);
Hope this helps!

Controlling rotation axis with webkit 3d transform

I'm creating a card-flip effect using webkit transformations. I have it working as I like in one section, where I have a DIV that rotates around its center axis giving the look of a card that is flipping over.
I now want to add this same effect to a page transition. I'm using the same CSS and HTML structure, but in this case I'm not getting an effect that rotates around a center axis.
Instead, it looks like the transformation is rotating along the y axis anchored to the left of the object rather than the center (so it looks like a door opening, rather than a card flipping).
I've been reading through the spec's but can't figure out which property controls the rotation axis' position. What do I need to add or change with this to get the flip working?
html structure:
<div id="frontbackwrapper">
<div id="front"></div>
<div id="back"></div>
</div>
and the css (.flip is being added via jQuery to start the effect)
#frontbackwrapper {
position: absolute;
-webkit-perspective: 1000;
-webkit-transition-duration: 1s;
-webkit-transform-style: preserve-3d;
-webkit-transition: 1s;
}
#frontbackwrapper.flip {
-webkit-transform: rotateY(180deg);
}
#frontbackwrapper.flip #front,
#frontbackwrapper.flip #back {
-webkit-transform: rotateY(180deg);
-webkit-transition: 1s;
}
#front, #back {
position: absolute;
-webkit-backface-visibility: hidden;
}
#back {
-webkit-transform: rotateY(180deg);
}
Try this on your wrapper
-webkit-transform-origin: 50% 0 0;
Though you may or may not have to have its width explicitly set.