Git Product home page Git Product logo

motion's Introduction

๐Ÿคน @vueuse/motion

npm npm Netlify Status

Vue Composables putting your components in motion

  • ๐ŸŽ Smooth animations based on Popmotion
  • ๐ŸŽฎ Declarative API inspired by Framer Motion
  • ๐Ÿš€ Plug & play with 20+ presets
  • ๐ŸŒ SSR Ready
  • ๐Ÿšš First-class support for Nuxt 3
  • โœจ Written in TypeScript
  • ๐Ÿ‹๏ธโ€โ™€๏ธ Lightweight with <20kb bundle size

๐ŸŒ Documentation

๐Ÿ‘€ Demos

Quick Start

Let's get started by installing the package and adding the plugin.

From your terminal:

yarn add @vueuse/motion

In your Vue app entry file:

import { createApp } from 'vue'
import { MotionPlugin } from '@vueuse/motion'
import App from './App.vue'

const app = createApp(App)

app.use(MotionPlugin)

app.mount('#app')

You can now animate any of your component, HTML or SVG elements using v-motion.

<template>
  <div
    v-motion
    :initial="{
      opacity: 0,
      y: 100,
    }"
    :enter="{
      opacity: 1,
      y: 0,
    }"
  />
</template>

To see more about how to use directives, check out Directive Usage.

To see more about what properties you can animate, check out Motion Properties.

To see more about how to create your own animation styles, check out Transition Properties.

To see more about what are variants and how you can use them, check out Variants.

To see more about how to control your declared variants, check out Motion Instance.

Credits

This package is heavily inspired by Framer Motion by @mattgperry.

If you are interested in using WAAPI, check out Motion.dev!

I would also like to thank antfu, patak-dev and kazupon for their kind help!

If you like this package, consider following me on GitHub and on Twitter.

๐Ÿ‘‹

motion's People

Contributors

0fatihyildiz avatar abdul-alhasany avatar alex-eliot avatar antfu avatar bobbiegoede avatar cerinoligutom avatar cjboy76 avatar cpreston321 avatar danielroe avatar daopk avatar donaldxdonald avatar eertmanhidde avatar florian-lefebvre avatar grunghi avatar hajiskyy avatar hannoeru avatar idered avatar leomp12 avatar lukadriel7 avatar matheus-rodrigues00 avatar maxtechnics avatar p-james avatar rvmourik avatar ryan2128 avatar saintpeter avatar santicros avatar shawn-mty avatar tahul avatar timpulver avatar userquin 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  avatar  avatar

motion's Issues

Vue 2 support

I've installed this package in an existing Vue 2 project started with vue cli and I can't seem to get it working I have the following packages installed:

    "@vue/composition-api": "^1.0.0-rc.2",
    "@vueuse/motion": "^1.0.5",

my main.js looks like

import Vue from 'vue'
import VueCompositionAPI from '@vue/composition-api'

// Packages
import { MotionPlugin } from '@vueuse/motion'

Vue.use(VueCompositionAPI)
Vue.use(MotionPlugin);

export default new Vue({
    render: h => h(App),
}).$mount('#app');

I've tested the package in a Vue 3 project running with Vite and it's works really well.

Quasar SSR mode error with vueuse/motion

Hello, I am currently using quasar/app-vite and trying to add vueuse/motion to a project. It works without any problem in dev but the production mode shows an error:

Instead change the require of D:\DiskC\Documents\VSCode\Quasar\test\test-ssr\node_modules\@vueuse\motion\dist\index.mjs to a dynamic import() which is available in all CommonJS modules.
    at Module.<anonymous> (D:\DiskC\Documents\VSCode\Quasar\test\test-ssr\dist\ssr\server\server-entry.js:1:960)
    at Object.<anonymous> (D:\DiskC\Documents\VSCode\Quasar\test\test-ssr\dist\ssr\index.js:1:1517)
    at Object.<anonymous> (C:\Users\User\AppData\Local\Yarn\Data\global\node_modules\@quasar\cli\bin\quasar-serve:113:5)
    at Object.<anonymous> (C:\Users\User\AppData\Local\Yarn\Data\global\node_modules\@quasar\cli\bin\quasar:29:3) {
  code: 'ERR_REQUIRE_ESM'
}

I tried on webpack but got a similar error even in dev:

[Quasar Dev Webserver] / -> error during render
Error [ERR_REQUIRE_ESM]: require() of ES Module D:\DiskC\Documents\VSCode\Quasar\quasar-project\node_modules\@vueuse\motion\dist\index.mjs not supported.
Instead change the require of D:\DiskC\Documents\VSCode\Quasar\quasar-project\node_modules\@vueuse\motion\dist\index.mjs to a dynamic import() which is available in all CommonJS modules.

My guess is that it is because the server uses CommonJS but tries to require an ES module. Has anyone encountered this problem before or know how to solve it ?

Error TS2694: Namespace has no exported member 'ColorAdjustProperty'

Hi, unfortunately, beta12 is still throwing errors on my Vite system.
I'm using Vite + Vue 3 + Typescript

Command that's causing the issue

npm run build

System Information:

Node Version: v16.13.2 System: Win10 x64

main.ts

import { createApp } from 'vue';
import { createPinia } from 'pinia'
import { createRouter, createWebHistory } from "vue-router";
import { MotionPlugin } from '@vueuse/motion'

