Giter Site home page Giter Site logo

chenqingspring / vue-lottie Goto Github PK

View Code? Open in Web Editor NEW
1.3K 13.0 284.0 2 MB

Render After Effects animations on Vue based on Bodymovin

License: MIT License

HTML 32.92% Vue 42.23% JavaScript 24.85%
vuejs2 vue vue-components vue-animate bodymovin lottie-animation lottie

vue-lottie's Introduction

Lottie Animation View for Vue (React, Angular)

npm version

Generated by create-vue-component

Wapper of bodymovin.js

bodymovin is Adobe After Effects plugin for exporting animations as JSON, also it provide bodymovin.js for vender them as svg/canvas/html.

Demo

https://chenqingspring.github.io/vue-lottie

Why Lottie?

Flexible After Effects features

We currently support solids, shape layers, masks, alpha mattes, trim paths, and dash patterns. And we’ll be adding new features on a regular basis.

Manipulate your animation any way you like

You can go forward, backward, and most importantly you can program your animation to respond to any interaction.

Small file sizes

Bundle vector animations within your app without having to worry about multiple dimensions or large file sizes. Alternatively, you can decouple animation files from your app’s code entirely by loading them from a JSON API.

Learn morehttp://airbnb.design/lottie/

Looking for lottie files › https://www.lottiefiles.com/

Installation

Install through npm:

npm install --save vue-lottie

Usage

<template>
    <div id="app">
        <lottie :options="defaultOptions" :height="400" :width="400" v-on:animCreated="handleAnimation"/>
        <div>
            <p>Speed: x{{animationSpeed}}</p>
            <input type="range" value="1" min="0" max="3" step="0.5"
                   v-on:change="onSpeedChange" v-model="animationSpeed">
        </div>
        <button v-on:click="stop">stop</button>
        <button v-on:click="pause">pause</button>
        <button v-on:click="play">play</button>
    </div>
</template>

<script>
  import Lottie from './lottie.vue';
  import * as animationData from './assets/pinjump.json';

  export default {
    name: 'app',
    components: {
      'lottie': Lottie
    },
    data() {
      return {
        defaultOptions: {animationData: animationData},
        animationSpeed: 1
      }
    },
    methods: {
      handleAnimation: function (anim) {
        this.anim = anim;
      },

      stop: function () {
        this.anim.stop();
      },

      play: function () {
        this.anim.play();
      },

      pause: function () {
        this.anim.pause();
      },

      onSpeedChange: function () {
        this.anim.setSpeed(this.animationSpeed);
      }
    }
  }
</script>

Configuration

You can pass a configuration object through options property:

  • animationData: an Object with the exported animation data.
  • path: the relative path to the animation object. (animationData and path are mutually exclusive)
  • loop: true / false / number
  • autoplay: true / false it will start playing as soon as it is ready
  • name: animation name for future reference
  • renderer: 'svg' / 'canvas' / 'html' to set the renderer
  • container: the dom element on which to render the animation

More information on Bodymoving Documentation

Related Projects

Contribution

Your contributions and suggestions are heartily welcome.

License

MIT

vue-lottie's People

Contributors

chenqingspring avatar th1nkk1d avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue-lottie's Issues

Ios and Android integration

Hi thanks for your awesome package.
I was wondering if we have to add dependencies for android and ios.
If so do i have to add this on my webpack configuration ?
I also notice that if you zoom on the animation on mobile it could slow down.
Does it related ?

vue-lottie (seemingly) not currently setup for use with canvas elements.

On review of the current source code located at vue-lottie/src/lottie.vue, it seems that 'svg' has been hard coded in as the renderer for the animation instance. When I modified the source to accept user input I am noticing that if I select to use the 'canvas' option, on reload all of my animations disappear in chrome and firefox, but stay when using Edge. The 'svg' option is working in all the browsers I've tested. Is there something extra I need to be doing to keep this from happening with canvas elements?

https://github.com/chenqingspring/vue-lottie/blob/master/src/lottie.vue

loop number not working for me

loop: number is not working for me. Setting it to true or false works

<lottie :options="defaultOptions" :height="100" :width="100" v-on:animCreated="handleAnimation"/>

data() {
return {

defaultOptions: {
animationData: animationData.default,
loop: 2, // <== not working for me
autoplay: true
},
animationSpeed: 1
}
}

Templalte doesn't compile / Can't use with import

