├── .husky └── .gitignore ├── TODO.md ├── .browserslistrc ├── _config.yml ├── docs ├── robots.txt ├── favicon.ico ├── favicon.png ├── og-image.jpg ├── favicon-16x16.png ├── favicon-32x32.png ├── mstile-70x70.png ├── mstile-150x150.png ├── mstile-310x150.png ├── apple-touch-icon.png ├── android-chrome-96x96.png ├── android-chrome-144x144.png ├── apple-touch-icon-57x57.png ├── apple-touch-icon-60x60.png ├── apple-touch-icon-72x72.png ├── apple-touch-icon-76x76.png ├── apple-touch-icon-precomposed.png ├── img │ └── lighthouse-audit.91ed377c.jpg ├── apple-touch-icon-57x57-precomposed.png ├── apple-touch-icon-60x60-precomposed.png ├── apple-touch-icon-72x72-precomposed.png ├── apple-touch-icon-76x76-precomposed.png ├── humans.txt ├── browserconfig.xml ├── site.webmanifest ├── safari-pinned-tab.svg ├── css │ ├── app.2d445fa2.css │ └── chunk-vendors.36e46d09.css └── index.html ├── public ├── robots.txt ├── favicon.ico ├── favicon.png ├── og-image.jpg ├── favicon-16x16.png ├── favicon-32x32.png ├── mstile-70x70.png ├── apple-touch-icon.png ├── mstile-150x150.png ├── mstile-310x150.png ├── android-chrome-96x96.png ├── android-chrome-144x144.png ├── apple-touch-icon-57x57.png ├── apple-touch-icon-60x60.png ├── apple-touch-icon-72x72.png ├── apple-touch-icon-76x76.png ├── apple-touch-icon-precomposed.png ├── apple-touch-icon-57x57-precomposed.png ├── apple-touch-icon-60x60-precomposed.png ├── apple-touch-icon-72x72-precomposed.png ├── apple-touch-icon-76x76-precomposed.png ├── humans.txt ├── browserconfig.xml ├── site.webmanifest ├── safari-pinned-tab.svg └── index.html ├── .markdownlint.json ├── .eslintignore ├── renovate.json ├── .prettierignore ├── .stylelintignore ├── lighthouse-audit.jpg ├── commitlint.config.js ├── .lintstagedrc ├── .travis.yml ├── husky.config.js ├── src ├── VApp │ ├── index.js │ ├── style.scss │ └── VApp.vue ├── CursorFx │ ├── global.scss │ ├── index.js │ ├── style.scss │ ├── cursor-fx.js │ └── CursorFx.vue ├── library.js ├── main.js └── main.scss ├── babel.config.js ├── .github ├── FUNDING.yml ├── workflows │ └── blank.yml └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── .editorconfig ├── jsconfig.json ├── .gitignore ├── .prettierrc ├── .env ├── tsconfig.json ├── postcss.config.js ├── dist ├── CursorFx.css └── CursorFx.umd.min.js ├── LICENSE ├── .vscode ├── extensions.json └── settings.json ├── vue.config.js ├── CHANGELOG.md ├── package.json ├── stylelint.config.js ├── README.md └── .eslintrc.js /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # TODO 2 | -------------------------------------------------------------------------------- /.browserslistrc: -------------------------------------------------------------------------------- 1 | defaults 2 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman 2 | -------------------------------------------------------------------------------- /docs/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: / 3 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: / 3 | -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "MD013": false 3 | } 4 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | docs/ 3 | 4 | bower_components/ 5 | node_modules/ 6 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "@vuejs" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | docs/ 3 | 4 | bower_components/ 5 | node_modules/ 6 | -------------------------------------------------------------------------------- /.stylelintignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | docs/ 3 | 4 | bower_components/ 5 | node_modules/ 6 | -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/docs/favicon.ico -------------------------------------------------------------------------------- /docs/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/docs/favicon.png -------------------------------------------------------------------------------- /docs/og-image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/docs/og-image.jpg -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/public/favicon.png -------------------------------------------------------------------------------- /public/og-image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/public/og-image.jpg -------------------------------------------------------------------------------- /docs/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/docs/favicon-16x16.png -------------------------------------------------------------------------------- /docs/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/docs/favicon-32x32.png -------------------------------------------------------------------------------- /docs/mstile-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/docs/mstile-70x70.png -------------------------------------------------------------------------------- /lighthouse-audit.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/lighthouse-audit.jpg -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: [ '@commitlint/config-conventional' ], 3 | }; 4 | -------------------------------------------------------------------------------- /docs/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/docs/mstile-150x150.png -------------------------------------------------------------------------------- /docs/mstile-310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/docs/mstile-310x150.png -------------------------------------------------------------------------------- /public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/public/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/public/favicon-32x32.png -------------------------------------------------------------------------------- /public/mstile-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/public/mstile-70x70.png -------------------------------------------------------------------------------- /docs/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/docs/apple-touch-icon.png -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/public/apple-touch-icon.png -------------------------------------------------------------------------------- /public/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/public/mstile-150x150.png -------------------------------------------------------------------------------- /public/mstile-310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/public/mstile-310x150.png -------------------------------------------------------------------------------- /docs/android-chrome-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/docs/android-chrome-96x96.png -------------------------------------------------------------------------------- /docs/android-chrome-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/docs/android-chrome-144x144.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/docs/apple-touch-icon-57x57.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/docs/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/docs/apple-touch-icon-72x72.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/docs/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /public/android-chrome-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/public/android-chrome-96x96.png -------------------------------------------------------------------------------- /public/android-chrome-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/public/android-chrome-144x144.png -------------------------------------------------------------------------------- /public/apple-touch-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/public/apple-touch-icon-57x57.png -------------------------------------------------------------------------------- /public/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/public/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /public/apple-touch-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/public/apple-touch-icon-72x72.png -------------------------------------------------------------------------------- /public/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/public/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/docs/apple-touch-icon-precomposed.png -------------------------------------------------------------------------------- /docs/img/lighthouse-audit.91ed377c.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/docs/img/lighthouse-audit.91ed377c.jpg -------------------------------------------------------------------------------- /public/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/public/apple-touch-icon-precomposed.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-57x57-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/docs/apple-touch-icon-57x57-precomposed.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-60x60-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/docs/apple-touch-icon-60x60-precomposed.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-72x72-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/docs/apple-touch-icon-72x72-precomposed.png -------------------------------------------------------------------------------- /docs/apple-touch-icon-76x76-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/docs/apple-touch-icon-76x76-precomposed.png -------------------------------------------------------------------------------- /public/apple-touch-icon-57x57-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/public/apple-touch-icon-57x57-precomposed.png -------------------------------------------------------------------------------- /public/apple-touch-icon-60x60-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/public/apple-touch-icon-60x60-precomposed.png -------------------------------------------------------------------------------- /public/apple-touch-icon-72x72-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/public/apple-touch-icon-72x72-precomposed.png -------------------------------------------------------------------------------- /public/apple-touch-icon-76x76-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuXDAmore/vue-cursor-fx/HEAD/public/apple-touch-icon-76x76-precomposed.png -------------------------------------------------------------------------------- /.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "*.vue": "lint", 3 | "*.{ts,js}": "eslint", 4 | "*.css": "stylelint", 5 | "*.scss": "stylelint --syntax=scss" 6 | } 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '8' 4 | script: 5 | - npm run test 6 | - npm run publish 7 | branches: 8 | only: 9 | - master 10 | -------------------------------------------------------------------------------- /husky.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | hooks: { 3 | 'commit-msg': 'commitlint -E HUSKY_GIT_PARAMS', 4 | 'pre-commit': 'lint-staged', 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /src/VApp/index.js: -------------------------------------------------------------------------------- 1 | // Import vue component 2 | import component from './VApp.vue'; 3 | 4 | // To allow use as module (npm/webpack/etc.) export component 5 | export default component; 6 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ 4 | '@vue/app', 5 | { 6 | useBuiltIns: false, 7 | }, 8 | ], 9 | ], 10 | }; 11 | -------------------------------------------------------------------------------- /docs/humans.txt: -------------------------------------------------------------------------------- 1 | /* TEAM */ 2 | Creative developer: Luca Iaconelli 3 | Twitter: @luxdamore 4 | Instagram: @luxdamore 5 | From: Faenza, Italia 6 | 7 | /* SITE */ 8 | Language: Italian 9 | Doctype: HTML5 10 | IDE: Visual Studio Code 11 | -------------------------------------------------------------------------------- /public/humans.txt: -------------------------------------------------------------------------------- 1 | /* TEAM */ 2 | Creative developer: Luca Iaconelli 3 | Twitter: @luxdamore 4 | Instagram: @luxdamore 5 | From: Faenza, Italia 6 | 7 | /* SITE */ 8 | Language: Italian 9 | Doctype: HTML5 10 | IDE: Visual Studio Code 11 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | patreon: luxdamore 4 | open_collective: luca-iaconelli 5 | ko_fi: luxdamore 6 | liberapay: luxdamore 7 | issuehunt: luxdamore 8 | otechie: luxdamore 9 | custom: ['https://www.paypal.me/luxdamore'] 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 4 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.yml] 12 | indent_size = 2 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "~/*": ["./*"], 6 | "@/*": ["./*"], 7 | "~~/*": ["./*"], 8 | "@@/*": ["./*"] 9 | } 10 | }, 11 | "exclude": ["node_modules", ".nuxt", "dist", "docs"] 12 | } 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Common 2 | .DS_Store 3 | .env 4 | desktop.ini 5 | node_modules/ 6 | bower_components/ 7 | 8 | # Library 9 | dist/demo.html 10 | 11 | # Log files 12 | npm-debug.log* 13 | yarn-debug.log* 14 | yarn-error.log* 15 | report.* 16 | *.heapsnapshot 17 | 18 | # Editor directories and files 19 | .idea 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw* 25 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120, 3 | "singleQuote": true, 4 | "trailingComma": "all", 5 | "bracketSpacing": true, 6 | "jsxBracketSameLine": true, 7 | "semi": true, 8 | "requirePragma": true, 9 | "insertPragma": true, 10 | "useTabs": false, 11 | "tabWidth": 4, 12 | "arrowParens": "avoid", 13 | "proseWrap": "preserve" 14 | } 15 | -------------------------------------------------------------------------------- /src/CursorFx/global.scss: -------------------------------------------------------------------------------- 1 | .cursor-fx { 2 | 3 | opacity: 0; 4 | 5 | } 6 | 7 | .is-cursor-fx-active { 8 | 9 | &, 10 | * { 11 | 12 | cursor: none; 13 | 14 | } 15 | 16 | .cursor-fx { 17 | 18 | transition-delay: .3s; 19 | 20 | &.cursor-fx--loaded { 21 | 22 | opacity: 1; 23 | 24 | } 25 | 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/library.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Creates an instance of the design system 3 | * 4 | * @function install 5 | * @param {VueInstance} Vue Vue instance. 6 | */ 7 | export default { 8 | install( 9 | Vue, 10 | options, 11 | ) { 12 | 13 | const OPTIONS = options; 14 | 15 | Vue.library = OPTIONS; 16 | Vue.prototype.$library = OPTIONS; 17 | 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /.github/workflows/blank.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v1 12 | - name: Run a one-line script 13 | run: echo Hello, world! 14 | - name: Run a multi-line script 15 | run: | 16 | echo Add other actions to build, 17 | echo test, and deploy your project. 18 | -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | VUE_APP_AUTHOR="Luca Iaconelli" 2 | VUE_APP_TWITTER="@LuXDAmore" 3 | VUE_APP_FACEBOOK="LuXDamore" 4 | VUE_APP_LIBRARY="vue-cursor-fx" 5 | VUE_APP_TITLE="Vue Cursor Fx" 6 | VUE_APP_DESCRIPTION="An animated custom cursor effects for interactive elements like navigation - w/ VueJS - SSR Compatible" 7 | VUE_APP_LOCALE="en" 8 | VUE_APP_COLOR="#333333" 9 | 10 | BASE_URL="https://luxdamore.github.io/vue-cursor-fx" 11 | -------------------------------------------------------------------------------- /docs/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | #333333 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /public/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | #333333 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /docs/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CursorFx", 3 | "short_name": "CFx", 4 | "icons": [ 5 | { 6 | "src": "android-chrome-96x96.png", 7 | "sizes": "96x96", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "android-chrome-144x144.png", 12 | "sizes": "144x144", 13 | "type": "image/png" 14 | } 15 | ], 16 | "start_url": "https://luxdamore.github.io/vue-cursor-fx", 17 | "theme_color": "#ffffff", 18 | "background_color": "#ffffff", 19 | "display": "standalone" 20 | } 21 | -------------------------------------------------------------------------------- /public/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CursorFx", 3 | "short_name": "CFx", 4 | "icons": [ 5 | { 6 | "src": "android-chrome-96x96.png", 7 | "sizes": "96x96", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "android-chrome-144x144.png", 12 | "sizes": "144x144", 13 | "type": "image/png" 14 | } 15 | ], 16 | "start_url": "https://luxdamore.github.io/vue-cursor-fx", 17 | "theme_color": "#ffffff", 18 | "background_color": "#ffffff", 19 | "display": "standalone" 20 | } 21 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2018", 4 | "module": "ESNext", 5 | "moduleResolution": "Node", 6 | "lib": ["ESNext", "ESNext.AsyncIterable", "DOM"], 7 | "esModuleInterop": true, 8 | "allowJs": true, 9 | "sourceMap": true, 10 | "strict": true, 11 | "noEmit": true, 12 | "experimentalDecorators": true, 13 | "baseUrl": ".", 14 | "paths": { 15 | "~/*": ["./*"], 16 | "@/*": ["./*"] 17 | }, 18 | "types": ["@types/node"] 19 | }, 20 | "exclude": ["node_modules", ".nuxt", "dist", "docs"] 21 | } 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /docs/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 11 | -------------------------------------------------------------------------------- /public/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 11 | -------------------------------------------------------------------------------- /src/CursorFx/index.js: -------------------------------------------------------------------------------- 1 | // Import vue component 2 | import component from './CursorFx.vue'; 3 | 4 | const plugin = { 5 | CursorFx: component, 6 | installed: false, 7 | install( 8 | Vue, 9 | ) { 10 | 11 | if( plugin.installed ) 12 | return; 13 | 14 | plugin.installed = true; 15 | 16 | Vue.component( 17 | component.name, 18 | component, 19 | ); 20 | 21 | }, 22 | }; 23 | 24 | // Auto install 25 | let GlobalVue = null; 26 | 27 | if( typeof window !== 'undefined' ) 28 | GlobalVue = window.Vue; 29 | else if( typeof global !== 'undefined' ) 30 | GlobalVue = global.Vue; 31 | 32 | GlobalVue && GlobalVue.use( 33 | plugin, 34 | ); 35 | 36 | // To allow use as module (npm/webpack/etc.) export component 37 | export default plugin; 38 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | // Vue 2 | import Vue from 'vue'; 3 | 4 | // Skeleton 5 | import 'modern-normalize/modern-normalize.css'; 6 | import 'github-markdown-css'; 7 | import './main.scss'; 8 | import VApp from './VApp'; 9 | 10 | // Component 11 | import Library from './library'; 12 | import CursorFx from './CursorFx/CursorFx.vue'; 13 | 14 | // Install 15 | Vue.component( 16 | CursorFx.name, 17 | CursorFx, 18 | ); 19 | 20 | // Library data 21 | Vue.use( 22 | Library, 23 | process.env, 24 | ); 25 | 26 | // Config 27 | const IS_DEV = process.env.NODE_ENV === 'development'; 28 | 29 | Vue.config.silent = ! IS_DEV; 30 | Vue.config.productionTip = IS_DEV; 31 | 32 | 33 | const vm = new Vue( 34 | { 35 | render: h => h( 36 | VApp, 37 | ), 38 | }, 39 | ); 40 | 41 | vm.$mount( 42 | '#app', 43 | ); 44 | 45 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | // Exports 2 | module.exports = { 3 | parser: 'postcss-scss', 4 | syntax: 'postcss-scss', 5 | plugins: [ 6 | require( 7 | 'postcss-import', 8 | )(), 9 | require( 10 | 'postcss-url', 11 | )(), 12 | require( 13 | 'postcss-preset-env', 14 | )( 15 | { 16 | stage: 2, 17 | autoprefixer: { 18 | cascade: false, 19 | grid: true, 20 | }, 21 | }, 22 | ), 23 | require( 24 | 'postcss-combine-duplicated-selectors', 25 | )( 26 | { 27 | removeDuplicatedProperties: true, 28 | }, 29 | ), 30 | require( 31 | 'cssnano', 32 | )( 33 | { 34 | preset: 'default', 35 | }, 36 | ), 37 | ], 38 | }; 39 | -------------------------------------------------------------------------------- /dist/CursorFx.css: -------------------------------------------------------------------------------- 1 | .cursor-fx{opacity:0}.is-cursor-fx-active,.is-cursor-fx-active *{cursor:none}.is-cursor-fx-active .cursor-fx{transition-delay:.3s}.is-cursor-fx-active .cursor-fx.cursor-fx--loaded{opacity:1}.cursor-fx[data-v-f3f73494]{color:var(--color,#333);transition:color .18s ease-in-out,opacity .6s ease-in-out}.cursor-fx--hover[data-v-f3f73494]{color:var(--color-hover,#333)}.cursor-fx__inner[data-v-f3f73494]{position:absolute;top:0;left:0;z-index:999!important;border-radius:100%;transition-timing-function:ease;transition-duration:.23s;transition-property:color,width,height,background-color,border-radius,border-color;pointer-events:none;will-change:auto}.cursor-fx__inner__outside[data-v-f3f73494]{border:1px solid}.cursor-fx__inner__custom[data-v-f3f73494],.cursor-fx__inner__outside[data-v-f3f73494]{width:64px;height:64px}.cursor-fx__inner__inside[data-v-f3f73494]{width:6px;height:6px;background-color:currentColor}.cursor-fx--shape-square>.cursor-fx__inner[data-v-f3f73494]{border-radius:0} -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Luca Iaconelli (https://lucaiaconelli.it) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/CursorFx/style.scss: -------------------------------------------------------------------------------- 1 | .cursor-fx { 2 | 3 | $prefix: &; 4 | $color: #333; 5 | 6 | color: #{$color}; 7 | color: var( --color, #{$color} ); 8 | transition: color .18s ease-in-out, opacity .6s ease-in-out; 9 | 10 | &--hover { 11 | 12 | color: #{$color}; 13 | color: var( --color-hover, #{$color} ); 14 | 15 | } 16 | 17 | &__inner { 18 | 19 | position: absolute; 20 | 21 | top: 0; 22 | left: 0; 23 | z-index: 999 !important; 24 | border-radius: 100%; 25 | transition-timing-function: ease; 26 | transition-duration: .23s; 27 | 28 | transition-property: color, width, height, background-color, border-radius, border-color; 29 | pointer-events: none; 30 | 31 | will-change: auto; 32 | 33 | &__outside { 34 | 35 | border: 1px solid; 36 | border-color: currentColor; 37 | 38 | } 39 | 40 | &__outside, 41 | &__custom { 42 | 43 | width: 64px; 44 | 45 | height: 64px; 46 | 47 | } 48 | 49 | &__inside { 50 | 51 | width: 6px; 52 | height: 6px; 53 | background-color: currentColor; 54 | 55 | } 56 | 57 | } 58 | 59 | &--shape { 60 | 61 | &-square { 62 | 63 | > #{$prefix}__inner { 64 | 65 | border-radius: 0; 66 | 67 | } 68 | 69 | } 70 | 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/VApp/style.scss: -------------------------------------------------------------------------------- 1 | $color: #333; 2 | $background-color: #fff; 3 | 4 | :root { 5 | 6 | --color: #{$color}; 7 | --background-color: #{$background-color}; 8 | 9 | } 10 | 11 | .app { 12 | 13 | width: 100%; 14 | 15 | min-height: 100vh; 16 | color: #{$color}; 17 | color: var( --color, #{$color} ); 18 | background-color: #{$background-color}; 19 | background-color: var( --background-color, #{$background-color} ); 20 | 21 | .grid-container { 22 | 23 | padding: 8px; 24 | 25 | @media ( min-width: 768px ) { 26 | 27 | display: grid; 28 | grid-template-areas: "left right"; 29 | grid-template-rows: 1fr; 30 | grid-template-columns: 33% 1fr; 31 | 32 | } 33 | 34 | .grid-cell { 35 | 36 | padding: 16px; 37 | 38 | } 39 | 40 | .left { 41 | 42 | grid-area: left; 43 | 44 | } 45 | 46 | .right { 47 | 48 | grid-area: right; 49 | overflow: hidden; 50 | 51 | } 52 | 53 | } 54 | 55 | label { 56 | 57 | display: block; 58 | 59 | } 60 | 61 | section { 62 | 63 | margin: 0 0 16px; 64 | 65 | } 66 | 67 | /* Better UI for the generated for the Readme */ 68 | .readme ::v-deep article > p:nth-child(2) { 69 | 70 | display: flex; 71 | flex: 1 1 100%; 72 | flex-direction: row; 73 | flex-wrap: nowrap; 74 | min-height: 36px; 75 | padding: 6px 12px; 76 | overflow-x: auto; 77 | font-size: 0; 78 | background-color: rgba( 220, 230, 240, .63 ); 79 | border-radius: 5px; 80 | 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. 3 | // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp 4 | // List of extensions which should be recommended for users of this workspace. 5 | "recommendations": [ 6 | "formulahendry.auto-close-tag", 7 | "formulahendry.auto-rename-tag", 8 | "kevinkyang.auto-comment-blocks", 9 | "dzannotti.vscode-babel-coloring", 10 | "editorconfig.editorconfig", 11 | "davidanson.vscode-markdownlint", 12 | "dbaeumer.vscode-eslint", 13 | "mohseenrm.lit-it", 14 | "mubaidr.vuejs-extension-pack", 15 | "jeremyrajan.webpack", 16 | "mikestead.dotenv", 17 | "eg2.vscode-npm-script", 18 | "wallabyjs.quokka-vscode", 19 | "mrmlnc.vscode-attrs-sorter", 20 | "wayou.vscode-todo-highlight", 21 | "jock.svg", 22 | "octref.vetur", 23 | "dariofuzinato.vue-peek", 24 | "christian-kohler.npm-intellisense", 25 | "sdras.vue-vscode-snippets", 26 | "hookyqr.beautify", 27 | "wmaurer.change-case", 28 | "naumovs.color-highlight", 29 | "wix.vscode-import-cost", 30 | "xabikos.javascriptsnippets", 31 | "esbenp.prettier-vscode", 32 | "cssho.vscode-svgviewer", 33 | "dotjoshjohnson.xml", 34 | "cpylua.language-postcss", 35 | "syler.sass-indented", 36 | "stylelint.vscode-stylelint" 37 | ], 38 | // List of extensions recommended by VS Code that should not be recommended for users of this workspace. 39 | "unwantedRecommendations": [] 40 | } 41 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | const IS_DEV = process.env.NODE_ENV !== 'production' 2 | , BASE_URL = ( 3 | ! IS_DEV 4 | ? process.env.BASE_URL 5 | : '/' 6 | ) 7 | ; 8 | 9 | module.exports = { 10 | publicPath: BASE_URL, 11 | lintOnSave: IS_DEV, 12 | productionSourceMap: false, 13 | configureWebpack: { 14 | output: { 15 | libraryExport: 'default', 16 | }, 17 | }, 18 | chainWebpack( 19 | config, 20 | ) { 21 | 22 | config.resolve.symlinks( 23 | false, 24 | ); 25 | 26 | config 27 | .module 28 | .rule( 29 | 'vue', 30 | ) 31 | .use( 32 | 'vue-loader', 33 | ) 34 | .loader( 35 | 'vue-loader', 36 | ) 37 | .tap( 38 | options => { 39 | 40 | options.compilerOptions.preserveWhitespace = false; 41 | options.compilerOptions.whitespace = 'condense'; 42 | 43 | return options; 44 | 45 | }, 46 | ) 47 | ; 48 | 49 | config.module 50 | .rule( 51 | 'md', 52 | ) 53 | .test( 54 | /\.md/, 55 | ) 56 | .use( 57 | 'vue-loader', 58 | ) 59 | .loader( 60 | 'vue-loader', 61 | ) 62 | .end() 63 | .use( 64 | 'vue-markdown-loader', 65 | ) 66 | .loader( 67 | 'vue-markdown-loader/lib/markdown-compiler', 68 | ) 69 | .options( 70 | { 71 | wrapper: 'article', 72 | raw: true, 73 | breaks: true, 74 | typographer: true, 75 | preventExtract: true, 76 | }, 77 | ) 78 | ; 79 | 80 | }, 81 | }; 82 | -------------------------------------------------------------------------------- /src/main.scss: -------------------------------------------------------------------------------- 1 | $color-start: #cb2d3e; 2 | $color-end: #ef473a; 3 | $color-accessible: #2c3e50; 4 | 5 | :root { 6 | 7 | --color-start: #{$color-start}; 8 | --color-end: #{$color-end}; 9 | --color-accessible: #{$color-accessible}; 10 | 11 | font-size: 16px; 12 | 13 | } 14 | 15 | // Skeleton 16 | body { 17 | 18 | padding-top: env( safe-area-inset-top, 0 ); 19 | padding-right: env( safe-area-inset-right, 0 ); 20 | padding-bottom: env( safe-area-inset-bottom, 0 ); 21 | padding-left: env( safe-area-inset-left, 0 ); 22 | line-height: 1.5; 23 | 24 | } 25 | 26 | .markdown-body .button, 27 | .markdown-body button, 28 | .markdown-body a, 29 | .button, 30 | button, 31 | a { 32 | 33 | display: inline-block; 34 | margin: 0 4px 4px; 35 | border: 0; 36 | 37 | border-radius: 3px; 38 | transition: all .3s cubic-bezier( .455, .03, .515, .955 ); 39 | will-change: auto; 40 | 41 | } 42 | 43 | .markdown-body .button, 44 | .markdown-body button, 45 | .button, 46 | button { 47 | 48 | padding: 8px 16px; 49 | color: #fff; 50 | text-decoration: none; 51 | background-image: linear-gradient( to right, #{$color-start} 0%, #{$color-end} 51%, #{$color-start} 100% ); 52 | background-image: linear-gradient( to right, var( --color-start, #{$color-start} ) 0%, var( --color-end, #{$color-end} ) 51%, var( --color-start, #{$color-start} ) 100% ); 53 | background-position: left center; 54 | appearance: none; 55 | 56 | &:hover { 57 | 58 | background-position: right center; 59 | 60 | } 61 | 62 | } 63 | 64 | .markdown-body a, 65 | a { 66 | 67 | color: #{$color-start}; 68 | color: var( --color-start, #{$color-start} ); 69 | 70 | } 71 | 72 | .markdown-body { 73 | 74 | img { 75 | 76 | width: 100%; 77 | height: auto; 78 | max-height: 100%; 79 | 80 | } 81 | 82 | .hljs-meta, 83 | .hljs-meta-keyword, 84 | .hljs-attr, 85 | .hljs-comment { 86 | 87 | color: #{$color-accessible} !important; 88 | color: var( --color-accessible, #{$color-accessible} ) !important; 89 | 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | // CSS 3 | "css.validate": false, 4 | "less.validate": false, 5 | "scss.validate": false, 6 | "html.validate.styles": false, 7 | // Markdown 8 | "markdownlint.ignore": [ 9 | "CHANGELOG.md" 10 | ], 11 | // ESLint 12 | "eslint.alwaysShowStatus": true, 13 | "eslint.options": { 14 | "extensions": [ 15 | ".js", 16 | ".vue" 17 | ] 18 | }, 19 | "editor.codeActionsOnSave": { 20 | "source.fixAll.eslint": true, 21 | "source.fixAll.stylelint": true 22 | }, 23 | "stylelint.enable": true, 24 | "stylelint.snippet": [ 25 | "css", 26 | "less", 27 | "postcss", 28 | "sass", 29 | "scss", 30 | "stylus" 31 | ], 32 | // Vue 33 | "vetur.format.styleInitialIndent": true, 34 | "vetur.validation.template": false, 35 | "vetur.format.defaultFormatter.css": "prettier", 36 | "vetur.format.defaultFormatter.scss": "prettier", 37 | "vetur.format.defaultFormatter.js": "prettier-eslint", 38 | "vetur.format.defaultFormatter.ts": "prettier-tslint", 39 | "vetur.format.options.tabSize": 4, 40 | "prettier.vueIndentScriptAndStyle": true, 41 | "vetur.experimental.templateInterpolationService": true, 42 | // Colors 43 | "workbench.colorCustomizations": { 44 | "activityBar.background": "#65c89b", 45 | "activityBar.activeBorder": "#945bc4", 46 | "activityBar.foreground": "#15202b", 47 | "activityBar.inactiveForeground": "#15202b99", 48 | "activityBarBadge.background": "#945bc4", 49 | "activityBarBadge.foreground": "#e7e7e7", 50 | "titleBar.activeBackground": "#42b883", 51 | "titleBar.inactiveBackground": "#42b88399", 52 | "titleBar.activeForeground": "#15202b", 53 | "titleBar.inactiveForeground": "#15202b99", 54 | "statusBar.background": "#42b883", 55 | "statusBarItem.hoverBackground": "#359268", 56 | "statusBar.foreground": "#15202b", 57 | "activityBar.activeBackground": "#65c89b" 58 | }, 59 | "peacock.color": "#42b883", 60 | // Dictionary 61 | "cSpell.language": "en,it", 62 | "cSpell.allowCompoundWords": true, 63 | "cSpell.ignorePaths": [ 64 | ".vscode", 65 | ".git", 66 | ".nuxt", 67 | "coverage", 68 | "dist", 69 | "ssr", 70 | "node_modules", 71 | "bower_components" 72 | ], 73 | "cSpell.words": [ 74 | "codrops" 75 | ], 76 | "cSpell.ignoreWords": [] 77 | } 78 | -------------------------------------------------------------------------------- /docs/css/app.2d445fa2.css: -------------------------------------------------------------------------------- 1 | :root{--color-start:#cb2d3e;--color-end:#ef473a;--color-accessible:#2c3e50;font-size:16px}body{padding:env(safe-area-inset-top,0) env(safe-area-inset-right,0) env(safe-area-inset-bottom,0) env(safe-area-inset-left,0);line-height:1.5}.button,.markdown-body .button,.markdown-body a,.markdown-body button,a,button{display:inline-block;margin:0 4px 4px;border:0;border-radius:3px;transition:all .3s cubic-bezier(.455,.03,.515,.955);will-change:auto}.button,.markdown-body .button,.markdown-body button,button{padding:8px 16px;color:#fff;text-decoration:none;background-image:linear-gradient(90deg,var(--color-start,#cb2d3e),var(--color-end,#ef473a) 51%,var(--color-start,#cb2d3e));background-position:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.button:hover,.markdown-body .button:hover,.markdown-body button:hover,button:hover{background-position:100%}.markdown-body a,a{color:var(--color-start,#cb2d3e)}.markdown-body img{width:100%;height:auto;max-height:100%}.markdown-body .hljs-attr,.markdown-body .hljs-comment,.markdown-body .hljs-meta,.markdown-body .hljs-meta-keyword{color:var(--color-accessible,#2c3e50)!important}[data-v-36227c26]:root{--color:#333;--background-color:#fff}.app[data-v-36227c26]{width:100%;min-height:100vh;color:var(--color,#333);background-color:var(--background-color,#fff)}.app .grid-container[data-v-36227c26]{padding:8px}@media (min-width:768px){.app .grid-container[data-v-36227c26]{display:grid;grid-template-areas:"left right";-ms-grid-rows:1fr;grid-template-rows:1fr;-ms-grid-columns:33% 1fr;grid-template-columns:33% 1fr}}.app .grid-container .grid-cell[data-v-36227c26]{padding:16px}.app .grid-container .left[data-v-36227c26]{grid-area:left}.app .grid-container .right[data-v-36227c26]{grid-area:right;overflow:hidden}@media (min-width:768px){.app .grid-container .left[data-v-36227c26]{-ms-grid-row:1;-ms-grid-column:1}.app .grid-container .right[data-v-36227c26]{-ms-grid-row:1;-ms-grid-column:2}}.app label[data-v-36227c26]{display:block}.app section[data-v-36227c26]{margin:0 0 16px}.app .readme[data-v-36227c26] article>p:nth-child(2){display:flex;flex:1 1 100%;flex-direction:row;flex-wrap:nowrap;min-height:36px;padding:6px 12px;overflow-x:auto;font-size:0;background-color:rgba(220,230,240,.63);border-radius:5px}.cursor-fx{opacity:0}.is-cursor-fx-active,.is-cursor-fx-active *{cursor:none}.is-cursor-fx-active .cursor-fx{transition-delay:.3s}.is-cursor-fx-active .cursor-fx.cursor-fx--loaded{opacity:1}.cursor-fx[data-v-f3f73494]{color:var(--color,#333);transition:color .18s ease-in-out,opacity .6s ease-in-out}.cursor-fx--hover[data-v-f3f73494]{color:var(--color-hover,#333)}.cursor-fx__inner[data-v-f3f73494]{position:absolute;top:0;left:0;z-index:999!important;border-radius:100%;transition-timing-function:ease;transition-duration:.23s;transition-property:color,width,height,background-color,border-radius,border-color;pointer-events:none;will-change:auto}.cursor-fx__inner__outside[data-v-f3f73494]{border:1px solid}.cursor-fx__inner__custom[data-v-f3f73494],.cursor-fx__inner__outside[data-v-f3f73494]{width:64px;height:64px}.cursor-fx__inner__inside[data-v-f3f73494]{width:6px;height:6px;background-color:currentColor}.cursor-fx--shape-square>.cursor-fx__inner[data-v-f3f73494]{border-radius:0} -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | ### [1.6.1](https://github.com/LuXDAmore/vue-cursor-fx/compare/v1.6.0...v1.6.1) (2021-02-23) 6 | 7 | - docs: updated github pages 8 | 9 | ## [1.6.0](https://github.com/LuXDAmore/vue-cursor-fx/compare/v1.5.0...v1.6.0) (2021-02-23) 10 | 11 | - fix: issue with z-index close #2 12 | 13 | ## [1.5.0](https://github.com/LuXDAmore/vue-cursor-fx/compare/v1.4.0...v1.5.0) (2021-01-01) 14 | 15 | - feat: added new events and methods 16 | - fix: some bugs 17 | - chore: updated library 18 | 19 | ## [1.4.0](https://github.com/LuXDAmore/vue-cursor-fx/compare/v1.3.4...v1.4.0) (2019-01-08) 20 | 21 | - feat: added mix-lend-mode prop and buttons 22 | - feat: added allow-on-mobile prop 23 | - docs: updated documentation 24 | - chore: updated dev dep 25 | - chore: linted 26 | 27 | ## [1.3.4](https://github.com/LuXDAmore/vue-cursor-fx/compare/v1.3.3...v1.3.4) (2019-12-19) 28 | 29 | - chore: updated dev dep 30 | - refactor: classes and slots data evaluation 31 | 32 | ## [1.3.3](https://github.com/LuXDAmore/vue-cursor-fx/compare/v1.3.2...v1.3.3) (2019-12-09) 33 | 34 | - CHORE: Updated DevDep. 35 | 36 | ## [1.3.2](https://github.com/LuXDAmore/vue-cursor-fx/compare/v1.3.1...v1.3.2) (2019-11-09) 37 | 38 | - CHORE: Updated DevDep; 39 | - CHORE: Better linting. 40 | 41 | ## [1.3.1](https://github.com/LuXDAmore/vue-cursor-fx/compare/v1.3.0...v1.3.1) (2019-10-17) 42 | 43 | - CHORE: Updated version of vue-cli. 44 | 45 | ## [1.3.0](https://github.com/LuXDAmore/vue-cursor-fx/compare/v1.2.4...v1.3.0) (2019-09-20) 46 | 47 | - CHORE: Updated documentations. 48 | - FIX: Better exports due to the vue-cli limitation. 49 | 50 | ## [1.2.4](https://github.com/LuXDAmore/vue-cursor-fx/compare/v1.2.3...v1.2.4) (2019-09-20) 51 | 52 | - CHORE: Updated documentations. 53 | 54 | ## [1.2.3](https://github.com/LuXDAmore/vue-cursor-fx/compare/v1.2.2...v1.2.3) (2019-09-18) 55 | 56 | ## CHORE 57 | 58 | - Updated Readme and documentation. 59 | 60 | ## [1.2.2](https://github.com/LuXDAmore/vue-cursor-fx/compare/v1.2.1...v1.2.2) (2019-09-18) 61 | 62 | - chore: updated DevDep. 63 | 64 | ## [1.2.1](https://github.com/LuXDAmore/vue-cursor-fx/compare/v1.2.0...v1.2.1) (2019-09-18) 65 | 66 | - chore: updated DevDep. 67 | 68 | ## [1.2.0](https://github.com/LuXDAmore/vue-cursor-fx/compare/v1.1.0...v1.2.0) (2019-08-09) 69 | 70 | ## FIX 71 | 72 | - Autoprefixer now goes. 73 | 74 | ## STYLE 75 | 76 | - Better colors management in scss. 77 | 78 | ## [1.1.0](https://github.com/LuXDAmore/vue-cursor-fx/compare/v1.0.3...v1.1.0) (2019-07-29) 79 | 80 | ## Feat 81 | 82 | - Change color on hover with color-hover prop. 83 | - Exportable as auto-installer, or as a component. 84 | 85 | ## Chore 86 | 87 | - Removed extra console.log. 88 | 89 | ## [1.0.3](https://github.com/LuXDAmore/vue-cursor-fx/compare/v1.0.2...v1.0.3) (2019-07-25) 90 | 91 | ## Fix 92 | 93 | - CursorFx now goes as expected. 94 | 95 | ## [1.0.2](https://github.com/LuXDAmore/vue-cursor-fx/compare/v1.0.1...v1.0.2) (2019-07-18) 96 | 97 | ## Feature 98 | 99 | - New props: color, outerSize, insideSize and shape; 100 | - Added slot default for custom cursors. 101 | 102 | ## [1.0.1](https://github.com/LuXDAmore/vue-cursor-fx/compare/v1.0.0...v1.0.1) (2019-07-17) 103 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | <%= VUE_APP_TITLE %> 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 66 | 67 |
68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | Vue Cursor Fx
-------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@luxdamore/vue-cursor-fx", 3 | "version": "1.6.2", 4 | "description": "An animated custom cursor effects for interactive elements like navigation - w/ VueJS - SSR Compatible", 5 | "author": "Luca Iaconelli (https://lucaiaconelli.it)", 6 | "homepage": "https://luxdamore.github.io/vue-cursor-fx", 7 | "main": "dist/CursorFx.umd.min.js", 8 | "umd": "dist/CursorFx.umd.min.js", 9 | "unpkg": "dist/CursorFx.umd.min.js", 10 | "commonjs": "dist/CursorFx.common.js", 11 | "browser": "dist/CursorFx.umd.min.js", 12 | "style": "dist/CursorFx.css", 13 | "keywords": [ 14 | "vuejs", 15 | "nuxtjs", 16 | "cursor", 17 | "effects", 18 | "design", 19 | "tympanus", 20 | "codrops" 21 | ], 22 | "scripts": { 23 | "test": "echo \"Error: no test specified\" && exit 1", 24 | "dev": "vue-cli-service serve", 25 | "serve": "vue-cli-service serve", 26 | "build:library": "vue-cli-service build --dest ./dist --target lib --name CursorFx ./src/CursorFx/index.js", 27 | "build:docs": "vue-cli-service build --modern --dest ./docs", 28 | "build": "yarn build:library && yarn build:docs", 29 | "prepare": "yarn build", 30 | "check-linting": "vue-cli-service lint", 31 | "eslint": "eslint --ext .js,.vue .", 32 | "eslint-fix": "eslint --fix --ext .js,.vue .", 33 | "stylelint": "stylelint ./src/**/*.scss", 34 | "stylelint-fix": "stylelint ./src/**/*.scss --fix", 35 | "lint": "yarn eslint && yarn stylelint", 36 | "lint-fix": "yarn eslint-fix", 37 | "precommit": "yarn lint", 38 | "prerelease": "yarn lint && yarn build", 39 | "release": "standard-version && git push --follow-tags && yarn publish" 40 | }, 41 | "dependencies": { 42 | "vue": "^2.6.11" 43 | }, 44 | "devDependencies": { 45 | "@commitlint/cli": "^11.0.0", 46 | "@commitlint/config-conventional": "^11.0.0", 47 | "@nuxtjs/eslint-config": "^2.0.0", 48 | "@vue/cli-plugin-babel": "^4.1.2", 49 | "@vue/cli-plugin-eslint": "^4.1.2", 50 | "@vue/cli-service": "^4.1.2", 51 | "@vue/eslint-config-prettier": "^6.0.0", 52 | "babel-eslint": "^10.0.3", 53 | "cssnano": "^4.1.10", 54 | "eslint": "^6.8.0", 55 | "eslint-config-standard": "^14.1.0", 56 | "eslint-loader": "^3.0.3", 57 | "eslint-plugin-compat": "^3.3.0", 58 | "eslint-plugin-import": "^2.19.1", 59 | "eslint-plugin-node": "^11.0.0", 60 | "eslint-plugin-nuxt": "^0.5.0", 61 | "eslint-plugin-prettier": "^3.1.2", 62 | "eslint-plugin-promise": "^4.2.1", 63 | "eslint-plugin-standard": "^4.0.1", 64 | "eslint-plugin-unicorn": "^15.0.1", 65 | "eslint-plugin-vue": "^6.1.2", 66 | "github-markdown-css": "^3.0.1", 67 | "highlight.js": "^10.6.0", 68 | "lint-staged": "^10.5.4", 69 | "markdownlint": "^0.23.0", 70 | "modern-normalize": "^1.0.0", 71 | "node-sass": "^4.13.0", 72 | "postcss-combine-duplicated-selectors": "^8.1.0", 73 | "postcss-import": "^12.0.1", 74 | "postcss-loader": "^3.0.0", 75 | "postcss-preset-env": "^6.7.0", 76 | "postcss-scss": "^2.0.0", 77 | "postcss-url": "^8.0.0", 78 | "prettier": "^1.19.1", 79 | "prettier-eslint": "^9.0.1", 80 | "prettier-stylelint": "^0.4.2", 81 | "sass-loader": "^8.0.0", 82 | "standard-version": "^9.1.0", 83 | "stylelint": "^12.0.1", 84 | "stylelint-config-rational-order": "^0.1.2", 85 | "stylelint-config-sass-guidelines": "^6.2.0", 86 | "stylelint-config-standard": "^19.0.0", 87 | "stylelint-no-unsupported-browser-features": "^4.0.0", 88 | "stylelint-order": "^4.0.0", 89 | "vue-markdown-loader": "^2.4.1", 90 | "vue-template-compiler": "^2.6.11" 91 | }, 92 | "license": "MIT", 93 | "repository": { 94 | "type": "git", 95 | "url": "git+https://github.com/LuXDAmore/vue-cursor-fx.git" 96 | }, 97 | "bugs": { 98 | "url": "https://github.com/LuXDAmore/vue-cursor-fx/issues" 99 | }, 100 | "files": [ 101 | "dist" 102 | ], 103 | "publishConfig": { 104 | "access": "public" 105 | }, 106 | "lint-staged": { 107 | "*.{js,vue}": [ 108 | "vue-cli-service lint", 109 | "git add" 110 | ] 111 | }, 112 | "gitHooks": { 113 | "pre-commit": "lint-staged" 114 | }, 115 | "husky": { 116 | "hooks": { 117 | "pre-commit": "lint-staged" 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /stylelint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: [ 4 | 'stylelint-config-standard', 5 | 'stylelint-config-sass-guidelines', 6 | 'stylelint-config-rational-order', 7 | ], 8 | plugins: [ 9 | 'stylelint-scss', 10 | 'stylelint-no-unsupported-browser-features', 11 | ], 12 | // add your custom rules here 13 | defaultSeverity: 'warning', 14 | rules: { 15 | // Plugins 16 | 'plugin/no-unsupported-browser-features': [ 17 | true, 18 | { 19 | severity: 'warning', 20 | ignore: [ 21 | 'multicolumn', 22 | 'calc', 23 | 'border-radius', 24 | 'user-select-none', 25 | 'pointer-events', 26 | 'background-img-opts', 27 | 'boxshadow', 28 | 'css-boxshadow', 29 | 'animation', 30 | 'css-animation', 31 | 'gradients', 32 | 'css-gradients', 33 | 'transitions', 34 | 'css-transitions', 35 | 'transform', 36 | 'will-change', 37 | 'font-unicode-range', 38 | 'transforms2d', 39 | 'transforms3d', 40 | 'viewport-units', 41 | 'css-appearance', 42 | 'css-filters', 43 | 'css3-cursors', 44 | 'css3-cursors-newer', 45 | 'outline', 46 | 'flexbox', 47 | 'fixed', 48 | 'fontface', 49 | 'css-fixed', 50 | ], 51 | }, 52 | ], 53 | // Property Order 54 | 'order/properties-order': [ 55 | [], 56 | { 57 | severity: 'warning', 58 | }, 59 | ], 60 | 'order/properties-alphabetical-order': null, 61 | 'plugin/rational-order': [ 62 | true, 63 | { 64 | severity: 'warning', 65 | }, 66 | ], 67 | // Generic 68 | 'indentation': 4, 69 | 'no-descending-specificity': null, 70 | 'selector-type-no-unknown': [ 71 | true, 72 | { 73 | ignore: [ 'custom-elements' ], 74 | ignoreTypes: [ 'css-doodle' ], 75 | }, 76 | ], 77 | 'selector-pseudo-element-no-unknown': [ 78 | true, 79 | { 80 | ignorePseudoElements: [ 81 | 'v-deep', 82 | 'css-doodle', 83 | ], 84 | }, 85 | ], 86 | 'custom-property-empty-line-before': [ 87 | 'always', 88 | { 89 | except: [ 90 | 'after-comment', 91 | 'after-custom-property', 92 | ], 93 | ignore: [ 94 | 'after-comment', 95 | 'inside-single-line-block', 96 | ], 97 | }, 98 | ], 99 | 'block-closing-brace-newline-before': [ 'always-multi-line' ], 100 | 'block-closing-brace-empty-line-before': [ 'always-multi-line' ], 101 | 'string-quotes': 'double', 102 | 'media-feature-parentheses-space-inside': 'always', 103 | 'function-parentheses-space-inside': 'always', 104 | 'block-no-empty': null, 105 | 'function-url-quotes': 'always', 106 | 'max-empty-lines': [ 2 ], 107 | 'selector-max-compound-selectors': [ 5 ], 108 | 'max-nesting-depth': [ 6 ], 109 | 'at-rule-no-unknown': null, 110 | 'property-no-vendor-prefix': true, 111 | 'selector-descendant-combinator-no-non-space': true, 112 | 'unit-whitelist': [ 113 | 'vh', 114 | 'vw', 115 | 'px', 116 | 'em', 117 | 'rem', 118 | 's', 119 | 'fr', 120 | 'deg', 121 | '%', 122 | ], 123 | 'rule-empty-line-before': [ 124 | 'always', 125 | { 126 | except: [ 'after-single-line-comment' ], 127 | ignore: [ 128 | 'after-comment', 129 | 'inside-block', 130 | ], 131 | }, 132 | ], 133 | 'selector-no-qualifying-type': [ 134 | true, 135 | { 136 | ignore: [ 'class' ], 137 | }, 138 | ], 139 | 'at-rule-empty-line-before': [ 140 | 'always', 141 | { 142 | except: [ 143 | 'after-same-name', 144 | 'blockless-after-same-name-blockless', 145 | 'blockless-after-blockless', 146 | ], 147 | ignore: [ 148 | 'after-comment', 149 | 'first-nested', 150 | ], 151 | }, 152 | ], 153 | 'number-leading-zero': 'never', 154 | 'declaration-empty-line-before': [ 155 | 'always', 156 | { 157 | except: [ 158 | 'after-comment', 159 | 'after-declaration', 160 | ], 161 | ignore: [ 'after-declaration' ], 162 | }, 163 | ], 164 | 'block-opening-brace-space-before': 'always', 165 | 'selector-list-comma-newline-after': 'always', 166 | 'selector-class-pattern': [ 167 | // http://stylelint.cn/user-guide/faq/ 168 | // .your-component--primary 169 | // .your-component__container 170 | '^([a-z][a-z0-9]*)((--?|(__)?)[a-z0-9]+)*$', 171 | { 172 | resolveNestedSelectors: true, 173 | }, 174 | ], 175 | 'block-closing-brace-newline-after': [ 176 | 'always', 177 | { 178 | 'ignoreAtRules': [ 179 | 'if', 180 | 'else', 181 | ], 182 | }, 183 | ], 184 | 'at-rule-name-space-after': 'always', 185 | // SASS - SCSS 186 | // If - Else 187 | 'scss/at-else-closing-brace-newline-after': 'always-last-in-chain', 188 | 'scss/at-else-closing-brace-space-after': 'always-intermediate', 189 | 'scss/at-else-empty-line-before': 'never', 190 | 'scss/at-if-closing-brace-newline-after': 'always-last-in-chain', 191 | 'scss/at-if-closing-brace-space-after': 'always-intermediate', 192 | 'scss/at-function-parentheses-space-before': 'never', 193 | }, 194 | }; 195 | -------------------------------------------------------------------------------- /src/CursorFx/cursor-fx.js: -------------------------------------------------------------------------------- 1 | const SCALE_MIN = 0.5 2 | , SCALE_MAX = 1 3 | , lerp = ( 4 | a, 5 | b, 6 | n, 7 | ) => ( ( 1 - n ) * a + n * b ) 8 | , getMousePos = e => { 9 | 10 | let posx = 0 11 | , posy = 0 12 | ; 13 | 14 | if( ! e ) 15 | e = window.event; 16 | 17 | if( e.pageX || e.pageY ) { 18 | 19 | posx = e.pageX; 20 | posy = e.pageY; 21 | 22 | } else if( e.clientX || e.clientY ) { 23 | 24 | posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; 25 | posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; 26 | 27 | } 28 | 29 | return { 30 | x: posx, 31 | y: posy, 32 | }; 33 | 34 | } 35 | ; 36 | 37 | export default class CursorFx { 38 | constructor( 39 | { 40 | el, 41 | base_class, 42 | }, 43 | options = {}, 44 | ) { 45 | 46 | this.DOM = { 47 | el, 48 | }; 49 | this.$options = Object.freeze( 50 | { 51 | mixBlendMode: null, 52 | lerps: { 53 | dot: 1, 54 | circle: 0.18, 55 | custom: 0.23, 56 | }, 57 | scale: { 58 | ratio: 0.18, 59 | min: SCALE_MIN, 60 | max: SCALE_MAX, 61 | }, 62 | opacity: 0.1, 63 | ... options, 64 | }, 65 | ); 66 | 67 | this.DOM.dot = this.DOM.el.querySelector( 68 | `${ base_class }__inner__inside`, 69 | ); 70 | this.DOM.circle = this.DOM.el.querySelector( 71 | `${ base_class }__inner__outside`, 72 | ); 73 | this.DOM.custom = this.DOM.el.querySelector( 74 | `${ base_class }__inner__custom`, 75 | ); 76 | 77 | this.bounds = { 78 | dot: this.DOM.dot ? this.DOM.dot.getBoundingClientRect() : null, 79 | circle: this.DOM.circle ? this.DOM.circle.getBoundingClientRect() : null, 80 | custom: this.DOM.custom ? this.DOM.custom.getBoundingClientRect() : null, 81 | }; 82 | 83 | if( this.bounds.dot && ! this.bounds.dot.width ) { 84 | 85 | const COMPUTED_STYLES = window.getComputedStyle( 86 | this.DOM.dot, 87 | ); 88 | 89 | this.bounds.dot.width = parseInt( 90 | COMPUTED_STYLES 91 | .getPropertyValue( 92 | 'width', 93 | ) 94 | .replace( 95 | 'px', 96 | '', 97 | ), 98 | ) 99 | ; 100 | this.bounds.dot.height = parseInt( 101 | COMPUTED_STYLES 102 | .getPropertyValue( 103 | 'height', 104 | ) 105 | .replace( 106 | 'px', 107 | '', 108 | ), 109 | ) 110 | ; 111 | 112 | } 113 | 114 | if( this.bounds.circle && ! this.bounds.circle.width ) { 115 | 116 | const COMPUTED_STYLES = window.getComputedStyle( 117 | this.DOM.circle, 118 | ); 119 | 120 | this.bounds.circle.width = parseInt( 121 | COMPUTED_STYLES 122 | .getPropertyValue( 123 | 'width', 124 | ) 125 | .replace( 126 | 'px', 127 | '', 128 | ), 129 | ) 130 | ; 131 | this.bounds.circle.height = parseInt( 132 | COMPUTED_STYLES 133 | .getPropertyValue( 134 | 'height', 135 | ) 136 | .replace( 137 | 'px', 138 | '', 139 | ), 140 | ) 141 | ; 142 | 143 | } 144 | 145 | if( this.bounds.custom && ! this.bounds.custom.width ) { 146 | 147 | const COMPUTED_STYLES = window.getComputedStyle( 148 | this.DOM.custom, 149 | ); 150 | 151 | this.bounds.custom.width = parseInt( 152 | COMPUTED_STYLES 153 | .getPropertyValue( 154 | 'width', 155 | ) 156 | .replace( 157 | 'px', 158 | '', 159 | ), 160 | ) 161 | ; 162 | this.bounds.custom.height = parseInt( 163 | COMPUTED_STYLES 164 | .getPropertyValue( 165 | 'height', 166 | ) 167 | .replace( 168 | 'px', 169 | '', 170 | ), 171 | ) 172 | ; 173 | 174 | } 175 | 176 | this.scale = this.$options.scale.min; 177 | this.lastScale = this.$options.scale.max; 178 | this.opacity = this.$options.opacity; 179 | this.lastOpacity = 1; 180 | 181 | this.mousePos = { 182 | x: 0, 183 | y: 0, 184 | }; 185 | this.lastMousePos = { 186 | dot: ( 187 | this.DOM.dot 188 | ? this.DOM.dot.getBoundingClientRect() 189 | : { 190 | top: 0, 191 | left: 0, 192 | } 193 | ), 194 | custom: ( 195 | this.DOM.custom 196 | ? this.DOM.custom.getBoundingClientRect() 197 | : { 198 | top: 0, 199 | left: 0, 200 | } 201 | ), 202 | circle: ( 203 | this.DOM.circle 204 | ? this.DOM.circle.getBoundingClientRect() 205 | : { 206 | top: 0, 207 | left: 0, 208 | } 209 | ), 210 | }; 211 | 212 | this.initEvents(); 213 | 214 | this.$raf = requestAnimationFrame( 215 | () => this.render(), 216 | ); 217 | 218 | } 219 | 220 | initEvents( 221 | add = true 222 | ) { 223 | 224 | const mouseMove = ev => ( 225 | this.mousePos = getMousePos( 226 | ev, 227 | ) 228 | ); 229 | 230 | window.removeEventListener( 231 | 'mousemove', 232 | mouseMove, 233 | false 234 | ); 235 | 236 | add && window.addEventListener( 237 | 'mousemove', 238 | mouseMove, 239 | false, 240 | ); 241 | 242 | } 243 | 244 | render() { 245 | 246 | this.$raf = requestAnimationFrame( 247 | () => this.render(), 248 | ); 249 | 250 | const { 251 | lerps: { 252 | dot, 253 | circle, 254 | custom, 255 | }, 256 | scale: { ratio }, 257 | opacity, 258 | } = this.$options; 259 | 260 | this.lastScale = lerp( 261 | this.lastScale, 262 | this.scale, 263 | ratio, 264 | ); 265 | this.lastOpacity = lerp( 266 | this.lastOpacity, 267 | this.opacity, 268 | opacity, 269 | ); 270 | 271 | if( this.bounds.dot ) { 272 | 273 | this.lastMousePos.dot.x = lerp( 274 | this.lastMousePos.dot.x, 275 | this.mousePos.x - ( this.bounds.dot.width / 2 ), 276 | dot, 277 | ); 278 | this.lastMousePos.dot.y = lerp( 279 | this.lastMousePos.dot.y, 280 | this.mousePos.y - ( this.bounds.dot.height / 2 ), 281 | dot, 282 | ); 283 | 284 | this.DOM.dot.style.transform = `translate3d(${ this.lastMousePos.dot.x }px, ${ this.lastMousePos.dot.y }px, 0)`; 285 | 286 | } 287 | 288 | if( this.bounds.circle ) { 289 | 290 | this.lastMousePos.circle.x = lerp( 291 | this.lastMousePos.circle.x, 292 | this.mousePos.x - ( this.bounds.circle.width / 2 ), 293 | circle, 294 | ); 295 | this.lastMousePos.circle.y = lerp( 296 | this.lastMousePos.circle.y, 297 | this.mousePos.y - ( this.bounds.circle.height / 2 ), 298 | circle, 299 | ); 300 | 301 | this.DOM.circle.style.transform = `translate3d(${ this.lastMousePos.circle.x }px, ${ this.lastMousePos.circle.y }px, 0) scale(${ this.lastScale })`; 302 | 303 | } 304 | 305 | if( this.bounds.custom ) { 306 | 307 | this.lastMousePos.custom.x = lerp( 308 | this.lastMousePos.custom.x, 309 | this.mousePos.x - ( this.bounds.custom.width / 2 ), 310 | custom, 311 | ); 312 | this.lastMousePos.custom.y = lerp( 313 | this.lastMousePos.custom.y, 314 | this.mousePos.y - ( this.bounds.custom.height / 2 ), 315 | custom, 316 | ); 317 | 318 | this.DOM.custom.style.transform = `translate3d(${ ( this.lastMousePos.custom.x ) }px, ${ this.lastMousePos.custom.y }px, 0) scale(${ this.lastScale })`; 319 | 320 | } 321 | 322 | } 323 | 324 | destroy() { 325 | 326 | this.$raf && cancelAnimationFrame( 327 | this.$raf 328 | ); 329 | 330 | this.initEvents( 331 | false 332 | ); 333 | 334 | this.DOM = null; 335 | 336 | } 337 | 338 | enter( 339 | scale = this.$options.scale.max, 340 | ) { 341 | 342 | this.scale = scale; 343 | 344 | } 345 | 346 | leave( 347 | scale = this.$options.scale.min, 348 | ) { 349 | 350 | this.scale = scale; 351 | 352 | } 353 | 354 | click( 355 | scale = this.$options.scale.min, 356 | opacity = 0, 357 | ) { 358 | 359 | this.lastScale = scale; 360 | this.lastOpacity = opacity; 361 | 362 | } 363 | 364 | enterHidden() { 365 | 366 | if( ! this.DOM ) 367 | return; 368 | 369 | this.DOM.el.style.visibility = 'hidden'; 370 | 371 | } 372 | 373 | leaveHidden() { 374 | 375 | if( ! this.DOM ) 376 | return; 377 | 378 | this.DOM.el.style.visibility = 'visible'; 379 | 380 | } 381 | 382 | mixBlendMode( 383 | value = this.$options.mixBlendMode, 384 | ) { 385 | 386 | if( ! this.DOM ) 387 | return; 388 | 389 | this.DOM.el.style.mixBlendMode = value || null; 390 | 391 | } 392 | } 393 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🎉 Vue Cursor Fx 2 | 3 | [![Code Quality][quality-src]][quality-href] 4 | [![Downloads][npm-downloads-src]][npm-downloads-href] 5 | [![Dependencies][dependencies-src]][dependencies-href] 6 | [![Version][npm-version-src]][npm-version-href] 7 | [![Donate][paypal-donate-src]][paypal-donate-href] 8 | 9 | [quality-src]: https://img.shields.io/badge/code%20quality-A-informational?style=flat 10 | [quality-href]: https://luxdamore.github.io/vue-cursor-fx/ 11 | 12 | [npm-downloads-src]: https://img.shields.io/npm/dt/@luxdamore/vue-cursor-fx.svg?style=flat&color=darkgreen 13 | [npm-downloads-href]: https://npmjs.com/package/@luxdamore/vue-cursor-fx 14 | 15 | [dependencies-src]: https://img.shields.io/badge/dependencies-up%20to%20date-darkgreen.svg?style=flat 16 | [dependencies-href]: https://npmjs.com/package/@luxdamore/vue-cursor-fx 17 | 18 | [npm-version-src]: https://img.shields.io/npm/v/@luxdamore/vue-cursor-fx/latest.svg?style=flat&color=darkorange&label=version 19 | [npm-version-href]: https://npmjs.com/package/@luxdamore/vue-cursor-fx 20 | 21 | [paypal-donate-src]: https://img.shields.io/badge/paypal-donate-black.svg?style=flat 22 | [paypal-donate-href]: https://www.paypal.me/luxdamore 23 | [patreon-donate-href]: https://www.patreon.com/luxdamore 24 | [kofi-donate-href]: https://ko-fi.com/luxdamore 25 | 26 | > An animated custom cursor effects for interactive elements like navigation - w/ VueJS - SSR Compatible 27 | 28 | ## Installation 29 | 30 | This package is available on `npm` and `yarn`. 31 | 32 | ```bash 33 | 34 | # Deps 35 | npm install --save @luxdamore/vue-cursor-fx 36 | 37 | # Or 38 | yarn add @luxdamore/vue-cursor-fx 39 | 40 | ``` 41 | 42 | ### Usage 43 | 44 | #### As component 45 | 46 | ```js 47 | 48 | // Global component and css 49 | import { CursorFx } from '@luxdamore/vue-cursor-fx'; 50 | import '@luxdamore/vue-cursor-fx/dist/CursorFx.css'; 51 | 52 | // Install 53 | Vue.component( 54 | CursorFx.name, 55 | CursorFx 56 | ); 57 | 58 | 59 | // Or, in a .vue file 60 | import { CursorFx } from '@luxdamore/vue-cursor-fx'; 61 | 62 | export default { 63 | components: { 64 | 'cursor-fx': CursorFx, 65 | }, 66 | }; 67 | 68 | 69 | 70 | ``` 71 | 72 | #### As a global plugin 73 | 74 | ```js 75 | 76 | // Plugin 77 | import CursorFx from '@luxdamore/vue-cursor-fx'; 78 | import '@luxdamore/vue-cursor-fx/dist/CursorFx.css'; 79 | 80 | // Install 81 | Vue.use( 82 | CursorFx 83 | ); 84 | 85 | ``` 86 | 87 | #### Browser's way 88 | 89 | ```html 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | ``` 123 | 124 | #### Markup 125 | 126 | _Use one time in the main file of your project or in every views, where you want it._ 127 | 128 | ```html 129 | 130 | 137 | 138 | 145 | 146 | 154 | 155 | 156 | 157 | ``` 158 | 159 | ### Options 160 | 161 | _N.B.: the cursor is not activated on touchscreen devices._ 162 | 163 | #### Slots 164 | 165 | ```bash 166 | 167 | # Available 168 | slot="default" # Add some content in the middle of the cursor 169 | 170 | ``` 171 | 172 | #### Events 173 | 174 | ```html 175 | 176 | 183 | 184 | ``` 185 | 186 | #### Props 187 | 188 | | Attribute | Type | Default value | About | 189 | |:--------------------:|--------------------|:-------:|-------------------------------------| 190 | | config | Object | {} | The default options applied to cursor, see below the `BASE_CONFIG` | 191 | | color | String | #333333 |Color for the cursor | 192 | | color-hover | String | #333333 | Color, on hover, for the cursor | 193 | | outside-size | String | null | The size of outer circle | 194 | | inside-size | String | null | The size of inner dot | 195 | | shape | String | null | Only available shapes are `circle` and `square` | 196 | | delay | String, Number | 60 | Activate cursor after x seconds | 197 | | mix-blend-mode | String | null | Set the global `mix-blend-mode` style | 198 | | force-custom-slot | Boolean | false | Show or hide the internal default slot | 199 | | allow-on-mobile | Boolean | false | Allow the cursor on mobile devices | 200 | | hide-outside | Boolean | false | Hide outer circle | 201 | | hide-inside | Boolean | false | Hide inner dot | 202 | | disabled | Boolean | false | Disable the activation of the cursor | 203 | 204 | ```js 205 | 206 | const BASE_CONFIG = { 207 | lerps: { 208 | dot: 1, 209 | circle: 0.18, 210 | custom: 0.23, 211 | }, 212 | scale: { 213 | ratio: 0.18, 214 | min: 0.5, 215 | max: 1, 216 | }, 217 | opacity: 0.1, 218 | }; 219 | 220 | ``` 221 | 222 | #### Methods 223 | 224 | ```html 225 | 226 | 227 | 235 | 236 | 237 | 258 | 259 | ``` 260 | 261 | #### Integrations 262 | 263 | ##### VueRouter 264 | 265 | ```html 266 | 267 | 268 | 277 | 278 | ``` 279 | 280 | ##### NuxtJs 281 | 282 | - For the entire website: place the component in the desired layouts (ex. layouts/default.vue); 283 | - For some pages only: place the component in the desired pages (ex. pages/index.vue). 284 | 285 | ```html 286 | 287 | 288 | 299 | 300 | ``` 301 | 302 | ##### Tips 303 | - Q: How to fix problem with the disappearance of the cursor on nuxt route change ? 304 | - A: Trigger cursor refresh on route change where component is placed. 305 | 306 | ```js 307 | 308 | watch: { 309 | $route( to, from ) { 310 | 311 | this.$nextTick( () => this.$refs.cursor.refresh() ); 312 | 313 | }, 314 | }, 315 | 316 | ``` 317 | 318 | ___ 319 | 320 | ## 👩🏻‍💻👨🏻‍💻 Development 321 | 322 | 1. **Clone** the repository: 323 | - `git clone https://github.com/LuXDAmore/vue-cursor-fx.git`; 324 | 2. **Install** dependencies: 325 | - `yarn install` (or `npm install`); 326 | 3. **Start** a development server: 327 | - `yarn dev` (or `npm run dev`); 328 | 4. **Extra**, build the documentation ([*Github Pages*](https://pages.github.com/)): 329 | - `yarn build` (or `npm run build`); 330 | - _the content is automatically generated into the `/docs` folder_. 331 | 332 | ## 🐞 Issues 333 | 334 | Please make sure to read the [**issue reporting checklist**](./.github/ISSUE_TEMPLATE/bug_report.md) before opening an issue. 335 | *Issues not conforming to the guidelines may be closed immediately*. 336 | 337 | ## 📝 Discussions 338 | 339 | We're using [**Github discussions**](https://github.com/LuXDAmore/vue-cursor-fx/discussions) as a place to connect with other members of our community. 340 | *You are free to ask questions and share ideas, so enjoy yourself*. 341 | 342 | ## 👥 Contribution 343 | 344 | Please make sure to read the [**contributing guide**](./.github/ISSUE_TEMPLATE/feature_request.md) before making a pull request. 345 | 346 | ## 📖 Changelog 347 | 348 | Details changes for each release are documented in the [**release notes**](./CHANGELOG.md). 349 | 350 | ### 🆓 License 351 | 352 | [MIT License](./LICENSE) // Copyright (©) 2019-now [Luca Iaconelli](https://lucaiaconelli.it) 353 | 354 | #### 💼 Hire me 355 | 356 | [![Contacts](https://img.shields.io/badge/Contact%20Me-Let's%20Talk-informational?style=social&logo=minutemailer)](https://curriculumvitae.lucaiaconelli.it) 357 | 358 | #### 💸 Are you feeling generous today? 359 | 360 | If You want to share a beer, we can be really good friends 😄 361 | 362 | __[Paypal][paypal-donate-href] // [Patreon][patreon-donate-href] // [Ko-fi][kofi-donate-href]__ 363 | 364 | > ☀ _It's always a good day to be magnanimous_ - cit. 365 | 366 | ___ 367 | 368 | #### 💡 Lighthouse 369 | 370 | ![Lighthouse audit score](./lighthouse-audit.jpg) 371 | 372 | ___ 373 | 374 | #### 💘 Inspired by 375 | 376 | [CustomCursors by Tympanus](https://tympanus.net/Tutorials/CustomCursors/index3.html) 377 | -------------------------------------------------------------------------------- /src/CursorFx/CursorFx.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 472 | 473 | 477 | 478 | 483 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parserOptions: { 4 | parser: 'babel-eslint', 5 | sourceType: 'module', 6 | }, 7 | extends: [ 8 | '@nuxtjs', 9 | 'eslint:recommended', 10 | 'plugin:nuxt/recommended', 11 | 'plugin:vue/recommended', 12 | '@vue/prettier', 13 | ], 14 | plugins: [ 15 | 'standard', 16 | 'compat', 17 | 'import', 18 | 'promise', 19 | 'unicorn', 20 | ], 21 | rules: { 22 | 'indent': 'off', 23 | 'no-console': 'off', 24 | 'no-debugger': 'error', 25 | 'one-var': [ 26 | 'warn', 27 | { 28 | separateRequires: true, 29 | var: 'consecutive', 30 | let: 'consecutive', 31 | const: 'consecutive', 32 | } 33 | ], 34 | 'spaced-comment': [ 'warn', 'always' ], 35 | 'function-call-argument-newline': [ 'warn', 'always' ], 36 | 'prefer-const': 'warn', 37 | 'no-useless-rename': [ 38 | 'warn', 39 | { 40 | ignoreExport: true, 41 | }, 42 | ], 43 | 'rest-spread-spacing': [ 44 | 'warn', 45 | 'always', 46 | ], 47 | 'template-curly-spacing': [ 48 | 'warn', 49 | 'always', 50 | ], 51 | 'array-element-newline': [ 52 | 'warn', 53 | { 54 | minItems: 2, 55 | multiline: true, 56 | } 57 | ], 58 | 'array-bracket-newline': [ 59 | 'warn', 60 | { 61 | minItems: 2, 62 | multiline: true, 63 | } 64 | ], 65 | 'function-paren-newline': [ 66 | 'warn', 67 | { 68 | minItems: 1, 69 | } 70 | ], 71 | 'brace-style': [ 72 | 'warn', 73 | '1tbs', 74 | { 75 | allowSingleLine: true, 76 | } 77 | ], 78 | 'comma-style': [ 79 | 'warn', 80 | 'first', 81 | { 82 | exceptions: { 83 | ArrayExpression: true, 84 | ObjectExpression: true, 85 | } 86 | } 87 | ], 88 | 'comma-spacing': [ 89 | 'warn', 90 | { 91 | before: false, 92 | after: true, 93 | } 94 | ], 95 | quotes: [ 96 | 'warn', 97 | 'single', 98 | { 99 | avoidEscape: true, 100 | allowTemplateLiterals: true, 101 | } 102 | ], 103 | semi: [ 104 | 'warn', 105 | 'always', 106 | ], 107 | 'no-unreachable': 'warn', 108 | 'no-confusing-arrow': 'warn', 109 | 'no-constant-condition': 'warn', 110 | curly: [ 111 | 'warn', 112 | 'multi-or-nest', 113 | ], 114 | 'padding-line-between-statements': [ 115 | 'warn', 116 | { 117 | blankLine: 'always', 118 | prev: [ 119 | 'const', 120 | 'let', 121 | 'var', 122 | ], 123 | next: '*', 124 | }, 125 | { 126 | blankLine: 'any', 127 | prev: [ 128 | 'const', 129 | 'let', 130 | 'var', 131 | ], 132 | next: [ 133 | 'const', 134 | 'let', 135 | 'var', 136 | ] 137 | } 138 | ], 139 | 'no-empty': 'warn', 140 | 'no-return-await': 'warn', 141 | 'no-multiple-empty-lines': [ 142 | 'warn', 143 | { 144 | max: 2, 145 | maxBOF: 1, 146 | } 147 | ], 148 | 'lines-around-comment': [ 149 | 'warn', 150 | { 151 | beforeBlockComment: false, 152 | afterBlockComment: false, 153 | beforeLineComment: false, 154 | afterLineComment: false, 155 | allowBlockStart: true, 156 | allowBlockEnd: true, 157 | allowObjectStart: true, 158 | allowObjectEnd: true, 159 | allowArrayStart: true, 160 | allowArrayEnd: true, 161 | } 162 | ], 163 | 'no-inner-declarations': [ 164 | 'warn', 165 | 'functions', 166 | ], 167 | 'no-tabs': 'warn', 168 | 'operator-linebreak': [ 169 | 'warn', 170 | 'before', 171 | ], 172 | 'block-spacing': [ 173 | 'warn', 174 | 'always', 175 | ], 176 | 'dot-location': [ 177 | 'warn', 178 | 'property', 179 | ], 180 | 'func-call-spacing': [ 181 | 'warn', 182 | 'never', 183 | ], 184 | 'key-spacing': [ 185 | 'warn', 186 | { 187 | beforeColon: false, 188 | } 189 | ], 190 | 'new-cap': [ 191 | 'warn', 192 | { 193 | newIsCap: true, 194 | } 195 | ], 196 | 'no-duplicate-imports': [ 197 | 'warn', 198 | { 199 | includeExports: true, 200 | } 201 | ], 202 | 'no-floating-decimal': 'warn', 203 | 'no-multi-spaces': 'warn', 204 | 'no-return-assign': [ 205 | 'warn', 206 | 'except-parens', 207 | ], 208 | 'require-await': 'warn', 209 | 'no-undef': 'warn', 210 | 'no-undef-init': 'warn', 211 | 'no-whitespace-before-property': 'warn', 212 | 'object-property-newline': [ 213 | 'warn', 214 | { 215 | allowAllPropertiesOnSameLine: false, 216 | } 217 | ], 218 | 'object-curly-newline': [ 219 | 'warn', 220 | { 221 | ObjectExpression: { 222 | multiline: true, 223 | minProperties: 1, 224 | }, 225 | ObjectPattern: { 226 | multiline: true, 227 | minProperties: 2, 228 | }, 229 | ImportDeclaration: { 230 | multiline: true, 231 | consistent: false, 232 | minProperties: 3, 233 | }, 234 | ExportDeclaration: { 235 | multiline: true, 236 | consistent: false, 237 | minProperties: 2, 238 | } 239 | } 240 | ], 241 | 'padded-blocks': [ 242 | 'warn', 243 | { 244 | switches: 'never', 245 | blocks: 'always', 246 | } 247 | ], 248 | 'yield-star-spacing': [ 249 | 'warn', 250 | 'both', 251 | ], 252 | 'one-var-declaration-per-line': [ 253 | 'warn', 254 | 'always', 255 | ], 256 | 'space-infix-ops': 'warn', 257 | 'require-atomic-updates': 'warn', 258 | 'comma-dangle': [ 259 | 'warn', 260 | { 261 | arrays: 'always-multiline', 262 | objects: 'always-multiline', 263 | exports: 'always-multiline', 264 | imports: 'always-multiline', 265 | functions: 'only-multiline', 266 | } 267 | ], 268 | 'dot-notation': 'warn', 269 | 'eqeqeq': [ 'warn', 'always' ], 270 | 'camelcase': [ 271 | 'off', 272 | { 273 | ignoreDestructuring: true, 274 | }, 275 | ], 276 | 'no-prototype-builtins': 'warn', 277 | 'no-extra-semi': 'warn', 278 | 'no-new-object': 'warn', 279 | 'no-array-constructor': 'warn', 280 | 'no-new-wrappers': 'warn', 281 | 'no-mixed-spaces-and-tabs': 'warn', 282 | 'space-before-function-paren': [ 283 | 'warn', 284 | 'never', 285 | ], 286 | 'space-before-blocks': 'warn', 287 | 'array-bracket-spacing': [ 288 | 'warn', 289 | 'always', 290 | { 291 | singleValue: true, 292 | objectsInArrays: false, 293 | arraysInArrays: true, 294 | } 295 | ], 296 | 'computed-property-spacing': [ 297 | 'warn', 298 | 'always' 299 | ], 300 | 'space-in-parens': [ 301 | 1, 302 | 'always' 303 | ], 304 | 'object-curly-spacing': [ 305 | 'warn', 306 | 'always' 307 | ], 308 | 'keyword-spacing': [ 309 | 'warn', 310 | { 311 | after: false, 312 | overrides: { 313 | const: { 314 | after: true, 315 | }, 316 | else: { 317 | before: true, 318 | after: true, 319 | }, 320 | from: { 321 | before: true, 322 | after: true, 323 | }, 324 | return: { 325 | after: true, 326 | }, 327 | default: { 328 | after: true, 329 | }, 330 | export: { 331 | after: true, 332 | }, 333 | import: { 334 | after: true, 335 | }, 336 | case: { 337 | after: true, 338 | }, 339 | try: { 340 | after: true, 341 | }, 342 | catch: { 343 | before: true, 344 | after: false, 345 | } 346 | } 347 | } 348 | ], 349 | 'arrow-parens': [ 350 | 'warn', 351 | 'as-needed' 352 | ], 353 | 'no-irregular-whitespace': 'warn', 354 | 'space-unary-ops': [ 355 | 'warn', 356 | { 357 | words: true, 358 | nonwords: true, 359 | } 360 | ], 361 | 'arrow-spacing': [ 362 | 1, 363 | { 364 | before: true, 365 | after: true, 366 | } 367 | ], 368 | 'object-shorthand': [ 369 | 'warn', 370 | 'always', 371 | ], 372 | 'no-unused-vars': [ 373 | 'warn', 374 | { 375 | vars: 'all', 376 | args: 'after-used', // This needs to be off so we can specify mixin interfaces 377 | ignoreRestSiblings: true, 378 | caughtErrors: 'all', 379 | argsIgnorePattern: '^_', 380 | } 381 | ], 382 | 'max-len': [ 383 | 'warn', 384 | 300, 385 | 4, 386 | { 387 | ignoreUrls: true, 388 | ignoreTemplateLiterals: true, 389 | ignoreStrings: true, 390 | } 391 | ], 392 | 'max-statements': [ 393 | 'warn', 394 | 72, 395 | { 396 | ignoreTopLevelFunctions: true, 397 | } 398 | ], 399 | 'lines-between-class-members': [ 400 | 'warn', 401 | 'always', 402 | { 403 | exceptAfterSingleLine: true, 404 | } 405 | ], 406 | // Plugins 407 | // Standard 408 | 'unicorn/prefer-includes': 'warn', 409 | 'standard/computed-property-even-spacing': 'off', 410 | 'standard/object-curly-even-spacing': [ 411 | 'warn', 412 | 'either', 413 | ], 414 | // Import 415 | 'import/order': 'warn', 416 | 'import/first': 'warn', 417 | 'import/namespace': [ 418 | 'warn', 419 | { 420 | allowComputed: true, 421 | } 422 | ], 423 | // Compat 424 | 'compat/compat': 'warn', 425 | // Vuejs 426 | 'vue/require-default-prop': 'warn', 427 | 'vue/require-prop-types': 'warn', 428 | 'vue/no-v-html': 'off', 429 | 'vue/no-unused-vars': 'warn', 430 | 'vue/no-unused-components': 'warn', 431 | 'vue/no-use-v-if-with-v-for': [ 432 | 'warn', 433 | { 434 | allowUsingIterationVar: true, 435 | } 436 | ], 437 | 'vue/component-name-in-template-casing': [ 438 | 'warn', 439 | 'kebab-case', 440 | ], 441 | 'vue/name-property-casing': [ 442 | 'warn', 443 | 'kebab-case' 444 | ], 445 | 'vue/attribute-hyphenation': [ 446 | 'warn', 447 | 'always' 448 | ], 449 | 'vue/max-attributes-per-line': [ 450 | 'warn', 451 | { 452 | 'singleline': 2, 453 | 'multiline': { 454 | 'max': 1, 455 | 'allowFirstLine': false 456 | } 457 | } 458 | ], 459 | 'vue/html-end-tags': 'warn', 460 | 'vue/html-indent': [ 461 | 'warn', 462 | 4 463 | ], 464 | 'vue/html-self-closing': 'warn', 465 | 'vue/attributes-order': 'warn', 466 | 'vue/html-quotes': [ 467 | 'warn', 468 | 'double' 469 | ], 470 | 'vue/order-in-components': 'warn', 471 | 'vue/html-closing-bracket-newline': [ 472 | 'warn', 473 | { 474 | singleline: 'never', 475 | multiline: 'always' 476 | } 477 | ], 478 | 'vue/html-closing-bracket-spacing': [ 479 | 'warn', 480 | { 481 | startTag: 'never', 482 | endTag: 'never', 483 | selfClosingTag: 'always' 484 | } 485 | ], 486 | 'vue/script-indent': [ 487 | 'warn', 488 | 4, 489 | { 490 | baseIndent: 1 491 | } 492 | ], 493 | }, 494 | }; 495 | -------------------------------------------------------------------------------- /docs/css/chunk-vendors.36e46d09.css: -------------------------------------------------------------------------------- 1 | /*! modern-normalize v1.0.0 | MIT License | https://github.com/sindresorhus/modern-normalize */*,:after,:before{box-sizing:border-box}:root{-moz-tab-size:4;-o-tab-size:4;tab-size:4}html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0;font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,Helvetica,Arial,Apple Color Emoji,Segoe UI Emoji}hr{height:0;color:inherit}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}::-moz-focus-inner{border-style:none;padding:0}:-moz-focusring{outline:1px dotted ButtonText}:-moz-ui-invalid{box-shadow:none}legend{padding:0}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}@font-face{font-family:octicons-link;src:url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAZwABAAAAAACFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEU0lHAAAGaAAAAAgAAAAIAAAAAUdTVUIAAAZcAAAACgAAAAoAAQAAT1MvMgAAAyQAAABJAAAAYFYEU3RjbWFwAAADcAAAAEUAAACAAJThvmN2dCAAAATkAAAABAAAAAQAAAAAZnBnbQAAA7gAAACyAAABCUM+8IhnYXNwAAAGTAAAABAAAAAQABoAI2dseWYAAAFsAAABPAAAAZwcEq9taGVhZAAAAsgAAAA0AAAANgh4a91oaGVhAAADCAAAABoAAAAkCA8DRGhtdHgAAAL8AAAADAAAAAwGAACfbG9jYQAAAsAAAAAIAAAACABiATBtYXhwAAACqAAAABgAAAAgAA8ASm5hbWUAAAToAAABQgAAAlXu73sOcG9zdAAABiwAAAAeAAAAME3QpOBwcmVwAAAEbAAAAHYAAAB/aFGpk3jaTY6xa8JAGMW/O62BDi0tJLYQincXEypYIiGJjSgHniQ6umTsUEyLm5BV6NDBP8Tpts6F0v+k/0an2i+itHDw3v2+9+DBKTzsJNnWJNTgHEy4BgG3EMI9DCEDOGEXzDADU5hBKMIgNPZqoD3SilVaXZCER3/I7AtxEJLtzzuZfI+VVkprxTlXShWKb3TBecG11rwoNlmmn1P2WYcJczl32etSpKnziC7lQyWe1smVPy/Lt7Kc+0vWY/gAgIIEqAN9we0pwKXreiMasxvabDQMM4riO+qxM2ogwDGOZTXxwxDiycQIcoYFBLj5K3EIaSctAq2kTYiw+ymhce7vwM9jSqO8JyVd5RH9gyTt2+J/yUmYlIR0s04n6+7Vm1ozezUeLEaUjhaDSuXHwVRgvLJn1tQ7xiuVv/ocTRF42mNgZGBgYGbwZOBiAAFGJBIMAAizAFoAAABiAGIAznjaY2BkYGAA4in8zwXi+W2+MjCzMIDApSwvXzC97Z4Ig8N/BxYGZgcgl52BCSQKAA3jCV8CAABfAAAAAAQAAEB42mNgZGBg4f3vACQZQABIMjKgAmYAKEgBXgAAeNpjYGY6wTiBgZWBg2kmUxoDA4MPhGZMYzBi1AHygVLYQUCaawqDA4PChxhmh/8ODDEsvAwHgMKMIDnGL0x7gJQCAwMAJd4MFwAAAHjaY2BgYGaA4DAGRgYQkAHyGMF8NgYrIM3JIAGVYYDT+AEjAwuDFpBmA9KMDEwMCh9i/v8H8sH0/4dQc1iAmAkALaUKLgAAAHjaTY9LDsIgEIbtgqHUPpDi3gPoBVyRTmTddOmqTXThEXqrob2gQ1FjwpDvfwCBdmdXC5AVKFu3e5MfNFJ29KTQT48Ob9/lqYwOGZxeUelN2U2R6+cArgtCJpauW7UQBqnFkUsjAY/kOU1cP+DAgvxwn1chZDwUbd6CFimGXwzwF6tPbFIcjEl+vvmM/byA48e6tWrKArm4ZJlCbdsrxksL1AwWn/yBSJKpYbq8AXaaTb8AAHja28jAwOC00ZrBeQNDQOWO//sdBBgYGRiYWYAEELEwMTE4uzo5Zzo5b2BxdnFOcALxNjA6b2ByTswC8jYwg0VlNuoCTWAMqNzMzsoK1rEhNqByEyerg5PMJlYuVueETKcd/89uBpnpvIEVomeHLoMsAAe1Id4AAAAAAAB42oWQT07CQBTGv0JBhagk7HQzKxca2sJCE1hDt4QF+9JOS0nbaaYDCQfwCJ7Au3AHj+LO13FMmm6cl7785vven0kBjHCBhfpYuNa5Ph1c0e2Xu3jEvWG7UdPDLZ4N92nOm+EBXuAbHmIMSRMs+4aUEd4Nd3CHD8NdvOLTsA2GL8M9PODbcL+hD7C1xoaHeLJSEao0FEW14ckxC+TU8TxvsY6X0eLPmRhry2WVioLpkrbp84LLQPGI7c6sOiUzpWIWS5GzlSgUzzLBSikOPFTOXqly7rqx0Z1Q5BAIoZBSFihQYQOOBEdkCOgXTOHA07HAGjGWiIjaPZNW13/+lm6S9FT7rLHFJ6fQbkATOG1j2OFMucKJJsxIVfQORl+9Jyda6Sl1dUYhSCm1dyClfoeDve4qMYdLEbfqHf3O/AdDumsjAAB42mNgYoAAZQYjBmyAGYQZmdhL8zLdDEydARfoAqIAAAABAAMABwAKABMAB///AA8AAQAAAAAAAAAAAAAAAAABAAAAAA==) format("woff")}.markdown-body .octicon{display:inline-block;fill:currentColor;vertical-align:text-bottom}.markdown-body .anchor{float:left;line-height:1;margin-left:-20px;padding-right:4px}.markdown-body .anchor:focus{outline:none}.markdown-body h1 .octicon-link,.markdown-body h2 .octicon-link,.markdown-body h3 .octicon-link,.markdown-body h4 .octicon-link,.markdown-body h5 .octicon-link,.markdown-body h6 .octicon-link{color:#1b1f23;vertical-align:middle;visibility:hidden}.markdown-body h1:hover .anchor,.markdown-body h2:hover .anchor,.markdown-body h3:hover .anchor,.markdown-body h4:hover .anchor,.markdown-body h5:hover .anchor,.markdown-body h6:hover .anchor{text-decoration:none}.markdown-body h1:hover .anchor .octicon-link,.markdown-body h2:hover .anchor .octicon-link,.markdown-body h3:hover .anchor .octicon-link,.markdown-body h4:hover .anchor .octicon-link,.markdown-body h5:hover .anchor .octicon-link,.markdown-body h6:hover .anchor .octicon-link{visibility:visible}.markdown-body{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;color:#24292e;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;font-size:16px;line-height:1.5;word-wrap:break-word}.markdown-body .pl-c{color:#6a737d}.markdown-body .pl-c1,.markdown-body .pl-s .pl-v{color:#005cc5}.markdown-body .pl-e,.markdown-body .pl-en{color:#6f42c1}.markdown-body .pl-s .pl-s1,.markdown-body .pl-smi{color:#24292e}.markdown-body .pl-ent{color:#22863a}.markdown-body .pl-k{color:#d73a49}.markdown-body .pl-pds,.markdown-body .pl-s,.markdown-body .pl-s .pl-pse .pl-s1,.markdown-body .pl-sr,.markdown-body .pl-sr .pl-cce,.markdown-body .pl-sr .pl-sra,.markdown-body .pl-sr .pl-sre{color:#032f62}.markdown-body .pl-smw,.markdown-body .pl-v{color:#e36209}.markdown-body .pl-bu{color:#b31d28}.markdown-body .pl-ii{background-color:#b31d28;color:#fafbfc}.markdown-body .pl-c2{background-color:#d73a49;color:#fafbfc}.markdown-body .pl-c2:before{content:"^M"}.markdown-body .pl-sr .pl-cce{color:#22863a;font-weight:700}.markdown-body .pl-ml{color:#735c0f}.markdown-body .pl-mh,.markdown-body .pl-mh .pl-en,.markdown-body .pl-ms{color:#005cc5;font-weight:700}.markdown-body .pl-mi{color:#24292e;font-style:italic}.markdown-body .pl-mb{color:#24292e;font-weight:700}.markdown-body .pl-md{background-color:#ffeef0;color:#b31d28}.markdown-body .pl-mi1{background-color:#f0fff4;color:#22863a}.markdown-body .pl-mc{background-color:#ffebda;color:#e36209}.markdown-body .pl-mi2{background-color:#005cc5;color:#f6f8fa}.markdown-body .pl-mdr{color:#6f42c1;font-weight:700}.markdown-body .pl-ba{color:#586069}.markdown-body .pl-sg{color:#959da5}.markdown-body .pl-corl{color:#032f62;text-decoration:underline}.markdown-body details{display:block}.markdown-body summary{display:list-item}.markdown-body a{background-color:transparent;color:#0366d6;text-decoration:none}.markdown-body a:active,.markdown-body a:hover{outline-width:0}.markdown-body strong{font-weight:600}.markdown-body h1{margin:.67em 0;font-size:2em}.markdown-body img{border-style:none;background-color:#fff;box-sizing:content-box;max-width:100%}.markdown-body code,.markdown-body kbd,.markdown-body pre{font-family:monospace,monospace;font-size:1em}.markdown-body hr{box-sizing:content-box;background:transparent;overflow:hidden;background-color:#e1e4e8;border:0;height:.25em;margin:24px 0;padding:0;border-bottom-color:#eee}.markdown-body input{font:inherit;margin:0;overflow:visible;font-family:inherit;font-size:inherit;line-height:inherit}.markdown-body [type=checkbox]{box-sizing:border-box;padding:0}.markdown-body *{box-sizing:border-box}.markdown-body a:hover{text-decoration:underline}.markdown-body hr:after,.markdown-body hr:before{content:"";display:table}.markdown-body hr:after{clear:both}.markdown-body table{border-collapse:collapse;border-spacing:0;display:block;overflow:auto;width:100%}.markdown-body td,.markdown-body th{padding:0}.markdown-body details summary{cursor:pointer}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{font-weight:600;line-height:1.25;margin-bottom:16px;margin-top:24px}.markdown-body h1,.markdown-body h2{font-weight:600;border-bottom:1px solid #eaecef;padding-bottom:.3em}.markdown-body h2{font-size:1.5em}.markdown-body h3{font-size:1.25em}.markdown-body h3,.markdown-body h4{font-weight:600}.markdown-body h4{font-size:1em}.markdown-body h5{font-size:.875em}.markdown-body h5,.markdown-body h6{font-weight:600}.markdown-body h6{color:#6a737d;font-size:.85em}.markdown-body p{margin-bottom:10px;margin-top:0}.markdown-body blockquote{margin:0;border-left:.25em solid #dfe2e5;color:#6a737d;padding:0 1em}.markdown-body ol,.markdown-body ul{margin-bottom:0;margin-top:0;padding-left:2em}.markdown-body ol ol,.markdown-body ul ol{list-style-type:lower-roman}.markdown-body ol ol ol,.markdown-body ol ul ol,.markdown-body ul ol ol,.markdown-body ul ul ol{list-style-type:lower-alpha}.markdown-body dd{margin-left:0}.markdown-body code,.markdown-body pre{font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;font-size:12px}.markdown-body pre{margin-bottom:0;margin-top:0;word-wrap:normal}.markdown-body input::-webkit-inner-spin-button,.markdown-body input::-webkit-outer-spin-button{-webkit-appearance:none;appearance:none;margin:0}.markdown-body .border{border:1px solid #e1e4e8!important}.markdown-body .border-0{border:0!important}.markdown-body .border-bottom{border-bottom:1px solid #e1e4e8!important}.markdown-body .rounded-1{border-radius:3px!important}.markdown-body .bg-white{background-color:#fff!important}.markdown-body .bg-gray-light{background-color:#fafbfc!important}.markdown-body .text-gray-light{color:#6a737d!important}.markdown-body .mb-0{margin-bottom:0!important}.markdown-body .my-2{margin-bottom:8px!important;margin-top:8px!important}.markdown-body .pl-0{padding-left:0!important}.markdown-body .py-0{padding-bottom:0!important;padding-top:0!important}.markdown-body .pl-1{padding-left:4px!important}.markdown-body .pl-2{padding-left:8px!important}.markdown-body .py-2{padding-bottom:8px!important;padding-top:8px!important}.markdown-body .pl-3,.markdown-body .px-3{padding-left:16px!important}.markdown-body .px-3{padding-right:16px!important}.markdown-body .pl-4{padding-left:24px!important}.markdown-body .pl-5{padding-left:32px!important}.markdown-body .pl-6{padding-left:40px!important}.markdown-body .f6{font-size:12px!important}.markdown-body .lh-condensed{line-height:1.25!important}.markdown-body .text-bold{font-weight:600!important}.markdown-body:after,.markdown-body:before{content:"";display:table}.markdown-body:after{clear:both}.markdown-body>:first-child{margin-top:0!important}.markdown-body>:last-child{margin-bottom:0!important}.markdown-body a:not([href]){color:inherit;text-decoration:none}.markdown-body blockquote,.markdown-body dl,.markdown-body ol,.markdown-body p,.markdown-body pre,.markdown-body table,.markdown-body ul{margin-bottom:16px;margin-top:0}.markdown-body blockquote>:first-child{margin-top:0}.markdown-body blockquote>:last-child{margin-bottom:0}.markdown-body kbd{font-size:11px;background-color:#fafbfc;border:1px solid #d1d5da;border-bottom-color:#c6cbd1;border-radius:3px;box-shadow:inset 0 -1px 0 #c6cbd1;color:#444d56;display:inline-block;font:11px SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;line-height:10px;padding:3px 5px;vertical-align:middle}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-bottom:0;margin-top:0}.markdown-body li{word-wrap:break-all}.markdown-body li>p{margin-top:16px}.markdown-body li+li{margin-top:.25em}.markdown-body dl{padding:0}.markdown-body dl dt{font-size:1em;font-style:italic;font-weight:600;margin-top:16px;padding:0}.markdown-body dl dd{margin-bottom:16px;padding:0 16px}.markdown-body table th{font-weight:600}.markdown-body table td,.markdown-body table th{border:1px solid #dfe2e5;padding:6px 13px}.markdown-body table tr{background-color:#fff;border-top:1px solid #c6cbd1}.markdown-body table tr:nth-child(2n){background-color:#f6f8fa}.markdown-body img[align=right]{padding-left:20px}.markdown-body img[align=left]{padding-right:20px}.markdown-body code{background-color:rgba(27,31,35,.05);border-radius:3px;font-size:85%;margin:0;padding:.2em .4em}.markdown-body pre>code{background:transparent;border:0;font-size:100%;margin:0;padding:0;white-space:pre;word-break:normal}.markdown-body .highlight{margin-bottom:16px}.markdown-body .highlight pre{margin-bottom:0;word-break:normal}.markdown-body .highlight pre,.markdown-body pre{background-color:#f6f8fa;border-radius:3px;font-size:85%;line-height:1.45;overflow:auto;padding:16px}.markdown-body pre code{background-color:transparent;border:0;display:inline;line-height:inherit;margin:0;max-width:auto;overflow:visible;padding:0;word-wrap:normal}.markdown-body .commit-tease-sha{color:#444d56;display:inline-block;font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;font-size:90%}.markdown-body .blob-wrapper{border-bottom-left-radius:3px;border-bottom-right-radius:3px;overflow-x:auto;overflow-y:hidden}.markdown-body .blob-wrapper-embedded{max-height:240px;overflow-y:auto}.markdown-body .blob-num{-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;color:rgba(27,31,35,.3);cursor:pointer;font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;font-size:12px;line-height:20px;min-width:50px;padding-left:10px;padding-right:10px;text-align:right;user-select:none;vertical-align:top;white-space:nowrap;width:1%}.markdown-body .blob-num:hover{color:rgba(27,31,35,.6)}.markdown-body .blob-num:before{content:attr(data-line-number)}.markdown-body .blob-code{line-height:20px;padding-left:10px;padding-right:10px;position:relative;vertical-align:top}.markdown-body .blob-code-inner{color:#24292e;font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;font-size:12px;overflow:visible;white-space:pre;word-wrap:normal}.markdown-body .pl-token.active,.markdown-body .pl-token:hover{background:#ffea7f;cursor:pointer}.markdown-body :checked+.radio-label{border-color:#0366d6;position:relative;z-index:1}.markdown-body .tab-size[data-tab-size="1"]{-moz-tab-size:1;-o-tab-size:1;tab-size:1}.markdown-body .tab-size[data-tab-size="2"]{-moz-tab-size:2;-o-tab-size:2;tab-size:2}.markdown-body .tab-size[data-tab-size="3"]{-moz-tab-size:3;-o-tab-size:3;tab-size:3}.markdown-body .tab-size[data-tab-size="4"]{-moz-tab-size:4;-o-tab-size:4;tab-size:4}.markdown-body .tab-size[data-tab-size="5"]{-moz-tab-size:5;-o-tab-size:5;tab-size:5}.markdown-body .tab-size[data-tab-size="6"]{-moz-tab-size:6;-o-tab-size:6;tab-size:6}.markdown-body .tab-size[data-tab-size="7"]{-moz-tab-size:7;-o-tab-size:7;tab-size:7}.markdown-body .tab-size[data-tab-size="8"]{-moz-tab-size:8;-o-tab-size:8;tab-size:8}.markdown-body .tab-size[data-tab-size="9"]{-moz-tab-size:9;-o-tab-size:9;tab-size:9}.markdown-body .tab-size[data-tab-size="10"]{-moz-tab-size:10;-o-tab-size:10;tab-size:10}.markdown-body .tab-size[data-tab-size="11"]{-moz-tab-size:11;-o-tab-size:11;tab-size:11}.markdown-body .tab-size[data-tab-size="12"]{-moz-tab-size:12;-o-tab-size:12;tab-size:12}.markdown-body .task-list-item{list-style-type:none}.markdown-body .task-list-item+.task-list-item{margin-top:3px}.markdown-body .task-list-item input{margin:0 .2em .25em -1.6em;vertical-align:middle}.markdown-body .pl-3{padding-left:16px!important}.markdown-body .pl-7{padding-left:48px!important}.markdown-body .pl-8{padding-left:64px!important}.markdown-body .pl-9{padding-left:80px!important}.markdown-body .pl-10{padding-left:96px!important}.markdown-body .pl-11{padding-left:112px!important}.markdown-body .pl-12{padding-left:128px!important}.hljs{display:block;overflow-x:auto;padding:.5em;color:#333;background:#f8f8f8}.hljs-comment,.hljs-quote{color:#998;font-style:italic}.hljs-keyword,.hljs-selector-tag,.hljs-subst{color:#333;font-weight:700}.hljs-literal,.hljs-number,.hljs-tag .hljs-attr,.hljs-template-variable,.hljs-variable{color:teal}.hljs-doctag,.hljs-string{color:#d14}.hljs-section,.hljs-selector-id,.hljs-title{color:#900;font-weight:700}.hljs-subst{font-weight:400}.hljs-class .hljs-title,.hljs-type{color:#458;font-weight:700}.hljs-attribute,.hljs-name,.hljs-tag{color:navy;font-weight:400}.hljs-link,.hljs-regexp{color:#009926}.hljs-bullet,.hljs-symbol{color:#990073}.hljs-built_in,.hljs-builtin-name{color:#0086b3}.hljs-meta{color:#999;font-weight:700}.hljs-deletion{background:#fdd}.hljs-addition{background:#dfd}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} -------------------------------------------------------------------------------- /src/VApp/VApp.vue: -------------------------------------------------------------------------------- 1 | 441 | 442 | 625 | 626 | 631 | -------------------------------------------------------------------------------- /dist/CursorFx.umd.min.js: -------------------------------------------------------------------------------- 1 | (function(t,e){"object"===typeof exports&&"object"===typeof module?module.exports=e():"function"===typeof define&&define.amd?define([],e):"object"===typeof exports?exports["CursorFx"]=e():t["CursorFx"]=e()})("undefined"!==typeof self?self:this,(function(){return function(t){var e={};function r(n){if(e[n])return e[n].exports;var o=e[n]={i:n,l:!1,exports:{}};return t[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}return r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"===typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)r.d(n,o,function(e){return t[e]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t["default"]}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s="fb15")}({"1c95":function(t,e,r){"use strict";r("5bcc")},4362:function(t,e,r){e.nextTick=function(t){var e=Array.prototype.slice.call(arguments);e.shift(),setTimeout((function(){t.apply(null,e)}),0)},e.platform=e.arch=e.execPath=e.title="browser",e.pid=1,e.browser=!0,e.env={},e.argv=[],e.binding=function(t){throw new Error("No such module. (Possibly not yet loaded)")},function(){var t,n="/";e.cwd=function(){return n},e.chdir=function(e){t||(t=r("df7c")),n=t.resolve(e,n)}}(),e.exit=e.kill=e.umask=e.dlopen=e.uptime=e.memoryUsage=e.uvCounters=function(){},e.features={}},5118:function(t,e,r){(function(t){var n="undefined"!==typeof t&&t||"undefined"!==typeof self&&self||window,o=Function.prototype.apply;function i(t,e){this._id=t,this._clearFn=e}e.setTimeout=function(){return new i(o.call(setTimeout,n,arguments),clearTimeout)},e.setInterval=function(){return new i(o.call(setInterval,n,arguments),clearInterval)},e.clearTimeout=e.clearInterval=function(t){t&&t.close()},i.prototype.unref=i.prototype.ref=function(){},i.prototype.close=function(){this._clearFn.call(n,this._id)},e.enroll=function(t,e){clearTimeout(t._idleTimeoutId),t._idleTimeout=e},e.unenroll=function(t){clearTimeout(t._idleTimeoutId),t._idleTimeout=-1},e._unrefActive=e.active=function(t){clearTimeout(t._idleTimeoutId);var e=t._idleTimeout;e>=0&&(t._idleTimeoutId=setTimeout((function(){t._onTimeout&&t._onTimeout()}),e))},r("6017"),e.setImmediate="undefined"!==typeof self&&self.setImmediate||"undefined"!==typeof t&&t.setImmediate||this&&this.setImmediate,e.clearImmediate="undefined"!==typeof self&&self.clearImmediate||"undefined"!==typeof t&&t.clearImmediate||this&&this.clearImmediate}).call(this,r("c8ba"))},"5bcc":function(t,e,r){},6017:function(t,e,r){(function(t,e){(function(t,r){"use strict";if(!t.setImmediate){var n,o=1,i={},s=!1,c=t.document,u=Object.getPrototypeOf&&Object.getPrototypeOf(t);u=u&&u.setTimeout?u:t,"[object process]"==={}.toString.call(t.process)?h():p()?m():t.MessageChannel?v():c&&"onreadystatechange"in c.createElement("script")?y():g(),u.setImmediate=a,u.clearImmediate=l}function a(t){"function"!==typeof t&&(t=new Function(""+t));for(var e=new Array(arguments.length-1),r=0;r([\\d\\D]*?)<\\/script>[\\d\\D]*","i"),o=r.replace(n,"$1").trim());for(var d=0;d=0;--i){var s=this.tryEntries[i],c=s.completion;if("root"===s.tryLoc)return o("end");if(s.tryLoc<=this.prev){var u=n.call(s,"catchLoc"),a=n.call(s,"finallyLoc");if(u&&a){if(this.prev=0;--r){var o=this.tryEntries[r];if(o.tryLoc<=this.prev&&n.call(o,"finallyLoc")&&this.prev=0;--e){var r=this.tryEntries[e];if(r.finallyLoc===t)return this.complete(r.completion,r.afterLoc),j(r),m}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var r=this.tryEntries[e];if(r.tryLoc===t){var n=r.completion;if("throw"===n.type){var o=n.arg;j(r)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(t,r,n){return this.delegate={iterator:L(t),resultName:r,nextLoc:n},"next"===this.method&&(this.arg=e),m}},t}(t.exports);try{regeneratorRuntime=n}catch(o){Function("r","regeneratorRuntime = r")(n)}},a34a:function(t,e,r){t.exports=r("96cf")},ab2f:function(t,e,r){"use strict";r("b6b5")},b6b5:function(t,e,r){},b7a4:function(t,e,r){"use strict";var n=function(){var t=this,e=t.$createElement,r=t._self._c||e;return t.destroyed?t._e():r("div",{directives:[{name:"show",rawName:"v-show",value:t.loaded,expression:"loaded"}],ref:"cursor",staticClass:"cursor-fx",class:t.classes,style:t.cssVars,attrs:{id:t.id}},[r("div",{directives:[{name:"show",rawName:"v-show",value:!t.hideOutside,expression:"! hideOutside"}],staticClass:"cursor-fx__inner cursor-fx__inner__outside",style:t.outsideSizes}),r("div",{directives:[{name:"show",rawName:"v-show",value:!!t.$slots.default||!!t.$scopedSlots.default||t.forceCustomSlot,expression:"( !! $slots.default || !! $scopedSlots.default ) || forceCustomSlot"}],staticClass:"cursor-fx__inner cursor-fx__inner__custom",style:t.outsideSizes},[t._t("default")],2),r("div",{directives:[{name:"show",rawName:"v-show",value:!t.hideInside,expression:"! hideInside"}],staticClass:"cursor-fx__inner cursor-fx__inner__inside",style:t.insideSizes})])},o=[],i=r("a34a"),s=r.n(i),c=r("5118");function u(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),r.push.apply(r,n)}return r}function a(t){for(var e=1;e1&&void 0!==arguments[1]?arguments[1]:{};if(f(this,t),this.DOM={el:n},this.$options=Object.freeze(a({mixBlendMode:null,lerps:{dot:1,circle:.18,custom:.23},scale:{ratio:.18,min:p,max:m},opacity:.1},i)),this.DOM.dot=this.DOM.el.querySelector("".concat(o,"__inner__inside")),this.DOM.circle=this.DOM.el.querySelector("".concat(o,"__inner__outside")),this.DOM.custom=this.DOM.el.querySelector("".concat(o,"__inner__custom")),this.bounds={dot:this.DOM.dot?this.DOM.dot.getBoundingClientRect():null,circle:this.DOM.circle?this.DOM.circle.getBoundingClientRect():null,custom:this.DOM.custom?this.DOM.custom.getBoundingClientRect():null},this.bounds.dot&&!this.bounds.dot.width){var s=window.getComputedStyle(this.DOM.dot);this.bounds.dot.width=parseInt(s.getPropertyValue("width").replace("px","")),this.bounds.dot.height=parseInt(s.getPropertyValue("height").replace("px",""))}if(this.bounds.circle&&!this.bounds.circle.width){var c=window.getComputedStyle(this.DOM.circle);this.bounds.circle.width=parseInt(c.getPropertyValue("width").replace("px","")),this.bounds.circle.height=parseInt(c.getPropertyValue("height").replace("px",""))}if(this.bounds.custom&&!this.bounds.custom.width){var u=window.getComputedStyle(this.DOM.custom);this.bounds.custom.width=parseInt(u.getPropertyValue("width").replace("px","")),this.bounds.custom.height=parseInt(u.getPropertyValue("height").replace("px",""))}this.scale=this.$options.scale.min,this.lastScale=this.$options.scale.max,this.opacity=this.$options.opacity,this.lastOpacity=1,this.mousePos={x:0,y:0},this.lastMousePos={dot:this.DOM.dot?this.DOM.dot.getBoundingClientRect():{top:0,left:0},custom:this.DOM.custom?this.DOM.custom.getBoundingClientRect():{top:0,left:0},circle:this.DOM.circle?this.DOM.circle.getBoundingClientRect():{top:0,left:0}},this.initEvents(),this.$raf=requestAnimationFrame((function(){return r.render()}))}return h(t,[{key:"initEvents",value:function(){var t=this,e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],r=function(e){return t.mousePos=y(e)};window.removeEventListener("mousemove",r,!1),e&&window.addEventListener("mousemove",r,!1)}},{key:"render",value:function(){var t=this;this.$raf=requestAnimationFrame((function(){return t.render()}));var e=this.$options,r=e.lerps,n=r.dot,o=r.circle,i=r.custom,s=e.scale.ratio,c=e.opacity;this.lastScale=v(this.lastScale,this.scale,s),this.lastOpacity=v(this.lastOpacity,this.opacity,c),this.bounds.dot&&(this.lastMousePos.dot.x=v(this.lastMousePos.dot.x,this.mousePos.x-this.bounds.dot.width/2,n),this.lastMousePos.dot.y=v(this.lastMousePos.dot.y,this.mousePos.y-this.bounds.dot.height/2,n),this.DOM.dot.style.transform="translate3d(".concat(this.lastMousePos.dot.x,"px, ").concat(this.lastMousePos.dot.y,"px, 0)")),this.bounds.circle&&(this.lastMousePos.circle.x=v(this.lastMousePos.circle.x,this.mousePos.x-this.bounds.circle.width/2,o),this.lastMousePos.circle.y=v(this.lastMousePos.circle.y,this.mousePos.y-this.bounds.circle.height/2,o),this.DOM.circle.style.transform="translate3d(".concat(this.lastMousePos.circle.x,"px, ").concat(this.lastMousePos.circle.y,"px, 0) scale(").concat(this.lastScale,")")),this.bounds.custom&&(this.lastMousePos.custom.x=v(this.lastMousePos.custom.x,this.mousePos.x-this.bounds.custom.width/2,i),this.lastMousePos.custom.y=v(this.lastMousePos.custom.y,this.mousePos.y-this.bounds.custom.height/2,i),this.DOM.custom.style.transform="translate3d(".concat(this.lastMousePos.custom.x,"px, ").concat(this.lastMousePos.custom.y,"px, 0) scale(").concat(this.lastScale,")"))}},{key:"destroy",value:function(){this.$raf&&cancelAnimationFrame(this.$raf),this.initEvents(!1),this.DOM=null}},{key:"enter",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.$options.scale.max;this.scale=t}},{key:"leave",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.$options.scale.min;this.scale=t}},{key:"click",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.$options.scale.min,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;this.lastScale=t,this.lastOpacity=e}},{key:"enterHidden",value:function(){this.DOM&&(this.DOM.el.style.visibility="hidden")}},{key:"leaveHidden",value:function(){this.DOM&&(this.DOM.el.style.visibility="visible")}},{key:"mixBlendMode",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.$options.mixBlendMode;this.DOM&&(this.DOM.el.style.mixBlendMode=t||null)}}]),t}();function b(t,e,r,n,o,i,s){try{var c=t[i](s),u=c.value}catch(a){return void r(a)}c.done?e(u):Promise.resolve(u).then(n,o)}function w(t){return function(){var e=this,r=arguments;return new Promise((function(n,o){var i=t.apply(e,r);function s(t){b(i,n,o,s,c,"next",t)}function c(t){b(i,n,o,s,c,"throw",t)}s(void 0)}))}}function x(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),r.push.apply(r,n)}return r}function O(t){for(var e=1;et.length)&&(e=t.length);for(var r=0,n=new Array(e);r0||navigator.msMaxTouchPoints>0},cursorHover:function(){this.hover=!0,this.$cursor&&this.$cursor.enter()},cursorLeave:function(){this.hover=!1,this.$cursor&&this.$cursor.leave()},cursorClick:function(){this.$cursor&&this.$cursor.click()},cursorEnterHidden:function(){this.$cursor&&this.$cursor.enterHidden()},cursorLeaveHidden:function(){this.$cursor&&this.$cursor.leaveHidden()},cursorMixBlendMode:function(t){var e,r,n;this.$cursor&&this.$cursor.mixBlendMode(null!==(e=null===t||void 0===t||null===(r=t.target)||void 0===r||null===(n=r.dataset)||void 0===n?void 0:n.cursorMixBlendMode)&&void 0!==e?e:null)},initEvents:function(){var t=this;M(document.querySelectorAll("[data-cursor-hover]")).forEach((function(e){e.addEventListener("mouseenter",t.cursorHover,!1),e.addEventListener("mouseleave",t.cursorLeave,!1),e.addEventListener("click",t.cursorClick,!1)})),M(document.querySelectorAll("[data-cursor-hidden]")).forEach((function(e){e.addEventListener("mouseenter",t.cursorEnterHidden,!1),e.addEventListener("mouseleave",t.cursorLeaveHidden,!1)})),M(document.querySelectorAll("[data-cursor-mix-blend-mode]")).forEach((function(e){e.addEventListener("mouseenter",t.cursorMixBlendMode,!1),e.addEventListener("mouseleave",t.cursorMixBlendMode,!1)}))},init:function(){var t=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];this.$cursor=new g({el:this.$refs.cursor,base_class:".cursor-fx"},O({mixBlendMode:this.mixBlendMode},this.config)),t&&this.initEvents(),this.loaded=!0,this.$emit("ready",this.$cursor),document.documentElement.classList.add("is-cursor-fx-active"),this.$emit("after-start")},destroy:function(){var t=arguments,e=this;return w(s.a.mark((function r(){var n;return s.a.wrap((function(r){while(1)switch(r.prev=r.next){case 0:return n=t.length>0&&void 0!==t[0]&&t[0],e.$emit("before-destroy"),e.destroyTimeout(),document.documentElement.classList.remove("is-cursor-fx-active"),e.loaded=!1,M(document.querySelectorAll("[data-cursor-hover]")).forEach((function(t){t.removeEventListener("mouseenter",e.cursorLeave,!1),t.removeEventListener("mouseleave",e.cursorLeave,!1),t.removeEventListener("click",e.cursorClick,!1)})),M(document.querySelectorAll("[data-cursor-hidden]")).forEach((function(t){t.removeEventListener("mouseenter",e.cursorEnterHidden,!1),t.removeEventListener("mouseleave",e.cursorLeaveHidden,!1)})),M(document.querySelectorAll("[data-cursor-mix-blend-mode]")).forEach((function(t){t.removeEventListener("mouseenter",e.cursorMixBlendMode,!1),t.removeEventListener("mouseleave",e.cursorMixBlendMode,!1)})),r.next=10,e.$nextTick();case 10:e.$cursor&&e.$cursor.destroy(),e.$cursor=null,e.destroyed=!0,e.$emit("after-destroy"),n&&e.start();case 15:case"end":return r.stop()}}),r)})))()},start:function(){var t=this;return w(s.a.mark((function e(){return s.a.wrap((function(e){while(1)switch(e.prev=e.next){case 0:if(t.destroyed){e.next=2;break}return e.abrupt("return");case 2:return t.destroyed=!1,t.destroyTimeout(),e.next=6,t.$nextTick();case 6:t.$emit("before-start"),t.$timeout=Object(c["setTimeout"])((function(){return t.init()}),parseInt(t.delay));case 8:case"end":return e.stop()}}),e)})))()},refresh:function(){this.destroy(!0)},destroyTimeout:function(){this.$timeout&&Object(c["clearTimeout"])(this.$timeout)}}},T=L;r("ab2f"),r("1c95");function k(t,e,r,n,o,i,s,c){var u,a="function"===typeof t?t.options:t;if(e&&(a.render=e,a.staticRenderFns=r,a._compiled=!0),n&&(a.functional=!0),i&&(a._scopeId="data-v-"+i),s?(u=function(t){t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,t||"undefined"===typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),o&&o.call(this,t),t&&t._registeredComponents&&t._registeredComponents.add(s)},a._ssrRegister=u):o&&(u=c?function(){o.call(this,(a.functional?this.parent:this).$root.$options.shadowRoot)}:o),u)if(a.functional){a._injectStyles=u;var l=a.render;a.render=function(t,e){return u.call(e),l(t,e)}}else{var f=a.beforeCreate;a.beforeCreate=f?[].concat(f,u):[u]}return{exports:t,options:a}}var D=k(T,n,o,!1,null,"f3f73494",null);e["a"]=D.exports},c8ba:function(t,e){var r;r=function(){return this}();try{r=r||new Function("return this")()}catch(n){"object"===typeof window&&(r=window)}t.exports=r},df7c:function(t,e,r){(function(t){function r(t,e){for(var r=0,n=t.length-1;n>=0;n--){var o=t[n];"."===o?t.splice(n,1):".."===o?(t.splice(n,1),r++):r&&(t.splice(n,1),r--)}if(e)for(;r--;r)t.unshift("..");return t}function n(t){"string"!==typeof t&&(t+="");var e,r=0,n=-1,o=!0;for(e=t.length-1;e>=0;--e)if(47===t.charCodeAt(e)){if(!o){r=e+1;break}}else-1===n&&(o=!1,n=e+1);return-1===n?"":t.slice(r,n)}function o(t,e){if(t.filter)return t.filter(e);for(var r=[],n=0;n=-1&&!n;i--){var s=i>=0?arguments[i]:t.cwd();if("string"!==typeof s)throw new TypeError("Arguments to path.resolve must be strings");s&&(e=s+"/"+e,n="/"===s.charAt(0))}return e=r(o(e.split("/"),(function(t){return!!t})),!n).join("/"),(n?"/":"")+e||"."},e.normalize=function(t){var n=e.isAbsolute(t),s="/"===i(t,-1);return t=r(o(t.split("/"),(function(t){return!!t})),!n).join("/"),t||n||(t="."),t&&s&&(t+="/"),(n?"/":"")+t},e.isAbsolute=function(t){return"/"===t.charAt(0)},e.join=function(){var t=Array.prototype.slice.call(arguments,0);return e.normalize(o(t,(function(t,e){if("string"!==typeof t)throw new TypeError("Arguments to path.join must be strings");return t})).join("/"))},e.relative=function(t,r){function n(t){for(var e=0;e=0;r--)if(""!==t[r])break;return e>r?[]:t.slice(e,r-e+1)}t=e.resolve(t).substr(1),r=e.resolve(r).substr(1);for(var o=n(t.split("/")),i=n(r.split("/")),s=Math.min(o.length,i.length),c=s,u=0;u=1;--i)if(e=t.charCodeAt(i),47===e){if(!o){n=i;break}}else o=!1;return-1===n?r?"/":".":r&&1===n?"/":t.slice(0,n)},e.basename=function(t,e){var r=n(t);return e&&r.substr(-1*e.length)===e&&(r=r.substr(0,r.length-e.length)),r},e.extname=function(t){"string"!==typeof t&&(t+="");for(var e=-1,r=0,n=-1,o=!0,i=0,s=t.length-1;s>=0;--s){var c=t.charCodeAt(s);if(47!==c)-1===n&&(o=!1,n=s+1),46===c?-1===e?e=s:1!==i&&(i=1):-1!==e&&(i=-1);else if(!o){r=s+1;break}}return-1===e||-1===n||0===i||1===i&&e===n-1&&e===r+1?"":t.slice(e,n)};var i="b"==="ab".substr(-1)?function(t,e,r){return t.substr(e,r)}:function(t,e,r){return e<0&&(e=t.length+e),t.substr(e,r)}}).call(this,r("4362"))},fb15:function(t,e,r){"use strict";if(r.r(e),"undefined"!==typeof window){var n=window.document.currentScript,o=r("8875");n=o(),"currentScript"in document||Object.defineProperty(document,"currentScript",{get:o});var i=n&&n.src.match(/(.+\/)[^/]+\.js(\?.*)?$/);i&&(r.p=i[1])}var s=r("6d28");e["default"]=s["a"]}})["default"]})); --------------------------------------------------------------------------------