const app = createApp({

})
app.use(createPinia())
app.use(router)
app.use(MotionPlugin)
app.mount('#app');

package.json

  "scripts": {
    "dev": "vite",
    "build": "vue-tsc --noEmit && vite build",
    "preview": "vite preview --host",
    "check:updates": "ncu"
  },
 "dependencies": {
    "@headlessui/vue": "^1.5.0",
    "@vueuse/core": "^8.1.1",
    "@vueuse/motion": "^2.0.0-beta.12",
    "bootstrap-icons-vue": "^1.8.1",
    "pinia": "^2.0.12",
    "vue": "^3.2.31",
    "vue-router": "^4.0.14"
  },
  "devDependencies": {
    "@babel/types": "^7.17.0",
    "@types/node": "^17.0.21",
    "@vitejs/plugin-vue": "^2.2.4",
    "@vueuse/components": "^8.1.1",
    "autoprefixer": "^10.4.4",
    "postcss": "^8.4.12",
    "sass": "^1.49.9",
    "tailwindcss": "^3.0.23",
    "typescript": "^4.6.2",
    "vite": "^2.8.6",
    "vite-imagetools": "^4.0.3",
    "vue-tsc": "^0.33.2"
  }

Errors:

node_modules/@vueuse/motion/dist/index.d.ts:762:31 - error TS2694: Namespace '"/node_modules/csstype/index"' has no exported member 'ColorAdjustProperty'.

762         colorAdjust?: csstype.ColorAdjustProperty | undefined;
                                  ~~~~~~~~~~~~~~~~~~~

node_modules/@vueuse/motion/dist/index.d.ts:1262:42 - error TS2694: Namespace '"/node_modules/csstype/index"' has no exported member 'ColorAdjustProperty'.

1262         WebkitPrintColorAdjust?: csstype.ColorAdjustProperty | undefined;
                                              ~~~~~~~~~~~~~~~~~~~

node_modules/@vueuse/motion/dist/index.d.ts:1536:34 - error TS2694: Namespace '"/node_modules/csstype/index"' has no exported member 'ColorAdjustProperty'.

1536         "color-adjust"?: csstype.ColorAdjustProperty | undefined;
                                      ~~~~~~~~~~~~~~~~~~~

node_modules/@vueuse/motion/dist/index.d.ts:1998:48 - error TS2694: Namespace '"/node_modules/csstype/index"' has no exported member 'ColorAdjustProperty'.
1998         "-webkit-print-color-adjust"?: csstype.ColorAdjustProperty | undefined;
                                                    ~~~~~~~~~~~~~~~~~~~

node_modules/@vueuse/motion/dist/index.d.ts:2316:31 - error TS2694: Namespace '"/node_modules/csstype/index"' has no exported member 'ColorAdjustProperty'.
2316         colorAdjust?: csstype.ColorAdjustProperty | undefined;
                                   ~~~~~~~~~~~~~~~~~~~

node_modules/@vueuse/motion/dist/index.d.ts:2816:42 - error TS2694: Namespace '"/node_modules/csstype/index"' has no exported member 'ColorAdjustProperty'.
2816         WebkitPrintColorAdjust?: csstype.ColorAdjustProperty | undefined;
                                              ~~~~~~~~~~~~~~~~~~~

node_modules/@vueuse/motion/dist/index.d.ts:3090:34 - error TS2694: Namespace '"/node_modules/csstype/index"' has no exported member 'ColorAdjustProperty'.
3090         "color-adjust"?: csstype.ColorAdjustProperty | undefined;
                                      ~~~~~~~~~~~~~~~~~~~

node_modules/@vueuse/motion/dist/index.d.ts:3552:48 - error TS2694: Namespace '"/node_modules/csstype/index"' has no exported member 'ColorAdjustProperty'.
3552         "-webkit-print-color-adjust"?: csstype.ColorAdjustProperty | undefined;
                                                    ~~~~~~~~~~~~~~~~~~~

node_modules/@vueuse/motion/dist/index.d.ts:3889:31 - error TS2694: Namespace '"/node_modules/csstype/index"' has no exported member 'ColorAdjustProperty'.
3889         colorAdjust?: csstype.ColorAdjustProperty | undefined;
                                   ~~~~~~~~~~~~~~~~~~~

node_modules/@vueuse/motion/dist/index.d.ts:4389:42 - error TS2694: Namespace '"/node_modules/csstype/index"' has no exported member 'ColorAdjustProperty'.
4389         WebkitPrintColorAdjust?: csstype.ColorAdjustProperty | undefined;
                                              ~~~~~~~~~~~~~~~~~~~

node_modules/@vueuse/motion/dist/index.d.ts:4663:34 - error TS2694: Namespace '"/node_modules/csstype/index"' has no exported member 'ColorAdjustProperty'.
4663         "color-adjust"?: csstype.ColorAdjustProperty | undefined;
                                      ~~~~~~~~~~~~~~~~~~~

node_modules/@vueuse/motion/dist/index.d.ts:5125:48 - error TS2694: Namespace '"/node_modules/csstype/index"' has no exported member 'ColorAdjustProperty'.
5125         "-webkit-print-color-adjust"?: csstype.ColorAdjustProperty | undefined;
                                                    ~~~~~~~~~~~~~~~~~~~

