How to make an onClick event on interactive map Leaflet? - reactjs

I created interactive map. It work quite good but I cannot send currentId or Name of volveship I click. I get error that this property is undefined and I do not know how to fix this. I use this date https://github.com/ppatrzyk/polska-geojson/blob/master/wojewodztwa/wojewodztwa-min.geojson?short_path=898b1e2
import React, { useState } from 'react';
import {
MapContainer,
TileLayer,
Polygon
} from 'react-leaflet';
import 'leaflet/dist/leaflet.css';
import { statesData } from './data';
import './App.css';
const center = [52.237049, 21.017532];
export default function App() {
const [currentID, setCurrentID] = useState();
return (
<>
<MapContainer
center={center}
zoom={6}
style={{ width: '100vw', height: '100vh' }}
>
<TileLayer
url="https://api.maptiler.com/maps/basic/tiles.json?key=MyKey"
attribution='© MapTiler © OpenStreetMap contributors'
/>
{
statesData.features.map((state) => {
const coordinates = state.geometry.coordinates[0].map((item) => [item[1], item[0]]);
return (<Polygon
pathOptions={{
fillColor: '#ae4a84',
fillOpacity: 0.7,
weight: 2,
opacity: 1,
dashArray: 3,
color: 'white'
}}
positions={coordinates}
eventHandlers={{
mouseover: (e) => {
const layer = e.target;
layer.setStyle({
dashArray: "",
fillColor: "#003263",
fillOpacity: 0.7,
weight: 2,
opacity: 1,
color: "white",
})
},
mouseout: (e) => {
const layer = e.target;
layer.setStyle({
fillOpacity: 0.7,
weight: 2,
dashArray: "3",
color: 'white',
fillColor: '#ae4a84'
});
},
click: (e) => {
setCurrentID(e.target.id) }
}}
/>)
})
}
</MapContainer>
</>
);
}

Related

How can I get my Modal in Leaflet to appear in front of the map?

I am using leaflet to display a map of Jamaica which should prompt a modal to pop up once the user clicks on one of the parishes (states). Currently the modal appears behind the map once a parish is clicked.
Below I have placed the react code.
const center = [18.19368269899244, -77.39527725784035];
export default function App() {
const [show, setShow] = useState(false)
return (
<MapContainer
center={center}
zoom={9}
style={{ width: '100vw', height: '100vh' }}
>
<TileLayer
url="https://api.maptiler.com/maps/basic/256/{z}/{x}/{y}.png?key=73p7aIRQ0vUQYQlwBn1Q"
attribution='© MapTiler © OpenStreetMap contributors'
/>
{
parishesData.features.map((parish) => {
const coordinates = parish.geometry.coordinates[0].map((item) => [item[1], item[0]]);
console.log(parish.properties.name, coordinates)
const color = (d) => {
return d > 1000 ? '#800026' :
d > 500 ? '#BD0026' :
d > 200 ? '#E31A1C' :
d > 100 ? '#FC4E2A' :
d > 50 ? '#FD8D3C' :
d > 20 ? '#FEB24C' :
d > 10 ? '#FED976' :
'#FFEDA0';
}
return (<Polygon
pathOptions={{
fillColor: color(parish.properties.density),
fillOpacity: 0.7,
weight: 2,
opacity: 1,
dashArray: 3,
color: 'white'
}}
positions={coordinates}
eventHandlers={{
mouseover: (e) => {
const layer = e.target;
layer.setStyle({
dashArray: "",
fillColor: "#BD0026",
fillOpacity: 0.7,
weight: 2,
opacity: 1,
color: "white",
})
},
mouseout: (e) => {
const layer = e.target;
layer.setStyle({
fillOpacity: 0.7,
weight: 2,
dashArray: "3",
color: 'white',
fillColor: color(parish.properties.density),
});
},
click: (e) => {
const layer = e.target;
setShow(true);
console.log("zoom to", parish.properties.name);
}
}}
/>)
})
}
<div className='login-modal'>
<button onClick={()=>{
console.log("button pressed")
setShow(true)
}}>Show Modal</button>
<Modal show={show} title ="Logins" onClose={()=> setShow(false)}>
<div className='modal-body'>Logins go here</div>
<div className='modal-body'>Logins go here</div>
</Modal>
</div>
</MapContainer>
);
}
I have tried changing the z-index of the MapContainer and the login modal div but the modal still appeared behind the map. Additionally I have a button that is appearing at the top left of the screen behind the map. How do I get these elements to show on top of the map where I have it zoomed in?

