Animations stop working after building and deploying to Firebase - javascript

I'm having a problem where my animations stop working once I npm run-script build and firebase deploy my react app to Firebase hosting.
No idea why this is happening, I've added every web browser compatible keyframes.
Here's what my app looks like when ran on localhost (npm start):
And then what it looks like hosted from firebase:
It's like it can't read my keyframe animations.
Here's index.js:
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import { Provider } from "react-redux";
import { createStore, applyMiddleware, compose, combineReducers } from "redux";
import thunk from "redux-thunk";
import * as serviceWorker from "./serviceWorker";
import userReducer from "./store/reducers/user";
import { WithClass } from "./hoc/WithClass";
import classes from "./index.module.css";
import App from "./App";
// Icons made by Freepik from www.flaticon.com
// Reducers
const rootReducer = combineReducers({
user: userReducer,
});
// Store
const store = createStore(rootReducer, applyMiddleware(thunk));
const app = (
<Provider store={store}>
<WithClass>
<BrowserRouter>
<App />
</BrowserRouter>
</WithClass>
</Provider>
);
ReactDOM.render(app, document.getElementById("root"));
App.js:
import React from "react";
import { Route, Switch, withRouter, Redirect } from "react-router-dom";
import HomePage from "./pages/HomePage/HomePage";
import AboutPage from "./pages/AboutPage/AboutPage";
import WorkPage from "./pages/WorkPage/WorkPage";
import PhotographyPage from "./pages/PhotographyPage/PhotographyPage";
import ContactPage from "./pages/ContactPage/ContactPage";
import { WithClass } from "./hoc/WithClass";
/**
* Contains switch routing to components
*
* Called by index.js in ReactDOM.render()
*/
const App = () => {
return (
<WithClass>
<Switch>
<Route path="/about" exact component={AboutPage} />
<Route path="/work" exact component={WorkPage} />
<Route path="/photography" exact component={PhotographyPage} />
<Route path="/contact" exact component={ContactPage} />
<Route path="/" exact component={HomePage} />
<Redirect to="/" />
{/* Redirect anything other than routes specified to "/" */}
</Switch>
</WithClass>
);
};
export default withRouter(App);
HomePage.js:
import React, { useEffect } from "react";
import AnimatedSlideShowText from "../../components/UI/AnimatedSlideShowText/AnimatedSlideShowText";
import HeaderAnimated from "../../components/UI/HeaderAnimated/HeaderAnimated";
import HeaderStatic from "../../components/UI/HeaderStatic/HeaderStatic";
import SocialMediaFooter from "../../components/UI/SocialMediaFooter/SocialMediaFooter";
import { useDispatch, useSelector } from "react-redux";
import { loadedOnce } from "../../store/actions/user";
import classes from "./HomePage.module.css";
const HomePage = () => {
const dispatch = useDispatch();
const didLoadOnce = useSelector((state) => state.user.loadedOnce);
useEffect(() => {
setTimeout(() => {
dispatch(loadedOnce());
}, 2000);
}, []);
return (
<div className={classes.MainContainer}>
<div className={classes.HeaderContainer}>
{didLoadOnce ? <HeaderStatic /> : <HeaderAnimated />}
</div>
<div className={classes.BodyContainer}>
<div className={classes.NameContainer}>
<AnimatedSlideShowText tag="h1">
Christian Nicoletti
</AnimatedSlideShowText>
<AnimatedSlideShowText
tag="h2"
mainTextStyle={classes.Title}
>
Software Engineer
</AnimatedSlideShowText>
<AnimatedSlideShowText
tag="h3"
mainTextStyle={classes.School}
>
University of California, Santa Cruz graduate
</AnimatedSlideShowText>
</div>
<div className={classes.FooterContainer}>
<SocialMediaFooter />
</div>
</div>
</div>
);
};
export default HomePage;
HomePage.module.css:
.MainContainer {
width: 100vw;
height: 100vh;
min-width: 1500px;
}
.BodyContainer {
display: flex;
height: 100%;
justify-content: center;
margin-left: 20%;
flex-direction: column;
}
.NameContainer {
display: flex;
height: 250px;
width: 500px;
}
.Title {
margin-top: 60px;
-webkit-animation-delay: 0.2s;
animation-delay: 0.2s;
}
.School {
margin-top: 120px;
-webkit-animation-delay: 0.3s;
animation-delay: 0.3s;
}
.HeaderContainer {
position: absolute;
right: 100px;
}
.FooterContainer {
width: 500px;
}
AnimatedSlideShowText.js:
import React from "react";
import classes from "./AnimatedSlideShowText.module.css";
const AnimatedSlideShowText = (props) => {
const CustomTag = `${props.tag}`;
return (
<CustomTag className={`${classes.MainText} ${props.mainTextStyle}`}>
{props.children}
</CustomTag>
);
};
export default AnimatedSlideShowText;
AnimatedSlideShowText.module.css:
.MainText {
color: white;
position: absolute;
opacity: 0;
margin-left: -10%;
font-family: Calibri;
font-weight: 300;
-webkit-animation: slide 0.5s forwards;
animation: slide 0.5s forwards;
}
#-o-keyframes slide {
100% {
margin-left: 0%;
opacity: 100%;
}
}
#-ms-keyframes slide {
100% {
margin-left: 0%;
opacity: 100%;
}
}
#-moz-keyframes slide {
100% {
margin-left: 0%;
opacity: 100%;
}
}
#-webkit-keyframes slide {
100% {
margin-left: 0%;
opacity: 100%;
}
}
#keyframes slide {
100% {
margin-left: 0%;
opacity: 100%;
}
}
#-webkit-keyframes show {
/* Chrome, Safari */
0% {
width: 100%;
}
100% {
width: 0%;
}
}
#-moz-keyframes show {
/* FF */
0% {
width: 100%;
}
100% {
width: 0%;
}
}
#-ms-keyframes show {
/* IE10 */
0% {
width: 100%;
}
100% {
width: 0%;
}
}
#-o-keyframes show {
/* Opera */
0% {
width: 100%;
}
100% {
width: 0%;
}
}
#keyframes show {
0% {
width: 100%;
}
100% {
width: 0%;
}
}
I'd add more component source code, but I think AnimatedSlideShowText is all that is needed to understand the problem.
So again, I'm just trying to get my animations to work when built and deployed. I'm not sure why they would stop working when built and deployed.
Is it possible that using module.css has an impact on animations when built/deployed? Any help would be super appreciated, and if you need more source code let me know.