node_modules/@vueuse/motion/dist/index.d.ts:5402:35 - error TS2694: Namespace '"/node_modules/csstype/index"' has no exported member 'ColorAdjustProperty'.
5402             colorAdjust?: csstype.ColorAdjustProperty | undefined;
                                       ~~~~~~~~~~~~~~~~~~~

node_modules/@vueuse/motion/dist/index.d.ts:5910:46 - error TS2694: Namespace '"/node_modules/csstype/index"' has no exported member 'ColorAdjustProperty'.
5910             WebkitPrintColorAdjust?: csstype.ColorAdjustProperty | undefined;
                                                  ~~~~~~~~~~~~~~~~~~~

node_modules/@vueuse/motion/dist/index.d.ts:6184:38 - error TS2694: Namespace '"/node_modules/csstype/index"' has no exported member 'ColorAdjustProperty'.
6184             "color-adjust"?: csstype.ColorAdjustProperty | undefined;
                                          ~~~~~~~~~~~~~~~~~~~

node_modules/@vueuse/motion/dist/index.d.ts:6646:52 - error TS2694: Namespace '"/node_modules/csstype/index"' has no exported member 'ColorAdjustProperty'.
6646             "-webkit-print-color-adjust"?: csstype.ColorAdjustProperty | undefined;
                                                        ~~~~~~~~~~~~~~~~~~~

node_modules/@vueuse/motion/dist/index.d.ts:7329:31 - error TS2694: Namespace '"/node_modules/csstype/index"' has no exported member 'ColorAdjustProperty'.
7329         colorAdjust?: csstype.ColorAdjustProperty | undefined;
                                   ~~~~~~~~~~~~~~~~~~~

node_modules/@vueuse/motion/dist/index.d.ts:7829:42 - error TS2694: Namespace '"/node_modules/csstype/index"' has no exported member 'ColorAdjustProperty'.
7829         WebkitPrintColorAdjust?: csstype.ColorAdjustProperty | undefined;
                                              ~~~~~~~~~~~~~~~~~~~

node_modules/@vueuse/motion/dist/index.d.ts:8103:34 - error TS2694: Namespace '"/node_modules/csstype/index"' has no exported member 'ColorAdjustProperty'.
8103         "color-adjust"?: csstype.ColorAdjustProperty | undefined;
                                      ~~~~~~~~~~~~~~~~~~~

node_modules/@vueuse/motion/dist/index.d.ts:8565:48 - error TS2694: Namespace '"/node_modules/csstype/index"' has no exported member 'ColorAdjustProperty'.
8565         "-webkit-print-color-adjust"?: csstype.ColorAdjustProperty | undefined;
                                                    ~~~~~~~~~~~~~~~~~~~


Found 20 errors in the same file, starting at: node_modules/@vueuse/motion/dist/index.d.ts:762

Timeline

I think I need something like https://popmotion.io/api/timeline/

Do you think there is a way to fit this in @vueuse/motion ?

I'd like to help and make a PR but I am not sure how to get started.

Thanks

Suggestion: Reduce the usage of bold texts in docs

When reading the docs I'm continuously distracted by the (seemly random) bold texts all over the places. I feel it would be better to remove most of them, and only leaves the few really important ones.

SSR doesn't seem to work as intended

As per docs on SSR Support section, there are 2 options that should work:

<template>
  <div
    v-motion="{
      initial: {
        y: 100,
        opacity: 0
      },
      enter: {
        y: 0,
        opacity: 1
      }
    }"
  >
    Hello
  </div>

  <!-- OR -->

  <div
    v-motion
    :initial="initial"
    :enter="enter"
  >
    Hello
  </div>
</template>

<script setup>
const initial = ref({
  y: 100,
  opacity: 0,
})

const enter = ref({
  y: 0,
  opacity: 1,
})
</script>

The 1st option where we put a stringified object as value on the v-motion directive works. However, the 2nd option where we bind variables to :initial and :enter doesn't work. The latter shows the elements normally and then the animations get applied afterwards. See gif below:

issue demo

That said, the composable usage isn't working either. It seems to behave as if the variables only gets bound on mounted but that doesn't work for SSR.

Additional Context:

This works and I'm getting away with this for the meantime:

<template>
  <div v-motion="motion">Hello</div>
</template>

<script setup>
const motion = {
  initial: {
    y: 100,
    opacity: 0
  },
  enter: {
    y: 0,
    opacity: 1
  }
};
</script>

Versions used:

{
  "nuxt3": "latest",
  "@vueuse/motion": "2.0.0-beta.18"
}

Elements do not return to `:initial` after leaving the `:hovered` state

I am wondering if this is intentional or an oversight. With most reactive animation libraries, I typically expect a transition to be reversed when a hovered state is left. Currently, elements respect the :hovered transition, but when the mouse leaves the element, the :initial variant is not re-applied. It would be great if it were, otherwise everything is left "stuck" in the hovered state. This makes it difficult to implement any user-interactive animations. Otherwise, the library looks great

reactiveStyle example

toggleColor
state.backgroundColor === 'red' // X
state.backgroundColor = 'red' // OK

TypeScript Errors thrown upon leave transition

I'm having a series of errors being thrown in Nuxt 2.15.3 when using a leave transition just like the example here (without importing and using useToggle)