react The swipe animation will be performed twice

When you press the Circle button, the Box moves to the right and disappears from the screen.
Additional information (FW/tool version, etc.)
react
scss
Typescript
framer-motion
import "./style.scss";
import React, { FunctionComponent, useState } from "react";
import { useMotionValue, useTransform } from "framer-motion";
import { SwipeBox } from "./SwipeBox";
const App: FunctionComponent = () => {
const [cards, setCards] = useState([
const onClic = () => {
animateCardSwipe({ x: -1400, y: 0 });
}; <div
style={{
width: "400px",
height: "300px",
background: `${card.background}`
}}
>
) : (
</div>
);
};
export default App;
The problem is that the animation is happening on mount and you're updating state twice inside the animateCardSwipe function:
const animateCardSwipe = (animation: { x: number, y: number }) => {
setAnime({ ...anime, animation });
setTimeout(() => {
x.set(0);
y.set(0);
setCards([...cards.slice(0, cards.length - 1)]);
}, 200);
};
I personally like to use a more imperative approach here for starting the animation using animate:
const animateCardSwipe = (animation: { x: number, y: number }) => {
animate(x, animation.x, {
duration: 1,
onComplete: () => {
x.set(0);
y.set(0);
setCards([...cards.slice(0, cards.length - 1)]);
},
});
};
This implementation also waits for the animation to complete before rearranging the cards.
Full example:
import React, { FunctionComponent, useState } from "react";
import {
animate,
useAnimation,
useMotionValue,
useTransform,
MotionValue,
motion,
} from "framer-motion";
interface Props {
animate?: { x: number; y: number };
style: {
x?: MotionValue;
y?: MotionValue;
zIndex: number;
rotate?: MotionValue;
};
card: { text: string; background: string };
}
const SwipeBox: React.FunctionComponent<Props> = (props) => {
return (
<motion.div
animate={props.animate}
className="card"
style={{
...props.style,
background: "white",
borderRadius: "8px",
display: "grid",
top: 0,
left: 0,
placeItems: "center center",
position: "absolute",
width: "100%",
}}
transition={{ duration: 1 }}
>
{props.children}
</motion.div>
);
};
const App: FunctionComponent = () => {
const controls = useAnimation();
console.log(controls);
const [cards, setCards] = useState([
{ text: "Up or down", background: "red" },
{ text: "Left or right", background: "green" },
{ text: "Swipe me!", background: "gray" },
{ text: "Swipe me!", background: "purple" },
{ text: "Swipe me!", background: "yellow" },
]);
const x = useMotionValue(0);
const y = useMotionValue(0);
const animateCardSwipe = (animation: { x: number; y: number }) => {
animate(x, animation.x, {
duration: 1,
onComplete: () => {
x.set(0);
y.set(0);
setCards([...cards.slice(0, cards.length - 1)]);
},
});
};
const [anime, setAnime] = useState<{ animation: { x: number; y: number } }>({
animation: { x: 0, y: 0 },
});
const rotate = useTransform(x, [-950, 950], [-30, 30]);
const onClickLeft = () => {
animateCardSwipe({ x: 1400, y: 0 });
};
const onClickRight = () => {
animateCardSwipe({ x: -1400, y: 0 });
};
return (
<div style={{ display: "flex", flexDirection: "column" }}>
<div>
{cards.map((card, index) =>
index === cards.length - 1 ? (
<SwipeBox
animate={anime.animation}
card={card}
key={index}
style={{ x, y, zIndex: index, rotate: rotate }}
>
<div
style={{
width: "400px",
height: "300px",
background: `${card.background}`,
}}
>
{card.text}
</div>
</SwipeBox>
) : (
<SwipeBox
card={card}
key={index}
style={{
zIndex: index,
}}
>
<div
style={{
width: "400px",
height: "300px",
background: `${card.background}`,
}}
>
{card.text}
</div>
</SwipeBox>
)
)}
</div>
<div style={{ zIndex: 999 }}>
<button onClick={onClickRight}>✖️</button>
<button onClick={onClickLeft}>○</button>
</div>
</div>
);
};
export default App;
Codesandbox Demo

Three.js and React-three-fiber model is completely black?

This model seems to load completely black - but others do not. https://d1iczm3wxxz9zd.cloudfront.net/e4a5c9ee-9fa0-46b2-9ff5-8e52e6286a3b/5ee3baf2-2524-4617-99a7-2a91b4bd20c1/11/ITEM_PREVIEW1.glb
Anyone happen to know why?
Other GLB files have no issues with textures. This one seems to have an issue. But when loaded in other online GLB viewers it loads fine.
Using reactjs, react-three-fibre and three.js.
Here is the three.js code:
import * as THREE from "three";
import React, { useRef, Suspense } from "react";
import { Canvas, useThree, useFrame, extend } from "react-three-fiber";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { Box } from "./Box";
import { Model } from "./Model";
extend({ OrbitControls });
const Controls = (props) => {
const { gl, camera } = useThree();
const ref = useRef();
//#ts-ignore
useFrame(() => ref.current.update());
//#ts-ignore
return <orbitControls ref={ref} args={[camera, gl.domElement]} {...props} />;
};
const ThreeJSComponent = (props) => {
const {
width,
height,
fallback,
modelSuccess,
setBackground,
background,
} = props;
return (
<div
style={{
width: width,
height: height,
position: "relative",
}}
>
<div
onClick={() => setBackground("black")}
style={{
position: "absolute",
top: "0",
right: "0",
width: "25px",
borderRadius: "5px",
height: "25px",
background: "black",
zIndex: 50,
border: "white 1px solid",
}}
></div>
<div
onClick={() => setBackground("white")}
style={{
position: "absolute",
top: "0",
right: "50px",
width: "25px",
height: "25px",
borderRadius: "5px",
background: "white",
border: "black 1px solid",
zIndex: 50,
}}
></div>
<Canvas
style={{
width: "100%",
height: "100%",
background: background,
}}
onCreated={({ gl }) => {
gl.shadowMap.enabled = true;
gl.shadowMap.type = THREE.PCFShadowMap;
//#ts-ignore
gl.outputEncoding = false;
gl.toneMappingExposure = 0;
}}
camera={{
position: [0, 0, 10],
isPerspectiveCamera: true,
}}
//shadowMap
>
{" "}
<ambientLight intensity={0x222222} />
<Suspense fallback={fallback}>
<Model url={props.modelURL} modelSuccess={modelSuccess} />
</Suspense>
<Controls
autoRotate
enablePan={true}
enableZoom={true}
enableDamping
dampingFactor={0.5}
rotateSpeed={1}
/>
</Canvas>
</div>
);
};
export default ThreeJSComponent;
and Model:
import React, { useState, useEffect } from "react";
import { useLoader } from "react-three-fiber";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
export const Model = (props) => {
const { url, modelSuccess } = props;
const [model, setModel] = useState();
const loadedModel = useLoader(GLTFLoader, url, (loader) => {
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath("/draco-gltf/");
loader.setDRACOLoader(dracoLoader);
});
useEffect(() => {
if (!model) {
setModel(loadedModel);
}
}, []);
if (model) {
modelSuccess();
return (
<primitive
position={[0, 0, 0]}
scale={[1, 1, 1]}
object={model.scene}
dispose={null}
></primitive>
);
} else return null;
};
you dont need setState, useLoader uses suspense, loadedModel will contain the model guaranteed, or the component will throw.
const { scene } = useLoader(GLTFLoader, url, ...)
return <primitive object={scene} dispose={null} />
ambientlight intensity is also wrong, 0 is no light, 1 is the default, then it goes higher. you're giving it an impossibly high value.
other than that it could be that the model is outside the cameras frustrum (too big), it could also be too small. or the path is wrong (it should either be in /public, or you need to it import modelUrl as "./model.glb".
here's a working example: https://codesandbox.io/s/r3f-ibl-envmap-simple-k7q9h?file=/src/App.js
import React, { Suspense } from 'react'
import { Canvas, useLoader } from 'react-three-fiber'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { OrbitControls, Html, draco } from 'drei'
function Model({ url }) {
const { scene } = useLoader(GLTFLoader, url, draco())
return <primitive object={scene} dispose={null} />
}
export default function App() {
return (
<Canvas camera={{ position: [0, 5, 1] }}>
<directionalLight position={[10, 10, 5]} intensity={2} />
<directionalLight position={[-10, -10, -5]} intensity={1} />
<OrbitControls />
<Suspense fallback={<Html>loading..</Html>}>
<Model url="/suzanne-draco.glb" />
</Suspense>
</Canvas>
)
}

How to update fillColor of polygonOptions with props?

I'm drawing custom polygon with DrawingManager.
I would like of modify fillColor of polygon with props. What should I do?
import React from 'react'
import GoogleMap from 'google-map-react'
export default (props: any) => {
let {color} = props
const handleGoogleMapApi = (google: any) => {
console.log(google)
var drawingManager = new google.maps.drawing.DrawingManager({
drawingMode: google.maps.drawing.OverlayType.POLYGON,
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: ['polygon'],
},
polygonOptions: {
strokeWeight: 5,
fillOpacity: 0.45,
fillColor: color,
},
})
google.maps.event.addListener(drawingManager, 'polygoncomplete', (polygon: any) => {
let points: any = polygon.getPath().getArray()
points.forEach((point: any) => {
const {lat, lng} = point
console.log(lat(), lng())
})
})
google.map.setMapTypeId('satellite')
drawingManager.setMap(google.map)
}
return (
<div style={{height: '60%', width: '100%'}}>
<GoogleMap
defaultCenter={{lat: -19.810968444640704, lng: -43.54377112158203}}
defaultZoom={15}
yesIWantToUseGoogleMapApiInternals
onGoogleApiLoaded={handleGoogleMapApi}
onChange={handleGoogleMapApi}
bootstrapURLKeys={{libraries: 'drawing', key: `${process.env.REACT_APP_PROVIDER_GOOGLE}`}}
/>
</div>
)
}
I have a lot of experience working with GIS + React, but never work with google API. I'd dig into your problem and there's suggestion:
Probably you've chosen wrong library. I've read source code, examples of "google-map-react" - it's destitute maintained.
There are more popular alternatives such a https://github.com/fullstackreact/google-maps-react#polygon
Even from example you'll get how to change color of Polygon.
render() {
const center = this.getvalue();
const {area=[]} = this.props;
console.log(this.props);
return (
<googlemap
defaultzoom={14}
center={center}
onrightclick={this.erasepolygon}>
{
this.state.bounds.length != 0 &&
<polygon
paths={this.state.bounds}
options={{
strokecolor:"#d34052",
fillcolor:"#d34052",
strokeopacity:"0.5",
strokeweight:'2'
}}
/>
}
{
<drawingmanager
drawingmode={google.maps.drawing.overlaytype.polygon}
onpolygoncomplete={this.handleoverlay}
defaultoptions={{
drawingcontrol: true,
drawingcontroloptions: {
position: google.maps.controlposition.top_center,
drawingmodes:['polygon']
},
polygonoptions: {
fillcolor: `#ffffff`,
fillopacity: 0.7,
strokeweight: 1,
clickable: true,
editable: true,
zindex: 1
}
}}
/>
}
<marker
position={center}
/>
{
area.map((value, index) => {
return (
<polygon
key={index}
paths={value.bounds}
options={{
strokecolor:"#e34052",
fillcolor:"#e3352",
strokeopacity:"0.5",
strokeweight:'2'
}}
/>
)
})
}
</googlemap>
)
}
}