I've had a similar problem before but I was using a CSS framework. The problem was with the build cache on my hosting provider. When using create-react-app (that uses Webpack), on the build stage happens the so called 'tree-shake'. It gets rid of unused styles, classes etc from your modules.
A module that works locally might not work on production because it was rid off on your first build and is then not used on the new build due to the build cache.
I don't know if it's the solution to your problem but I suggest you check it out since it worked for me in the past.

Ok so! I managed to fix it. I thought this was a lot more complex than it actually was.
Short answer: I had to change all my opacity: 100% to opacity: 1 and suddenly everything appeared and worked correctly.
Long answer: I had to dabble in the console for a bit, and realized that all my components and text were there, but just not showing up. I played with the animations by disabling and re-enabling, and stuff would flicker for a second. I realized that it was rendering the opacity as: opacity: 1% instead of opacity: 100%. Apparently, when building with npm run-script build, it acts as if 100% has trailing zeros(??).
Anyway, I appreciate the help, and everything works perfectly now.

Related

Why is my Swiper render buggy at the first time render using React

I'm using React and trying to fetch some of my anime into the home banner using Swiper
I don't know why when I refresh my page, it'll only render at half of the swiper.
Here's how it display:
However, if I press the next or back button, it'll display normally again.
Here's my code in my Home Component:
import { useState, useEffect } from "react"
import ReactHlsPlayer from 'react-hls-player';
import './home.css'
import { supabase } from '../../supabaseClient'
import { Swiper, SwiperSlide } from 'swiper/react'
import SwiperCore, { Pagination,Navigation } from 'swiper';
import 'swiper/css'
SwiperCore.use([Pagination,Navigation]);
function Home(){
useEffect(async ()=>{
fetchAnime()
}, [])
const [animeDetail, setAnimeDetail] = useState([])
async function fetchAnime() {
const { data } = await supabase
.from ('anime')
.select ()
setAnimeDetail(data)
}
return (
<>
<div className="spacer">
</div>
<div className="home-section">
<h2>Home Page</h2>
<Swiper
centeredSlides={true}
slidesPerView={7}
spaceBetween={10}
loop={true}
pagination={false}
navigation={true} className="mySwiper">
{animeDetail.map((element, i)=>
(
<SwiperSlide key = {i}><img src={element.anime_image}/></SwiperSlide>
)
)}
</Swiper>
</div>
</>
)
}
export default Home
And here's my Home CSS, sorry if it's a bit messy, I'm still trying it here and there, but I'm stuck.
.swiper {
width: 100%;
height: 100%;
margin-left: auto;
margin-right: auto;
}
.swiper-wrapper{
width: 100%
}
.swiper-slide {
text-align: center;
font-size: 18px;
display: flex;
justify-content: center;
align-items: center;
max-width: 280px;
}
.swiper-slide img {
display: block;
box-sizing: border-box;
border: none;
max-height: 350px;
min-height: 350px;
-o-object-fit: cover;
object-fit: cover;
transition: all .3s ease;
opacity: 0.5
}
.swiper-slide-active {
transform: scale(1.2);
z-index: 2
}
.swiper-slide-active img{
transition: all .3 ease;
opacity: 1
}
And if someone figures it out, please help me a bit, I tried to whenever the item in the middle is in active, it'll pop out bigger, but I can't do it with transform: scale(number) - I have tried it (It does get bigger when it's active but it doesn't display bigger at the height, I haven't figured it out some ways at the moment)
you have to set the initialSlide prop on the Swiper element to an index of the slide in the middle. so that the slider starts from there.
Also in this case, you can set the centeredSlides prop to true as the active slide remains in the middle.
Here's a possible fix for your issue and for everyone else that comes here looking for answers.
Use conditional rendering of the Swiper component, something like this:
{animeDetail.length>0 && <Swiper
centeredSlides={true}
slidesPerView={7}
spaceBetween={10}
loop={true}
pagination={false}
navigation={true} className="mySwiper">
{animeDetail.map((element, i)=>
(
<SwiperSlide key = {i}><img src={element.anime_image}/></SwiperSlide>
)
)}
</Swiper>}

Using router link on a div in react

Can anyone help me incorporate routing in my project? I am trying to route to a different page when a div is clicked but for some reason the div does not show up unless you put something in it(the text "Card") and also not how I styled it in my stylesheet.
The div is inside a component I did not fully finish making yet, but essentially when you click on this parent div it takes you to a different page.
The code in the main App component is this:
import React from 'react';
import {BrowserRouter as Router, Switch, Route} from 'react-router-dom'
import { Link } from 'react-router-dom'
import NAVBAR from './components/NAVBAR.js';
import CARD from './components/CARD.js'
import CONTENTS from './components/CONTENTS.js'
import './App.css'
import HOME_PAGE from './components/pages/HOME_PAGE.js';
function App() {
return (
<>
<body>
<header>
<NAVBAR />
</header>
<div className = "info-container">
<div className="cards-container">
<Link to = "/components/pages/HOME_PAGE.js"><CARD id = "pendulum"/></Link>
</div>
<CONTENTS />
</div>
<Router>
<Switch>
<Route exact path = "/components/pages/HOME_PAGE.js" component = {HOME_PAGE}/>
</Switch>
</Router>
</body>
</>
);
}
export default App;
The code of the div components(CARD) is this:
import React from 'react'
import './card.css'
import { Link } from 'react-router-dom'
export default function CARD({ id }) {
return (
<>
<div className = "card-container">
</div>
</>
)
}
I basically wrapped the div components(CARD) with a Link tag and pointed it towards the page I want it to render. But the div just does not appear(It does appear if put some text inside the Link tags but also not how I styled the div). The styles are simple but it might be a styling issue so here are the styles:
card.css:
.card-container{
height: 47.1%;
width: 100%;
background-image: linear-gradient(to right, #0c0624, #0c0625, #0b0726, #0b0727, #0a0828, #090d2b, #08112e, #071531, #071b36, #07213b, #082740, #0b2d45);
border-radius: 15px;
margin-bottom: 20px;
}
App.css:
*, *::before, *::after{
box-sizing: border-box;
}
body{
margin: 0;
overflow: none;
background-image: linear-gradient(to left top, #3e000b, #39030a, #330508, #2e0607, #290606, #270505, #260505, #240404, #250303, #260203, #260102, #270002);
}
.info-container{
display: flex;
flex-wrap: nowrap;
justify-content: center;
align-self: center;
height: 90vh;
width: 100%;
padding: 12px;
position: relative;
overflow: hidden;
scroll-behavior: smooth;
}
.cards-container{
display: flex;
flex-wrap: wrap;
height: 100%;
width: 100%;
margin: 5px;
margin: 10px 0px 0px 0px;
border-radius: 15px;
overflow: scroll;
}
If i get you right, you can't wrap a div with a Link what you must know is that a react-router-dom Link component is just a regular html a tag. What you can essentially do to get this to work is to use the react-router-dom useHistory() hook and push or replace the history on your single page application. How you can do it?
In your Card component, which is the component yiu are trying to click and navigate you somewhere do this
import React from 'react'
import './card.css'
import { useHistory } from 'react-router-dom'
export default function CARD({ id }) {
const history = useHistory()
const navigate =() => history.push('/components/pages/HOME_PAGE.js' )
return (
<div className = "card-container" onClick={navigate} >
</div>
)
}
I hope you get the idea
Little addition, I'm just learning react it's probably not the best solution but it seems to work for me.
Exactly you can use history.push to do everything, for example history.push(path/${id}). Hope you get the idea
---> reply
function TourItem({ currentItems }) {
const [itemId, setItemId] = useState();
useEffect(()=>{
if (itemId) {
history.push(`/tour-detail/${itemId}`);
}
}, [itemId]);
return (
<div className={cx("wrapper")}>
{currentItems && currentItems.map(item => (
<div key={item.id} className={cx("item")} onClick={()=>setItemId(item.id)}>
<div className={cx("inner")}>
<div className={cx("image")}>
<img src={item.images[0]} alt={item.tourName} />
</div>
<div className={cx("meta")}>
<h4 className={cx("tour-name")}>
<Link to={`/tour-detail/${item.id}`}>{item.tourName}</Link>
</h4>
<p>Khởi hành từ: <span>{item.departureFrom}</span></p>
<p>Thời gian: <span>{item.time}</span></p>
<p>Giá từ: <span><FormatPrice>{item.price}</FormatPrice> VNĐ</span></p>
</div>
</div>
</div>
))}
</div>
);
}

how to show min and max value in horizontal manner?

I am using react-d3-speedometer package for a speedometer. i am able to implement it. but it's max value and minimum value i need to display in horizontal manner. npm package
code
import React, { Component } from 'react';
import ReactSpeedometer from "react-d3-speedometer";
export default class GaugeChart extends Component {
constructor(props) {
super(props);
}
render() {
return <React.Fragment>
<ReactSpeedometer
maxValue={7000}
value={7000}
valueFormat=".1s"
needleColor="red"
startColor="#ffc7ba"
segments={630}
maxSegmentLabels={1}
endColor="#FF471A"
/>
</React.Fragment>
}
}
current view
expected view
Use Below style and add in your CSS file
<style>
text.segment-value:nth-child(1){
font-size: 16px !important;
font-weight: bold;
fill: unset !important;
transform: rotate(0deg) translate(-105px, 20px);
}
text.segment-value:nth-child(2){
font-size: 16px !important;
font-weight: bold;
fill: unset !important;
transform: rotate(0deg) translate(105px, 20px);
}
</style>
OutPut : https://prnt.sc/q5vvzg
Hope I have clear Your answer!

How trigger animation using ref in ReactJS

here my demo: https://stackblitz.com/edit/react-pwdkse note: use your browser console instead of the Stackblitz's one. Seems the browser console is much more complete in terms of information_feedback
I would trigger animation using ReactJS ref's references instead of changing className inside the element's scope. Currently nothing is happening.
What I may missing?
here my Reacts' snippets:
component
import React, { Component } from 'react';
import { render } from 'react-dom';
import './style.module.css';
class App extends Component {
constructor() {
super();
this.state = {
name: 'React'
};
this.animateRef = React.createRef();
// this.triggerAnimation = this.triggerAnimation.bind(this);
}
componentDidMount(){
// empty scope right now
}
triggerAnimation=()=>{
console.log("trigger animateRef animation")
// this.animateRef.current.style.animationName="animateElement"
// this.animateRef.current.style.animation="1.5s 4.3s 3 alternate forwards"
this.animateRef.current.className.concat(`animation_trigger`)
console.log("animateRef: ", this.animateRef)
}
render() {
return (
<div>
<p>
Start editing to see some magic happen :)
</p>
<div className="animatedElementStyle" ref={this.animateRef}>
I am rendered !
</div>
<button onClick={this.triggerAnimation}>
trigger animation
</button>
</div>
);
}
}
render(<App />, document.getElementById('root'));
stylesheet
h1, p {
font-family: Arial;
}
.animatedElementStyle{
position:absolute;
top:61%;
left:10%;
width:15w;
height:25vh;
visibility: hidden;
opacity:0;
}
.animation_trigger{
animation: animateElement 1.5s 0.5s 3 alternate forwards;
}
#keyframes animateElement{
from{
opacity:0;
visibility:hidden;
}
100%{
transform: translate(15%,0);
opacity:1;
visibility:visible;
color:orange;
font-size:3em;
}
}
thanks for any hint
You just have to change this
this.animateRef.current.className.concat(`animation_trigger`)
To:
this.animateRef.current.classList.add(`animation_trigger`);

Components not animating with react-transition-group, just updates instantly?

I'm trying to animate a sidebar component following the first section on this page. When I follow this the component doesn't animate, but simply mounts/unmounts.
The component SidePage is as follows:
import React from "react"
import { TransitionGroup, CSSTransition } from "react-transition-group"
import "./sidePage.css"
class SidePage extends React.Component {
componentWillMount() {
console.log("will mount")
}
componentDidMount() {
console.log("did mount")
}
componentWillUnmount() {
console.log("will unmount")
}
render() {
const { content, sidePageOpen } = this.props
return (
<TransitionGroup component={null}>
{sidePageOpen && (
<CSSTransition key={content.id} classNames="sidepage" timeout={2000}>
<div
key={content.id}
className="sidepage"
dangerouslySetInnerHTML={{ __html: content.html }}
/>
</CSSTransition>
)}
</TransitionGroup>
)
}
}
export default SidePage
and the css file:
.sidepage-enter {
opacity: 0;
}
.sidepage-enter-active {
opacity: 1;
transition: all 2s;
}
.sidepage-exit {
opacity: 1;
}
.sidepage-exit-active {
opacity: 0;
transition: all 2s;
}
.sidepage {
background: white;
padding: 10px;
height: 100%;
width: 90vw;
position: absolute;
top: 0;
right: 0;
z-index: 10;
opacity: 0.4;
transition: all 0.6s;
}
Basic stuff I think — the sidePageOpen is a boolean state passed down, I have a button on another page that toggles this state. If anyone has any ideas/suggestions that would be brilliant and appreciated.
Remove the opacity property from sidepage class.
.sidepage {
background: white;
padding: 10px;
height: 100%;
width: 90vw;
position: absolute;
top: 0;
right: 0;
z-index: 10;
opacity: 0.4; // remove me
transition: all 0.6s;
}
The element get's added with a class of sidepage which has a opacity of 0.4, thats whats breaking the animation. Working demo here
Eventually found the solution — I had a styled <Wrapper> div created using emotion.sh styled components, I was using this to contain all of my content, not sure why but this didn't allow any animations — changing this to a simple <div> seemed to fix it.
Edit: Probably because it was recreating the Wrapper component on every state change.

Categories