ERROR  ERROR in /Users/brendan/dev/bee/web/node_modules/@vueuse/core/dist/index.d.ts(685,17):
685:17 Cannot find name 'GeolocationCoordinates'.
   683 | declare function useGeolocation(options?: GeolocationOptions): {
   684 |     isSupported: boolean | undefined;
 > 685 |     coords: Ref<GeolocationCoordinates>;
       |                 ^
   686 |     locatedAt: Ref<number | null>;
   687 |     error: Ref<{
   688 |         readonly code: number;

...

ERROR  ERROR in /Users/brendan/dev/bee/web/node_modules/@vueuse/core/dist/index.d.ts(1414,16):
1414:16 Cannot find name 'SpeechRecognitionErrorEvent'.
   1412 |     recognition: SpeechRecognition | undefined;
   1413 |     result: Ref<string>;
 > 1414 |     error: Ref<SpeechRecognitionErrorEvent | undefined>;
        |                ^
   1415 |     toggle: (value?: boolean) => void;
   1416 |     start: () => void;
   1417 |     stop: () => void;

...

ERROR  ERROR in /Users/brendan/dev/bee/web/node_modules/@vueuse/motion/dist/index.d.ts(6,10):
6:10 Module '"../../../vue-demi/lib"' has no exported member 'CSSProperties'.
   4 |   * @license MIT
   5 |   */
 > 6 | import { CSSProperties, SVGAttributes, Ref, UnwrapRef, Directive, Plugin, ComputedRef } from 'vue-demi';
     |          ^
   9 | import { MaybeRef as MaybeRef$1 } from '@vueuse/shared';

...

ERROR  ERROR in /Users/brendan/dev/bee/web/node_modules/@vueuse/motion/dist/index.d.ts(6,25):
6:25 Module '"../../../vue-demi/lib"' has no exported member 'SVGAttributes'.
   4 |   * @license MIT
   5 |   */
 > 6 | import { CSSProperties, SVGAttributes, Ref, UnwrapRef, Directive, Plugin, ComputedRef } from 'vue-demi';
     |                         ^

...

ERROR  ERROR in /Users/brendan/dev/bee/web/node_modules/@vueuse/motion/dist/index.d.ts(6,56):
6:56 Module '"../../../vue-demi/lib"' has no exported member 'Directive'. Did you mean 'isReactive'?
   4 |   * @license MIT
   5 |   */
 > 6 | import { CSSProperties, SVGAttributes, Ref, UnwrapRef, Directive, Plugin, ComputedRef } from 'vue-demi';
     |                          

...

ERROR  ERROR in /Users/brendan/dev/bee/web/node_modules/@vueuse/motion/dist/index.d.ts(6,67):
6:67 Module '"../../../vue-demi/lib"' has no exported member 'Plugin'.
   4 |   * @license MIT
   5 |   */
 > 6 | import { CSSProperties, SVGAttributes, Ref, UnwrapRef, Directive, Plugin, ComputedRef } from 'vue-demi';
     |                                                                   ^

...

ERROR  ERROR in /Users/brendan/dev/bee/web/node_modules/@vueuse/motion/dist/index.d.ts(8,8214):
8:8214 Cannot find module 'csstype' or its corresponding type declarations.

How can i make a vue router leave transition?

How can i make a vue router leave transition with this? i could only make enter animation using the docs,
I want to implement when i navigate back with vue router and get different animation?

i tried using :leave="{ opacity: 0, y: -100 }"

but it only plays enter animation when navigating back or forward

Here is the code:

<transition> <router-view v-motion :initial="{ opacity: 0, y: 100 }" :enter="{ opacity: 1, y: 0 }" :leave="{ opacity: 0, y: -100 }" /> </transition>

animate dynamic list items

How can I animate dynamic list items.
with enter and leave animations.

this method is not working.

<transition v-motion="'cube'" :css="false" @leave="(_, done) => motions.cube.leave(done)">
    <ul class="tasksContainer" v-if="list.length" :style="todoHeight">
      <li
        v-for="(value, key) in list"
        :key="value.id"
        v-motion
        :initial="{
          opacity: 0,
          transform: 'scale(0)',
        }"
        :enter="{
          opacity: 1,
          transform: 'scale(1)',
          transition: {
            type: 'spring',
            stiffness: '50',
            mass: 0.5,
          },
        }"
        :leave="{
          opacity: 0,
          transform: 'translateX(-50%)',
          transition: {
            type: 'spring',
            stiffness: '50',
            mass: 0.5,
          },
        }"

Demo not working

Hi @Tahul! I'm here again testing it haha ๐Ÿ’–

My first problem was that the demo component on the website and README isn't working as is.
First, the code I'm talking about is (I've just added 3 lines of CSS):

<template>
  <div
    id="test-box"
    v-motion="'smoothestDiv'"
    :initial="{
      opacity: 0,
      y: 100,
    }"
    :enter="{
      opacity: 1,
      y: 0,
    }"
  />
</template>

<script setup>
import { useMotions } from "@vueuse/motion";

// Get access to motion instance using useMotions
const { smoothestDiv } = useMotions();

// From smoothest div to biggest div real quick ๐Ÿ˜Ž
smoothestDiv.apply({ scale: 4 });
</script>

<style>
#test-box {
  width: 20rem;
  height: 20rem;
  background: red;
}
</style>
  1. The App breaks because it's not finding smoothestDiv and so can't apply:
