Reputation: 97
I made a React component that changes dynamically the background of 4 divs in an infinite loop, each time it changes the background, there's a css animation triggered with a toggle class.
To get all the images, I'm using the Webpack 'require.context' function paired to the url-loader to have an array of base64 data url to use them as the new source for the background.
The way I've done that works as expected in Chrome (69.0.3497.100), Opera (56.0.3051.43) and Firefox (62.0.3). But it doesn't work well in Safari (12.0), I can see some "glitches".
When I inspect the page, I can see that the animation is triggered correctly, but the images appear after it, and sometimes the image is not visible.
Another strange behavior, is that it affects fixed element that are above the section that contains the divs, they are blinking.
I recorded the problem so you can see what I mean: https://www.youtube.com/watch?v=EO-9Ks-FhOo
There's also a staging version of it here. http://ferrarism.at/today/staging
Here's my React component :
import React from "react"
function importAll(r) {
return r.keys().map(r);
}
const imageArray = importAll(require.context('../img/clients', true));
export default class ClientReel extends React.Component {
constructor(props){
super(props);
this.state = {
images: imageArray
}
}
render(){
const {images} = this.state
var count;
const randomClient = [];
for (count = 1; count <= 4; ++count) {
var i = Math.floor((Math.random() * (images.length - count)) + 1);
randomClient.push(images[i]);
images[i] = images[images.length - count];
}
const ImagesToRender = randomClient.map((item, i) => {
return (
<div key={i} className="clientReel-item">
<div className="itemImage" style={{ background: `url(${item}) center center / 100% no-repeat` }}></div>
</div>
)
})
return(
<React.Fragment>
{ImagesToRender}
</React.Fragment>
)
}
componentDidMount(){
const {images} = this.state
const reelItemImage = document.querySelectorAll(".itemImage")
const reelItems = document.querySelectorAll(".clientReel-item")
var i = 0;
var f = 0;
var timing = 500;
(function loop() {
setTimeout(function () {
reelItems[i].classList.toggle("reelFlip")
}, timing - 100)
if (f < (images.length - 1)) {
f++;
reelItemImage[i].style.background = "url(" + images[f] + ") center center / 100% no-repeat"
} else {
f = 0;
reelItemImage[i].style.background = "url(" + images[f] + ") center center / 100% no-repeat"
}
if (i < (reelItems.length - 1)) {
i++;
} else {
i = 0;
}
setTimeout(loop, timing);
})();
}
}
Here's my component compiled css:
.section__client-reel .wrapper #clientReel .clientReel-item {
flex-basis: 21.739%;
height: 91px;
margin: 18px 0;
transform: rotateX(0deg);
transition: all 0.5s cubic-bezier(0.3, 1, 0.3, 1);
-webkit-transition: all 0.5s cubic-bezier(0.3, 1, 0.3, 1);
}
.section__client-reel .wrapper #clientReel .clientReel-item .itemImage {
width: 100%;
height: 100%;
}
.section__client-reel .wrapper #clientReel .reelFlip {
transform: rotateX(-180deg);
-webkit-transform: rotateX(-180deg);
transition: all 0.5s cubic-bezier(0.3, 1, 0.3, 1);
-webkit-transition: all 0.5s cubic-bezier(0.3, 1, 0.3, 1);
}
.section__client-reel .wrapper #clientReel .reelFlip .itemImage {
transform: rotateX(180deg);
-webkit-transform: rotateX(180deg);
}
It's been hours that I'm looking for a solution but I found nothing. If you have some idea, feel free !
Upvotes: 0
Views: 1911
Reputation: 97
[FIX]
Adding transform: translate3D(0,0,0)
to the parent element solved the problem
Upvotes: 1
Reputation: 97
[EDIT] Just tried to do it with PHP, I encountered the exact same issue as with React, so now I'm almost sure that it's a css related problem.
It happens with this Css property:
transform: rotateX(-180deg)
If I use:
transform: rotateZ(-180deg)
instead of the rotateX there's no more "glitches" But I would like to have it on rotateX. Using TweenMax could be a valid option, right? (I already have GSAP as a dependency)
Upvotes: 0