react-lottie
react-lottie copied to clipboard
How to locate /images/ for the animation
Hey there,
So we've got a data.json full of our animation data and an /images/ directory including the images that will be animated, given to us by our designer. However, I didn't see any mention of how the /images/ paths can be found through react-lottie? Unsure if this is the correct place to ask, but if anyone has come across this issue (as I myself don't know enough about After Effects - which it was exported with), could you advise?
I have seen this issue crop up on lottie-web itself and people suggest a way so that the /images/ folder doesn't appear on export, or does react-lottie have something like lottie-web, when it comes to picking up assetPaths for the .json? To ensure it finds the images.
Apologies if this seems vague, I'm just not very well versed in the design process itself.
Hey @sgript
I solved it by creating my own json withing a javascript file.
Instead of using the animation.json
directly, create a animation.js
file where you import the image and replace the [image_in_question].png
occurrences for your image_in_question_name
. Remember to fix the folders path and delete it.
You are basically recreating the json with your own paths. This way, your image paths will be correct.
import image_in_question_name from './images/[image_in_question].png'
export default {"v": ...... ANIMATION JSON ....... };
This worked for me and I am using gatsby
.
Hope it helps!
I'm building a chrome extension and in that case images get a special path. I can access that path from javascript. How would I change the JSON so that it uses the correct path?
@wahlforss look at this example:
import img_0 from './images/img_0.png'
export default {
v: '5.2.1',
fr: 25,
ip: 1,
op: 74,
w: 500,
h: 500,
nm: 'pulseloop',
ddd: 0,
assets: [
{ id: 'image_0', w: 701, h: 632, u: '', p: img_0, e: 0 },
{
id: 'comp_0',
layers: [
{
ddd: 0,
ind: 1,
ty: 2,
nm: img_0,
cl: 'png',
refId: 'image_0',
....
I changed the u:'path-to-folder'
to u: ''
and all the occurrences where you use the image name to img_0
which represents the image direct path.
Hope it helps π
@rageofflames
Thank you man! That fixed it :)
@rageofflames @sgript
Hey! it seems you can also just place it in the public folder with the same path structure ('./public/images/img_0.png) and it will work.
haven't tested with multiple files so names might clash too, in which case renaming .png names as mentioned before will work too.
had a quick read through the animation.json and found that the structure of the json is different from the one @rageofflames posted, so because versions, YMMV.
*tested on react-lottie 1.2.3
@panzerstadt Yes, adding directly to the public folder makes the image available but how did you automate the process of placing the image in the public folder?
If the structure is different, you just have to assure the image path is correct π
oh sorry about that @rageofflames , I might not have been answering the main thread directly. I manually edited them because i was only dealing with a small number of animations.
I only mentioned it in case others came along (like me) looking for the easiest way to make lottie pngs work in react and didn't know that we could just place it in the public folder.
your method looks really good for automating image imports, I'll do that from now on!
@wahlforss look at this example:
import img_0 from './images/img_0.png' export default { v: '5.2.1', fr: 25, ip: 1, op: 74, w: 500, h: 500, nm: 'pulseloop', ddd: 0, assets: [ { id: 'image_0', w: 701, h: 632, u: '', p: img_0, e: 0 }, { id: 'comp_0', layers: [ { ddd: 0, ind: 1, ty: 2, nm: img_0, cl: 'png', refId: 'image_0', ....
I changed the
u:'path-to-folder'
tou: ''
and all the occurrences where you use the image name toimg_0
which represents the image direct path.Hope it helps
Thank you!
The images aren't visible outside public folder, move the png's to the public folder (you can put them wherever, like in "public/animations/[animationName]/"). In the .json, change u:"images/"
for the folder where your images are ( using the last example should be u:animations/[animationName]/
)
@wahlforss look at this example:
import img_0 from './images/img_0.png' export default { v: '5.2.1', fr: 25, ip: 1, op: 74, w: 500, h: 500, nm: 'pulseloop', ddd: 0, assets: [ { id: 'image_0', w: 701, h: 632, u: '', p: img_0, e: 0 }, { id: 'comp_0', layers: [ { ddd: 0, ind: 1, ty: 2, nm: img_0, cl: 'png', refId: 'image_0', ....
I changed the
u:'path-to-folder'
tou: ''
and all the occurrences where you use the image name toimg_0
which represents the image direct path.Hope it helps π
Thanks dude, this worked!
I understand the solution that is given in previous answers, but I can't seem to figure out how to import and use this as animationData for the Lottie component.
My snippet:
import * as React from 'react';
import Lottie from 'react-lottie';
import animationData from '../../assets/animations/background-animation/animation.js';
export default class BackgroundAnimation extends React.Component {
constructor(props) {
super(props);
this.state = {isStopped: false, isPaused: false};
}
render() {
const defaultOptions = {
loop: true,
autoplay: true,
animationData: animationData,
rendererSettings: {
preserveAspectRatio: 'xMidYMid slice'
}
};
return <Lottie options={defaultOptions}/>
}
}
@Skagoo
import animationData from '../../assets/animations/background-animation/animation.js';
Try removing the .js
extension and if it doesn't work can you share the animation.js
file?
Make sure the path to the animationData is correct and then make the json file a js file and import the pictures into js file you are trying to use. Then in assets in the js file change the βpβ to the imported picture variable name. I used βimg_0β and so on
Sent from my iPhone
On Apr 3, 2019, at 7:05 AM, Sacha [email protected] wrote:
I understand the solution that is given in previous answers, but I can't seem to figure out how to import and use this as animationData for the Lottie component.
My snippet:
import * as React from 'react'; import Lottie from 'react-lottie'; import animationData from '../../assets/animations/background-animation/animation.js';
export default class BackgroundAnimation extends React.Component {
constructor(props) { super(props); this.state = {isStopped: false, isPaused: false}; } render() { const defaultOptions = { loop: true, autoplay: true, animationData: animationData, rendererSettings: { preserveAspectRatio: 'xMidYMid slice' } }; return <Lottie options={defaultOptions}/> }
} β You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.
Thanks for replying.
@rowgregory, what you described is exactly what I did. The issue I'm facing tho is that the import of the animation.js file throws Uncaught Error: Cannot find module '../../assets/animations/background-animation/animation.js'
@rageofflames, removing the .js
extension results in the same error Uncaught Error: Cannot find module '../../assets/animations/background-animation/animation'
but without the .js
ofcourse. This is a snippet from my animation.js
file.
import img_0 from './images/img_0.png'
import img_1 from './images/img_1.png'
...
export default {
"v": "5.4.4",
"fr": 30,
"ip": 0,
"op": 930,
"w": 1920,
"h": 1080,
"nm": "TV - landscape",
"ddd": 0,
"assets": [
{
"id": "image_0",
"w": 2349,
"h": 1134,
"u": "",
"p": img_0,
"e": 0
},
{
"id": "image_1",
"w": 1138,
"h": 1139,
"u": "",
"p": img_1,
"e": 0
},
...
]
}
@Skagoo your code appears to be similar to mine, the problem seems to be related to the paths and it's hard to help you π€Check the import path, recompile, manually check if the file is at the expected path...
Yeah you probably need to get rid of ../../
Sent from my iPhone
On Apr 3, 2019, at 8:42 AM, Sacha [email protected] wrote:
Thanks for replying. @rowgregory, what you described is exactly what I did. The issue I'm facing tho is that the import of the animation.js file throws Uncaught Error: Cannot find module '../../assets/animations/background-animation/animation.js'
@rageofflames, removing the .js extension results in the same error Uncaught Error: Cannot find module '../../assets/animations/background-animation/animation' but without the .js ofcourse. This is a snippet from my animation.js file.
import img_0 from './images/img_0.png' import img_1 from './images/img_1.png' ...
export default { "v": "5.4.4", "fr": 30, "ip": 0, "op": 930, "w": 1920, "h": 1080, "nm": "TV - landscape", "ddd": 0, "assets": [ { "id": "image_0", "w": 2349, "h": 1134, "u": "", "p": img_0, "e": 0 }, { "id": "image_1", "w": 1138, "h": 1139, "u": "", "p": img_1, "e": 0 }, ... ] } β You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.
@rageofflames after digging a bit deeper I found the following issue Module not found: Error: Can't resolve 'source-map-loader' in '/Users/sacha/Documents/dev/DocFoundry/af-doc-fe/src'
@rowgregory I've tried that as well.. Been playing around with the path but that doesn't seem to do the trick.
This is the relevant project structure.
.
βββ src
βββ assets
β βββ animations
β βββ background-animation
β βββ images
β β βββ img_0.png
β β βββ img_1.png
β βββ animation.js
βββ modules
βββ Waldo
βββ BackgroundAnimation.tsx
Thanks for helping me out, I will keep you posted if anything changes.
Update: If I place the contents of animation.js
in the same file as BackgroundAnimation.tsx
It works perfectly fine. So it is indeed an issue in the import reference.. Can't seem to find out what is wrong with the statement though.
EDIT
Tis issue is still not resolved, for now I am placing the json animationData in the same file, BackgroundAnimation.tsx
.
My issue was fixed by placing the json in a .tsx file instead of .js.
I've found another way and I guess this is easier than converting JSON to JS.
If you are using Gatsby, you should move your assets for the animation to the static
folder.
The static
folder should be at the root of your project.
For example. -static --animations ---img_0.png ---img_1.png ---img_2.png
After that in your JSON file you should only change the path parameter - "u": "animations/"
and that's it.
Gatsby automatically copies the static
folder into the public
folder, and here you will see new folder animations
from the static
folder with your images, that you created.
@wahlforss look at this example:
import img_0 from './images/img_0.png' export default { v: '5.2.1', fr: 25, ip: 1, op: 74, w: 500, h: 500, nm: 'pulseloop', ddd: 0, assets: [ { id: 'image_0', w: 701, h: 632, u: '', p: img_0, e: 0 }, { id: 'comp_0', layers: [ { ddd: 0, ind: 1, ty: 2, nm: img_0, cl: 'png', refId: 'image_0', ....
I changed the
u:'path-to-folder'
tou: ''
and all the occurrences where you use the image name toimg_0
which represents the image direct path.Hope it helps π
thanks a lot !!!!!!
I found myself processing a lot of Lottie files this way so I wrote a really hacky node script if anyone's interested - it takes a command line argument of the path of the .json file and the images/ folder and writes an index.js file there with the correct image imports and asset "p" names:
const fs = require('fs');
const util = require('util');
const path = require("path")
const readdir = util.promisify(fs.readdir);
const filePath = process.argv.slice(2)[0]
async function getFileNames(pathToDir) {
let names;
try {
names = await readdir(pathToDir);
} catch (err) {
console.log(err);
}
if (names === undefined) {
console.log('undefined');
} else {
return names
}
}
// provide the location of .json file and /images w/ path
let jsonFile
let imageNames
getFileNames(filePath).then(allFiles => {
allFiles.forEach(file => {
if (path.extname(file) === ".json") {
jsonFile = file
}
})
let json = JSON.parse(fs.readFileSync(filePath + "/" + jsonFile, 'utf8'))
json.assets.forEach(asset => {
if (asset.id.slice(0, 5) === "image") {
asset.u = ''
const assetString = asset.p.replace(".png", "")
asset.p = "REPLACE" + assetString + "REPLACE"
}
})
getFileNames(filePath + "/images").then(res => {
imageNames = res
imageNames = imageNames.map(image => "import " + image.replace(".png", "") + " from './images/" + image + "'")
let finalFile = imageNames.join("\n") + "\n" +
// then read json file and remove "u":"images/","p":"img_2.png" => "u":"","p":img_2
"export default " + JSON.stringify(json).replace(/"REPLACE|REPLACE"/g, "")
fs.writeFile(filePath + "/" + "index.js", finalFile, err => err && console.log("error", err))
})
})
So you could invoke it like:
node <this-scripts-name>.js /Users/YOURUSERNAME/Downloads/lotties/my-lottie-folder
I've found another way and I guess this is easier than converting JSON to JS. If you are using Gatsby, you should move your assets for the animation to the
static
folder. Thestatic
folder should be at the root of your project.For example. -static --animations ---img_0.png ---img_1.png ---img_2.png
After that in your JSON file you should only change the path parameter -
"u": "animations/"
and that's it.Gatsby automatically copies the
static
folder into thepublic
folder, and here you will see new folderanimations
from thestatic
folder with your images, that you created.
Hope this works for NextJS, but sadly it doesnt.
Anybody working with image lottie on NextJS?
----- EDIT ----
It worked. I missed trailing /
on the path
In addition to the solution above, for the NextJS the static folder is currently deprecated and you can move the your animation folder into your public folder directly. In your JSON file only change the path parameter - "u": "animation's directory name/" like the solution above
Hey @sgript
I solved it by creating my own json withing a javascript file.
Instead of using the
animation.json
directly, create aanimation.js
file where you import the image and replace the[image_in_question].png
occurrences for yourimage_in_question_name
. Remember to fix the folders path and delete it.You are basically recreating the json with your own paths. This way, your image paths will be correct.
import image_in_question_name from './images/[image_in_question].png' export default {"v": ...... ANIMATION JSON ....... };
This worked for me and I am using
gatsby
.Hope it helps!
Thanks This worked :smiley:
animations @necheporenko It really works perfectly from me. Thanks a lot. :)