[Vue warn]: Unhandled error during execution of setup function 
  at <App>
  
App.vue:23 Uncaught TypeError: Cannot read property 'apply' of undefined
    at setup (App.vue:23)
  1. So then I added a check, so we don't apply if the code is smoothestDiv is undefined:
smoothestDiv?.apply({ scale: 4 });

The thing is it's always undefined. I think we should do something like:

onMounted(() => {
  smoothestDiv?.apply({ scale: 4 });
});
  1. Yet it's not working! hahahah I think it's because when desctructuring motions from useMotions() we are loosing reactivity, so if we use motions.smoothestDiv everything works.

So here's the working demo:

<template>
  <div
    id="test-box"
    v-motion="'smoothestDiv'"
    :initial="{
      opacity: 0,
      y: 100,
    }"
    :enter="{
      opacity: 1,
      y: 0,
    }"
  />
</template>

<script setup>
import { useMotions } from "@vueuse/motion";
import { onMounted } from "vue";

// Get access to motion instance using useMotions
const motions = useMotions();

// From smoothest div to biggest div real quick ๐Ÿ˜Ž
onMounted(() => {
  motions?.smoothestDiv?.apply({ scale: 4 });
});
</script>

<style>
#test-box {
  width: 20rem;
  height: 20rem;
  background: red;
}
</style>

Let me know if it should be like that! Thanks ;)

How to interact with multiple instances of the same transition?

I have a component as followed.

//motionfx.vue

<template>
    <transition @leave="(el, done) => motions.notification.leave(done)">
        <div
            v-if="copied"
            v-motion-pop="'notification'"
            class="bg-yellow-300 fixed py-4 px-8 rounded-full bottom-16 right-4 z-10"
        >
            <p class="text-yellow-900">Message Copied!</p>

            <button
                class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
                @click="copied = !copied"
            >closenotification</button>
        </div>
    </transition>

    <button
        class="py-4 px-8 rounded-full bottom-16 right-4 bg-red-600"
        @click="copied = !copied"
    >Open</button>
</template>

<script>
import { useMotions } from '@vueuse/motion'
import { ref } from '@vue/reactivity'
export default {

    setup() {
        const copied = ref(false)
        const motions = useMotions()

        return {
            copied, motions
        }
    }

}
</script>

in my parent where the component is initiated multiple times.:

    <motionfx></motionfx>
    <motionfx></motionfx>
    <motionfx></motionfx>
    <motionfx></motionfx>
    <motionfx></motionfx>

it functions as expected, up until i open multiple components and then clicking 'close'/@Leave transition.

Cannot read property 'leave' of undefined

I am assuming it is something to do with:
https://motion.vueuse.org/api/use-motions.html

If you declare a name using v-motion attribute value, the motion instances will be added to the global useMotions state and be accessible from any component.

Be careful about duplicating the same name, note that the name can be including a variable.

Of course I don't understand how to get around this. :)

difference between useSpring and useMotion? And their use cases?

Looking at the docs example.
https://motion.vueuse.org/api/use-spring.html#example
it uses scale I can't get the example to work. I am trying to toggle between 2 values.

<script setup>
import { ref } from "vue";
import { useSpring } from "@vueuse/motion";

const active = ref(false);
const target = ref();

const { set } = useSpring(target, {
  damping: 50,
  stiffness: 400,
  restDelta: 1,
  mass: 1,
});


const toggle = () => {
  active.value = !active.value;
  if (active.value) {
    set({
      x: 20,
    });
  } else {
    set({
      x: 0,
    });
  }
};
</script>

<template>
  <div class="outer" @click="toggle">
    <div class="toggle" ref="target"></div>
  </div>
</template>


<style>
.outer {
  background: rgb(192, 192, 192);
  border-radius: 3em;
  width: 50px;
  height: 20px;
}

.toggle {
  background: rgb(255, 255, 255);
  border-radius: 5em;
  transition: all 0.5s;
  width: 20px;
  height: 20px;
  box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.5);
}
</style>

Update:

after some more digging i figured i can use the apply. from usemotion

however i am bit confused on the difference between

const target = ref();
const { apply } = useMotion(target);

and

const target = ref()

const { motionProperties } = useMotionProperties(target)

const { apply } = useMotionControls(motionProperties)

Relative motion properties

First, this is a great library, thanks to everyone who contributed to it.

I'm trying to use it with relative(percentage) properties like this:

<div
    v-motion
    :initial="{ x: '0%' }"
    :enter="{ x: '60%' }"
/>

And I'm getting the "TypeError: v.match is not a function" error.

Is this not supported? Thanks!

directive not working vite app

I tried using both presets and a custom directive with this component and faced issues where the environment crashes.

<template>
  <article v-motion-fade-visible  class="my-2 flex md:h-32">
    <code class="w-full text-sm xl:text-xl leading-loose">
      <div>
        <span class="text-blue-600">const</span>
        <span class="ml-2 text-orange-400">lakshya</span>
        :
        <span class="text-green-400">Ingredient</span>
        []
        <span class="text-blue-600">=</span>
        [
      </div>
      <div class="lg:pl-8">
        <span class="text-red-500">Hacker</span>,
        <span class="text-red-500">Developer</span>,
        <span class="text-red-500">Photographer</span>,
        <span class="text-red-500">Writer</span>,
      </div>
      <div class="lg:pl-8">
        <span class="text-red-500">Cool</span>,
        <span class="text-red-500">Hot</span>,
        <span class="text-red-500">...everythingNice</span>
      </div>
      <div>];</div>
    </code>
  </article>