Can't declare keyframe within withStyles HOC (container.addRule(...).addRule is not a function)

So I got the latest versions of jss and material ui.
Im using withStyles HOC and dynamically changing css in styles object, but I cant seem to be able to declare keyframes in css. Im also using nextjs if that makes any difference. Ive looked at how material-ui declares their animations, and I'm following their example https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/ButtonBase/TouchRipple.js.
import React, { useEffect, useState } from "react";
import classnames from "classnames";
import PropTypes from "prop-types";
import { withStyles, makeStyles } from "#material-ui/core/styles";
import { sectionAnchors, maxContentWidth } from "../../../util/constants";
import LearnMoreLink from "./LearnMoreLink";
import SectionContent from "../../common/SectionContent";
import content from "../../../../content";
import useRealHeight from "../../../util/useRealHeight";
import SplashHeading from "./SplashHeading";
import { singleHeight, doubleHeight } from "../../common/Footer";
import GetStartedForm from "./GetStartedForm";
import { withRouter } from "next/router";
import SwipeableTextMobileStepper from "./SwipeableTextMobileStepper";
import { Link } from 'next/router'
import Radio from '#material-ui/core/Radio';
import RadioGroup from '#material-ui/core/RadioGroup';
import FormHelperText from '#material-ui/core/FormHelperText';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import FormControl from '#material-ui/core/FormControl';
import FormLabel from '#material-ui/core/FormLabel';
import { green } from '#material-ui/core/colors';
import RadioButtonUncheckedIcon from '#material-ui/icons/RadioButtonUnchecked';
import RadioButtonCheckedIcon from '#material-ui/icons/RadioButtonChecked';
import Switch from '#material-ui/core/Switch';
import Button from '#material-ui/core/Button';
const styles = theme => ({
heading: {
marginBottom: theme.spacing.unit * 6
},
headingColored: {
marginBottom: 0,
color: theme.palette.primary.dark
},
container: {
width: "100%",
// '#keyframes fade': {
// '0%': {
// opacity: 1
// },
// '100%': {
// opacity: 0
// }
// },
'#keyframes enter': {
'0%': {
transform: 'scale(0)',
opacity: 0.1,
},
'100%': {
transform: 'scale(1)',
opacity: 0.3,
},
},
// backgroundColor: theme.palette.primary.dark,
// background: 'url(https://images.newscientist.com/wp-content/uploads/2019/04/08111018/screenshot-2019-04-08-10.24.34.jpg)',
backgroundImage: props => props.background,
backgroundSize: "cover",
// animation: '$fadeMe linear 1s infinite',
// animationName: '#fadeMe',
// animdationDuration: '1s',
// animation:
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center"
},
containerWizard: {
background: "none",
marginBottom: -doubleHeight,
paddingBottom: doubleHeight + theme.spacing.unit * 3,
[theme.breakpoints.up("sm")]: {
marginBottom: -singleHeight,
paddingBottom: singleHeight + theme.spacing.unit * 3
}
},
inner: {
maxWidth: maxContentWidth,
width: "100%",
flex: "1 0 auto",
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center"
},
flex: {
flex: "1 0 auto"
},
form: {
width: "100%",
maxWidth: maxContentWidth / 2,
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center"
}
});
// http://www.coverbash.com/wp-content/covers/caeli_flowers_facebook_cover.jpg
function SplashLogic() {
const [selectedValue, setSelectedValue] = React.useState(1);
let int
useEffect(() => { int = init(1) }, []);
let background = selectedValue == 1 ? bG('http://www.coverbash.com/wp-content/covers/caeli_flowers_facebook_cover.jpg') :
bG('https://images.newscientist.com/wp-content/uploads/2019/04/08111018/screenshot-2019-04-08-10.24.34.jpg?')
const handleChange = event => {
setSelectedValue(event.target.value);
clearInterval(int)
int = init(event.target.value)
};
function init(num) {
return setInterval(() => {
background = bG('http://www.coverbash.com/wp-content/covers/caeli_flowers_facebook_cover.jpg')
setSelectedValue(2)
}, 4000)
}
return <SplashFull {...{ setSelectedValue, selectedValue, background, handleChange }}></SplashFull>
}
const SplashSection = ({ classes, router, setSelectedValue, selectedValue, background, handleChange }) => {
// const [height] = useRealHeight({ resize: false });
console.log(classes.container)
useEffect(() => {
router.prefetch("/signup");
}, []);
const onSubmit = values => {
router.push(`/signup?destination=${values.destination}`, "/signup");
};
return (
<SectionContent id={sectionAnchors.SPLASH} className={classes.container}>
<div className="bg-white opacity-50 rounded-full">
<Radio
checked={selectedValue === 1}
onChange={handleChange}
value={1}
name="radio-button-demo"
inputProps={{ 'aria-label': 'A' }}
/>
<Radio
checked={selectedValue === 2}
onChange={handleChange}
value={2}
name="radio-button-demo"
inputProps={{ 'aria-label': 'B' }}
/>
<Radio
checked={selectedValue === 3}
onChange={handleChange}
value={3}
name="radio-button-demo"
inputProps={{ 'aria-label': 'D' }}
/>
<Radio
checked={selectedValue === 4}
onChange={handleChange}
value={4}
name="radio-button-demo"
inputProps={{ 'aria-label': 'E' }}
/>
</div>
<div className={classes.inner}>
<SplashHeading
classes={{
container: classes.heading
}}
/>
<GetStartedForm className={classes.form} onSubmit={onSubmit} />
</div>
<Button variant="contained" >
Default
</Button>
<LearnMoreLink />
</SectionContent>
// <SwipeableTextMobileStepper></SwipeableTextMobileStepper>
);
};
SplashSection.propTypes = {
classes: PropTypes.object.isRequired
};
function bG(arg) {
return `url(${arg})`
}
const SplashFull = withStyles(styles)(withRouter(SplashSection));
export default SplashLogic
I get error:
container.addRule(...).addRule is not a function
TypeError: container.addRule(...).addRule is not a function
at Array.onProcessStyle (/workspace/travelcontacts/node_modules/jss-plugin-nested/dist/jss-plugin-nested.cjs.js:96:10)
at PluginsRegistry.onProcessStyle (/workspace/travelcontacts/node_modules/jss/dist/jss.cjs.js:1246:51)
at PluginsRegistry.onProcessRule (/workspace/travelcontacts/node_modules/jss/dist/jss.cjs.js:1235:26)
at Array.forEach (<anonymous>)
at RuleList.process (/workspace/travelcontacts/node_modules/jss/dist/jss.cjs.js:871:25)
at new StyleSheet (/workspace/travelcontacts/node_modules/jss/dist/jss.cjs.js:1041:16)
at Jss.createStyleSheet (/workspace/travelcontacts/node_modules/jss/dist/jss.cjs.js:2007:17)
at attach (/workspace/travelcontacts/node_modules/#material-ui/styles/makeStyles/makeStyles.js:116:39)
at /workspace/travelcontacts/node_modules/#material-ui/styles/makeStyles/makeStyles.js:256:7
at useSynchronousEffect (/workspace/travelcontacts/node_modules/#material-ui/styles/makeStyles/makeStyles.js:210:14)
at /workspace/travelcontacts/node_modules/#material-ui/styles/makeStyles/makeStyles.js:248:5
at Object.WithStyles [as render] (/workspace/travelcontacts/node_modules/#material-ui/styles/withStyles/withStyles.js:70:21)
at ReactDOMServerRenderer.render (/workspace/travelcontacts/node_modules/react-dom/cjs/react-dom-server.node.development.js:3758:44)
at ReactDOMServerRenderer.read (/workspace/travelcontacts/node_modules/react-dom/cjs/react-dom-server.node.development.js:3538:29)
at renderToString (/workspace/travelcontacts/node_modules/react-dom/cjs/react-dom-server.node.development.js:4247:27)
at render (/workspace/travelcontacts/node_modules/next-server/dist/server/render.js:86:16)
The issue appears to be resolved by not nesting #keyframes definitions. The hint was in the second application of the addRule function in the error: container.addRule(...).addRule is not a function.
Solution
Try moving your keyframe animations to the root level. So from this
const styles = theme => ({
container: {
'#keyframes enter': {
'0%': {
transform: 'scale(0)',
opacity: 0.1,
},
'100%': {
transform: 'scale(1)',
opacity: 0.3,
},
}
}
}
to this
const styles = theme => ({
'#keyframes enter': {
'0%': {
transform: 'scale(0)',
opacity: 0.1,
},
'100%': {
transform: 'scale(1)',
opacity: 0.3,
},
}
}
Hope that helps.
Interesting side note: nesting the animation another level removes the error, but does not instantiate the CSS animation.
from
const styles = theme => ({
container: {
'#keyframes enter': {
'0%': {
transform: 'scale(0)',
opacity: 0.1,
},
'100%': {
transform: 'scale(1)',
opacity: 0.3,
},
}
}
}
to
const styles = theme => ({
'#global':{ //need add into global rules
'#keyframes enter': {
'0%': {
transform: 'scale(0)',
opacity: 0.1,
},
'100%': {
transform: 'scale(1)',
opacity: 0.3,
},
}
}
}

Resources