Steps to Reproduce

  import Lottie from 'vue-lottie';
  import * as animationData from '@/assets/animations/loading.json';

  export default {
    name: 'example',
    components: {
      lottie: Lottie,
    },

What Happens

The template doesn't get compiled and this js error is shown

Uncaught SyntaxError: Unexpected token <
    at createScript (vm.js:74:10)
    at Object.runInThisContext (vm.js:116:10)
    at Module._compile (module.js:533:28)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:503:32)
    at tryModuleLoad (module.js:466:12)

Expected Behaviour

the lottie.vue-file should be compiled or the dist/build.js-File should be imported when it's used like this.

But The Build.js doesn't work either with import Lottie from 'vue-lottie'

ps. I use vue-electron

webpack.config.js

'use strict'


process.env.BABEL_ENV = 'renderer'

const path = require('path')
const { dependencies } = require('../package.json')

const webpack = require('webpack')
const BabiliWebpackPlugin = require('babili-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')

const HtmlWebpackPlugin = require('html-webpack-plugin')

/**
 * List of node_modules to include in webpack bundle
 *
 * Required for specific packages like Vue UI libraries
 * that provide pure *.vue files that need compiling
 * https://simulatedgreg.gitbooks.io/electron-vue/content/en/webpack-configurations.html#white-listing-externals
 */
let whiteListedModules = ['vue']

let rendererConfig = {
  devtool: '#cheap-module-eval-source-map',
  entry: {
    renderer: path.join(__dirname, '../src/renderer/main.js')
  },
  externals: [
    ...Object.keys(dependencies || {}).filter(d => !whiteListedModules.includes(d))
  ],
  module: {
    rules: [
      {
        test: /\.(js|vue)$/,
        enforce: 'pre',
        exclude: /node_modules/,
        use: {
          loader: 'eslint-loader',
          options: {
            formatter: require('eslint-friendly-formatter')
          }
        }
      },
      {
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: 'css-loader'
        })
      },
      {
        test: /\.html$/,
        use: 'vue-html-loader'
      },
      {
        test: /\.js$/,
        use: 'babel-loader',
        exclude: /node_modules/
      },
      {
        test: /\.node$/,
        use: 'node-loader'
      },
      {
        test: /\.vue$/,
        use: {
          loader: 'vue-loader',
          options: {
            extractCSS: process.env.NODE_ENV === 'production',
            loaders: {
              scss: (process.env.NODE_ENV === 'production') ?  ExtractTextPlugin.extract({
                use: 'css-loader!sass-loader',
                fallback: 'vue-style-loader'
              }) : 'vue-style-loader!css-loader!sass-loader',
              sass: (process.env.NODE_ENV === 'production') ? ExtractTextPlugin.extract({
                use: 'css-loader!sass-loader?indentedSyntax',
                fallback: 'vue-style-loader'
              }) : 'vue-style-loader!css-loader!sass-loader?indentedSyntax=1'
            }
          }
        }
      },
      {
        test: /\.(png|jpe?g|gif)(\?.*)?$/,
        use: {
          loader: 'url-loader',
          query: {
            limit: 10000,
            name: 'imgs/[name]--[folder].[ext]'
          }
        }
      },
      {
        test: /\.svg$/,
        loader: 'vue-svg-loader', // `vue-svg` for webpack 1.x
        options: {
          svgo: {
            plugins: [
              {
                removeDoctype: true
              },
              {
                removeComments: true
              }
            ]
          }
        }
      },
      {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: 'media/[name]--[folder].[ext]'
        }
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        use: {
          loader: 'url-loader',
          query: {
            limit: 10000,
            name: 'fonts/[name]--[folder].[ext]'
          }
        }
      }
    ]
  },
  node: {
    __dirname: process.env.NODE_ENV !== 'production',
    __filename: process.env.NODE_ENV !== 'production'
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env.CMS_URL': JSON.stringify(process.env.CMS_URL),
    }),
    new ExtractTextPlugin('styles.css'),
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: path.resolve(__dirname, '../src/index.ejs'),
      minify: {
        collapseWhitespace: true,
        removeAttributeQuotes: true,
        removeComments: true
      },
      nodeModules: process.env.NODE_ENV !== 'production'
        ? path.resolve(__dirname, '../node_modules')
        : false
    }),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoEmitOnErrorsPlugin()
  ],
  output: {
    filename: '[name].js',
    libraryTarget: 'commonjs2',
    path: path.join(__dirname, '../dist/electron')
  },
  resolve: {
    alias: {
      '@': path.join(__dirname, '../src/renderer'),
      'vue$': 'vue/dist/vue.esm.js'
    },
    extensions: ['.js', '.vue', '.json', '.css', '.node']
  },
  target: 'electron-renderer'
}