</template>

This was what was logged into the console rest of the page was not rendering anything

Screenshot_20210502_012609

This is how am registering the plugin. The other plugins registered include @vueuse/head, vue-router and vue-i18n

import { MotionPlugin } from '@vueuse/motion'
import 'virtual:windi-devtools'
import 'virtual:windi.css'
import { createApp } from 'vue'
import App from './App.vue'
import { head, i18n, router } from './modules'

const app = createApp(App)
app.use(head)
app.use(i18n)
app.use(router)
app.use(MotionPlugin)

app.mount('#app')

My Vite config is as follows

import VueI18n from '@intlify/vite-plugin-vue-i18n'
import vue from '@vitejs/plugin-vue'
import path from 'path'
import { defineConfig } from 'vite'
import ViteComponents from 'vite-plugin-components'
import ViteFonts from 'vite-plugin-fonts'
import Icons, { ViteIconsResolver } from 'vite-plugin-icons'
import Markdown from 'vite-plugin-md'
import Pages from 'vite-plugin-pages'
import Layouts from 'vite-plugin-vue-layouts'
import WindiCSS from 'vite-plugin-windicss'

// https://vitejs.dev/config/
export default defineConfig({
  resolve: {
    alias: [
      {
        find: '@components',
        replacement: path.resolve(__dirname, './src/components')
      },
      { find: '@assets', replacement: path.resolve(__dirname, './src/assets') },
      { find: '@', replacement: path.resolve(__dirname, './src') }
    ]
  },
  plugins: [
    vue({
      include: [/\.vue$/, /\.md$/]
    }),
    Pages({
      extensions: ['vue', 'md']
    }),
    Layouts(),
    Markdown({
      wrapperClasses: 'prose prose-sm m-auto text-left',
      headEnabled: true
    }),
    ViteComponents({
      extensions: ['vue', 'md'],
      customLoaderMatcher: (id) => id.endsWith('.md'),
      customComponentResolvers: ViteIconsResolver({
        componentPrefix: '',
        enabledCollections: ['mdi', 'carbon']
      })
    }),
    Icons({
      defaultStyle: 'vertical-align: middle;'
    }),
    WindiCSS({
      safelist: 'prose prose-sm m-auto text-left'
    }),
    VueI18n({
      include: [path.resolve(__dirname, 'locales/**')]
    }),
    ViteFonts({
      google: {
        families: ['Satisfy']
      }
    })
  ],
  optimizeDeps: {
    include: ['vue', 'vue-router', '@vueuse/core']
  }
})

How can I make `leave` transition in general?

Hello, I'm trying to make a Reusable Modal with animation baked in using vueuse/motion. And I'm stuck with leave animation. I followed the demo folder's Transitions.vue and it is showing TypeError: Cannot read property 'leave' of undefined.

Which is as far as I know, in <transition :css="false" @leave="(el, done) => motions.pop.leave(done)"> code pop is undefined. Am I missing anything?

Here's is my code. https://codesandbox.io/s/vueuse-motion-playground-71ut4

Vitepress compatibility

Tried using v-motion directives is my vitepress project and got this error:

build error:  SyntaxError: Custom directive is missing corresponding SSR transform and will be ignored.

Seems like there's a way to make motion compatible with SSR. That could be a great feature.

useSpring example not working

Hi,

I've used the useSpring example from the documentation but it doesn't seem to work. Am I missing something or is the documentation incorrect? This is my very simple component. I have globally installed vue motion in my app.

When I click the div, I see 'click' appear in the console but no animation is triggered.

I get an error in this codesandbox when triggering the animation that I'm not getting in my local app, I'm not sure if it's related. Cannot read properties of undefined (reading 'apply')
https://codesandbox.io/s/vueuse-motion-forked-i76zv6?file=/src/components/Bar.vue

Can anyone shed some light?

<template>
  <div ref="target" class="bar" @click="onClick"></div>
</template>

<script lang="ts" setup>
import { ref } from "vue";
import { useSpring } from "@vueuse/motion";

const target = ref<HTMLElement>()

const { set, values, stop } = useSpring(target as any, {
  damping: 50,
  stiffness: 220,
})

const onClick = () => {
  console.log('click')
  set({
    scale: 3,
  })
}

const onClickOut = () => {
  set({
    scale: 1,
  })
}

const stopTransitions = () => {
  stop()
}
</script>

<style lang="scss">
.bar {
  height: 100px;
  width: 40px;
  background-color: red;
}
</style>

Vue 3 Issue - Might be a webpack issue not sure?

Hi everyone,
I'm sorry if this is not a issue with vueuse/motion and is a webpack issue, but I'm not sure.
This is the error that I keep getting:
INFO Starting development server...
98% after emitting CopyPlugin

 ERROR  Failed to compile with 1 error        1:30:37 PM

 error  in ./node_modules/@vueuse/motion/dist/index.esm-bundler.js

