22 |
23 |
24 |
25 |
26 |
27 |
28 |
49 |
--------------------------------------------------------------------------------
/docs/content/2.usage/4.presets.md:
--------------------------------------------------------------------------------
1 | # Presets
2 |
3 | For reoccuring animations you can define presets in `nuxt.config.ts`
4 |
5 | ## Add option in config
6 |
7 | To add a preset, create an array `presets` in the config options for `vgsap`
8 |
9 | ::code-group
10 |
11 | ```ts [nuxt.config.ts]
12 | vgsap: {
13 | presets: []
14 | }
15 | ```
16 | ::
17 |
18 | ## Add a preset
19 |
20 | A preset is of the following type
21 |
22 | ```ts
23 | {
24 | name: string;
25 | modifiers: string;
26 | value: any;
27 | }
28 | ```
29 |
30 | - `name` is what is used to access the preset later
31 | - `modifiers` refers to whats usually the lefthand side of the directive entry.
32 | - only include what should follow after `v-gsap.`, separated by `.`
33 | - `value` is the actual parameter that is passed to the directive.
34 |
35 | Here's an example of an actual preset:
36 |
37 | ```ts
38 | vgsap: {
39 | presets: [
40 | {
41 | name: 'stagger-right',
42 | modifiers: 'whenVisible.stagger.once.from',
43 | value: { autoAlpha: 0, x: -32 }
44 | }
45 | ]
46 | }
47 | ```
48 |
49 | For better understanding - this is what the above preset represents:
50 | ```vue
51 |
52 | ```
53 |
54 | ## Use the preset
55 |
56 | To use a preset, simply access it via the modifier `.preset` with the value being the name of the preset:
57 |
58 | ```vue
59 |
60 | ```
61 |
--------------------------------------------------------------------------------
/docs/content/1.installation/4.vue.only.md:
--------------------------------------------------------------------------------
1 | # Vue only
2 |
3 | Since Version `1.2.1` you can also use this module for Vue - instead of Nuxt.
4 |
5 | ::alert{type="info"}
6 | This feature is still experimental and to use with caution.
7 | Please report any issues on the [Github Issues Tab](https://github.com/holux-design/v-gsap-nuxt/issues)
8 | ::
9 |
10 | ## 1. Install package
11 |
12 | To use with Vue, do not use the auto-install command, since this is a nuxt-specific module install. Instead install the package itself through npm:
13 |
14 | ```bash [npx]
15 | npm i v-gsap-nuxt
16 | ```
17 |
18 | ## 2. Import directive
19 |
20 | In the second step go to your `main.ts` file for your vue app, import the Vue plugin and add it to your app **after initialization and before mount**:
21 |
22 | ::code-group
23 |
24 | ```ts [main.ts]
25 | import { vGsapVue } from 'v-gsap-nuxt/vue';
26 |
27 | // const app = createApp(App);
28 | app.directive('gsap', vGsapVue());
29 | // app.mount('#app');
30 | ::
31 |
32 |
33 | ## Configuration
34 |
35 | Since global configuration for nuxt happens in `nuxt.config.ts` which is not available in Vue, you can add these settings directly during initialization. All props are the same as with nuxt.
36 |
37 | ::code-group
38 |
39 | ```ts [main.ts]
40 | app.directive('gsap', vGsapVue({
41 | presets: [],
42 | breakpoint: 768,
43 | scroller: '',
44 | composable: true
45 | }));
46 | ::
47 |
48 | [See reference](/installation/configuration)
--------------------------------------------------------------------------------
/docs/components/DemoStateArray.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
8 | Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
9 |
10 |
11 | Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
12 |
13 |
14 |
15 |
16 |
32 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "v-gsap-nuxt",
3 | "version": "1.4.4",
4 | "description": "GSAP Directive for Nuxt 3",
5 | "repository": "holux-design/v-gsap-nuxt",
6 | "homepage": "https://v-gsap-nuxt.vercel.app",
7 | "contributors": [
8 | {
9 | "name": "Lukas Hofstätter (Holux Design)"
10 | }
11 | ],
12 | "author": {
13 | "name": "Lukas Hofstätter",
14 | "email": "office@holux-design.at"
15 | },
16 | "keywords": [
17 | "v-gsap",
18 | "gsap",
19 | "nuxt",
20 | "nuxt3",
21 | "animation",
22 | "motion",
23 | "nuxt-gsap",
24 | "gsap-nuxt",
25 | "gsap-directive"
26 | ],
27 | "license": "MIT",
28 | "type": "module",
29 | "exports": {
30 | ".": {
31 | "types": "./dist/types.d.ts",
32 | "import": "./dist/module.mjs",
33 | "require": "./dist/module.cjs"
34 | },
35 | "./vue": {
36 | "import": "./dist/runtime/vue.js",
37 | "types": "./dist/runtime/vue.d.ts"
38 | }
39 | },
40 | "main": "./dist/module.cjs",
41 | "types": "./dist/types.d.ts",
42 | "files": [
43 | "dist"
44 | ],
45 | "scripts": {
46 | "prepack": "nuxt-module-build build",
47 | "prepare": "nuxt prepare",
48 | "dev:docs": "nuxi dev docs --host",
49 | "dev:check": "npm run lint:fix && npm run test",
50 | "build:docs": "cd docs && npm i && cd .. && nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare docs && nuxi build docs",
51 | "prepare:docs": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare docs",
52 | "dev:playground": "nuxi dev playground",
53 | "build:playground": "nuxi build playground",
54 | "prepare:playground": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
55 | "release": "npm run lint:fix && npm run test && npm run prepack && changelogen --release && npm publish && git push --follow-tags",
56 | "lint": "eslint .",
57 | "test": "vitest run",
58 | "test:watch": "vitest watch",
59 | "test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit",
60 | "lint:fix": "eslint . --fix"
61 | },
62 | "dependencies": {
63 | "@nuxt/kit": "^3.14.1592",
64 | "defu": "^6.1.4",
65 | "gsap": "^3.12.5"
66 | },
67 | "devDependencies": {
68 | "@nuxt/devtools": "^1.6.1",
69 | "@nuxt/eslint-config": "^0.7.2",
70 | "@nuxt/module-builder": "^0.8.4",
71 | "@nuxt/schema": "^3.14.1592",
72 | "@nuxt/test-utils": "^3.14.4",
73 | "@types/node": "latest",
74 | "changelogen": "^0.5.7",
75 | "eslint": "^9.15.0",
76 | "nuxt": "^3.14.1592",
77 | "typescript": "latest",
78 | "vitest": "^2.1.6",
79 | "vue-tsc": "^2.1.10"
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/docs/content/1.installation/3.Philosophy.md:
--------------------------------------------------------------------------------
1 | # Philosophy
2 |
3 | ## Why is `v-gsap` a thing?
4 |
5 | Animations are an essential today, since they greatly enhance the user experience of any app or website. With an evergrowing ecosystem of frameworks and libraries, we as developers find ourselves in a constant battle of choosing a technology to provide us with the best Developer Experience and the lowest barrier for our ADHD.
6 |
7 | GSAP is one of the most complete and grown-up animation libraries out there. But I always found myself adding animations _after_ finalising the UI, since there is a mental barrier to set up a function to initialize the animation timeline yadiyadiyada.
8 | Growing accustomed to directly writing inline with tailwind, the strive to do the same thing just as easily for animations grew.
9 |
10 | `v-gsap` attempts to solve this mental barrier issue by breaking down everyday animations into a comfortable and readable format.
11 |
12 | Animations like
13 |
14 | ```
15 | v-gsap.whenVisible.stagger.once.from=...
16 | ```
17 |
18 | show how easily read- and writeable this inline format is.
19 |
20 | Whenever possible, all the properties are named the same as we are familiar with GSAP. However, for some reoccuring usecases I took the freedom to create new names like `whenVisible` for ScrollTrigger, or `parallax` as a global term for translateY animations.
21 |
22 | ## Why choose over other libraries
23 |
24 | I'll be honest: v-gsap kinda grew out of jealousy of framer motion. It's syntax isnt especially natural, but the basic idea of writing animations inline is a big step in DX.
25 |
26 | Of course there is the direct framermotion-competitor in the nuxt ecosystem: vueuse/motion. One could argue it lacks feature richness and it's state based approach (just like framer-motion) is an overkill in many situations. If your html bloats due to directive use, then it fuels the problem it was trying to solve.
27 |
28 | One could also compare with tailwind animations, but speaking of feature richness, it's a nope.
29 |
30 | A new package that can be seen as an alternative is [Glaze](https://glaze.dev). I admire their approach, since it is the exact same thought as `v-gsap-nuxt` but in plain JS for all tech stacks to use. However, it's syntax can get quite overwhelming when dealing with more complex animations. Being bound to nuxt, v-gsap-nuxt can utilize modifiers to simplify these animations and therefore provide a slightly better DX.
31 |
32 | ## What it is not
33 |
34 | This plugin certainly is a convenient drop-in for quick and easy wow-effects. It certainly isnt suitable for more complex animations with multiple steps or custom state logic like popups. There are plans on the roadmap to include state-logic, but it is not yet clear how that fits the general philosophy.
35 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # `v-gsap` for Nuxt (and Vue)
2 |
3 | [![npm version][npm-version-src]][npm-version-href]
4 | [![npm downloads][npm-downloads-src]][npm-downloads-href]
5 | [![License][license-src]][license-href] [![Nuxt][nuxt-src]][nuxt-href]
6 |
7 | [](https://v-gsap-nuxt.vercel.app/) (Click image to
8 | visit the docs)
9 |
10 | ## Features
11 |
12 | - 🚀 Smooth animations with [GSAP](https://gsap.com/)
13 | - 🖍️ Easy to use directive syntax with
14 | [`v-gsap`](https://v-gsap-nuxt.vercel.app/playground)
15 | - 📦 [`useGSAP()`](https://v-gsap-nuxt.vercel.app/usage/composable) composable
16 | for complex animations
17 | - 🪄 [``](https://v-gsap-nuxt.vercel.app/usage/v-if) to animate
18 | `v-if`
19 | - ⌨️ Powerful
20 | [entrance presets](https://v-gsap-nuxt.vercel.app/usage/modifiers#entrance)
21 | and [custom presets](https://v-gsap-nuxt.vercel.app/usage/presets)
22 | - 🧩 Full GSAP
23 | [Plugin extensibility](https://v-gsap-nuxt.vercel.app/information/gsap-plugins)
24 |
25 | ## Installation
26 |
27 | Install the module to your Nuxt application with one command:
28 |
29 | ```bash
30 | npx nuxi module add v-gsap-nuxt
31 | ```
32 |
33 | That's it! You can now use `v-gsap` in your Nuxt app ✨
34 |
35 | ### Want to use it with Vue? [Learn about Vue usage](https://v-gsap-nuxt.vercel.app/installation/vue.only)
36 |
37 | ## Docs
38 |
39 | ### 👁️ Find the full docs and examples here: [Documentation](https://v-gsap-nuxt.vercel.app/)
40 |
41 | ---
42 |
43 | ### GSAP Licensing
44 |
45 | GSAP is subject to its own licensing terms. Before incorporating GSAP with
46 | `v-gsap-nuxt` (as dependency), ensure you review and comply with the
47 | [GSAP Standard License](https://gsap.com/community/standard-license/).
48 |
49 | This module itself is licensed under the MIT License.
50 |
51 | ---
52 |
53 | ## Contribution
54 |
55 |
56 | Local development
57 |
58 | ```bash
59 | # Install dependencies
60 | npm install
61 |
62 | # Generate type stubs
63 | npm run dev:prepare
64 |
65 | # Develop with the playground
66 | npm run dev:playground
67 | # OR
68 | # Develop with the Docs
69 | npm run dev:docs
70 |
71 | # Build the playground
72 | npm run dev:build
73 |
74 | # Run ESLint
75 | npm run dev:check
76 |
77 | # Release new version
78 | npm run release
79 | ```
80 |
81 |
82 |
83 |
84 |
85 | [npm-version-src]:
86 | https://img.shields.io/npm/v/v-gsap-nuxt/latest.svg?style=flat&colorA=020420&colorB=00DC82
87 | [npm-version-href]: https://npmjs.com/package/v-gsap-nuxt
88 | [npm-downloads-src]:
89 | https://img.shields.io/npm/dm/v-gsap-nuxt.svg?style=flat&colorA=020420&colorB=00DC82
90 | [npm-downloads-href]: https://npm.chart.dev/v-gsap-nuxt
91 | [license-src]:
92 | https://img.shields.io/npm/l/v-gsap-nuxt.svg?style=flat&colorA=020420&colorB=00DC82
93 | [license-href]: https://npmjs.com/package/v-gsap-nuxt
94 | [nuxt-src]: https://img.shields.io/badge/Nuxt-020420?logo=nuxt.js
95 | [nuxt-href]: https://nuxt.com
96 |
--------------------------------------------------------------------------------
/docs/components/Snippet.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
66 |
--------------------------------------------------------------------------------
/docs/content/2.usage/2.examples.md:
--------------------------------------------------------------------------------
1 | # Examples
2 |
3 | Here you'll find some use-cases and examples.
4 | [See it in action](/playground)
5 |
6 | ## Entrance
7 |
8 | [See reference](/usage/modifiers#whenvisible)
9 |
10 | ### Basic fade-in from left
11 |
12 | ```vue
13 |
14 | ```
15 |
16 | ### Custom start / end
17 |
18 | ```vue
19 |
26 | ```
27 |
28 | ### Entrance only single time
29 |
30 | ```vue
31 |
32 | ```
33 |
34 | ### With `.entrance`
35 |
36 | ```vue
37 |
38 | ```
39 |
40 | ::alert{type="info"}
41 | There are multiple presets for entrace [See details](/usage/modifiers#entrance)
42 | ::
43 |
44 | ### Debug with markers
45 |
46 | ```vue
47 |
48 | ```
49 |
50 | ---
51 |
52 | ## Magnetic
53 |
54 | [See reference](/usage/modifiers#magnetic)
55 |
56 | ### Basic
57 |
58 | ```vue
59 |
60 | ```
61 |
62 | ### Strong
63 |
64 | ```vue
65 |
66 | ```
67 |
68 | ---
69 |
70 | ## Stagger
71 |
72 | [See reference](/usage/modifiers#stagger)
73 |
74 | ```html
75 |
9 |
10 | ```
11 |
12 | By default, the wrapped content will animate `opacity` with a (gsap-)default
13 | duration of `0.5s`.
14 |
15 | You can add custom properties to the `hidden` object to customize the animation.
16 | These values will be merged with the default opacity behaviour, so opacity
17 | doesnt need to be specified.
18 |
19 | ```vue
20 |
21 |
Hello World
22 |
23 | ```
24 |
25 | ## Multiple elements
26 |
27 | In addition to the `` component, Vue provides a ``
28 | for transitioning multiple elements. Mostly this is done with `v-for` to show
29 | the appearance of a list of items.
30 |
31 | We utilise Vue's default group component by using the `group` flag on
32 | ``.
33 |
34 | ```vue
35 |
36 |
40 | {{ item.name }}
41 |
42 |
43 | ```
44 |
45 | Visually transitioning multiple elements is best done with a slight `stagger`.
46 |
47 | To enable a stagger, `` has to have access to the element's
48 | index, which is done using `:data-index="idx"` on the transitioning elements.
49 |
50 | There is a default value of `0.1s` for the stagger, which can be configured.
51 |
52 | ```vue
53 |
54 |
59 | {{ item.name }}
60 |
61 |
62 | ```
63 |
64 | ## Properties
65 |
66 | | Prop | Type | Description |
67 | | -------- | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
68 | | hidden | `GSAPTweenVars` | State of the toggled element when hidden |
69 | | duration | `number`, default: `0.5` | The duration of the animation in seconds |
70 | | appear | `boolean`, default: `false` | Wether or not to run the enter-animation on initial load |
71 | | ease | `string`, default: `power1.inOut` | The ease of the animation. Can be overriden by the `ease` modifier in `hidden` |
72 | | delay | `number`, default: `0` | Initial delay of the transition animation in seconds |
73 | | group | `boolean`, default: `false` | Wether or not the transition applies to multiple elements. Most of the times paired with `v-if` |
74 | | stagger | `number`, default: `0.1` | Delay the appearance of each next element when using `group`. For this to work you also have to put `:data-index="idx"` on the element. |
75 |
76 | ## Full Example
77 |
78 | ```vue
79 |
86 |
Hello World
87 |
88 | ```
89 |
90 | ### Disabling default opacity animation
91 |
92 | If you want to disable the default opacity behaviour, you can set the `opacity`
93 | property in `hidden` to `1`. This way it will animate from 1 to 1 and
94 | essentially disable toggling opacity therefore.
95 |
96 | Example:
97 |
98 | ```vue
99 |
100 |
Hello World
101 |
102 | ```
103 |
--------------------------------------------------------------------------------
/docs/content/2.usage/5.timeline.md:
--------------------------------------------------------------------------------
1 | # Timeline
2 |
3 | The modifier `.timeline` lets you create complex and dependent animation timelines.
4 |
5 | ## `.timeline`
6 |
7 | For a timeline to be instantiated, place `v-gsap.timeline` on the parent. You can then add animation steps on each child with `.add`
8 |
9 | ```html
10 |
11 |
Hello World
12 |
They see me animating
13 |
14 | ```
15 |
16 | A timeline also supports `.whenVisible` so you can define complex entrance animations together
17 |
18 | ```html
19 |
20 |
Hello World
21 |
They see me animating
22 |
23 | ```
24 |
25 |
26 | See more detailed explanation below
27 |
28 | ### `.timeline.pinned`
29 |
30 | Lets you create an animation that gets pinned once in position to then play each added steps.
31 | To define when and how long a section gets pinned, use the following properties
32 |
33 | - `start`
34 | - default `center center`
35 | - `end`
36 | - default: '+=1000px'
37 |
38 | You can set these properties individually like so:
39 | ```vue
40 |
41 | ```
42 |
43 | ---
44 |
45 | ### `.add`
46 |
47 | To add each individual animation step inside a timeline, use `.add`
48 |
49 | ```html
50 |
51 |
Hello World
52 |
Still here
53 |
54 | ```
55 |
56 | ---
57 |
58 | #### Ordering
59 |
60 | By default, all steps are ordered like they appear in the html.
61 |
62 | ```html
63 |
64 |
Hello World
65 |
66 | They see me animating
67 | They see me animating
68 |
69 |
Still here
70 |
71 | ```
72 |
73 | #### `.order-`
74 |
75 | If your animation steps need to be in a custom order you can use `.order` to define the order yourself:
76 |
77 | ```html
78 |
79 |
Hello World
80 |
81 | They see me animating
82 | They see me animating
83 |
84 |
Still here
85 |
86 | ```
87 |
88 | #### `.withPrevious`
89 |
90 | If you want to run an animation step parallel to the one before, you can use this modifier.
91 |
92 | ```html
93 |
94 |
This runs at the
95 |
same time
96 |
97 | ```
98 |
99 | ::alert{type="info"}
100 | For single elements with multiple steps, `.withPrevious` references the previous animation step, not the previous **element**
101 | ::
102 |
103 | ---
104 |
105 | #### Multiple Steps per Element
106 | You can also add multiple steps on one element:
107 |
108 | ```html
109 |
110 |
113 | Hello World
114 |
115 |
116 | ```
117 |
118 | ::alert{type="warning"}
119 | You can not use the same modifier combination multiple times. A dirty hack would be to add some made-up modifier to satisfy the error.
120 | ::
121 |
122 | ---
123 |
124 | ### Callbacks
125 |
126 | There are five callbacks available that you can attach to a timeline
127 |
128 | - `.onEnter`
129 | - `.onEnterBack`
130 | - `.onLeave`
131 | - `.onLeaveBack`
132 | - `.onUpdate`
133 |
134 | All of them will pass a timeline snapshot that you can receive as prop.
135 |
136 | You can use them like so:
137 |
138 | ```vue
139 |
140 | ...
141 |
142 | ```
143 |
144 | ::alert{type="info"}
145 | Due to the nature of directives, you can only use one callback per timeline.
146 | Hint: `.onUpdate` contains all information that you need deduce the other events, mainly from `direction` and `progress`
147 | ::
148 |
--------------------------------------------------------------------------------
/docs/tokens.config.ts:
--------------------------------------------------------------------------------
1 | import { defineTheme } from 'pinceau'
2 |
3 | export default defineTheme({
4 | color: {
5 | black: '#0B0A0A',
6 | // Primary is modified lightblue
7 | primary: {
8 | 50: '#effef2',
9 | 100: '#d8ffe3',
10 | 200: '#b4fec7',
11 | 300: '#7afb9d',
12 | 400: '#39ef6b',
13 | 500: '#10d747',
14 | 600: '#06b236',
15 | 700: '#098c2e',
16 | 800: '#0d6e29',
17 | 900: '#0d5a25',
18 | 950: '#003310',
19 | },
20 | gray: {
21 | 50: '#FBFBFB',
22 | 100: '#F6F5F4',
23 | 200: '#ECEBE8',
24 | 300: '#DBD9D3',
25 | 400: '#ADA9A4',
26 | 500: '#97948F',
27 | 600: '#67635D',
28 | 700: '#36332E',
29 | 800: '#201E1B',
30 | 900: '#121110',
31 | },
32 | red: {
33 | 50: '#FFF9F8',
34 | 100: '#FFF3F0',
35 | 200: '#FFDED7',
36 | 300: '#FFA692',
37 | 400: '#FF7353',
38 | 500: '#FF3B10',
39 | 600: '#BB2402',
40 | 700: '#701704',
41 | 800: '#340A01',
42 | 900: '#1C0301',
43 | },
44 | blue: {
45 | 50: '#F2FAFF',
46 | 100: '#DFF3FF',
47 | 200: '#C6EAFF',
48 | 300: '#A1DDFF',
49 | 400: '#64C7FF',
50 | 500: '#1AADFF',
51 | 600: '#0069A6',
52 | 700: '#014267',
53 | 800: '#002235',
54 | 900: '#00131D',
55 | },
56 | green: {
57 | 50: '#ECFFF7',
58 | 100: '#DEFFF1',
59 | 200: '#C3FFE6',
60 | 300: '#86FBCB',
61 | 400: '#3CEEA5',
62 | 500: '#0DD885',
63 | 600: '#00B467',
64 | 700: '#006037',
65 | 800: '#002817',
66 | 900: '#00190F',
67 | },
68 | yellow: {
69 | 50: '#FFFCEE',
70 | 100: '#FFF6D3',
71 | 200: '#FFF0B1',
72 | 300: '#FFE372',
73 | 400: '#FFDC4E',
74 | 500: '#FBCA05',
75 | 600: '#CBA408',
76 | 700: '#614E02',
77 | 800: '#292100',
78 | 900: '#1B1500',
79 | },
80 | shadow: {
81 | initial: '{color.gray.400}',
82 | dark: '{color.gray.800}',
83 | },
84 | },
85 | shadow: {
86 | 'xs': '0px 1px 2px 0px {color.shadow}',
87 | 'sm': '0px 1px 3px 0px {color.shadow}, 0px 1px 2px -1px {color.shadow}',
88 | 'md': '0px 4px 6px -1px {color.shadow}, 0px 2px 4px -2px {color.shadow}',
89 | 'lg': '0px 10px 15px -3px {color.shadow}, 0px 4px 6px -4px {color.shadow}',
90 | 'xl': '0px 20px 25px -5px {color.shadow}, 0px 8px 10px -6px {color.shadow}',
91 | '2xl': '0px 25px 50px -12px {color.shadow}',
92 | 'none': '0px 0px 0px 0px transparent',
93 | },
94 | docus: {
95 | $schema: {
96 | title: 'All the configurable tokens from Docus.',
97 | tags: [
98 | '@studioIcon material-symbols:docs',
99 | ],
100 | },
101 | body: {
102 | backgroundColor: {
103 | initial: '{color.white}',
104 | dark: '{color.black}',
105 | },
106 | color: {
107 | initial: '{color.gray.800}',
108 | dark: '{color.gray.200}',
109 | },
110 | fontFamily: '{font.sans}',
111 | },
112 | header: {
113 | height: '64px',
114 | logo: {
115 | height: {
116 | initial: '{space.6}',
117 | sm: '{space.7}',
118 | },
119 | },
120 | title: {
121 | fontSize: '{fontSize.2xl}',
122 | fontWeight: '{fontWeight.bold}',
123 | color: {
124 | static: {
125 | initial: '{color.gray.900}',
126 | dark: '{color.gray.100}',
127 | },
128 | hover: '{color.primary.500}',
129 | },
130 | },
131 | },
132 | footer: { height: { initial: '145px', sm: '100px' }, padding: '{space.4} 0' },
133 | readableLine: '78ch',
134 | loadingBar: {
135 | height: '3px',
136 | gradientColorStop1: '#00dc82',
137 | gradientColorStop2: '#34cdfe',
138 | gradientColorStop3: '#0047e1',
139 | },
140 | search: {
141 | backdropFilter: 'blur(24px)',
142 | input: {
143 | borderRadius: '{radii.2xs}',
144 | borderWidth: '1px',
145 | borderStyle: 'solid',
146 | borderColor: {
147 | initial: '{color.gray.200}',
148 | dark: 'transparent',
149 | },
150 | fontSize: '{fontSize.sm}',
151 | gap: '{space.2}',
152 | padding: '{space.2} {space.4}',
153 | backgroundColor: {
154 | initial: '{color.gray.200}',
155 | dark: '{color.gray.800}',
156 | },
157 | },
158 | results: {
159 | window: {
160 | marginX: {
161 | initial: '0',
162 | sm: '{space.4}',
163 | },
164 | borderRadius: {
165 | initial: 'none',
166 | sm: '{radii.xs}',
167 | },
168 | marginTop: {
169 | initial: '0',
170 | sm: '20vh',
171 | },
172 | maxWidth: '640px',
173 | maxHeight: {
174 | initial: '100%',
175 | sm: '320px',
176 | },
177 | },
178 | selected: {
179 | backgroundColor: {
180 | initial: '{color.gray.300}',
181 | dark: '{color.gray.700}',
182 | },
183 | },
184 | highlight: {
185 | color: 'white',
186 | backgroundColor: '{color.primary.500}',
187 | },
188 | },
189 | },
190 | },
191 | typography: {
192 | color: {
193 | primary: {
194 | 50: '{color.primary.50}',
195 | 100: '{color.primary.100}',
196 | 200: '{color.primary.200}',
197 | 300: '{color.primary.300}',
198 | 400: '{color.primary.400}',
199 | 500: '{color.primary.500}',
200 | 600: '{color.primary.600}',
201 | 700: '{color.primary.700}',
202 | 800: '{color.primary.800}',
203 | 900: '{color.primary.900}',
204 | },
205 | secondary: {
206 | 50: '{color.gray.50}',
207 | 100: '{color.gray.100}',
208 | 200: '{color.gray.200}',
209 | 300: '{color.gray.300}',
210 | 400: '{color.gray.400}',
211 | 500: '{color.gray.500}',
212 | 600: '{color.gray.600}',
213 | 700: '{color.gray.700}',
214 | 800: '{color.gray.800}',
215 | 900: '{color.gray.900}',
216 | },
217 | },
218 | },
219 | })
220 |
--------------------------------------------------------------------------------
/docs/content/2.usage/3.modifiers.md:
--------------------------------------------------------------------------------
1 | # Modifiers
2 |
3 | Discover all the different features of `v-gsap`.
4 |
5 | ## `.from`, `.to`, `.fromTo`, `.call`
6 |
7 | V-GSAP supports the above four main animation types.
8 |
9 | - `.from` animates from a given state to its current state
10 | - `.to` animates from the current state to a given to-state
11 | - `.fromTo` combines both the above. It takes an Array of two states as value
12 | - `.call` takes an arrow function as value and executes it
13 | - when used with `.whenVisible.`, it will automatically be handled like
14 | `.once.`
15 |
16 | ---
17 |
18 | ## `.whenVisible`
19 |
20 | [See in Action](/playground#whenvisible)
21 |
22 | - enables scrollTrigger. It defaults to from `top 90%` to `top 50%` and `scrub`
23 | - you can overwrite these properties in the value Object. In combination with
24 | `.fromTo`, put the overrides in the second state
25 |
26 | ### `.fromInvisible`
27 |
28 | - Adds `opacity: 0` as initial state and includes `opacity: 1` in `.to` or
29 | `.fromTo`.
30 | - This prevents the element from being visible until the directive takes action.
31 | Especially needed for above-the-fold animations
32 | - With this modifier you can create entrance animations without always repeating
33 | the opacity hassle.
34 |
35 | ### `.once`
36 |
37 | Makes the animation play only once when scrolling down, and stay in its final
38 | state even when scrolling back up.
39 |
40 | ### `.once.reversible`
41 |
42 | Similar to `.once` but will reverse the animation when scrolling back up,
43 | allowing it to play again when scrolling down.
44 |
45 | ::alert{type="info"} This is the default previous behavior of `.once`. ::
46 |
47 | ### `.markers`
48 |
49 | Adds markers for debugging.
50 |
51 | ### Custom Scroller
52 |
53 | If your content is wrapped in an artificial scroll container, use
54 | `{ [...], scroller: '' }` as a selector string inside the value object
55 | to override the default scroll container. ::alert{type="info"} Note: You can
56 | also set this globally in the `nuxt.config.ts`
57 | [See details](/installation/configuration) ::
58 |
59 | ---
60 |
61 | ## `.onState--`
62 |
63 | The `.onState-` feature allows to play certain animations only when a
64 | data-attribute has a certain value.
65 |
66 | The modifier consists of 2 or 3 parts:
67 |
68 | `.onState--`
69 |
70 | - `key`: refers to the data attribute that is used as source. Example: key
71 | `test` would refer to `data-test=""`
72 | - `value`: (optional) the target value to trigger the animation.
73 | - If left out, the desired target value is `true`. This allows more readable
74 | syntax like `.onState-open`
75 |
76 | Example:
77 |
78 | ```typescript
79 |
82 | ```
83 |
84 | The above example code would run the animation when the `data-index` value is
85 | `2`
86 |
87 | This feature uses `MutationObserver` in the background that updates each time
88 | the given data-attribute changes. If the current value equals the target value,
89 | the animation is played. If the values don't match, the animation is reversed.
90 |
91 | ### .inherit
92 |
93 | This is a submodifier for `.onState-` and allows the data-attribute to be on
94 | some parent. This is useful if you want to update multiple child elements based
95 | on some parent state.
96 |
97 | In the background `el.closest()` is used to search for a parent that has the
98 | matching data-attribute.
99 |
100 | Simple example:
101 |
102 | ```typescript
103 |