/**
 * Adjust rendererConfig for development settings
 */
if (process.env.NODE_ENV !== 'production') {
  rendererConfig.plugins.push(
    new webpack.DefinePlugin({
      '__static': `"${path.join(__dirname, '../static').replace(/\\/g, '\\\\')}"`
    })
  )
}

/**
 * Adjust rendererConfig for production settings
 */
if (process.env.NODE_ENV === 'production') {
  rendererConfig.devtool = ''

  rendererConfig.plugins.push(
    new BabiliWebpackPlugin(),
    new CopyWebpackPlugin([
      {
        from: path.join(__dirname, '../static'),
        to: path.join(__dirname, '../dist/electron/static'),
        ignore: ['.*']
      }
    ]),
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': '"production"'
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: true
    })
  )
}

module.exports = rendererConfig

Update readme to reflect proper usage

Readme for usage should read

import lottie from 'vue-lottie';
  import * as animationData from './assets/pinjump.json';

  export default {
    name: 'app',
    components: {
      lottie
    },

Percentage based width?

I'm trying to make my animation 100% width of the page, however, I get the following error

invalid expression: Unexpected token } in

    100%

  Raw expression: :width="100%"

Initializing like so:

                    <lottie :options="defaultOptions" :width="100%" v-on:animCreated="handleAnimation"/>

Any idas how I can do this with vue? thanks

How to handle multiple animations on the same page

I am creating multiple lottie elements on the same page, but because the 'last' one added to the dom becomes the last this.anim only the last animation is working. What is the way to handle multiple animations on the same page correctly?

 handleAnimation: function (anim) {
        this.anim = anim;
      },

Animation with images is not working

If there is an animation that uses images then the images don't load. The SVG animations still work but the images from the /images folder just don't show up.

Fire animation after scroll into viewport

Been struggling to get this to work, any chance you could suggest a way?

this.anim.play();

error: Cannot pass anim object into function. Using this code

      function navSlide(anim) {
        var topthis = $('.animate-this').offset();
        var $window = $(window);
        if ( $window.scrollTop() >= topthis.top) {
          this.anim.play();
        }
      }

      navSlide();

error: vue.esm.js:591 [Vue warn]: Error in mounted hook: "TypeError: Cannot read property 'anim' of undefined"

请问资源文件该如何引入?

image
这是放置的目录路径

import * as PercentFour from '@/assets/QRcode/data.json'

这样导入后图片资源加载不出来
使用了vue全家桶

uniapp平台app端报错

uniapp平台app端报错如下:
image
测试demo:

<template>
	<div>
		<canvas id="test-canvas" canvas-id="test-canvas"></canvas>
	</div>
</template>
<script>
	import Anim from "../../assets/data.json"
	import lottie from "lottie-web";

	export default {
		onLoad() {
			let that = this;
			const canvasContext = uni.createCanvasContext("test-canvas");
			// 指定canvas大小
			canvasContext.canvas = {
				width: 100,
				height: 100,
			};
			lottie.loadAnimation({
				container: uni.createSelectorQuery().select("#test-canvas"),
				renderer: "canvas", 
				loop: true,
				autoplay: true,
				animationData: Anim,
				rendererSettings: {
					context: canvasContext,
					scaleMode: 'noScale',
					clearCanvas: false,
				},
			});
		},
	}
</script>

How to enable mouseover handler

Hello,

This is a question, not an issue. I am trying to enable the this.anim.play() to happen on mouseover of the lottie element:

      <lottie
        @mouseenter="play"
        :options="defaultOptions"
        :height="200"
        :width="200"
        @animCreated="handleAnimation"
      />
    </div>

---

    play: function() {
      this.anim.play();
    }
  }
};

But it doesnt seem to work. Any advice?

Vue-lottie wont run with npm run watch

Hello,

Vue-lottie will not run with npm run watch. I won't get any erros, the only thing I see is that the SVG isn't compiled in my Vue app. When I use npm run build and host my application via a live server or the serve -s dist command only then will the SVG work. Is it possible that Vue-lottie will compile the SVG with npm run watch?

That would save a lot of time during app development

Thanks!

-Dominique

设置renderer属性为"canvas"无效

问题:
如题,不想用svg渲染,想用canvas,设置renderer:"canvas"

结果:
无效,结果还是按svg渲染了。