Module parse failed: Unexpected token (131:18)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|  */
| class SubscriptionManager {
>     subscriptions = new Set();
|     add(handler) {
|         this.subscriptions.add(handler);

 @ ./src/main.js 8:0-46 27:61-73
 @ multi (webpack)-dev-server/client?http://10.0.0.105:8081&sockPath=/sockjs-node (webpack)/hot/dev-server.js ./src/main.js

I've uninstalled webpack and reinstalled, cleared the cache, and it's still not working! Thank you to anyone who can help!

Declare sideEffects in package.json to know size of exports

Hi Yaรซl,

First thanks for your package, it's sooo great to have a solid alternative of Framer-motion in Vue! ;)

One thing I was checking was the size of the package in Bundlephobia (https://bundlephobia.com/result?p=@vueuse/motion) and I saw that Export Analysis isn't shown because sideEffects hasn't been declared. I'm not 100% sure if the package meets the requirements to be sideEffects free, but I think so (here is a great explanation https://webpack.js.org/guides/tree-shaking/#mark-the-file-as-side-effect-free).

If it meets the requirements, with that change, users could better understand the size of each part of the package ๐Ÿ’ฏ

Thanks again for your work!!!!

Could not resolve `@vueuse/shared` on `2.0.0-beta.9`

Trying to replicate the pinch example from @vueuse/gesture I found that after installing the lib with npm i @vueuse/motion, vite started to fail showing a Could not resolve "@vueuse/shared" error message

npm run dev

> vite
> node_modules/@vueuse/motion/dist/index.mjs:3:43: error: Could not resolve "@vueuse/shared" (mark it as external to exclude it from the bundle)
    3 โ”‚ import { tryOnUnmounted, isFunction } from '@vueuse/shared';
      โ•ต                                            ~~~~~~~~~~~~~~~~

error when starting dev server:
Error: Build failed with 1 error:
node_modules/@vueuse/motion/dist/index.mjs:3:43: error: Could not resolve "@vueuse/shared" (mark it as external to exclude it from the bundle)
    at failureErrorWithLog (/.../node_modules/esbuild/lib/main.js:1493:15)
    at /.../node_modules/esbuild/lib/main.js:1151:28
    at runOnEndCallbacks (/.../node_modules/esbuild/lib/main.js:941:63)
    at buildResponseToResult (/.../node_modules/esbuild/lib/main.js:1149:7)
    at /.../node_modules/esbuild/lib/main.js:1258:14
    at /.../node_modules/esbuild/lib/main.js:629:9
    at handleIncomingPacket (/.../node_modules/esbuild/lib/main.js:726:9)
    at Socket.readFromStdout (/.../node_modules/esbuild/lib/main.js:596:7)
    at Socket.emit (node:events:390:28)
    at addChunk (node:internal/streams/readable:315:12)

npm run build

> vue-tsc --noEmit && vite build

node_modules/@vueuse/motion/dist/index.d.ts:7:40 - error TS2307: Cannot find module '@vueuse/shared' or its corresponding type declarations.

7 import { MaybeRef as MaybeRef$1 } from '@vueuse/shared';

package.json

{
  "dependencies": {
    "@vueuse/core": "^7.5.4",
    "@vueuse/gesture": "^2.0.0-beta.1",
    "@vueuse/motion": "^2.0.0-beta.9",
    "vue": "^3.2.25"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^2.0.0",
    "typescript": "^4.4.4",
    "vite": "^2.7.2",
    "vue-tsc": "^0.29.8"
  }
}

Just trying to import the composable make the serve/build fails

import { useMotion } from '@vueuse/motion'

System info

nodev16.13.1
npm v8.1.2
macOs Big Sur v11.2.3
Chrome v97.0.4692.71

Build fails with vite-ssg

I've encountered an error while building, I thought there was something wrong with my configuration then I tried to reproduce using https://github.com/antfu/vitesse.

I've tried using this two approach:

  1. content of main.ts:
import 'virtual:windi.css'
import './styles/main.css'
import { ViteSSG } from 'vite-ssg'
import generatedRoutes from 'virtual:generated-pages'
import { setupLayouts } from 'layouts-generated'
import { MotionPlugin } from '@vueuse/motion'
import App from './App.vue'

const routes = setupLayouts(generatedRoutes)

// https://github.com/antfu/vite-ssg
export const createApp = ViteSSG(
  App,
  { routes },
  (ctx) => {
    ctx.app.use(MotionPlugin)
    // install all modules under `modules/`
    Object.values(import.meta.globEager('./modules/*.ts')).map(i => i.install?.(ctx))
  },
)
  1. Using the module
import { MotionPlugin } from '@vueuse/motion';
import { UserModule } from '~/types';

export const install: UserModule = ({ app, isClient }) => {
  isClient && app.use(MotionPlugin);
};

The build script:
cross-env NODE_ENV=production vite-ssg build

and the result of the build returns the message:
image

What am I missing here? thank you

Could we make *-visible directives work when the element is visible from the start?

Hello,

As said in the title, In some cases, when doing responsive landing page design (e.g. 15" laptop screen vs 4k screen), it's not really possible to predict 100% of the time when an element will be visible on the first load.

In the cases when a *-visible directive is visible on the first load, the animation never trigger making the element invisible.

I made a repo to illustrate: https://github.com/xstevenyung/v-motion-visible-issue

I could work on a PR if this is something that make sense to change.

Cheers and thanks for your work !

No export name `MotionVariants`

Error thrown

Uncaught SyntaxError: The requested module '/node_modules/.vite/@vueuse_motion.js?v=35100442' does not provide an export named 'MotionVariants'

Issues with 2.0.0-beta.1

Hey,
I recently found out about this package and decided to give a try and unfortunately I kept getting 3 different Module not found errors. At first I thought it's a compatibility issue with vue 2 since I use that and I almost gave up.

I decided to try the previous release (1.6.0) and now it's working just fine!

I just wanted to let you know of the issue.

Thanks a lot and have a great day!

Add `:visible-once` variant

Related to #25, it would be great to be able to trigger an animation when visible only once. I suggest adding a new variant for that but it could be an attribute like once.

Delay does not track reactivity when used in :leave variant

My directive usage

v-motion="'leftBar'"
:initial="{x: -400, opacity: 0}"
:enter="{x: 0, opacity: 1, transition: {delay: barOpenDelay, type: 'spring', stiffness: 250, damping: 25, mass: 0.5}}"
:leave="{x: -400, opacity: 0, transition: {delay: leftBarCloseDelay, type: 'spring', stiffness: 200, damping: 25, mass: 1}}"
barOpenDelay(): number {
	return this.backdropIsRendered ? 300 : 0;
}
leftBarCloseDelay(): number {
	return this.leftSubBarIsRendered ? 300 : 0;
},

barOpenDelay works absolutely fine, but delay in :leave with leftBarCloseDelay always uses the first number it gets (in my example the site always opens with sidebars closed, so 0 is used). I also switched barOpenDelay and leftBarCloseDelay -- delay in :enter worked as expected.

I double-checked everything that could possibly be my mistake, but it is surely somewhere in motion's code.

Screenshot_20210906_183403

feat(docs): algolia doc search

Thank you for the awesome library!
I just wanted to ask if it would be possible to adapt the docs to have a search. There is so much going on in the library. Maybe also more practical examples?

@vueuse/motion not supports with tailwindcss

I'm using tailwindcss with @vueuse/motion. After I put v-motion in my html tags, I see that my hover transition from tailwindcss doesn't work anymore. I use hover from tailwindcss because whenever I use :hovered from @vueuse/motion and let it scales up on hover, it just stucks there. Even though I already bring my mouse out of it, it still scales up. However, others like tapped or focused didn't work with tailwindcss too. If there is a way that :hovered, :focused, :tapped can scale back to the same scale, which is 1, please feel free to advise me. The code below is what I've been working on. (btw, my :leave doesn't work when I click to change transition too)

  <div class="flex justify-center items-center border h-screen w-screen">
    <div id="start" class="flex flex-col justify-center items-center" >
      <h1 class="font-bold font-['Poppins'] text-5xl ">Math Quiz</h1>
      <button class="bg-green-300 my-16 py-5 px-16 font-semibold rounded-full"
      v-motion
      :initial="{ opacity:0 , x: -100, scale: 1 }"
      :enter="{ opacity: 1, x: 0 }"
      :delay="300"
      :hovered="{ scale: 1.25 }"
      >START</button>
    </div>
  </div>
</template>```

[feat-req] Add height preset

Hi,

I was checking the preset docs page of this package. I guess, adding a height preset will be great for people who want to create a collapse component.

This is useful in cases like: FAQ, QnA, Custom Collapse, etc.

Regards.

Installing with npm and vue3

When installing using npm I end up like this:

$ npm i @vueuse/motion     
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! 
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/vue
npm ERR!   vue@"^3.0.5" from the root project
npm ERR!   peer vue@"^2.0.0 || >=3.0.0-rc.0" from @vueuse/[email protected]
npm ERR!   node_modules/@vueuse/motion
npm ERR!     @vueuse/motion@"*" from the root project
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer vue@">= 2.5 < 3" from @vue/[email protected]
npm ERR! node_modules/@vue/composition-api
npm ERR!   peer @vue/composition-api@">=1.0.0-rc.1" from @vueuse/[email protected]
npm ERR!   node_modules/@vueuse/motion
npm ERR!     @vueuse/motion@"*" from the root project
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR! 
npm ERR! See /Users/dirk/.npm/eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/dirk/.npm/_logs/2021-02-22T15_35_15_422Z-debug.log

My projects dependencies are:

"dependencies": {
    "twindy": "^0.11.0",
    "twindy-headless": "^0.8.0",
    "vue": "^3.0.5",
    "vue-i18n": "^9.0.0-rc.7",
    "vue-router": "^4.0.3"
  },
  "devDependencies": {
    "@types/node": "^14.14.31",
    "@vitejs/plugin-legacy": "^1.3.1",
    "@vitejs/plugin-vue": "^1.1.4",
    "@vue/compiler-sfc": "^3.0.5",
    "@vuedx/typecheck": "^0.6.3",
    "@vuedx/typescript-plugin-vue": "^0.6.3",
    "markdown-it-anchor": "^7.0.2",
    "markdown-it-prism": "^2.1.4",
    "stylus": "^0.54.8",
    "typescript": "^4.1.5",
    "vite": "^2.0.1",
    "vite-plugin-md": "^0.5.1",
    "vite-plugin-pwa": "^0.5.3"
  }

Maybe a npm issue due to conditions like "^2.0.0 || >=3.0.0-rc.0"?

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.