期望:
能用canvas正确渲染

Vue should be peerDependency

Hey, thanks for the work, vue-lottie is really cool!
I think you want vue defined as a peerDependency instead of a straight dependency?
Currently, vue-lottie will install its own version of vue. I think it should be up to the consumer of vue-lottie to define which version of vue to use?

For example, I have a project that uses nuxt. We got a runtime error because vue-server-renderer is at version 2.5.13 (defined by nuxt) while vue is at version 2.5.16 (defined by vue-lottie). All of that can be fixed by me, but it wouldn't have been a problem in the first place if you defined vue as a peerDependency.

PlaySegments not working properly

handleAnimation2: function(anim2) { this.anim2 = anim2; this.anim2.playSegments([[138, 147], [148, 212], [212, 276]], true); },

I have this code in myLottie.vue component, but according to Hernan Torsi, the anim.PlaySegments should play the first two segments and loop on the last segment if the loop parameter is set during initialization.

But its not the case for this. The issue I'm having is the animation is skipping the first two segments and playing the last segment only.

Is there any way to fix this?

Simple use

PLS set prop main = "dist/build.js" in package.json

for use:
import lottie from 'vue-lottie'

<svg> attribute viewBox: Expected number, "0 0 undefined undefined"

Error: attribute viewBox: Expected number, "0 0 undefined undefi…".
Error: attribute width: Expected length, "undefined".
Error: attribute height: Expected length, "undefined".
Error: attribute width: Expected length, "undefined".
Error: attribute height: Expected length, "undefined".

I get the error above
I'm not using react JS #20

var animData = bodymovin.loadAnimation({
container: document.getElementById('animate-a'),
renderer: 'svg',
loop: true,
autoplay: true,
path: '/images/json/data.json'
});

Lottie js version 5.5.10

Any one help me.

TypeError: animData.layers is undefined

I'm using your demo code and i get this error:

[Vue warn]: Error in mounted hook: "TypeError: animData.layers is undefined"

found in

---> <Lottie> at node_modules/vue-lottie/src/lottie.vue
       <PageFontCharacter> at src/components/PageFontCharacter.vue
         <App> at src/App.vue
           <Root> 


TypeError: "animData.layers is undefined"
	configAnimation webpack-internal:///./node_modules/lottie-web/build/player/lottie.js:5960:5
	configAnimation webpack-internal:///./node_modules/lottie-web/build/player/lottie.js:9077:5
	setParams webpack-internal:///./node_modules/lottie-web/build/player/lottie.js:8944:9
	loadAnimation webpack-internal:///./node_modules/lottie-web/build/player/lottie.js:8728:9
	loadAnimation webpack-internal:///./node_modules/lottie-web/build/player/lottie.js:14154:16
	mounted webpack-internal:///./node_modules/cache-loader/dist/cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./node_modules/vue-lottie/src/lottie.vue?vue&type=script&lang=js&:32:17
	callHook webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:2916:9
	insert webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:4149:7
	invokeInsertHook webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:5944:28
	patch webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:6163:5
	_update webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:2665:16
	updateComponent webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:2783:7
	get webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:3137:13
	run webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:3214:17
	flushSchedulerQueue webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:2976:5
	nextTick webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:1832:9
	flushCallbacks webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:1753:14
	run webpack-internal:///./node_modules/core-js/modules/es6.promise.js:75:22
	notify webpack-internal:///./node_modules/core-js/modules/es6.promise.js:92:30
	flush webpack-internal:///./node_modules/core-js/modules/_microtask.js:18:9

Does vue-lottie support preserveAspectRatio like lottie-web?

Hello, I am trying to have my lottie animation embedded in my Vue page scale to fit its parent container. Although the SVG does scale, the internal animation preserves its aspect ratio. Is there a way around this like there is in lottie-web? Thank you!

Nuxt 3 - Failed to load module script:

Hello there,

I have a problem using this module on a Nuxt 3 project.
When I want to deploy my project on production with yarn generate on a VPS, I have this error :

Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "application/octet-stream". Strict MIME type checking is enforced for module scripts per HTML spec.

When I deploy my project on Netlify or on local I don't have this error.

Someone have an idea ?

Animation not running but rendered

Hello, nice job for this adaptation.
I have a problem with the animation. I work with symfony and vuejs and i have integrated the template for render in twig.

So, i can see your pinjump.svg and options buttons, but when i clicked, there is no animation. All files and dependencies are installed and called normaly. I work with webpack and no error.

Can you help me please ?
Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.