├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .stylelintrc ├── CONTRIBUTING.md ├── LICENSE ├── build ├── build.js ├── utils │ ├── index.js │ ├── log.js │ ├── style.js │ └── write.js ├── webpack.config.base.js ├── webpack.config.browser.js ├── webpack.config.common.js ├── webpack.config.dev.js └── webpack.config.dll.js ├── dist ├── ks-vue-fullpage.common.js ├── ks-vue-fullpage.css ├── ks-vue-fullpage.js ├── ks-vue-fullpage.min.css └── ks-vue-fullpage.min.js ├── package.json ├── readme.md ├── src ├── components │ ├── ksvuefp-nav.vue │ ├── ksvuefp-preloader.vue │ ├── ksvuefp-section.vue │ └── ksvuefp.vue ├── defaultOptions.js ├── index.js ├── ksvuefp-animations.js └── utils.js └── test ├── .eslintrc ├── helpers ├── Test.vue ├── index.js ├── utils.js └── wait-for-update.js ├── index.js ├── karma.conf.js ├── specs ├── Hello-jsx.spec.js └── Hello.spec.js └── visual.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "env", 5 | { 6 | "targets": { 7 | "browsers": [ 8 | "last 2 versions" 9 | ] 10 | } 11 | } 12 | ] 13 | ], 14 | "plugins": [ 15 | "transform-object-rest-spread" 16 | ], 17 | "env": { 18 | "test": { 19 | "plugins": [ 20 | "istanbul" 21 | ] 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist/*.js 2 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parser: 'babel-eslint', 4 | parserOptions: { 5 | sourceType: 'module' 6 | }, 7 | extends: 'vue', 8 | // add your custom rules here 9 | 'rules': { 10 | // allow async-await 11 | 'generator-star-spacing': 0, 12 | // allow debugger during development 13 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0 14 | }, 15 | globals: { 16 | requestAnimationFrame: true, 17 | performance: true 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | npm-debug.log 4 | test/coverage 5 | yarn-error.log 6 | reports 7 | -------------------------------------------------------------------------------- /.stylelintrc: -------------------------------------------------------------------------------- 1 | { 2 | "processors": ["stylelint-processor-html"], 3 | "extends": "stylelint-config-standard", 4 | "rules": { 5 | "no-empty-source": null 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions are **welcome** and will be fully **credited**. 4 | 5 | We accept contributions via Pull Requests on [Github](https://github.com/{{ githubAccount }}/{{ name }}). 6 | 7 | 8 | ## Pull Requests 9 | 10 | - **Keep the same style** - eslint will automatically be ran before committing 11 | 12 | - **Tip** to pass lint tests easier use the `npm run lint:fix` command 13 | 14 | - **Add tests!** - Your patch won't be accepted if it doesn't have tests. 15 | 16 | - **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date. 17 | 18 | - **Consider our release cycle** - We try to follow [SemVer v2.0.0](http://semver.org/). Randomly breaking public APIs is not an option. 19 | 20 | - **Create feature branches** - Don't ask us to pull from your master branch. 21 | 22 | - **One pull request per feature** - If you want to do more than one thing, send multiple pull requests. 23 | 24 | - **Send coherent history** - Make sure your commits message means something 25 | 26 | 27 | ## Running Tests 28 | 29 | Launch visual tests and watch the components at the same time 30 | 31 | ``` bash 32 | $ npm run dev 33 | ``` 34 | 35 | 36 | **Happy coding**! 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) {{ nowYear }} {{ authorFullNameFrom author }} 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | 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, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /build/build.js: -------------------------------------------------------------------------------- 1 | const mkdirp = require('mkdirp') 2 | const rollup = require('rollup').rollup 3 | const vue = require('rollup-plugin-vue') 4 | const jsx = require('rollup-plugin-jsx') 5 | const buble = require('rollup-plugin-buble') 6 | const replace = require('rollup-plugin-replace') 7 | const cjs = require('rollup-plugin-commonjs') 8 | const node = require('rollup-plugin-node-resolve') 9 | const uglify = require('uglify-js') 10 | const CleanCSS = require('clean-css') 11 | 12 | // Make sure dist dir exists 13 | mkdirp('dist') 14 | 15 | const { 16 | logError, 17 | write, 18 | banner, 19 | name, 20 | moduleName, 21 | version, 22 | processStyle 23 | } = require('./utils') 24 | 25 | function rollupBundle ({ env }) { 26 | return rollup({ 27 | entry: 'src/index.js', 28 | plugins: [ 29 | node({ 30 | extensions: ['.js', '.jsx', '.vue'] 31 | }), 32 | cjs(), 33 | vue({ 34 | compileTemplate: true, 35 | css (styles, stylesNodes) { 36 | // Only generate the styles once 37 | if (env['process.env.NODE_ENV'] === '"production"') { 38 | Promise.all( 39 | stylesNodes.map(processStyle) 40 | ).then(css => { 41 | const result = css.map(c => c.css).join('') 42 | // write the css for every component 43 | // TODO add it back if we extract all components to individual js 44 | // files too 45 | // css.forEach(writeCss) 46 | write(`dist/${name}.css`, result) 47 | write(`dist/${name}.min.css`, new CleanCSS().minify(result).styles) 48 | }).catch(logError) 49 | } 50 | } 51 | }), 52 | jsx({ factory: 'h' }), 53 | replace(Object.assign({ 54 | __VERSION__: version 55 | }, env)), 56 | buble({ 57 | objectAssign: 'Object.assign' 58 | }) 59 | ] 60 | }) 61 | } 62 | 63 | const bundleOptions = { 64 | banner, 65 | exports: 'named', 66 | format: 'umd', 67 | moduleName 68 | } 69 | 70 | function createBundle ({ name, env, format }) { 71 | return rollupBundle({ 72 | env 73 | }).then(function (bundle) { 74 | const options = Object.assign({}, bundleOptions) 75 | if (format) options.format = format 76 | const code = bundle.generate(options).code 77 | if (/min$/.test(name)) { 78 | const minified = uglify.minify(code, { 79 | output: { 80 | preamble: banner, 81 | ascii_only: true // eslint-disable-line camelcase 82 | } 83 | }).code 84 | return write(`dist/${name}.js`, minified) 85 | } else { 86 | return write(`dist/${name}.js`, code) 87 | } 88 | }).catch(logError) 89 | } 90 | 91 | // Browser bundle (can be used with script) 92 | createBundle({ 93 | name: `${name}`, 94 | env: { 95 | 'process.env.NODE_ENV': '"development"' 96 | } 97 | }) 98 | 99 | // Commonjs bundle (preserves process.env.NODE_ENV) so 100 | // the user can replace it in dev and prod mode 101 | createBundle({ 102 | name: `${name}.common`, 103 | env: {}, 104 | format: 'cjs' 105 | }) 106 | 107 | // uses export and import syntax. Should be used with modern bundlers 108 | // like rollup and webpack 2 109 | createBundle({ 110 | name: `${name}.esm`, 111 | env: {}, 112 | format: 'es' 113 | }) 114 | 115 | // Minified version for browser 116 | createBundle({ 117 | name: `${name}.min`, 118 | env: { 119 | 'process.env.NODE_ENV': '"production"' 120 | } 121 | }) 122 | -------------------------------------------------------------------------------- /build/utils/index.js: -------------------------------------------------------------------------------- 1 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 2 | const { join } = require('path') 3 | 4 | const { 5 | red, 6 | logError 7 | } = require('./log') 8 | 9 | const { 10 | processStyle 11 | } = require('./style') 12 | 13 | const uppercamelcase = require('uppercamelcase') 14 | 15 | exports.write = require('./write') 16 | 17 | const { 18 | author, 19 | name, 20 | version, 21 | dllPlugin 22 | } = require('../../package.json') 23 | 24 | const authorName = author.replace(/\s+<.*/, '') 25 | const minExt = process.env.NODE_ENV === 'production' ? '.min' : '' 26 | 27 | exports.author = authorName 28 | exports.version = version 29 | exports.dllName = dllPlugin.name 30 | exports.moduleName = uppercamelcase(name) 31 | exports.name = name 32 | exports.filename = name + minExt 33 | exports.banner = `/*! 34 | * ${name} v${version} 35 | * (c) ${new Date().getFullYear()} ${authorName} 36 | * Released under the MIT License. 37 | */ 38 | ` 39 | 40 | // log.js 41 | exports.red = red 42 | exports.logError = logError 43 | 44 | // It'd be better to add a sass property to the vue-loader options 45 | // but it simply don't work 46 | const sassOptions = { 47 | includePaths: [ 48 | join(__dirname, '../../node_modules') 49 | ] 50 | } 51 | 52 | // don't extract css in test mode 53 | const nullLoader = process.env.NODE_ENV === 'common' ? 'null-loader!' : '' 54 | exports.vueLoaders = 55 | process.env.BABEL_ENV === 'test' ? { 56 | css: 'css-loader', 57 | scss: `css-loader!sass-loader?${JSON.stringify(sassOptions)}` 58 | } : { 59 | css: ExtractTextPlugin.extract(`${nullLoader}css-loader`), 60 | scss: ExtractTextPlugin.extract( 61 | `${nullLoader}css-loader!sass-loader?${JSON.stringify(sassOptions)}` 62 | ) 63 | } 64 | 65 | // style.js 66 | exports.processStyle = processStyle 67 | -------------------------------------------------------------------------------- /build/utils/log.js: -------------------------------------------------------------------------------- 1 | function logError (e) { 2 | console.log(e) 3 | } 4 | 5 | function blue (str) { 6 | return `\x1b[1m\x1b[34m${str}\x1b[39m\x1b[22m` 7 | } 8 | 9 | function green (str) { 10 | return `\x1b[1m\x1b[32m${str}\x1b[39m\x1b[22m` 11 | } 12 | 13 | function red (str) { 14 | return `\x1b[1m\x1b[31m${str}\x1b[39m\x1b[22m` 15 | } 16 | 17 | function yellow (str) { 18 | return `\x1b[1m\x1b[33m${str}\x1b[39m\x1b[22m` 19 | } 20 | 21 | module.exports = { 22 | blue, 23 | green, 24 | red, 25 | yellow, 26 | logError 27 | } 28 | -------------------------------------------------------------------------------- /build/utils/style.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const postcss = require('postcss') 3 | const cssnext = require('postcss-cssnext') 4 | const CleanCSS = require('clean-css') 5 | const { logError } = require('./log.js') 6 | const write = require('./write.js') 7 | 8 | function processCss (style) { 9 | const componentName = path.basename(style.id, '.vue') 10 | return postcss([cssnext()]) 11 | .process(style.code, {}) 12 | .then(result => { 13 | return { 14 | name: componentName, 15 | css: result.css, 16 | map: result.map 17 | } 18 | }) 19 | } 20 | 21 | let stylus 22 | function processStylus (style) { 23 | try { 24 | stylus = stylus || require('stylus') 25 | } catch (e) { 26 | logError(e) 27 | } 28 | const componentName = path.basename(style.id, '.vue') 29 | return new Promise((resolve, reject) => { 30 | stylus.render(style.code, function (err, css) { 31 | if (err) return reject(err) 32 | resolve({ 33 | original: { 34 | code: style.code, 35 | ext: 'styl' 36 | }, 37 | name: componentName, 38 | css 39 | }) 40 | }) 41 | }) 42 | } 43 | 44 | function processStyle (style) { 45 | if (style.lang === 'css') { 46 | return processCss(style) 47 | } else if (style.lang === 'stylus') { 48 | return processStylus(style) 49 | } else { 50 | throw new Error(`Unknown style language '${style.lang}'`) 51 | } 52 | } 53 | 54 | function writeCss (style) { 55 | write(`dist/${style.name}.css`, style.css) 56 | if (style.original) { 57 | write(`dist/${style.name}.${style.original.ext}`, style.original.code) 58 | } 59 | if (style.map) write(`dist/${style.name}.css.map`, style.map) 60 | write(`dist/${style.name}.min.css`, new CleanCSS().minify(style.css).styles) 61 | } 62 | 63 | module.exports = { 64 | writeCss, 65 | processStyle 66 | } 67 | -------------------------------------------------------------------------------- /build/utils/write.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | 3 | const { blue } = require('./log.js') 4 | 5 | function write (dest, code) { 6 | return new Promise(function (resolve, reject) { 7 | fs.writeFile(dest, code, function (err) { 8 | if (err) return reject(err) 9 | console.log(blue(dest) + ' ' + getSize(code)) 10 | resolve(code) 11 | }) 12 | }) 13 | } 14 | 15 | function getSize (code) { 16 | return (code.length / 1024).toFixed(2) + 'kb' 17 | } 18 | 19 | module.exports = write 20 | -------------------------------------------------------------------------------- /build/webpack.config.base.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack') 2 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 3 | const { resolve } = require('path') 4 | 5 | const { 6 | banner, 7 | filename, 8 | version, 9 | vueLoaders 10 | } = require('./utils') 11 | 12 | const plugins = [ 13 | new webpack.DefinePlugin({ 14 | '__VERSION__': JSON.stringify(version), 15 | 'process.env.NODE_ENV': '"test"' 16 | }), 17 | new webpack.BannerPlugin({ banner, raw: true, entryOnly: true }), 18 | new ExtractTextPlugin({ 19 | filename: `${filename}.css`, 20 | // Don't extract css in test mode 21 | disable: /^(common|test)$/.test(process.env.NODE_ENV) 22 | }) 23 | ] 24 | 25 | module.exports = { 26 | output: { 27 | path: resolve(__dirname, '../dist'), 28 | filename: `${filename}.common.js` 29 | }, 30 | entry: './src/index.js', 31 | resolve: { 32 | extensions: ['.js', '.vue', '.jsx', 'css'], 33 | alias: { 34 | 'src': resolve(__dirname, '../src') 35 | } 36 | }, 37 | module: { 38 | rules: [ 39 | { 40 | test: /.jsx?$/, 41 | use: 'babel-loader', 42 | include: [ 43 | resolve(__dirname, '../node_modules/@material'), 44 | resolve(__dirname, '../src'), 45 | resolve(__dirname, '../test') 46 | ] 47 | }, 48 | { 49 | test: /\.vue$/, 50 | loader: 'vue-loader', 51 | options: { 52 | loaders: vueLoaders, 53 | postcss: [require('postcss-cssnext')()] 54 | } 55 | }, 56 | { 57 | test: require.resolve('velocity-animate'), 58 | use: [{ 59 | loader: 'expose-loader', 60 | options: 'Velocity' 61 | }] 62 | }, 63 | { 64 | test: require.resolve('hammerjs'), 65 | use: [{ 66 | loader: 'expose-loader', 67 | options: 'Hammer' 68 | }] 69 | } 70 | ] 71 | }, 72 | plugins 73 | } 74 | -------------------------------------------------------------------------------- /build/webpack.config.browser.js: -------------------------------------------------------------------------------- 1 | const merge = require('webpack-merge') 2 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 3 | const base = require('./webpack.config.base') 4 | const { resolve } = require('path') 5 | const { 6 | filename, 7 | moduleName, 8 | vueLoaders 9 | } = require('./utils') 10 | 11 | module.exports = merge(base, { 12 | output: { 13 | filename: `${filename}.js`, 14 | library: moduleName, 15 | libraryTarget: 'umd' 16 | }, 17 | module: { 18 | rules: [ 19 | { 20 | test: /.scss$/, 21 | use: vueLoaders.scss, 22 | include: [ 23 | resolve(__dirname, '../node_modules/@material'), 24 | resolve(__dirname, '../src') 25 | ] 26 | } 27 | ] 28 | }, 29 | plugins: [ 30 | new BundleAnalyzerPlugin({ 31 | analyzerMode: 'static', 32 | openAnalyzer: false, 33 | reportFilename: resolve(__dirname, `../reports/${process.env.NODE_ENV}.html`) 34 | }) 35 | ] 36 | }) 37 | -------------------------------------------------------------------------------- /build/webpack.config.common.js: -------------------------------------------------------------------------------- 1 | const merge = require('webpack-merge') 2 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 3 | const base = require('./webpack.config.base') 4 | const { resolve } = require('path') 5 | const { vueLoaders } = require('./utils') 6 | 7 | module.exports = merge(base, { 8 | output: { 9 | libraryTarget: 'commonjs2' 10 | }, 11 | target: 'node', 12 | module: { 13 | rules: [ 14 | { 15 | test: /.scss$/, 16 | use: vueLoaders.scss, 17 | include: [ 18 | resolve(__dirname, '../node_modules/@material'), 19 | resolve(__dirname, '../src') 20 | ] 21 | } 22 | ] 23 | }, 24 | plugins: [ 25 | new BundleAnalyzerPlugin({ 26 | analyzerMode: 'static', 27 | openAnalyzer: false, 28 | reportFilename: resolve(__dirname, `../reports/${process.env.NODE_ENV}.html`) 29 | }) 30 | ] 31 | }) 32 | -------------------------------------------------------------------------------- /build/webpack.config.dev.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack') 2 | const merge = require('webpack-merge') 3 | const HtmlWebpackPlugin = require('html-webpack-plugin') 4 | const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin') 5 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 6 | const DashboardPlugin = require('webpack-dashboard/plugin') 7 | const base = require('./webpack.config.base') 8 | const { resolve, join } = require('path') 9 | const { existsSync } = require('fs') 10 | const { 11 | dllName, 12 | logError, 13 | red, 14 | vueLoaders 15 | } = require('./utils') 16 | 17 | const rootDir = resolve(__dirname, '../test') 18 | const buildPath = resolve(rootDir, 'dist') 19 | 20 | if (!existsSync(join(buildPath, dllName) + '.dll.js')) { 21 | logError(red('The DLL manifest is missing. Please run `npm run build:dll` (Quit this with `q`)')) 22 | process.exit(1) 23 | } 24 | 25 | const dllManifest = require( 26 | join(buildPath, dllName) + '.json' 27 | ) 28 | 29 | module.exports = merge(base, { 30 | entry: { 31 | tests: resolve(rootDir, 'visual.js') 32 | }, 33 | output: { 34 | path: buildPath, 35 | filename: '[name].js', 36 | chunkFilename: '[id].js' 37 | }, 38 | module: { 39 | rules: [ 40 | { 41 | test: /.scss$/, 42 | loader: vueLoaders.scss, 43 | include: [ 44 | resolve(__dirname, '../node_modules/@material'), 45 | resolve(__dirname, '../src') 46 | ] 47 | } 48 | ] 49 | }, 50 | plugins: [ 51 | new webpack.DllReferencePlugin({ 52 | context: join(__dirname, '..'), 53 | manifest: dllManifest 54 | }), 55 | new HtmlWebpackPlugin({ 56 | chunkSortMode: 'dependency' 57 | }), 58 | new AddAssetHtmlPlugin({ 59 | filepath: require.resolve( 60 | join(buildPath, dllName) + '.dll.js' 61 | ) 62 | }), 63 | new webpack.optimize.CommonsChunkPlugin({ 64 | name: 'vendor', 65 | minChunks (module, count) { 66 | return ( 67 | module.resource && 68 | /\.js$/.test(module.resource) && 69 | module.resource.indexOf(join(__dirname, '../node_modules/')) === 0 70 | ) 71 | } 72 | }), 73 | new webpack.optimize.CommonsChunkPlugin({ 74 | name: 'manifest', 75 | chunks: ['vendor'] 76 | }), 77 | new DashboardPlugin(), 78 | new BundleAnalyzerPlugin({ 79 | analyzerMode: 'static', 80 | openAnalyzer: false, 81 | reportFilename: resolve(__dirname, `../reports/${process.env.NODE_ENV}.html`) 82 | }) 83 | ], 84 | devtool: '#eval-source-map', 85 | devServer: { 86 | inline: true, 87 | stats: { 88 | colors: true, 89 | chunks: false, 90 | cached: false 91 | }, 92 | contentBase: buildPath 93 | }, 94 | performance: { 95 | hints: false 96 | } 97 | }) 98 | -------------------------------------------------------------------------------- /build/webpack.config.dll.js: -------------------------------------------------------------------------------- 1 | const { resolve, join } = require('path') 2 | const webpack = require('webpack') 3 | const pkg = require('../package.json') 4 | 5 | const rootDir = resolve(__dirname, '../test') 6 | const buildPath = resolve(rootDir, 'dist') 7 | 8 | const entry = {} 9 | entry[pkg.dllPlugin.name] = pkg.dllPlugin.include 10 | 11 | module.exports = { 12 | devtool: '#source-map', 13 | entry, 14 | output: { 15 | path: buildPath, 16 | filename: '[name].dll.js', 17 | library: '[name]' 18 | }, 19 | plugins: [ 20 | new webpack.DllPlugin({ 21 | name: '[name]', 22 | path: join(buildPath, '[name].json') 23 | }) 24 | ], 25 | performance: { 26 | hints: false 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /dist/ks-vue-fullpage.common.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * ks-vue-fullpage v1.2.8 3 | * (c) 2017 pirony 4 | * Released under the MIT License. 5 | */ 6 | 7 | module.exports = 8 | /******/ (function(modules) { // webpackBootstrap 9 | /******/ // The module cache 10 | /******/ var installedModules = {}; 11 | /******/ 12 | /******/ // The require function 13 | /******/ function __webpack_require__(moduleId) { 14 | /******/ 15 | /******/ // Check if module is in cache 16 | /******/ if(installedModules[moduleId]) { 17 | /******/ return installedModules[moduleId].exports; 18 | /******/ } 19 | /******/ // Create a new module (and put it into the cache) 20 | /******/ var module = installedModules[moduleId] = { 21 | /******/ i: moduleId, 22 | /******/ l: false, 23 | /******/ exports: {} 24 | /******/ }; 25 | /******/ 26 | /******/ // Execute the module function 27 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 28 | /******/ 29 | /******/ // Flag the module as loaded 30 | /******/ module.l = true; 31 | /******/ 32 | /******/ // Return the exports of the module 33 | /******/ return module.exports; 34 | /******/ } 35 | /******/ 36 | /******/ 37 | /******/ // expose the modules object (__webpack_modules__) 38 | /******/ __webpack_require__.m = modules; 39 | /******/ 40 | /******/ // expose the module cache 41 | /******/ __webpack_require__.c = installedModules; 42 | /******/ 43 | /******/ // identity function for calling harmony imports with the correct context 44 | /******/ __webpack_require__.i = function(value) { return value; }; 45 | /******/ 46 | /******/ // define getter function for harmony exports 47 | /******/ __webpack_require__.d = function(exports, name, getter) { 48 | /******/ if(!__webpack_require__.o(exports, name)) { 49 | /******/ Object.defineProperty(exports, name, { 50 | /******/ configurable: false, 51 | /******/ enumerable: true, 52 | /******/ get: getter 53 | /******/ }); 54 | /******/ } 55 | /******/ }; 56 | /******/ 57 | /******/ // getDefaultExport function for compatibility with non-harmony modules 58 | /******/ __webpack_require__.n = function(module) { 59 | /******/ var getter = module && module.__esModule ? 60 | /******/ function getDefault() { return module['default']; } : 61 | /******/ function getModuleExports() { return module; }; 62 | /******/ __webpack_require__.d(getter, 'a', getter); 63 | /******/ return getter; 64 | /******/ }; 65 | /******/ 66 | /******/ // Object.prototype.hasOwnProperty.call 67 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 68 | /******/ 69 | /******/ // __webpack_public_path__ 70 | /******/ __webpack_require__.p = ""; 71 | /******/ 72 | /******/ // Load entry module and return exports 73 | /******/ return __webpack_require__(__webpack_require__.s = 10); 74 | /******/ }) 75 | /************************************************************************/ 76 | /******/ ([ 77 | /* 0 */ 78 | /***/ (function(module, exports) { 79 | 80 | /* globals __VUE_SSR_CONTEXT__ */ 81 | 82 | // this module is a runtime utility for cleaner component module output and will 83 | // be included in the final webpack user bundle 84 | 85 | module.exports = function normalizeComponent ( 86 | rawScriptExports, 87 | compiledTemplate, 88 | injectStyles, 89 | scopeId, 90 | moduleIdentifier /* server only */ 91 | ) { 92 | var esModule 93 | var scriptExports = rawScriptExports = rawScriptExports || {} 94 | 95 | // ES6 modules interop 96 | var type = typeof rawScriptExports.default 97 | if (type === 'object' || type === 'function') { 98 | esModule = rawScriptExports 99 | scriptExports = rawScriptExports.default 100 | } 101 | 102 | // Vue.extend constructor export interop 103 | var options = typeof scriptExports === 'function' 104 | ? scriptExports.options 105 | : scriptExports 106 | 107 | // render functions 108 | if (compiledTemplate) { 109 | options.render = compiledTemplate.render 110 | options.staticRenderFns = compiledTemplate.staticRenderFns 111 | } 112 | 113 | // scopedId 114 | if (scopeId) { 115 | options._scopeId = scopeId 116 | } 117 | 118 | var hook 119 | if (moduleIdentifier) { // server build 120 | hook = function (context) { 121 | // 2.3 injection 122 | context = 123 | context || // cached call 124 | (this.$vnode && this.$vnode.ssrContext) || // stateful 125 | (this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext) // functional 126 | // 2.2 with runInNewContext: true 127 | if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') { 128 | context = __VUE_SSR_CONTEXT__ 129 | } 130 | // inject component styles 131 | if (injectStyles) { 132 | injectStyles.call(this, context) 133 | } 134 | // register component module identifier for async chunk inferrence 135 | if (context && context._registeredComponents) { 136 | context._registeredComponents.add(moduleIdentifier) 137 | } 138 | } 139 | // used by ssr in case component is cached and beforeCreate 140 | // never gets called 141 | options._ssrRegister = hook 142 | } else if (injectStyles) { 143 | hook = injectStyles 144 | } 145 | 146 | if (hook) { 147 | var functional = options.functional 148 | var existing = functional 149 | ? options.render 150 | : options.beforeCreate 151 | if (!functional) { 152 | // inject component registration as beforeCreate hook 153 | options.beforeCreate = existing 154 | ? [].concat(existing, hook) 155 | : [hook] 156 | } else { 157 | // register for functioal component in vue file 158 | options.render = function renderWithStyleInjection (h, context) { 159 | hook.call(context) 160 | return existing(h, context) 161 | } 162 | } 163 | } 164 | 165 | return { 166 | esModule: esModule, 167 | exports: scriptExports, 168 | options: options 169 | } 170 | } 171 | 172 | 173 | /***/ }), 174 | /* 1 */ 175 | /***/ (function(module, exports, __webpack_require__) { 176 | 177 | "use strict"; 178 | 179 | 180 | Object.defineProperty(exports, "__esModule", { 181 | value: true 182 | }); 183 | exports.default = { 184 | bgOffset: function bgOffset(action, direction, offset) { 185 | var res = void 0; 186 | switch (action) { 187 | case 'enter': 188 | res = direction === 'up' ? offset || '0.5' : offset * -1 || '-0.5'; 189 | break; 190 | case 'leave': 191 | res = direction === 'up' ? offset * -1 || '-0.5' : offset || '0.5'; 192 | break; 193 | } 194 | 195 | return res; 196 | }, 197 | getDirection: function getDirection(e, animType) { 198 | e = e || window.event; 199 | switch (e.type) { 200 | case 'mousewheel': 201 | case 'wheel': 202 | var delta = (e.deltaY || -e.wheelDelta || e.detail) >> 10 || 1; 203 | if (delta < 0) return 'up'; 204 | return 'down'; 205 | case 'keydown': 206 | switch (e.key) { 207 | case 'ArrowDown': 208 | if (animType !== 'slideY') return 'none'; 209 | return 'down'; 210 | case 'ArrowUp': 211 | if (animType !== 'slideY') return 'none'; 212 | return 'up'; 213 | case 'ArrowLeft': 214 | if (animType !== 'slideX') return 'none'; 215 | return 'up'; 216 | case 'ArrowRight': 217 | if (animType !== 'slideX') return 'none'; 218 | return 'down'; 219 | default: 220 | return 'none'; // Quit when this doesn't handle the key event. 221 | } 222 | case 'swipeup': 223 | if (animType === 'slideX') return 'none'; 224 | return 'down'; 225 | case 'swipeleft': 226 | if (animType !== 'slideX') return 'none'; 227 | return 'down'; 228 | case 'swipedown': 229 | if (animType === 'slideX') return 'none'; 230 | return 'up'; 231 | case 'swiperight': 232 | if (animType !== 'slideX') return 'none'; 233 | return 'up'; 234 | case 'navclick': 235 | if (e.oldIndex < e.nextIndex) { 236 | return 'down'; 237 | } else { 238 | return 'up'; 239 | } 240 | default: 241 | return 'none'; 242 | 243 | } 244 | }, 245 | getWindowDim: function getWindowDim() { 246 | if (typeof window === 'undefined') global.window = {}; 247 | return { 248 | wHeight: window.innerHeight, 249 | wWidth: window.innerWidth 250 | }; 251 | }, 252 | getNextIndex: function getNextIndex(i, direction, length, options) { 253 | switch (direction) { 254 | case 'down': 255 | if (i !== length - 1) { 256 | i++; 257 | } else { 258 | if (options.loopBottom) i = 0; 259 | if (!options.loopBottom) i = 'none'; 260 | } 261 | break; 262 | case 'up': 263 | if (i !== 0) { 264 | i--; 265 | } else { 266 | if (options.loopTop) i = length - 1; 267 | if (!options.loopTop) i = 'none'; 268 | } 269 | break; 270 | default: 271 | } 272 | return i; 273 | } 274 | }; 275 | 276 | /***/ }), 277 | /* 2 */ 278 | /***/ (function(module, exports, __webpack_require__) { 279 | 280 | "use strict"; 281 | 282 | 283 | Object.defineProperty(exports, "__esModule", { 284 | value: true 285 | }); 286 | exports.dotsAnim = exports.fade = exports.slideY = exports.slideX = undefined; 287 | 288 | var _utils = __webpack_require__(1); 289 | 290 | var _utils2 = _interopRequireDefault(_utils); 291 | 292 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 293 | 294 | /** 295 | * Get animation params and store it in a constant 296 | * @param {object} ctx - the context 297 | * @param el - the element 298 | * @param {function} done - function to trigger when animation is finished 299 | */ 300 | var getAnimParams = function getAnimParams(ctx, el, done) { 301 | return { 302 | easing: ctx.props.options.easing || 'linear', 303 | duration: ctx.props.options.duration || 1000, 304 | complete: function complete() { 305 | // Velocity.hook(el, 'translateX', '0%') 306 | // Velocity.hook(el, 'backgroundPosition', '0 50%') 307 | done(); 308 | } 309 | }; 310 | }; 311 | 312 | // component datas for slideX option 313 | var slideX = exports.slideX = { 314 | 315 | props: ['options', 'slidingActive', 'sliderDirection'], 316 | functional: true, 317 | render: function render(h, ctx) { 318 | if (!ctx.parent.$ksvuefp.fpLoaded) return h('transition', ctx.data, ctx.children); // don't animate until the plugin is fully loaded 319 | 320 | ctx.data.on = { 321 | enter: function enter(el, done) { 322 | var animObj = {}; // empty object where we'll push animations 323 | 324 | if (ctx.props.options.parallax) { 325 | // if parallax is activated 326 | /** 327 | * Get section background's offset and store it in a constant 328 | * @param {string} action - enter or leave 329 | * @param {string} direction - up or down 330 | * @param {float} offset - the parallax offset defined in options 331 | */ 332 | var bgOffset = _utils2.default.bgOffset('enter', ctx.parent.$ksvuefp.sliderDirection, ctx.props.options.parallaxOffset); 333 | 334 | Velocity.hook(el, 'backgroundPositionX', bgOffset * ctx.parent.$ksvuefp.wWidth + 'px'); // Positionate the background before triggering the animation 335 | 336 | animObj['backgroundPosition'] = '0% 50%'; // Push bgPosition animation to our empty object animObj 337 | } 338 | 339 | var start = ctx.parent.$ksvuefp.sliderDirection === 'up' ? '-100%' : '100%'; // Define the full section's translate animation starting offset 340 | Velocity.hook(el, 'translateX', start); // Positionate the full section before triggering the animation 341 | Velocity.hook(el, 'translateY', '0%'); // Positionate the full section before triggering the animation 342 | Velocity.hook(el, 'opacity', 1); 343 | 344 | animObj['translateX'] = '0%'; 345 | animObj['translateZ'] = 0; // Force 3d rendering 346 | 347 | /** 348 | * Get animations params 349 | * @param {object} ctx - the context 350 | * @param {object} animObj - the animObject 351 | * @param {function} animParams - Velocity's animation options 352 | */ 353 | var animParams = getAnimParams(ctx, el, done); 354 | 355 | /** 356 | * Velocity anim function 357 | * @param el - the element 358 | * @param {object} animObj - the animObject 359 | * @param {function} animParams - Velocity's animation options 360 | */ 361 | Velocity(el, animObj, animParams); 362 | }, 363 | leave: function leave(el, done) { 364 | var animObj = {}; // empty object where we'll push animations 365 | if (ctx.props.options.parallax) { 366 | // if parallax is activated 367 | /** 368 | * Get section background's offset and store it in a constant 369 | * @param {string} action - enter or leave 370 | * @param {string} direction - up or down 371 | * @param {float} offset - the parallax offset defined in options 372 | */ 373 | var bgOffset = _utils2.default.bgOffset('leave', ctx.parent.$ksvuefp.sliderDirection, ctx.props.options.parallaxOffset); 374 | 375 | animObj['backgroundPositionX'] = bgOffset * ctx.parent.$ksvuefp.wWidth + 'px'; // Push bgPosition animation to our empty object animObj 376 | } 377 | 378 | var end = ctx.parent.$ksvuefp.sliderDirection === 'up' ? '100%' : '-100%'; // Define the full section's translate animation starting offset 379 | Velocity.hook(el, 'translateX', '0%'); // Positionate the full section before triggering the animation 380 | Velocity.hook(el, 'translateY', '0%'); // Positionate the full section before triggering the animation 381 | Velocity.hook(el, 'opacity', 1); 382 | 383 | animObj['translateX'] = end; // Push translate animation to our object animObj 384 | animObj['translateZ'] = 0; // Force 3d rendering 385 | 386 | /** 387 | * Get animations params 388 | * @param {object} ctx - the context 389 | * @param {object} animObj - the animObject 390 | * @param {function} animParams - Velocity's animation options 391 | */ 392 | var animParams = getAnimParams(ctx, el, done); 393 | 394 | /** 395 | * Velocity anim function 396 | * @param el - the element 397 | * @param {object} animObj - the animObject 398 | * @param {function} animParams - Velocity's animation options 399 | */ 400 | Velocity(el, animObj, animParams); 401 | }, 402 | afterLeave: function afterLeave(el) { 403 | Velocity.hook(el, 'backgroundPosition', '50% 50%'); 404 | } 405 | }; 406 | 407 | return h('transition', ctx.data, ctx.children); 408 | } 409 | 410 | // component datas for slideY option 411 | };var slideY = exports.slideY = { 412 | props: ['options'], 413 | functional: true, 414 | render: function render(h, ctx) { 415 | if (!ctx.parent.$ksvuefp.fpLoaded) return h('transition', ctx.data, ctx.children); // If the plugin is not fully loaded, don't animate and return h() directly 416 | ctx.data.on = { 417 | enter: function enter(el, done) { 418 | var animObj = {}; 419 | 420 | if (ctx.props.options.parallax) { 421 | /** 422 | * Get section background's offset and store it in a constant 423 | * @param {string} action - enter or leave 424 | * @param {string} direction - up or down 425 | * @param {float} offset - the parallax offset defined in options 426 | */ 427 | var bgOffset = _utils2.default.bgOffset('enter', ctx.parent.$ksvuefp.sliderDirection, ctx.props.options.parallaxOffset); 428 | 429 | Velocity.hook(el, 'backgroundPositionY', bgOffset * ctx.parent.$ksvuefp.wHeight + 'px'); 430 | 431 | animObj['backgroundPositionY'] = '0%'; 432 | } 433 | 434 | var start = ctx.parent.$ksvuefp.sliderDirection === 'up' ? '-100%' : '100%'; 435 | Velocity.hook(el, 'translateY', start); 436 | Velocity.hook(el, 'translateX', '0%'); 437 | Velocity.hook(el, 'opacity', 1); 438 | 439 | animObj['translateY'] = '0%'; 440 | animObj['translateZ'] = 0; // Force 3d rendering 441 | 442 | /** 443 | * Get animations params 444 | * @param {object} ctx - the context 445 | * @param {object} animObj - the animObject 446 | * @param {function} animParams - Velocity's animation options 447 | */ 448 | var animParams = getAnimParams(ctx, el, done); 449 | 450 | /** 451 | * Velocity anim function 452 | * @param el - the element 453 | * @param {object} animObj - the animObject 454 | * @param {function} animParams - Velocity's animation options 455 | */ 456 | Velocity(el, animObj, animParams); 457 | }, 458 | leave: function leave(el, done) { 459 | var animObj = {}; 460 | 461 | if (ctx.props.options.parallax) { 462 | /** 463 | * Get section background's offset and store it in a constant 464 | * @param {string} action - enter or leave 465 | * @param {string} direction - up or down 466 | * @param {float} offset - the parallax offset defined in options 467 | */ 468 | var bgOffset = _utils2.default.bgOffset('leave', ctx.parent.$ksvuefp.sliderDirection, ctx.props.options.parallaxOffset); 469 | 470 | animObj['backgroundPositionY'] = bgOffset * ctx.parent.$ksvuefp.wHeight + 'px'; 471 | } 472 | 473 | var end = ctx.parent.$ksvuefp.sliderDirection === 'up' ? '100%' : '-100%'; 474 | Velocity.hook(el, 'translateY', '0%'); 475 | Velocity.hook(el, 'translateX', '0%'); 476 | Velocity.hook(el, 'opacity', 1); 477 | 478 | animObj['translateY'] = end; 479 | animObj['translateZ'] = 0; // Force 3d rendering 480 | 481 | /** 482 | * Get animations params 483 | * @param {object} ctx - the context 484 | * @param {object} animObj - the animObject 485 | * @param {function} animParams - Velocity's animation options 486 | */ 487 | var animParams = getAnimParams(ctx, el, done); 488 | /** 489 | * Velocity anim function 490 | * @param el - the element 491 | * @param {object} animObj - the animObject 492 | * @param {function} animParams - Velocity's animation options 493 | */ 494 | Velocity(el, animObj, animParams); 495 | }, 496 | afterLeave: function afterLeave(el) { 497 | Velocity.hook(el, 'backgroundPosition', '50% 50%'); 498 | } 499 | }; 500 | return h('transition', ctx.data, ctx.children); 501 | } 502 | 503 | // component datas for fade option 504 | };var fade = exports.fade = { 505 | props: ['options'], 506 | functional: true, 507 | render: function render(h, ctx) { 508 | ctx.data.on = { 509 | enter: function enter(el, done) { 510 | Velocity.hook(el, 'translateX', '0%'); // Positionate the full section before triggering the animation 511 | Velocity.hook(el, 'translateY', '0%'); // Positionate the full section before triggering the animation 512 | Velocity.hook(el, 'opacity', 0); 513 | 514 | /** 515 | * Get animations params 516 | * @param {object} ctx - the context 517 | * @param {object} animObj - the animObject 518 | * @param {function} animParams - Velocity's animation options 519 | */ 520 | var animParams = getAnimParams(ctx, el, done); 521 | 522 | /** 523 | * Velocity anim function 524 | * @param el - the element 525 | * @param {object} animObj - the animObject 526 | * @param {function} animParams - Velocity's animation options 527 | */ 528 | Velocity(el, { 529 | opacity: 1 530 | }, animParams); 531 | }, 532 | leave: function leave(el, done) { 533 | /** 534 | * Get animations params 535 | * @param {object} ctx - the context 536 | * @param {object} animObj - the animObject 537 | * @param {function} animParams - Velocity's animation options 538 | */ 539 | var animParams = getAnimParams(ctx, el, done); 540 | 541 | /** 542 | * Velocity anim function 543 | * @param el - the element 544 | * @param {object} - the animObject 545 | * @param {function} animParams - Velocity's animation options 546 | */ 547 | Velocity(el, { 548 | opacity: 0 549 | }, animParams); 550 | } 551 | }; 552 | 553 | return h('transition', ctx.data, ctx.children); 554 | } 555 | 556 | // component datas for slideX option 557 | };var dotsAnim = exports.dotsAnim = { 558 | functional: true, 559 | render: function render(h, ctx) { 560 | ctx.props.name = 'dots-anim'; 561 | ctx.data.attrs['appear'] = true; 562 | ctx.data.on = { 563 | enter: function enter(el, done) { 564 | var animObj = {}; 565 | switch (ctx.props.currentPos) { 566 | case 'top': 567 | Velocity.hook(el, 'translateY', '-200px'); 568 | animObj['translateY'] = '0px'; 569 | break; 570 | case 'bottom': 571 | Velocity.hook(el, 'translateY', '200px'); 572 | animObj['translateY'] = '0px'; 573 | break; 574 | case 'left': 575 | Velocity.hook(el, 'translateX', '-200px'); 576 | animObj['translateX'] = '0px'; 577 | break; 578 | case 'right': 579 | Velocity.hook(el, 'translateX', '200px'); 580 | animObj['translateX'] = '0px'; 581 | break; 582 | } 583 | Velocity(el, animObj, { 584 | delay: el.dataset.index * 40, 585 | complete: done 586 | }); 587 | }, 588 | leave: function leave(el, done) { 589 | done(); 590 | } 591 | }; 592 | return h('transition-group', ctx.data, ctx.children); 593 | } 594 | 595 | // TODO: add prismX and prismY transitions 596 | 597 | }; 598 | 599 | /***/ }), 600 | /* 3 */ 601 | /***/ (function(module, exports, __webpack_require__) { 602 | 603 | "use strict"; 604 | 605 | 606 | Object.defineProperty(exports, "__esModule", { 607 | value: true 608 | }); 609 | exports.default = { 610 | /** 611 | * Html params 612 | * @property {String} sectionTag - The tag used to wrap each vsvuefp-section component. 613 | */ 614 | sectionTag: 'div', 615 | /** 616 | * Animation params 617 | * @property {String} animationType - Transition effect between 2 screens. Should be one of 'slideY', 'slideX', or 'fade' 618 | * @property {Number} duration - Duration of transition between 2 screens, in ms 619 | * @property {String} easing - Easing of the transition between 2 screens. Can be all easings supported by Velocity, including bezier curves. ex: [0.2, 0.5, 0.2, 0.5] 620 | * @property {Number} animDelay - Content animation delay. Help you define timing between screens transition and content animations 621 | */ 622 | animationType: 'slideY', 623 | duration: 1000, 624 | easing: 'easeInOutQuad', 625 | animDelay: 0, 626 | /** 627 | * Preloading params 628 | * @property {Boolean} preloaderEnabled - Add a fullscreen preloading overlay with loading animation 629 | * @property {String} preloaderBgColor - Background color for the preloader overlay. 630 | * @property {String} preloaderColor - Preloader icon and text color 631 | * @property {String} preloaderText - The text that will appear under the icon animation during loading 632 | * @property {Boolean} waitForBackgrounds - Wait for sections background images to be fully loaded before triggering $ksvuefp-ready event 633 | */ 634 | preloaderEnabled: true, 635 | preloaderBgColor: '#fff', 636 | preloaderColor: '#212121', 637 | preloaderText: 'Loading...', 638 | waitForBackgrounds: true, 639 | /** 640 | * Navigation params 641 | * @property {Boolean} dotNavEnabled - Add a dot navigation 642 | * @property {String} dotNavPosition - Change dotNav position. Should be one of top, bottom, left or right 643 | * @property {String} dotNavColor - Change dotNav color 644 | * @property {Boolean} loopBottom - Go to first section on scroll down while watching last section 645 | * @property {Boolean} loopTop - Go to last section on scroll up while watching first section 646 | */ 647 | dotNavEnabled: true, 648 | dotNavColor: '#fff', 649 | loopBottom: false, 650 | loopTop: false, 651 | /** 652 | * Design params 653 | * @property {Boolean - String} overlay - Insert a fullsize div between background and content, and set its background property. Must be a valid css background rule 654 | * @property {Boolean} parallax - Enable parallax effect on section's background 655 | * @property {Float} parallaxOffset - Parallax offset amount, default to 0.5. Should be between 0 and 1. 0 gives no parallax effect, 1 gives a "stacking effect" (the old section remains fixed during transition while the next one slides above it). 656 | */ 657 | overlay: 'rgba(0, 0, 0, 0.2)', 658 | parallax: false, 659 | parallaxOffset: 0.5 660 | }; 661 | 662 | /***/ }), 663 | /* 4 */ 664 | /***/ (function(module, exports, __webpack_require__) { 665 | 666 | function injectStyle (ssrContext) { 667 | var i 668 | __webpack_require__(15) 669 | } 670 | var Component = __webpack_require__(0)( 671 | /* script */ 672 | __webpack_require__(8), 673 | /* template */ 674 | __webpack_require__(22), 675 | /* styles */ 676 | injectStyle, 677 | /* scopeId */ 678 | null, 679 | /* moduleIdentifier (server only) */ 680 | "70e5dbc2" 681 | ) 682 | Component.options.__file = "C:\\Users\\romai\\ks-node\\vue-plugins\\node_modules\\ks-vue-fullpage\\src\\components\\ksvuefp-section.vue" 683 | if (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== "default" && key.substr(0, 2) !== "__"})) {console.error("named exports are not supported in *.vue files.")} 684 | if (Component.options.functional) {console.error("[vue-loader] ksvuefp-section.vue: functional components are not supported with templates, they should use render functions.")} 685 | 686 | module.exports = Component.exports 687 | 688 | 689 | /***/ }), 690 | /* 5 */ 691 | /***/ (function(module, exports, __webpack_require__) { 692 | 693 | function injectStyle (ssrContext) { 694 | var i 695 | __webpack_require__(12) 696 | } 697 | var Component = __webpack_require__(0)( 698 | /* script */ 699 | __webpack_require__(9), 700 | /* template */ 701 | __webpack_require__(19), 702 | /* styles */ 703 | injectStyle, 704 | /* scopeId */ 705 | null, 706 | /* moduleIdentifier (server only) */ 707 | "075510ac" 708 | ) 709 | Component.options.__file = "C:\\Users\\romai\\ks-node\\vue-plugins\\node_modules\\ks-vue-fullpage\\src\\components\\ksvuefp.vue" 710 | if (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== "default" && key.substr(0, 2) !== "__"})) {console.error("named exports are not supported in *.vue files.")} 711 | if (Component.options.functional) {console.error("[vue-loader] ksvuefp.vue: functional components are not supported with templates, they should use render functions.")} 712 | 713 | module.exports = Component.exports 714 | 715 | 716 | /***/ }), 717 | /* 6 */ 718 | /***/ (function(module, exports, __webpack_require__) { 719 | 720 | "use strict"; 721 | 722 | 723 | Object.defineProperty(exports, "__esModule", { 724 | value: true 725 | }); 726 | 727 | var _ksvuefpAnimations = __webpack_require__(2); 728 | 729 | exports.default = { 730 | components: { 731 | dotsAnim: _ksvuefpAnimations.dotsAnim 732 | }, 733 | props: ['sections', 'options'], 734 | data: function data() { 735 | return { 736 | navPosList: ['top', 'left', 'right', 'bottom'], 737 | keys: [] 738 | }; 739 | }, 740 | 741 | computed: { 742 | currentPos: function currentPos() { 743 | if (this.options.dotNavPosition) return this.options.dotNavPosition; 744 | switch (this.options.animationType) { 745 | case 'slideX': 746 | return 'bottom'; 747 | default: 748 | return 'right'; 749 | } 750 | } 751 | }, 752 | methods: { 753 | click: function click(nextIndex) { 754 | if (nextIndex === this.$ksvuefp.currentIndex) return; 755 | this.$ksvuefp.$emit('ksvuefp-nav-click', { nextIndex: nextIndex }); 756 | } 757 | } 758 | }; // 759 | // 760 | // 761 | // 762 | // 763 | // 764 | // 765 | // 766 | // 767 | 768 | /***/ }), 769 | /* 7 */ 770 | /***/ (function(module, exports, __webpack_require__) { 771 | 772 | "use strict"; 773 | 774 | 775 | Object.defineProperty(exports, "__esModule", { 776 | value: true 777 | }); 778 | // 779 | // 780 | // 781 | // 782 | // 783 | // 784 | // 785 | // 786 | // 787 | // 788 | // 789 | 790 | exports.default = { 791 | name: 'ksvuefpPreloader', 792 | props: ['backgroundColor', 'preloaderColor', 'preloaderText'] 793 | }; 794 | 795 | /***/ }), 796 | /* 8 */ 797 | /***/ (function(module, exports, __webpack_require__) { 798 | 799 | "use strict"; 800 | 801 | 802 | Object.defineProperty(exports, "__esModule", { 803 | value: true 804 | }); 805 | 806 | var _ksvuefpAnimations = __webpack_require__(2); 807 | 808 | var _imagesloaded = __webpack_require__(16); 809 | 810 | var _imagesloaded2 = _interopRequireDefault(_imagesloaded); 811 | 812 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 813 | 814 | // 815 | // 816 | // 817 | // 818 | // 819 | // 820 | // 821 | // 822 | // 823 | // 824 | // 825 | 826 | exports.default = { 827 | components: { 828 | slideY: _ksvuefpAnimations.slideY, 829 | slideX: _ksvuefpAnimations.slideX, 830 | fade: _ksvuefpAnimations.fade, 831 | 'tagger': { 832 | props: ['options', 'sectionIndex'], 833 | render: function render(h) { 834 | return h(this.options.sectionTag || 'div', this.$slots.default); 835 | }, 836 | mounted: function mounted() { 837 | var vm = this; 838 | vm.$nextTick(function () { 839 | setTimeout(function () { 840 | (0, _imagesloaded2.default)(vm.$el, { background: true }, function () { 841 | vm.$ksvuefp.$emit('ksvuefp-section-loaded', vm.sectionIndex); 842 | }); 843 | }, 300); 844 | }); 845 | } 846 | } 847 | }, 848 | props: ['section', 'backgroundImage', 'backgroundColor', 'sectionIndex', 'sectionOverlay'], 849 | computed: { 850 | showSection: function showSection() { 851 | return this.sectionIndex === this.$ksvuefp.currentIndex; 852 | } 853 | } 854 | }; 855 | 856 | /***/ }), 857 | /* 9 */ 858 | /***/ (function(module, exports, __webpack_require__) { 859 | 860 | "use strict"; 861 | 862 | 863 | Object.defineProperty(exports, "__esModule", { 864 | value: true 865 | }); 866 | 867 | var _utils = __webpack_require__(1); 868 | 869 | var _utils2 = _interopRequireDefault(_utils); 870 | 871 | var _ksvuefpNav = __webpack_require__(17); 872 | 873 | var _ksvuefpNav2 = _interopRequireDefault(_ksvuefpNav); 874 | 875 | var _ksvuefpPreloader = __webpack_require__(18); 876 | 877 | var _ksvuefpPreloader2 = _interopRequireDefault(_ksvuefpPreloader); 878 | 879 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 880 | 881 | exports.default = { 882 | props: { 883 | options: { 884 | type: Object, 885 | default: function _default() {} 886 | }, 887 | sections: { 888 | type: Array, 889 | default: function _default() { 890 | return []; 891 | } 892 | } 893 | }, 894 | components: { 895 | fpNav: _ksvuefpNav2.default, 896 | ksvuefpPreloader: _ksvuefpPreloader2.default 897 | }, 898 | created: function created() { 899 | this.$ksvuefp.$emit('ksvuefp-options-changed', this.options); 900 | }, 901 | mounted: function mounted() { 902 | var vm = this; 903 | vm.$nextTick(function () { 904 | /** 905 | * We listen to our custom navclick event on ksvuefp bus 906 | * @param Event 907 | */ 908 | vm.$ksvuefp.$on('ksvuefp-nav-click', function (e) { 909 | e.oldIndex = vm.$ksvuefp.currentIndex; 910 | e.type = 'navclick'; 911 | vm.changeIndex(e); 912 | }); 913 | 914 | vm.$ksvuefp.$on('ksvuefp-section-loaded', function (i) { 915 | if (i !== vm.sections.length - 1) return; 916 | setTimeout(function () { 917 | vm.$ksvuefp.$emit('ksvuefp-ready'); 918 | }, 300); 919 | }); 920 | /** 921 | * We listen to resize event and then emit on $ksvuefp bus 922 | */ 923 | window.addEventListener('resize', function () { 924 | vm.$ksvuefp.$emit('ksvuefp-resized'); 925 | }); 926 | /** 927 | * We set the list of actions we want to trigger the animation with 928 | * @const {array} 929 | * 930 | */ 931 | var actions = ['wheel', 'mousewheel', 'keydown']; 932 | /** 933 | * For each action in the above array, trigger changeIndex method 934 | * 935 | */ 936 | actions.forEach(function (a) { 937 | document.addEventListener(a, vm.changeIndex); 938 | }); 939 | 940 | vm.$ksvuefp.$emit('ksvuefp-options-changed', vm.options); 941 | 942 | /** 943 | * trigger changeIndex method on swipe with HAMMER.JS if touch is detected 944 | * 945 | */ 946 | var isTouch = 'ontouchstart' in window || navigator.msMaxTouchPoints > 0; 947 | if (!isTouch) return; 948 | 949 | var mc = new Hammer(vm.$el); 950 | mc.get('swipe').set({ direction: Hammer.DIRECTION_ALL }); 951 | 952 | mc.on('swipeup swipedown swiperight swipeleft', function (e) { 953 | vm.changeIndex(e); 954 | }); 955 | }); 956 | }, 957 | 958 | computed: { 959 | ksvuefpStyles: function ksvuefpStyles() { 960 | return { 961 | height: this.$ksvuefp.wHeight + 'px' 962 | }; 963 | } 964 | }, 965 | methods: { 966 | /** trigger the change index event 967 | * @param Event 968 | * 969 | */ 970 | changeIndex: function changeIndex(e) { 971 | if (e.defaultPrevented) { 972 | return; // Should do nothing if the key event was already consumed. 973 | } 974 | var vm = this; 975 | 976 | if (vm.$ksvuefp.slidingActive) return; // if last transition is not yet finished, return without doing anything 977 | 978 | var OldIndex = vm.$ksvuefp.currentIndex; 979 | var Length = vm.sections.length; 980 | var Options = vm.$ksvuefp.options; 981 | 982 | /** 983 | * We get the sliding direction using a custom func getDirection() in utils 984 | * @const String 985 | * @return up or down 986 | * 987 | */ 988 | var Direction = _utils2.default.getDirection(e, vm.$ksvuefp.options.animationType); 989 | 990 | if (Direction === 'none' || Direction === undefined) return; 991 | 992 | var nextIndex = void 0; 993 | 994 | /** 995 | * Get next index 996 | * @return index to go to 997 | * 998 | */ 999 | switch (e.type) { 1000 | case 'navclick': 1001 | // if is the event is from a click on navigation item 1002 | nextIndex = e.nextIndex; 1003 | break; 1004 | default: 1005 | // else 1006 | nextIndex = _utils2.default.getNextIndex(OldIndex, Direction, Length, Options); 1007 | break; 1008 | } 1009 | 1010 | if (nextIndex === 'none') return; 1011 | 1012 | this.$nextTick(function () { 1013 | // we wait for our computed datas to be ready 1014 | /** 1015 | * Emit change event on bus vm 1016 | * @param {integer} nextIndex 1017 | * @param {integer} OldIndex 1018 | * @param {String} Direction 1019 | * 1020 | */ 1021 | vm.$ksvuefp.$emit('ksvuefp-change-begin', nextIndex, OldIndex, Direction, vm.$ksvuefp.options.animDelay); 1022 | 1023 | /** 1024 | * Emit change-done event on bus vm when animation is finished 1025 | * 1026 | */ 1027 | setTimeout(function () { 1028 | vm.$ksvuefp.$emit('ksvuefp-change-done'); 1029 | }, vm.$ksvuefp.options.duration ? vm.$ksvuefp.options.duration + vm.$ksvuefp.options.animDelay + 100 : vm.$ksvuefp.options.animDelay + 1100); 1030 | }); 1031 | } 1032 | }, 1033 | watch: { 1034 | options: { 1035 | deep: true, 1036 | handler: function handler(val) { 1037 | this.$ksvuefp.$emit('ksvuefp-options-changed', val); 1038 | } 1039 | } 1040 | }, 1041 | beforeDestroy: function beforeDestroy() { 1042 | var vm = this; 1043 | /** 1044 | * We set the list of actions we want to trigger the animation with 1045 | * @const {array} 1046 | * 1047 | */ 1048 | var actions = ['wheel', 'mousewheel', 'keydown']; 1049 | /** 1050 | * For each action in the above array, trigger changeIndex method 1051 | * 1052 | */ 1053 | actions.forEach(function (a) { 1054 | document.removeEventListener(a, vm.changeIndex); 1055 | }); 1056 | window.addEventListener('resize', function () { 1057 | vm.$ksvuefp.$emit('ksvuefp-resized'); 1058 | }); 1059 | this.$off(); 1060 | this.$ksvuefp.$emit('ksvuefp-destroy'); 1061 | } 1062 | }; // 1063 | // 1064 | // 1065 | // 1066 | // 1067 | // 1068 | // 1069 | // 1070 | // 1071 | // 1072 | // 1073 | 1074 | /***/ }), 1075 | /* 10 */ 1076 | /***/ (function(module, exports, __webpack_require__) { 1077 | 1078 | "use strict"; 1079 | 1080 | 1081 | Object.defineProperty(exports, "__esModule", { 1082 | value: true 1083 | }); 1084 | exports.version = exports.ksvuefpSection = exports.ksvuefp = undefined; 1085 | 1086 | var _ksvuefp = __webpack_require__(5); 1087 | 1088 | var _ksvuefp2 = _interopRequireDefault(_ksvuefp); 1089 | 1090 | var _ksvuefpSection = __webpack_require__(4); 1091 | 1092 | var _ksvuefpSection2 = _interopRequireDefault(_ksvuefpSection); 1093 | 1094 | var _utils = __webpack_require__(1); 1095 | 1096 | var _utils2 = _interopRequireDefault(_utils); 1097 | 1098 | var _defaultOptions = __webpack_require__(3); 1099 | 1100 | var _defaultOptions2 = _interopRequireDefault(_defaultOptions); 1101 | 1102 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 1103 | 1104 | function plugin(Vue) { 1105 | Vue.prototype.$ksvuefp = new Vue({ 1106 | data: { 1107 | fpLoaded: false, 1108 | currentIndex: 0, 1109 | slidingActive: false, 1110 | sliderDirection: 'down', 1111 | wWidth: 0, 1112 | wHeight: 0, 1113 | options: {} 1114 | }, 1115 | created: function created() { 1116 | var vm = this; 1117 | vm.$on('ksvuefp-ready', function () { 1118 | vm.$emit('ksvuefp-resized'); 1119 | vm.fpLoaded = true; 1120 | }); 1121 | vm.$on('ksvuefp-options-changed', function (custom) { 1122 | vm.options = Object.assign({}, _defaultOptions2.default, custom); 1123 | }); 1124 | 1125 | vm.$on('ksvuefp-resized', function () { 1126 | vm.getWindowDim(); 1127 | }); 1128 | vm.$on('ksvuefp-destroy', function () { 1129 | vm.fpLoaded = false; 1130 | vm.currentIndex = 0; 1131 | vm.slidingActive = false; 1132 | vm.sliderDirection = 'down'; 1133 | vm.options = {}; 1134 | }); 1135 | 1136 | vm.$on('ksvuefp-change-begin', function (nextIndex, oldIndex, direction, delay) { 1137 | vm.slidingActive = true; 1138 | vm.sliderDirection = direction; 1139 | vm.$nextTick(function () { 1140 | setTimeout(function () { 1141 | vm.currentIndex = nextIndex; 1142 | }, delay || 0); 1143 | }); 1144 | }); 1145 | 1146 | vm.$on('ksvuefp-change-done', function () { 1147 | vm.slidingActive = false; 1148 | }); 1149 | }, 1150 | 1151 | methods: { 1152 | getWindowDim: function getWindowDim() { 1153 | var vm = this; 1154 | var Dimensions = _utils2.default.getWindowDim(); 1155 | vm.wWidth = Dimensions.wWidth; 1156 | vm.wHeight = Dimensions.wHeight; 1157 | vm.$nextTick(function () { 1158 | vm.$ksvuefp.$emit('ksvuefp-change-done'); 1159 | }); 1160 | }, 1161 | canAnimContent: function canAnimContent(index) { 1162 | var wait = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; 1163 | 1164 | if (index !== this.currentIndex) return; 1165 | if (wait) { 1166 | return !this.slidingActive ? true : false; 1167 | } 1168 | return true; 1169 | } 1170 | } 1171 | }); 1172 | Vue.component('ksvuefp', _ksvuefp2.default); 1173 | Vue.component('ksvuefp-section', _ksvuefpSection2.default); 1174 | } 1175 | 1176 | // Install by default if using the script tag 1177 | if (typeof window !== 'undefined' && window.Vue) { 1178 | window.Vue.use(plugin); 1179 | } 1180 | 1181 | exports.default = plugin; 1182 | 1183 | var version = '__VERSION__'; 1184 | // Export all components too 1185 | exports.ksvuefp = _ksvuefp2.default; 1186 | exports.ksvuefpSection = _ksvuefpSection2.default; 1187 | exports.version = version; 1188 | 1189 | /***/ }), 1190 | /* 11 */ 1191 | /***/ (function(module, exports, __webpack_require__) { 1192 | 1193 | var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/** 1194 | * EvEmitter v1.1.0 1195 | * Lil' event emitter 1196 | * MIT License 1197 | */ 1198 | 1199 | /* jshint unused: true, undef: true, strict: true */ 1200 | 1201 | ( function( global, factory ) { 1202 | // universal module definition 1203 | /* jshint strict: false */ /* globals define, module, window */ 1204 | if ( true ) { 1205 | // AMD - RequireJS 1206 | !(__WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 1207 | __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 1208 | (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : 1209 | __WEBPACK_AMD_DEFINE_FACTORY__), 1210 | __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 1211 | } else if ( typeof module == 'object' && module.exports ) { 1212 | // CommonJS - Browserify, Webpack 1213 | module.exports = factory(); 1214 | } else { 1215 | // Browser globals 1216 | global.EvEmitter = factory(); 1217 | } 1218 | 1219 | }( typeof window != 'undefined' ? window : this, function() { 1220 | 1221 | "use strict"; 1222 | 1223 | function EvEmitter() {} 1224 | 1225 | var proto = EvEmitter.prototype; 1226 | 1227 | proto.on = function( eventName, listener ) { 1228 | if ( !eventName || !listener ) { 1229 | return; 1230 | } 1231 | // set events hash 1232 | var events = this._events = this._events || {}; 1233 | // set listeners array 1234 | var listeners = events[ eventName ] = events[ eventName ] || []; 1235 | // only add once 1236 | if ( listeners.indexOf( listener ) == -1 ) { 1237 | listeners.push( listener ); 1238 | } 1239 | 1240 | return this; 1241 | }; 1242 | 1243 | proto.once = function( eventName, listener ) { 1244 | if ( !eventName || !listener ) { 1245 | return; 1246 | } 1247 | // add event 1248 | this.on( eventName, listener ); 1249 | // set once flag 1250 | // set onceEvents hash 1251 | var onceEvents = this._onceEvents = this._onceEvents || {}; 1252 | // set onceListeners object 1253 | var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {}; 1254 | // set flag 1255 | onceListeners[ listener ] = true; 1256 | 1257 | return this; 1258 | }; 1259 | 1260 | proto.off = function( eventName, listener ) { 1261 | var listeners = this._events && this._events[ eventName ]; 1262 | if ( !listeners || !listeners.length ) { 1263 | return; 1264 | } 1265 | var index = listeners.indexOf( listener ); 1266 | if ( index != -1 ) { 1267 | listeners.splice( index, 1 ); 1268 | } 1269 | 1270 | return this; 1271 | }; 1272 | 1273 | proto.emitEvent = function( eventName, args ) { 1274 | var listeners = this._events && this._events[ eventName ]; 1275 | if ( !listeners || !listeners.length ) { 1276 | return; 1277 | } 1278 | // copy over to avoid interference if .off() in listener 1279 | listeners = listeners.slice(0); 1280 | args = args || []; 1281 | // once stuff 1282 | var onceListeners = this._onceEvents && this._onceEvents[ eventName ]; 1283 | 1284 | for ( var i=0; i < listeners.length; i++ ) { 1285 | var listener = listeners[i] 1286 | var isOnce = onceListeners && onceListeners[ listener ]; 1287 | if ( isOnce ) { 1288 | // remove listener 1289 | // remove before trigger to prevent recursion 1290 | this.off( eventName, listener ); 1291 | // unset once flag 1292 | delete onceListeners[ listener ]; 1293 | } 1294 | // trigger listener 1295 | listener.apply( this, args ); 1296 | } 1297 | 1298 | return this; 1299 | }; 1300 | 1301 | proto.allOff = function() { 1302 | delete this._events; 1303 | delete this._onceEvents; 1304 | }; 1305 | 1306 | return EvEmitter; 1307 | 1308 | })); 1309 | 1310 | 1311 | /***/ }), 1312 | /* 12 */ 1313 | /***/ (function(module, exports) { 1314 | 1315 | // empty (null-loader) 1316 | 1317 | /***/ }), 1318 | /* 13 */ 1319 | /***/ (function(module, exports) { 1320 | 1321 | // empty (null-loader) 1322 | 1323 | /***/ }), 1324 | /* 14 */ 1325 | /***/ (function(module, exports) { 1326 | 1327 | // empty (null-loader) 1328 | 1329 | /***/ }), 1330 | /* 15 */ 1331 | /***/ (function(module, exports) { 1332 | 1333 | // empty (null-loader) 1334 | 1335 | /***/ }), 1336 | /* 16 */ 1337 | /***/ (function(module, exports, __webpack_require__) { 1338 | 1339 | var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 1340 | * imagesLoaded v4.1.3 1341 | * JavaScript is all like "You images are done yet or what?" 1342 | * MIT License 1343 | */ 1344 | 1345 | ( function( window, factory ) { 'use strict'; 1346 | // universal module definition 1347 | 1348 | /*global define: false, module: false, require: false */ 1349 | 1350 | if ( true ) { 1351 | // AMD 1352 | !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ 1353 | __webpack_require__(11) 1354 | ], __WEBPACK_AMD_DEFINE_RESULT__ = function( EvEmitter ) { 1355 | return factory( window, EvEmitter ); 1356 | }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 1357 | __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 1358 | } else if ( typeof module == 'object' && module.exports ) { 1359 | // CommonJS 1360 | module.exports = factory( 1361 | window, 1362 | require('ev-emitter') 1363 | ); 1364 | } else { 1365 | // browser global 1366 | window.imagesLoaded = factory( 1367 | window, 1368 | window.EvEmitter 1369 | ); 1370 | } 1371 | 1372 | })( typeof window !== 'undefined' ? window : this, 1373 | 1374 | // -------------------------- factory -------------------------- // 1375 | 1376 | function factory( window, EvEmitter ) { 1377 | 1378 | 'use strict'; 1379 | 1380 | var $ = window.jQuery; 1381 | var console = window.console; 1382 | 1383 | // -------------------------- helpers -------------------------- // 1384 | 1385 | // extend objects 1386 | function extend( a, b ) { 1387 | for ( var prop in b ) { 1388 | a[ prop ] = b[ prop ]; 1389 | } 1390 | return a; 1391 | } 1392 | 1393 | // turn element or nodeList into an array 1394 | function makeArray( obj ) { 1395 | var ary = []; 1396 | if ( Array.isArray( obj ) ) { 1397 | // use object if already an array 1398 | ary = obj; 1399 | } else if ( typeof obj.length == 'number' ) { 1400 | // convert nodeList to array 1401 | for ( var i=0; i < obj.length; i++ ) { 1402 | ary.push( obj[i] ); 1403 | } 1404 | } else { 1405 | // array of single index 1406 | ary.push( obj ); 1407 | } 1408 | return ary; 1409 | } 1410 | 1411 | // -------------------------- imagesLoaded -------------------------- // 1412 | 1413 | /** 1414 | * @param {Array, Element, NodeList, String} elem 1415 | * @param {Object or Function} options - if function, use as callback 1416 | * @param {Function} onAlways - callback function 1417 | */ 1418 | function ImagesLoaded( elem, options, onAlways ) { 1419 | // coerce ImagesLoaded() without new, to be new ImagesLoaded() 1420 | if ( !( this instanceof ImagesLoaded ) ) { 1421 | return new ImagesLoaded( elem, options, onAlways ); 1422 | } 1423 | // use elem as selector string 1424 | if ( typeof elem == 'string' ) { 1425 | elem = document.querySelectorAll( elem ); 1426 | } 1427 | 1428 | this.elements = makeArray( elem ); 1429 | this.options = extend( {}, this.options ); 1430 | 1431 | if ( typeof options == 'function' ) { 1432 | onAlways = options; 1433 | } else { 1434 | extend( this.options, options ); 1435 | } 1436 | 1437 | if ( onAlways ) { 1438 | this.on( 'always', onAlways ); 1439 | } 1440 | 1441 | this.getImages(); 1442 | 1443 | if ( $ ) { 1444 | // add jQuery Deferred object 1445 | this.jqDeferred = new $.Deferred(); 1446 | } 1447 | 1448 | // HACK check async to allow time to bind listeners 1449 | setTimeout( function() { 1450 | this.check(); 1451 | }.bind( this )); 1452 | } 1453 | 1454 | ImagesLoaded.prototype = Object.create( EvEmitter.prototype ); 1455 | 1456 | ImagesLoaded.prototype.options = {}; 1457 | 1458 | ImagesLoaded.prototype.getImages = function() { 1459 | this.images = []; 1460 | 1461 | // filter & find items if we have an item selector 1462 | this.elements.forEach( this.addElementImages, this ); 1463 | }; 1464 | 1465 | /** 1466 | * @param {Node} element 1467 | */ 1468 | ImagesLoaded.prototype.addElementImages = function( elem ) { 1469 | // filter siblings 1470 | if ( elem.nodeName == 'IMG' ) { 1471 | this.addImage( elem ); 1472 | } 1473 | // get background image on element 1474 | if ( this.options.background === true ) { 1475 | this.addElementBackgroundImages( elem ); 1476 | } 1477 | 1478 | // find children 1479 | // no non-element nodes, #143 1480 | var nodeType = elem.nodeType; 1481 | if ( !nodeType || !elementNodeTypes[ nodeType ] ) { 1482 | return; 1483 | } 1484 | var childImgs = elem.querySelectorAll('img'); 1485 | // concat childElems to filterFound array 1486 | for ( var i=0; i < childImgs.length; i++ ) { 1487 | var img = childImgs[i]; 1488 | this.addImage( img ); 1489 | } 1490 | 1491 | // get child background images 1492 | if ( typeof this.options.background == 'string' ) { 1493 | var children = elem.querySelectorAll( this.options.background ); 1494 | for ( i=0; i < children.length; i++ ) { 1495 | var child = children[i]; 1496 | this.addElementBackgroundImages( child ); 1497 | } 1498 | } 1499 | }; 1500 | 1501 | var elementNodeTypes = { 1502 | 1: true, 1503 | 9: true, 1504 | 11: true 1505 | }; 1506 | 1507 | ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) { 1508 | var style = getComputedStyle( elem ); 1509 | if ( !style ) { 1510 | // Firefox returns null if in a hidden iframe https://bugzil.la/548397 1511 | return; 1512 | } 1513 | // get url inside url("...") 1514 | var reURL = /url\((['"])?(.*?)\1\)/gi; 1515 | var matches = reURL.exec( style.backgroundImage ); 1516 | while ( matches !== null ) { 1517 | var url = matches && matches[2]; 1518 | if ( url ) { 1519 | this.addBackground( url, elem ); 1520 | } 1521 | matches = reURL.exec( style.backgroundImage ); 1522 | } 1523 | }; 1524 | 1525 | /** 1526 | * @param {Image} img 1527 | */ 1528 | ImagesLoaded.prototype.addImage = function( img ) { 1529 | var loadingImage = new LoadingImage( img ); 1530 | this.images.push( loadingImage ); 1531 | }; 1532 | 1533 | ImagesLoaded.prototype.addBackground = function( url, elem ) { 1534 | var background = new Background( url, elem ); 1535 | this.images.push( background ); 1536 | }; 1537 | 1538 | ImagesLoaded.prototype.check = function() { 1539 | var _this = this; 1540 | this.progressedCount = 0; 1541 | this.hasAnyBroken = false; 1542 | // complete if no images 1543 | if ( !this.images.length ) { 1544 | this.complete(); 1545 | return; 1546 | } 1547 | 1548 | function onProgress( image, elem, message ) { 1549 | // HACK - Chrome triggers event before object properties have changed. #83 1550 | setTimeout( function() { 1551 | _this.progress( image, elem, message ); 1552 | }); 1553 | } 1554 | 1555 | this.images.forEach( function( loadingImage ) { 1556 | loadingImage.once( 'progress', onProgress ); 1557 | loadingImage.check(); 1558 | }); 1559 | }; 1560 | 1561 | ImagesLoaded.prototype.progress = function( image, elem, message ) { 1562 | this.progressedCount++; 1563 | this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded; 1564 | // progress event 1565 | this.emitEvent( 'progress', [ this, image, elem ] ); 1566 | if ( this.jqDeferred && this.jqDeferred.notify ) { 1567 | this.jqDeferred.notify( this, image ); 1568 | } 1569 | // check if completed 1570 | if ( this.progressedCount == this.images.length ) { 1571 | this.complete(); 1572 | } 1573 | 1574 | if ( this.options.debug && console ) { 1575 | console.log( 'progress: ' + message, image, elem ); 1576 | } 1577 | }; 1578 | 1579 | ImagesLoaded.prototype.complete = function() { 1580 | var eventName = this.hasAnyBroken ? 'fail' : 'done'; 1581 | this.isComplete = true; 1582 | this.emitEvent( eventName, [ this ] ); 1583 | this.emitEvent( 'always', [ this ] ); 1584 | if ( this.jqDeferred ) { 1585 | var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve'; 1586 | this.jqDeferred[ jqMethod ]( this ); 1587 | } 1588 | }; 1589 | 1590 | // -------------------------- -------------------------- // 1591 | 1592 | function LoadingImage( img ) { 1593 | this.img = img; 1594 | } 1595 | 1596 | LoadingImage.prototype = Object.create( EvEmitter.prototype ); 1597 | 1598 | LoadingImage.prototype.check = function() { 1599 | // If complete is true and browser supports natural sizes, 1600 | // try to check for image status manually. 1601 | var isComplete = this.getIsImageComplete(); 1602 | if ( isComplete ) { 1603 | // report based on naturalWidth 1604 | this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' ); 1605 | return; 1606 | } 1607 | 1608 | // If none of the checks above matched, simulate loading on detached element. 1609 | this.proxyImage = new Image(); 1610 | this.proxyImage.addEventListener( 'load', this ); 1611 | this.proxyImage.addEventListener( 'error', this ); 1612 | // bind to image as well for Firefox. #191 1613 | this.img.addEventListener( 'load', this ); 1614 | this.img.addEventListener( 'error', this ); 1615 | this.proxyImage.src = this.img.src; 1616 | }; 1617 | 1618 | LoadingImage.prototype.getIsImageComplete = function() { 1619 | return this.img.complete && this.img.naturalWidth !== undefined; 1620 | }; 1621 | 1622 | LoadingImage.prototype.confirm = function( isLoaded, message ) { 1623 | this.isLoaded = isLoaded; 1624 | this.emitEvent( 'progress', [ this, this.img, message ] ); 1625 | }; 1626 | 1627 | // ----- events ----- // 1628 | 1629 | // trigger specified handler for event type 1630 | LoadingImage.prototype.handleEvent = function( event ) { 1631 | var method = 'on' + event.type; 1632 | if ( this[ method ] ) { 1633 | this[ method ]( event ); 1634 | } 1635 | }; 1636 | 1637 | LoadingImage.prototype.onload = function() { 1638 | this.confirm( true, 'onload' ); 1639 | this.unbindEvents(); 1640 | }; 1641 | 1642 | LoadingImage.prototype.onerror = function() { 1643 | this.confirm( false, 'onerror' ); 1644 | this.unbindEvents(); 1645 | }; 1646 | 1647 | LoadingImage.prototype.unbindEvents = function() { 1648 | this.proxyImage.removeEventListener( 'load', this ); 1649 | this.proxyImage.removeEventListener( 'error', this ); 1650 | this.img.removeEventListener( 'load', this ); 1651 | this.img.removeEventListener( 'error', this ); 1652 | }; 1653 | 1654 | // -------------------------- Background -------------------------- // 1655 | 1656 | function Background( url, element ) { 1657 | this.url = url; 1658 | this.element = element; 1659 | this.img = new Image(); 1660 | } 1661 | 1662 | // inherit LoadingImage prototype 1663 | Background.prototype = Object.create( LoadingImage.prototype ); 1664 | 1665 | Background.prototype.check = function() { 1666 | this.img.addEventListener( 'load', this ); 1667 | this.img.addEventListener( 'error', this ); 1668 | this.img.src = this.url; 1669 | // check if image is already complete 1670 | var isComplete = this.getIsImageComplete(); 1671 | if ( isComplete ) { 1672 | this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' ); 1673 | this.unbindEvents(); 1674 | } 1675 | }; 1676 | 1677 | Background.prototype.unbindEvents = function() { 1678 | this.img.removeEventListener( 'load', this ); 1679 | this.img.removeEventListener( 'error', this ); 1680 | }; 1681 | 1682 | Background.prototype.confirm = function( isLoaded, message ) { 1683 | this.isLoaded = isLoaded; 1684 | this.emitEvent( 'progress', [ this, this.element, message ] ); 1685 | }; 1686 | 1687 | // -------------------------- jQuery -------------------------- // 1688 | 1689 | ImagesLoaded.makeJQueryPlugin = function( jQuery ) { 1690 | jQuery = jQuery || window.jQuery; 1691 | if ( !jQuery ) { 1692 | return; 1693 | } 1694 | // set local variable 1695 | $ = jQuery; 1696 | // $().imagesLoaded() 1697 | $.fn.imagesLoaded = function( options, callback ) { 1698 | var instance = new ImagesLoaded( this, options, callback ); 1699 | return instance.jqDeferred.promise( $(this) ); 1700 | }; 1701 | }; 1702 | // try making plugin 1703 | ImagesLoaded.makeJQueryPlugin(); 1704 | 1705 | // -------------------------- -------------------------- // 1706 | 1707 | return ImagesLoaded; 1708 | 1709 | }); 1710 | 1711 | 1712 | /***/ }), 1713 | /* 17 */ 1714 | /***/ (function(module, exports, __webpack_require__) { 1715 | 1716 | function injectStyle (ssrContext) { 1717 | var i 1718 | __webpack_require__(14) 1719 | } 1720 | var Component = __webpack_require__(0)( 1721 | /* script */ 1722 | __webpack_require__(6), 1723 | /* template */ 1724 | __webpack_require__(21), 1725 | /* styles */ 1726 | injectStyle, 1727 | /* scopeId */ 1728 | null, 1729 | /* moduleIdentifier (server only) */ 1730 | "2fefe180" 1731 | ) 1732 | Component.options.__file = "C:\\Users\\romai\\ks-node\\vue-plugins\\node_modules\\ks-vue-fullpage\\src\\components\\ksvuefp-nav.vue" 1733 | if (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== "default" && key.substr(0, 2) !== "__"})) {console.error("named exports are not supported in *.vue files.")} 1734 | if (Component.options.functional) {console.error("[vue-loader] ksvuefp-nav.vue: functional components are not supported with templates, they should use render functions.")} 1735 | 1736 | module.exports = Component.exports 1737 | 1738 | 1739 | /***/ }), 1740 | /* 18 */ 1741 | /***/ (function(module, exports, __webpack_require__) { 1742 | 1743 | function injectStyle (ssrContext) { 1744 | var i 1745 | __webpack_require__(13) 1746 | } 1747 | var Component = __webpack_require__(0)( 1748 | /* script */ 1749 | __webpack_require__(7), 1750 | /* template */ 1751 | __webpack_require__(20), 1752 | /* styles */ 1753 | injectStyle, 1754 | /* scopeId */ 1755 | null, 1756 | /* moduleIdentifier (server only) */ 1757 | "06a62b93" 1758 | ) 1759 | Component.options.__file = "C:\\Users\\romai\\ks-node\\vue-plugins\\node_modules\\ks-vue-fullpage\\src\\components\\ksvuefp-preloader.vue" 1760 | if (Component.esModule && Object.keys(Component.esModule).some(function (key) {return key !== "default" && key.substr(0, 2) !== "__"})) {console.error("named exports are not supported in *.vue files.")} 1761 | if (Component.options.functional) {console.error("[vue-loader] ksvuefp-preloader.vue: functional components are not supported with templates, they should use render functions.")} 1762 | 1763 | module.exports = Component.exports 1764 | 1765 | 1766 | /***/ }), 1767 | /* 19 */ 1768 | /***/ (function(module, exports) { 1769 | 1770 | module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h; 1771 | return _c('div', { 1772 | class: ['ksvuefp', _vm.$ksvuefp.wWidth < _vm.$ksvuefp.options.normalScrollWidth ? 'is-ksvuefp-inactive' : null], 1773 | style: (_vm.ksvuefpStyles) 1774 | }, [_vm._ssrNode("
", "
", [_vm._t("default")], 2), _vm._ssrNode(" "), (_vm.$ksvuefp.options.preloaderEnabled) ? _c('transition', { 1775 | attrs: { 1776 | "name": _vm.$ksvuefp.options.preloaderTransitionName || 'fade-out' 1777 | } 1778 | }, [(!_vm.$ksvuefp.fpLoaded) ? _c('ksvuefp-preloader', { 1779 | attrs: { 1780 | "backgroundColor": _vm.$ksvuefp.options.preloaderBgColor || '', 1781 | "preloaderColor": _vm.$ksvuefp.options.preloaderColor || '', 1782 | "preloaderText": _vm.$ksvuefp.options.preloaderText 1783 | } 1784 | }) : _vm._e()], 1) : _vm._e(), _vm._ssrNode(" "), (_vm.$ksvuefp.options.dotNavEnabled) ? _c('fp-nav', { 1785 | attrs: { 1786 | "sections": _vm.sections, 1787 | "options": _vm.$ksvuefp.options 1788 | } 1789 | }) : _vm._e()], 2) 1790 | },staticRenderFns: []} 1791 | module.exports.render._withStripped = true 1792 | 1793 | /***/ }), 1794 | /* 20 */ 1795 | /***/ (function(module, exports) { 1796 | 1797 | module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h; 1798 | return _c('div', { 1799 | staticClass: "ksvuefp-preloader", 1800 | style: ({ 1801 | backgroundColor: _vm.backgroundColor || '#fff' 1802 | }) 1803 | }, [_vm._ssrNode("
" + (_vm._ssrList((4), function(n) { 1804 | return ("
") 1807 | })) + "

" + _vm._ssrEscape(_vm._s(_vm.preloaderText || 'loading...')) + "

")]) 1810 | },staticRenderFns: []} 1811 | module.exports.render._withStripped = true 1812 | 1813 | /***/ }), 1814 | /* 21 */ 1815 | /***/ (function(module, exports) { 1816 | 1817 | module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h; 1818 | return _c('div', _vm._l((_vm.navPosList), function(pos) { 1819 | return (_vm.currentPos === pos && _vm.$ksvuefp.fpLoaded) ? _c('dots-anim', { 1820 | key: pos, 1821 | class: ['ksvuefp-nav', 'is-' + _vm.currentPos], 1822 | attrs: { 1823 | "tag": "ul", 1824 | "appear": "", 1825 | "currentPos": _vm.currentPos 1826 | } 1827 | }, _vm._l((_vm.sections), function(s, index) { 1828 | return _c('li', { 1829 | directives: [{ 1830 | name: "show", 1831 | rawName: "v-show", 1832 | value: (_vm.currentPos === pos), 1833 | expression: "currentPos === pos" 1834 | }], 1835 | key: index, 1836 | staticClass: "ksvuefp-nav__item", 1837 | attrs: { 1838 | "data-index": index 1839 | } 1840 | }, [_c('span', { 1841 | class: ['ksvuefp-nav__dot', index === _vm.$ksvuefp.currentIndex ? 'active' : ''], 1842 | style: ({ 1843 | backgroundColor: _vm.options.dotNavColor 1844 | }), 1845 | on: { 1846 | "click": function($event) { 1847 | _vm.click(index) 1848 | } 1849 | } 1850 | })]) 1851 | })) : _vm._e() 1852 | })) 1853 | },staticRenderFns: []} 1854 | module.exports.render._withStripped = true 1855 | 1856 | /***/ }), 1857 | /* 22 */ 1858 | /***/ (function(module, exports) { 1859 | 1860 | module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h; 1861 | return _c(_vm.$ksvuefp.options.animationType, { 1862 | tag: "component", 1863 | attrs: { 1864 | "options": _vm.$ksvuefp.options, 1865 | "appear": false 1866 | } 1867 | }, [_c('tagger', { 1868 | directives: [{ 1869 | name: "show", 1870 | rawName: "v-show", 1871 | value: (_vm.showSection), 1872 | expression: "showSection" 1873 | }], 1874 | class: ['ksvuefp-section'], 1875 | style: ({ 1876 | backgroundImage: _vm.backgroundImage || '', 1877 | backgroundColor: _vm.backgroundColor || '' 1878 | }), 1879 | attrs: { 1880 | "sectionIndex": _vm.sectionIndex, 1881 | "options": _vm.$ksvuefp.options 1882 | } 1883 | }, [(_vm.$ksvuefp.options.overlay || _vm.sectionOverlay) ? _c('span', { 1884 | staticClass: "ksvuefp-section__overlay", 1885 | style: ({ 1886 | background: _vm.sectionOverlay ? _vm.sectionOverlay : _vm.$ksvuefp.options.overlay || 'rgba(0,0,0,0.2)' 1887 | }) 1888 | }) : _vm._e(), _vm._v(" "), _c('div', { 1889 | staticClass: "ksvuefp-section__content" 1890 | }, [_vm._t("default")], 2)])], 1) 1891 | },staticRenderFns: []} 1892 | module.exports.render._withStripped = true 1893 | 1894 | /***/ }) 1895 | /******/ ]); -------------------------------------------------------------------------------- /dist/ks-vue-fullpage.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * ks-vue-fullpage v1.2.8 3 | * (c) 2017 pirony 4 | * Released under the MIT License. 5 | */ 6 | 7 | 8 | .ksvuefp { 9 | width: 100%; 10 | height: 100%; 11 | position: relative; 12 | overflow: hidden 13 | } 14 | .ksvuefp.is-ksvuefp-inactive { 15 | overflow: auto 16 | } 17 | .ksvuefp-sections { 18 | position: relative; 19 | height: 100%; 20 | width: 100%; 21 | display: block; 22 | z-index: 1 23 | } 24 | .fade-out-enter-active, 25 | .fade-out-leave-active { 26 | transition: all 0.3s; 27 | opacity: 1; 28 | transition-delay: 0.3s; 29 | } 30 | .fade-out-enter, 31 | .fade-out-leave-active { 32 | opacity: 0; 33 | } 34 | 35 | .ksvuefp-nav { 36 | position: fixed; 37 | z-index: 2; 38 | list-style: none; 39 | margin: 0; 40 | display: -webkit-box; 41 | display: -ms-flexbox; 42 | display: flex; 43 | -webkit-box-pack: center; 44 | -ms-flex-pack: center; 45 | justify-content: center 46 | } 47 | .ksvuefp-nav.is-right, .ksvuefp-nav.is-left { 48 | -webkit-box-orient: vertical; 49 | -webkit-box-direction: normal; 50 | -ms-flex-direction: column; 51 | flex-direction: column 52 | } 53 | .ksvuefp-nav.is-right { 54 | top: 50%; 55 | right: 20px; 56 | -webkit-transform: translateY(-50%); 57 | transform: translateY(-50%) 58 | } 59 | .ksvuefp-nav.is-left { 60 | top: 50%; 61 | left: 20px; 62 | -webkit-transform: translateY(-50%); 63 | transform: translateY(-50%) 64 | } 65 | .ksvuefp-nav.is-top { 66 | top: 20px; 67 | left: 50%; 68 | -webkit-transform: translateX(-50%); 69 | transform: translateX(-50%) 70 | } 71 | .ksvuefp-nav.is-bottom { 72 | left: 50%; 73 | -webkit-transform: translateX(-50%); 74 | transform: translateX(-50%); 75 | bottom: 20px 76 | } 77 | .ksvuefp-nav .ksvuefp-nav__item { 78 | display: block; 79 | height: 22px; 80 | width: 22px; 81 | margin: 5px; 82 | display: -webkit-box; 83 | display: -ms-flexbox; 84 | display: flex; 85 | -webkit-box-pack: center; 86 | -ms-flex-pack: center; 87 | justify-content: center; 88 | -webkit-box-align: center; 89 | -ms-flex-align: center; 90 | align-items: center; 91 | } 92 | .ksvuefp-nav__dot { 93 | height: 8px; 94 | width: 8px; 95 | border-radius: 50%; 96 | background-color: white; 97 | display: block; 98 | margin: 15px auto; 99 | cursor: pointer; 100 | transition: background-color 0.3s ease; 101 | } 102 | .ksvuefp-nav__dot.active { 103 | height: 14px; 104 | width: 14px; 105 | cursor: default; 106 | } 107 | 108 | .ksvuefp-preloader { 109 | position: fixed; 110 | top: 0; 111 | left: 0; 112 | height: 100%; 113 | width: 100%; 114 | overflow: hidden; 115 | z-index: 99998; 116 | display: -webkit-box; 117 | display: -ms-flexbox; 118 | display: flex; 119 | -webkit-box-pack: center; 120 | -ms-flex-pack: center; 121 | justify-content: center; 122 | -webkit-box-align: center; 123 | -ms-flex-align: center; 124 | align-items: center 125 | } 126 | .ksvuefp-preloader__wrapper { 127 | margin: 20px auto; 128 | width: 40px; 129 | height: 40px; 130 | position: relative; 131 | -webkit-transform: rotateZ(45deg); 132 | transform: rotateZ(45deg) 133 | } 134 | .ksvuefp-preloader__text { 135 | display: block; 136 | text-align: center; 137 | margin-top: 15px 138 | } 139 | .ksvuefp-preloader .square { 140 | float: left; 141 | width: 50%; 142 | height: 50%; 143 | position: relative; 144 | -webkit-transform: scale(1.1); 145 | transform: scale(1.1); 146 | } 147 | .ksvuefp-preloader .square span { 148 | content: ''; 149 | position: absolute; 150 | top: 0; 151 | left: 0; 152 | width: 100%; 153 | height: 100%; 154 | -webkit-animation: ks-foldCubeAngle 2.4s infinite linear both; 155 | animation: ks-foldCubeAngle 2.4s infinite linear both; 156 | -webkit-transform-origin: 100% 100%; 157 | transform-origin: 100% 100%; 158 | } 159 | .ksvuefp-preloader .square2 { 160 | -webkit-transform: scale(1.1) rotateZ(90deg); 161 | transform: scale(1.1) rotateZ(90deg); 162 | } 163 | .ksvuefp-preloader .square3 { 164 | -webkit-transform: scale(1.1) rotateZ(270deg); 165 | transform: scale(1.1) rotateZ(270deg); 166 | } 167 | .ksvuefp-preloader .square4 { 168 | -webkit-transform: scale(1.1) rotateZ(180deg); 169 | transform: scale(1.1) rotateZ(180deg); 170 | } 171 | .ksvuefp-preloader .square2 span { 172 | -webkit-animation-delay: 0.3s; 173 | animation-delay: 0.3s; 174 | } 175 | .ksvuefp-preloader .square3 span { 176 | -webkit-animation-delay: 0.9s; 177 | animation-delay: 0.9s; 178 | } 179 | .ksvuefp-preloader .square4 span { 180 | -webkit-animation-delay: 0.6s; 181 | animation-delay: 0.6s; 182 | } 183 | @-webkit-keyframes ks-foldCubeAngle { 184 | 0%, 185 | 10% { 186 | -webkit-transform: perspective(140px) rotateX(-180deg); 187 | transform: perspective(140px) rotateX(-180deg); 188 | opacity: 0; 189 | } 190 | 25%, 191 | 75% { 192 | -webkit-transform: perspective(140px) rotateX(0deg); 193 | transform: perspective(140px) rotateX(0deg); 194 | opacity: 1; 195 | } 196 | 90%, 197 | 100% { 198 | -webkit-transform: perspective(140px) rotateY(180deg); 199 | transform: perspective(140px) rotateY(180deg); 200 | opacity: 0; 201 | } 202 | } 203 | @keyframes ks-foldCubeAngle { 204 | 0%, 205 | 10% { 206 | -webkit-transform: perspective(140px) rotateX(-180deg); 207 | transform: perspective(140px) rotateX(-180deg); 208 | opacity: 0; 209 | } 210 | 25%, 211 | 75% { 212 | -webkit-transform: perspective(140px) rotateX(0deg); 213 | transform: perspective(140px) rotateX(0deg); 214 | opacity: 1; 215 | } 216 | 90%, 217 | 100% { 218 | -webkit-transform: perspective(140px) rotateY(180deg); 219 | transform: perspective(140px) rotateY(180deg); 220 | opacity: 0; 221 | } 222 | } 223 | 224 | .ksvuefp-section { 225 | height: 100%; 226 | width: 100%; 227 | position: absolute; 228 | top: 0; 229 | left: 0; 230 | background-size: cover; 231 | padding: 0; 232 | margin: 0; 233 | background-position: center; 234 | background-repeat: no-repeat 235 | } 236 | .ksvuefp-section__overlay { 237 | display: block; 238 | width: 100%; 239 | height: 100%; 240 | position: absolute; 241 | top: 0; 242 | left: 0; 243 | z-index: 0 244 | } 245 | .ksvuefp-section__content { 246 | width: 100%; 247 | position: relative; 248 | z-index: 1 249 | } 250 | .ksvuefp-section.is-ksvuefp-inactive { 251 | position: relative 252 | } 253 | -------------------------------------------------------------------------------- /dist/ks-vue-fullpage.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * ks-vue-fullpage v1.2.8 3 | * (c) 2017 pirony 4 | * Released under the MIT License. 5 | */ 6 | 7 | .ksvuefp{width:100%;height:100%;position:relative;overflow:hidden}.ksvuefp.is-ksvuefp-inactive{overflow:auto}.ksvuefp-sections{position:relative;height:100%;width:100%;display:block;z-index:1}.fade-out-enter-active,.fade-out-leave-active{transition:all .3s;opacity:1;transition-delay:.3s}.fade-out-enter,.fade-out-leave-active{opacity:0}.ksvuefp-nav{position:fixed;z-index:2;list-style:none;margin:0;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.ksvuefp-nav.is-left,.ksvuefp-nav.is-right{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.ksvuefp-nav.is-right{right:20px}.ksvuefp-nav.is-left,.ksvuefp-nav.is-right{top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.ksvuefp-nav.is-left{left:20px}.ksvuefp-nav.is-top{top:20px}.ksvuefp-nav.is-bottom,.ksvuefp-nav.is-top{left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.ksvuefp-nav.is-bottom{bottom:20px}.ksvuefp-nav .ksvuefp-nav__item{display:block;height:22px;width:22px;margin:5px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.ksvuefp-nav__dot{height:8px;width:8px;border-radius:50%;background-color:#fff;display:block;margin:15px auto;cursor:pointer;transition:background-color .3s ease}.ksvuefp-nav__dot.active{height:14px;width:14px;cursor:default}.ksvuefp-preloader{position:fixed;top:0;left:0;height:100%;width:100%;overflow:hidden;z-index:99998;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.ksvuefp-preloader__wrapper{margin:20px auto;width:40px;height:40px;position:relative;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.ksvuefp-preloader__text{display:block;text-align:center;margin-top:15px}.ksvuefp-preloader .square{float:left;width:50%;height:50%;position:relative;-webkit-transform:scale(1.1);transform:scale(1.1)}.ksvuefp-preloader .square span{content:"";position:absolute;top:0;left:0;width:100%;height:100%;-webkit-animation:ks-foldCubeAngle 2.4s infinite linear both;animation:ks-foldCubeAngle 2.4s infinite linear both;-webkit-transform-origin:100% 100%;transform-origin:100% 100%}.ksvuefp-preloader .square2{-webkit-transform:scale(1.1) rotate(90deg);transform:scale(1.1) rotate(90deg)}.ksvuefp-preloader .square3{-webkit-transform:scale(1.1) rotate(270deg);transform:scale(1.1) rotate(270deg)}.ksvuefp-preloader .square4{-webkit-transform:scale(1.1) rotate(180deg);transform:scale(1.1) rotate(180deg)}.ksvuefp-preloader .square2 span{-webkit-animation-delay:.3s;animation-delay:.3s}.ksvuefp-preloader .square3 span{-webkit-animation-delay:.9s;animation-delay:.9s}.ksvuefp-preloader .square4 span{-webkit-animation-delay:.6s;animation-delay:.6s}@-webkit-keyframes ks-foldCubeAngle{0%,10%{-webkit-transform:perspective(140px) rotateX(-180deg);transform:perspective(140px) rotateX(-180deg);opacity:0}25%,75%{-webkit-transform:perspective(140px) rotateX(0deg);transform:perspective(140px) rotateX(0deg);opacity:1}90%,to{-webkit-transform:perspective(140px) rotateY(180deg);transform:perspective(140px) rotateY(180deg);opacity:0}}@keyframes ks-foldCubeAngle{0%,10%{-webkit-transform:perspective(140px) rotateX(-180deg);transform:perspective(140px) rotateX(-180deg);opacity:0}25%,75%{-webkit-transform:perspective(140px) rotateX(0deg);transform:perspective(140px) rotateX(0deg);opacity:1}90%,to{-webkit-transform:perspective(140px) rotateY(180deg);transform:perspective(140px) rotateY(180deg);opacity:0}}.ksvuefp-section{background-size:cover;padding:0;margin:0;background-position:50%;background-repeat:no-repeat}.ksvuefp-section,.ksvuefp-section__overlay{height:100%;width:100%;position:absolute;top:0;left:0}.ksvuefp-section__overlay{display:block;z-index:0}.ksvuefp-section__content{width:100%;position:relative;z-index:1}.ksvuefp-section.is-ksvuefp-inactive{position:relative} -------------------------------------------------------------------------------- /dist/ks-vue-fullpage.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * ks-vue-fullpage v1.2.8 3 | * (c) 2017 pirony 4 | * Released under the MIT License. 5 | */ 6 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.KsVueFullpage=t():e.KsVueFullpage=t()}(this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var i=n[o]={i:o,l:!1,exports:{}};return e[o].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=10)}([function(e,t){e.exports=function(e,t,n,o,i){var s,r=e=e||{},a=typeof e.default;"object"!==a&&"function"!==a||(s=e,r=e.default);var u="function"==typeof r?r.options:r;t&&(u.render=t.render,u.staticRenderFns=t.staticRenderFns),o&&(u._scopeId=o);var c;if(i?(c=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"==typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),n&&n.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(i)},u._ssrRegister=c):n&&(c=n),c){var p=u.functional,d=p?u.render:u.beforeCreate;p?u.render=function(e,t){return c.call(t),d(e,t)}:u.beforeCreate=d?[].concat(d,c):[c]}return{esModule:s,exports:r,options:u}}},function(e,t,n){"use strict";(function(e){Object.defineProperty(t,"__esModule",{value:!0}),t.default={bgOffset:function(e,t,n){var o=void 0;switch(e){case"enter":o="up"===t?n||"0.5":-1*n||"-0.5";break;case"leave":o="up"===t?-1*n||"-0.5":n||"0.5"}return o},getDirection:function(e,t){switch(e=e||window.event,e.type){case"mousewheel":case"wheel":return((e.deltaY||-e.wheelDelta||e.detail)>>10||1)<0?"up":"down";case"keydown":switch(e.key){case"ArrowDown":return"slideY"!==t?"none":"down";case"ArrowUp":return"slideY"!==t?"none":"up";case"ArrowLeft":return"slideX"!==t?"none":"up";case"ArrowRight":return"slideX"!==t?"none":"down";default:return"none"}case"swipeup":return"slideX"===t?"none":"down";case"swipeleft":return"slideX"!==t?"none":"down";case"swipedown":return"slideX"===t?"none":"up";case"swiperight":return"slideX"!==t?"none":"up";case"navclick":return e.oldIndex0){var t=new Hammer(e.$el);t.get("swipe").set({direction:Hammer.DIRECTION_ALL}),t.on("swipeup swipedown swiperight swipeleft",function(t){e.changeIndex(t)})}})},computed:{ksvuefpStyles:function(){return{height:this.$ksvuefp.wHeight+"px"}}},methods:{changeIndex:function(e){if(!e.defaultPrevented){var t=this;if(!t.$ksvuefp.slidingActive){var n=t.$ksvuefp.currentIndex,o=t.sections.length,i=t.$ksvuefp.options,r=s.default.getDirection(e,t.$ksvuefp.options.animationType);if("none"!==r&&void 0!==r){var a=void 0;switch(e.type){case"navclick":a=e.nextIndex;break;default:a=s.default.getNextIndex(n,r,o,i)}"none"!==a&&this.$nextTick(function(){t.$ksvuefp.$emit("ksvuefp-change-begin",a,n,r,t.$ksvuefp.options.animDelay),setTimeout(function(){t.$ksvuefp.$emit("ksvuefp-change-done")},t.$ksvuefp.options.duration?t.$ksvuefp.options.duration+t.$ksvuefp.options.animDelay+100:t.$ksvuefp.options.animDelay+1100)})}}}}},watch:{options:{deep:!0,handler:function(e){this.$ksvuefp.$emit("ksvuefp-options-changed",e)}}},beforeDestroy:function(){var e=this;["wheel","mousewheel","keydown"].forEach(function(t){document.removeEventListener(t,e.changeIndex)}),window.addEventListener("resize",function(){e.$ksvuefp.$emit("ksvuefp-resized")}),this.$off(),this.$ksvuefp.$emit("ksvuefp-destroy")}}},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}function i(e){e.prototype.$ksvuefp=new e({data:{fpLoaded:!1,currentIndex:0,slidingActive:!1,sliderDirection:"down",wWidth:0,wHeight:0,options:{}},created:function(){var e=this;e.$on("ksvuefp-ready",function(){e.$emit("ksvuefp-resized"),e.fpLoaded=!0}),e.$on("ksvuefp-options-changed",function(t){e.options=Object.assign({},f.default,t)}),e.$on("ksvuefp-resized",function(){e.getWindowDim()}),e.$on("ksvuefp-destroy",function(){e.fpLoaded=!1,e.currentIndex=0,e.slidingActive=!1,e.sliderDirection="down",e.options={}}),e.$on("ksvuefp-change-begin",function(t,n,o,i){e.slidingActive=!0,e.sliderDirection=o,e.$nextTick(function(){setTimeout(function(){e.currentIndex=t},i||0)})}),e.$on("ksvuefp-change-done",function(){e.slidingActive=!1})},methods:{getWindowDim:function(){var e=this,t=p.default.getWindowDim();e.wWidth=t.wWidth,e.wHeight=t.wHeight,e.$nextTick(function(){e.$ksvuefp.$emit("ksvuefp-change-done")})},canAnimContent:function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(e===this.currentIndex)return!t||!this.slidingActive}}}),e.component("ksvuefp",r.default),e.component("ksvuefp-section",u.default)}Object.defineProperty(t,"__esModule",{value:!0}),t.version=t.ksvuefpSection=t.ksvuefp=void 0;var s=n(5),r=o(s),a=n(4),u=o(a),c=n(1),p=o(c),d=n(3),f=o(d);"undefined"!=typeof window&&window.Vue&&window.Vue.use(i),t.default=i;t.ksvuefp=r.default,t.ksvuefpSection=u.default,t.version="__VERSION__"},function(e,t,n){var o,i;!function(s,r){o=r,void 0!==(i="function"==typeof o?o.call(t,n,t,e):o)&&(e.exports=i)}("undefined"!=typeof window&&window,function(){"use strict";function e(){}var t=e.prototype;return t.on=function(e,t){if(e&&t){var n=this._events=this._events||{},o=n[e]=n[e]||[];return-1==o.indexOf(t)&&o.push(t),this}},t.once=function(e,t){if(e&&t){this.on(e,t);var n=this._onceEvents=this._onceEvents||{};return(n[e]=n[e]||{})[t]=!0,this}},t.off=function(e,t){var n=this._events&&this._events[e];if(n&&n.length){var o=n.indexOf(t);return-1!=o&&n.splice(o,1),this}},t.emitEvent=function(e,t){var n=this._events&&this._events[e];if(n&&n.length){n=n.slice(0),t=t||[];for(var o=this._onceEvents&&this._onceEvents[e],i=0;i", 6 | "main": "dist/ks-vue-fullpage.common.js", 7 | "module": "dist/ks-vue-fullpage.esm.js", 8 | "browser": "dist/ks-vue-fullpage.js", 9 | "unpkg": "dist/ks-vue-fullpage.js", 10 | "style": "dist/ks-vue-fullpage.css", 11 | "files": [ 12 | "dist", 13 | "src" 14 | ], 15 | "scripts": { 16 | "clean": "rimraf dist", 17 | "build": "yon run build:common && yon run build:browser && yon run build:browser:min", 18 | "build:common": "cross-env NODE_ENV=common webpack --config build/webpack.config.common.js --progress --hide-modules", 19 | "build:browser:base": "webpack --config build/webpack.config.browser.js --progress --hide-modules", 20 | "build:browser": "cross-env NODE_ENV=browser yon run build:browser:base", 21 | "build:browser:min": "cross-env NODE_ENV=production yon run build:browser:base -- -p", 22 | "build:dll": "webpack --progress --config build/webpack.config.dll.js", 23 | "lint": "yon run lint:js && yon run lint:css", 24 | "lint:js": "eslint --ext js --ext jsx --ext vue src test/**/*.spec.js test/*.js build", 25 | "lint:js:fix": "yon run lint:js -- --fix", 26 | "lint:css": "stylelint src/**/*.{vue,css}", 27 | "lint:staged": "lint-staged", 28 | "pretest": "yon run lint", 29 | "test": "cross-env BABEL_ENV=test karma start test/karma.conf.js --single-run", 30 | "dev": "webpack-dashboard -- webpack-dev-server --config build/webpack.config.dev.js --open", 31 | "dev:coverage": "cross-env BABEL_ENV=test karma start test/karma.conf.js", 32 | "prepublish": "yon run build" 33 | }, 34 | "lint-staged": { 35 | "*.{vue,jsx,js}": [ 36 | "eslint --fix" 37 | ], 38 | "*.{vue,css}": [ 39 | "stylefmt", 40 | "stylelint", 41 | "stylefmt" 42 | ] 43 | }, 44 | "pre-commit": "lint:staged", 45 | "devDependencies": { 46 | "add-asset-html-webpack-plugin": "^2.0.0", 47 | "babel-core": "^6.24.0", 48 | "babel-eslint": "^7.2.0", 49 | "babel-helper-vue-jsx-merge-props": "^2.0.0", 50 | "babel-loader": "^7.0.0", 51 | "babel-plugin-istanbul": "^4.1.0", 52 | "babel-plugin-syntax-jsx": "^6.18.0", 53 | "babel-plugin-transform-object-rest-spread": "^6.23.0", 54 | "babel-plugin-transform-runtime": "^6.23.0", 55 | "babel-plugin-transform-vue-jsx": "^3.4.0", 56 | "babel-preset-env": "^1.4.0", 57 | "chai": "^3.5.0", 58 | "chai-dom": "^1.4.0", 59 | "cross-env": "^4.0.0", 60 | "css-loader": "^0.28.0", 61 | "eslint": "^3.19.0", 62 | "eslint-config-vue": "^2.0.0", 63 | "eslint-plugin-vue": "^2.0.0", 64 | "extract-text-webpack-plugin": "^2.1.2", 65 | "html-webpack-plugin": "^2.28.0", 66 | "karma": "^1.7.0", 67 | "karma-chai-dom": "^1.1.0", 68 | "karma-chrome-launcher": "^2.1.0", 69 | "karma-coverage": "^1.1.0", 70 | "karma-mocha": "^1.3.0", 71 | "karma-sinon-chai": "^1.3.0", 72 | "karma-sourcemap-loader": "^0.3.7", 73 | "karma-spec-reporter": "^0.0.31", 74 | "karma-webpack": "^2.0.0", 75 | "lint-staged": "^3.4.0", 76 | "mocha": "^3.3.0", 77 | "mocha-css": "^1.0.1", 78 | "node-sass": "^4.5.3", 79 | "null-loader": "^0.1.1", 80 | "postcss": "^6.0.0", 81 | "postcss-cssnext": "^2.10.0", 82 | "pre-commit": "^1.2.0", 83 | "rimraf": "^2.6.0", 84 | "sass-loader": "^6.0.6", 85 | "sinon": "2.2.0", 86 | "sinon-chai": "^2.10.0", 87 | "style-loader": "^0.17.0", 88 | "stylefmt": "^5.3.0", 89 | "stylelint": "^7.10.0", 90 | "stylelint-config-standard": "^16.0.0", 91 | "stylelint-processor-html": "^1.0.0", 92 | "uppercamelcase": "^3.0.0", 93 | "vue": "^2.3.0", 94 | "vue-loader": "^12.0.0", 95 | "vue-template-compiler": "^2.3.0", 96 | "webpack": "^2.5.0", 97 | "webpack-bundle-analyzer": "^2.4.0", 98 | "webpack-dashboard": "^0.4.0", 99 | "webpack-dev-server": "^2.4.0", 100 | "webpack-merge": "^4.0.0", 101 | "yarn-or-npm": "^2.0.0" 102 | }, 103 | "peerDependencies": { 104 | "vue": "^2.3.0" 105 | }, 106 | "dllPlugin": { 107 | "name": "vuePluginTemplateDeps", 108 | "include": [ 109 | "mocha/mocha.js", 110 | "style-loader!css-loader!mocha-css", 111 | "html-entities", 112 | "vue/dist/vue.js", 113 | "chai", 114 | "core-js/library", 115 | "url", 116 | "sockjs-client", 117 | "vue-style-loader/lib/addStylesClient.js", 118 | "events", 119 | "ansi-html", 120 | "style-loader/addStyles.js" 121 | ] 122 | }, 123 | "repository": { 124 | "type": "git", 125 | "url": "git+https://github.com/pirony/ks-vue-fullpage.git" 126 | }, 127 | "bugs": { 128 | "url": "https://github.com/pirony/ks-vue-fullpage/issues" 129 | }, 130 | "homepage": "https://github.com/pirony/ks-vue-fullpage#readme", 131 | "license": { 132 | "type": "MIT", 133 | "url": "http://www.opensource.org/licenses/mit-license.php" 134 | }, 135 | "dependencies": { 136 | "hammerjs": "^2.0.8", 137 | "velocity-animate": "^1.5.0" 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # ks-vue-fullpage 2 | 3 | [![ks-vue-fullpage](https://img.shields.io/npm/v/ks-vue-fullpage.svg)](https://www.npmjs.com/package/ks-vue-fullpage) [![vue2](https://img.shields.io/badge/vue-2.x-brightgreen.svg)](https://vuejs.org/) 4 | 5 | > 6 | A simple, flexible and easy to use Vue plugin to create fullscreen scrolling websites (also known as single page websites or onepage sites). 7 | No jQuery needed, pure Vanilla js. 8 | 9 | Try it in this [ fiddle ](https://jsfiddle.net/romainPouchol/rf7csunm/14/). 10 | 11 | ![ksvuefullpage-demo-slidey](https://user-images.githubusercontent.com/7433657/30744371-1a03b764-9fa2-11e7-8641-e05816e95854.gif) 12 | 13 | 14 | + x-axis or y-axis animations 15 | + w/without subtle parallax animations (on both axis) 16 | + multiple events triggered by the plugin on every components, listenable using vm.$ksvuefp 17 | 18 | Inspired by the awesome jQuery plugin [ "FullPage.js" ](https://github.com/alvarotrigo/fullPage.js), created by [ @Alvarotrigo ](https://github.com/alvarotrigo) 19 | 20 | --- 21 | ## Getting Started 22 | 23 | The plugin only works with 2nd version of Vue.js. Also, you'll need to include Velocity and hammerjs in your bundle (or directly in your html page if you choose the good old script tag method). 24 | 25 | ```bash 26 | npm i --save ks-vue-fullpage 27 | ``` 28 | 29 | ## Usage 30 | 31 | #### With Webpack 32 | 33 | ```js 34 | import KsVueFullpage from 'ks-vue-fullpage' 35 | Vue.use(KsVueFullpage) 36 | ``` 37 | #### With Nuxt 38 | 39 | Create a ksvuefp.js files in yur plugins folder, and add it to yout nuxt.config.js files with ssr: false option 40 | 41 | ksvuefp.js 42 | ```js 43 | import KsVueFullpage from 'ks-vue-fullpage' 44 | Vue.use(KsVueFullpage) 45 | ``` 46 | 47 | nuxt.config.js 48 | ```js 49 | { 50 | ... 51 | plugins: [{ 52 | src: '~/plugins/ksvuefp', 53 | ssr: false 54 | }] 55 | ... 56 | } 57 | ``` 58 | 59 | #### With a script tag 60 | 61 | ```html 62 | 63 | 64 | ``` 65 | 66 | Ks-vue-fullpage registers 2 new components: 67 | 68 | + "ksvuefp", which is the wrapper for our sections 69 | + "ksvuefp-section", which is the single section wrapper you'll use with v-for 70 | 71 | and add $ksvuefp property to every components, available at vm.$ksvuefp 72 | 73 | vm.$ksvuefp returns the following datas object 74 | ```js 75 | { 76 | options: [], // Default options (see below) merged with your prop options 77 | fpLoaded: false, // true when the plugin and his components are totally loaded 78 | currentIndex: 0, // the index currently shown 79 | slidingActive: false, // true if sections transition is occuring 80 | sliderDirection: 'down', // one of 'up' or 'down' 81 | wWidth: 0, // Integer. current screen width 82 | wHeight: 0 // Integer. current screen height 83 | } 84 | ``` 85 | 86 | ### Example code 87 | ```html 88 | ... 89 | // Where options is an object of options, and sections an array containing our sections datas 90 | 91 | 99 | 100 |

{{any_data}}

101 | 102 |
103 | 104 |
105 | ... 106 | 137 | ``` 138 | 139 | ### Default options 140 | 141 | ```js 142 | export default { 143 | /** 144 | * Html params 145 | * @property {String} sectionTag - The tag used to wrap each vsvuefp-section component. 146 | */ 147 | sectionTag: 'div', 148 | /** 149 | * Animation params 150 | * @property {String} animationType - Transition effect between 2 screens. Should be one of 'slideY', 'slideX', or 'fade' 151 | * @property {Number} duration - Duration of transition between 2 screens, in ms 152 | * @property {String} easing - Easing of the transition between 2 screens. Can be all easings supported by Velocity, including bezier curves. ex: [0.2, 0.5, 0.2, 0.5] 153 | * @property {Number} animDelay - Content animation delay. Help you define timing between screens transition and content animations 154 | */ 155 | animationType: 'slideY', 156 | duration: 1000, 157 | easing: 'easeInOutQuad', 158 | animDelay: 0, 159 | /** 160 | * Preloading params 161 | * @property {Boolean} preloaderEnabled - Add a fullscreen preloading overlay with loading animation 162 | * @property {String} preloaderBgColor - Background color for the preloader overlay. 163 | * @property {String} preloaderColor - Preloader icon and text color 164 | * @property {String} preloaderText - The text that will appear under the icon animation during loading 165 | * @property {Boolean} waitForBackgrounds - Wait for sections background images to be fully loaded before triggering $ksvuefp-ready event 166 | */ 167 | preloaderEnabled: true, 168 | preloaderBgColor: '#fff', 169 | preloaderColor: '#212121', 170 | preloaderText: 'Loading...', 171 | waitForBackgrounds: true, 172 | /** 173 | * Navigation params 174 | * @property {Boolean} dotNavEnabled - Add a dot navigation 175 | * @property {String} dotNavPosition - Change dotNav position. Should be one of top, bottom, left or right 176 | * @property {String} dotNavColor - Change dotNav color 177 | * @property {Boolean} loopBottom - Go to first section on scroll down while watching last section 178 | * @property {Boolean} loopTop - Go to last section on scroll up while watching first section 179 | */ 180 | dotNavEnabled: true, 181 | dotNavPosition: 'right', 182 | dotNavColor: '#fff', 183 | loopBottom: false, 184 | loopTop: false, 185 | /** 186 | * Design params 187 | * @property {Boolean - String} overlay - Insert a fullsize div between background and content, and set its background property. Must be a valid css background rule 188 | * @property {Boolean} parallax - Enable parallax effect on section's background 189 | * @property {Float} parallaxOffset - Parallax offset amount, default to 0.5. Should be between 0 and 1. 0 gives no parallax effect, 1 gives a "stacking effect" (the old section remains fixed during transition while the next one slides above it). 190 | */ 191 | overlay: 'rgba(0, 0, 0, 0.2)', 192 | parallax: false, 193 | parallaxOffset: 0.5, 194 | /** 195 | * Touch param 196 | * @property {Boolean} touchEnabled - On/off touch feature in devices with touch screen 197 | */ 198 | touchEnabled: true 199 | } 200 | ``` 201 | 202 | ### Available Properties 203 | 204 | #### ksvuefp component 205 | 206 | Name | Data type | Default value | Description 207 | ----- | ------------- | --- | --- 208 | options | object | - | custom options (cf example above) 209 | sections | array | - | sections list (cf example above) 210 | 211 | #### ksvuefp-section component 212 | 213 | Name | Data type | Default value | Description 214 | ----- | ------------- | --- | --- 215 | section | object, string | - | the single section datas issued from v-for loop (cf example above) 216 | key | int | - | A unique identifier for this item 217 | section-index | int | - | must be the section's index issued from v-for loop (cf example above) 218 | background-image | string | - | must be a valid css background rule. 219 | background-color | string | - | must be a valid css background rule. 220 | 221 | 222 | ### Available Events 223 | 224 | 225 | *You can listen to this events on all components using vm.$ksvuefp.$on :* 226 | 227 | Name | Datas | Description 228 | ----- | ------------- | --- 229 | ksvuefp-ready | - | Triggered when the plugin is fully loaded 230 | ksvuefp-change-begin | nextIndex, oldIndex, direction | Triggered when the animation between 2 sections begins 231 | ksvuefp-change-done | - | Triggered when the animation between 2 sections finishes 232 | ksvuefp-resized | - | Triggered on window.resize 233 | 234 | *You can emit this event from all components using vm.$ksvuefp.$emit :* 235 | 236 | Name | Datas | Description 237 | ----- | ------------- | --- 238 | ksvuefp-nav-click | nextIndex | Changes the current index to nextIndex 239 | 240 | For example, if you want to create a custom navigation: 241 | 242 | ```html 243 | 250 | ``` 251 | 252 | --- 253 | 254 | ## Remaining tasks 255 | 256 | - [x] Add parallax effect on both axis 257 | - [x] Make it Nuxt compatible 258 | - [x] Create demos (in progress) 259 | - [x] Add delay option, to enable content animations before sliding 260 | - [ ] Add better responsive features 261 | 262 | --- 263 | 264 | ## Contribution 265 | 266 | I'm just a lowly frontend developer trying to master ES6, so suggestions are more than welcome, not only for feature requests but also for coding style improvements. 267 | 268 | --- 269 | 270 | ## Licence 271 | 272 | [ MIT ](http://opensource.org/licenses/MIT) 273 | -------------------------------------------------------------------------------- /src/components/ksvuefp-nav.vue: -------------------------------------------------------------------------------- 1 | 10 | 42 | 102 | -------------------------------------------------------------------------------- /src/components/ksvuefp-preloader.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 18 | 19 | 146 | -------------------------------------------------------------------------------- /src/components/ksvuefp-section.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 45 | 46 | 79 | -------------------------------------------------------------------------------- /src/components/ksvuefp.vue: -------------------------------------------------------------------------------- 1 | 12 | 194 | 224 | -------------------------------------------------------------------------------- /src/defaultOptions.js: -------------------------------------------------------------------------------- 1 | export default { 2 | /** 3 | * Html params 4 | * @property {String} sectionTag - The tag used to wrap each vsvuefp-section component. 5 | */ 6 | sectionTag: 'div', 7 | /** 8 | * Animation params 9 | * @property {String} animationType - Transition effect between 2 screens. Should be one of 'slideY', 'slideX', or 'fade' 10 | * @property {Number} duration - Duration of transition between 2 screens, in ms 11 | * @property {String} easing - Easing of the transition between 2 screens. Can be all easings supported by Velocity, including bezier curves. ex: [0.2, 0.5, 0.2, 0.5] 12 | * @property {Number} animDelay - Content animation delay. Help you define timing between screens transition and content animations 13 | */ 14 | animationType: 'slideY', 15 | duration: 1000, 16 | easing: 'easeInOutQuad', 17 | animDelay: 0, 18 | /** 19 | * Preloading params 20 | * @property {Boolean} preloaderEnabled - Add a fullscreen preloading overlay with loading animation 21 | * @property {String} preloaderBgColor - Background color for the preloader overlay. 22 | * @property {String} preloaderColor - Preloader icon and text color 23 | * @property {String} preloaderText - The text that will appear under the icon animation during loading 24 | * @property {Boolean} waitForBackgrounds - Wait for sections background images to be fully loaded before triggering $ksvuefp-ready event 25 | */ 26 | preloaderEnabled: true, 27 | preloaderBgColor: '#fff', 28 | preloaderColor: '#212121', 29 | preloaderText: 'Loading...', 30 | waitForBackgrounds: true, 31 | /** 32 | * Navigation params 33 | * @property {Boolean} dotNavEnabled - Add a dot navigation 34 | * @property {String} dotNavPosition - Change dotNav position. Should be one of top, bottom, left or right 35 | * @property {String} dotNavColor - Change dotNav color 36 | * @property {Boolean} loopBottom - Go to first section on scroll down while watching last section 37 | * @property {Boolean} loopTop - Go to last section on scroll up while watching first section 38 | */ 39 | dotNavEnabled: true, 40 | dotNavColor: '#fff', 41 | loopBottom: false, 42 | loopTop: false, 43 | /** 44 | * Design params 45 | * @property {Boolean - String} overlay - Insert a fullsize div between background and content, and set its background property. Must be a valid css background rule 46 | * @property {Boolean} parallax - Enable parallax effect on section's background 47 | * @property {Float} parallaxOffset - Parallax offset amount, default to 0.5. Should be between 0 and 1. 0 gives no parallax effect, 1 gives a "stacking effect" (the old section remains fixed during transition while the next one slides above it). 48 | */ 49 | overlay: 'rgba(0, 0, 0, 0.2)', 50 | parallax: false, 51 | parallaxOffset: 0.5 52 | } 53 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import ksvuefp from './components/ksvuefp.vue' 2 | import ksvuefpSection from './components/ksvuefp-section.vue' 3 | import utils from './utils' 4 | import options from './defaultOptions' 5 | 6 | function plugin (Vue) { 7 | Vue.prototype.$ksvuefp = new Vue({ 8 | data: { 9 | fpLoaded: false, 10 | currentIndex: 0, 11 | slidingActive: false, 12 | sliderDirection: 'down', 13 | wWidth: 0, 14 | wHeight: 0, 15 | options: {} 16 | }, 17 | created () { 18 | const vm = this 19 | vm.$on('ksvuefp-ready', () => { 20 | vm.$emit('ksvuefp-resized') 21 | vm.fpLoaded = true 22 | }) 23 | vm.$on('ksvuefp-options-changed', (custom) => { 24 | vm.options = Object.assign({}, options, custom) 25 | }) 26 | 27 | vm.$on('ksvuefp-resized', () => { 28 | vm.getWindowDim() 29 | }) 30 | vm.$on('ksvuefp-destroy', () => { 31 | vm.fpLoaded = false 32 | vm.currentIndex = 0 33 | vm.slidingActive = false 34 | vm.sliderDirection = 'down' 35 | vm.options = {} 36 | }) 37 | 38 | vm.$on('ksvuefp-change-begin', (nextIndex, oldIndex, direction, delay) => { 39 | vm.slidingActive = true 40 | vm.sliderDirection = direction 41 | vm.$nextTick(() => { 42 | setTimeout(() => { 43 | vm.currentIndex = nextIndex 44 | }, delay || 0) 45 | }) 46 | }) 47 | 48 | vm.$on('ksvuefp-change-done', () => { 49 | vm.slidingActive = false 50 | }) 51 | }, 52 | methods: { 53 | getWindowDim () { 54 | const vm = this 55 | const Dimensions = utils.getWindowDim() 56 | vm.wWidth = Dimensions.wWidth 57 | vm.wHeight = Dimensions.wHeight 58 | vm.$nextTick(() => { 59 | vm.$ksvuefp.$emit('ksvuefp-change-done') 60 | }) 61 | }, 62 | canAnimContent (index, wait = true) { 63 | if (index !== this.currentIndex) return 64 | if (wait) { 65 | return !this.slidingActive? true : false 66 | } 67 | return true 68 | } 69 | } 70 | }) 71 | Vue.component('ksvuefp', ksvuefp) 72 | Vue.component('ksvuefp-section', ksvuefpSection) 73 | } 74 | 75 | // Install by default if using the script tag 76 | if (typeof window !== 'undefined' && window.Vue) { 77 | window.Vue.use(plugin) 78 | } 79 | 80 | export default plugin 81 | const version = '__VERSION__' 82 | // Export all components too 83 | export { 84 | ksvuefp, 85 | ksvuefpSection, 86 | version 87 | } 88 | -------------------------------------------------------------------------------- /src/ksvuefp-animations.js: -------------------------------------------------------------------------------- 1 | import utils from './utils.js' 2 | 3 | /** 4 | * Get animation params and store it in a constant 5 | * @param {object} ctx - the context 6 | * @param el - the element 7 | * @param {function} done - function to trigger when animation is finished 8 | */ 9 | const getAnimParams = (ctx, el, done) => { 10 | return { 11 | easing: ctx.props.options.easing || 'linear', 12 | duration: ctx.props.options.duration || 1000, 13 | complete () { 14 | // Velocity.hook(el, 'translateX', '0%') 15 | // Velocity.hook(el, 'backgroundPosition', '0 50%') 16 | done() 17 | } 18 | } 19 | } 20 | 21 | // component datas for slideX option 22 | export const slideX = { 23 | 24 | props: ['options', 'slidingActive', 'sliderDirection'], 25 | functional: true, 26 | render: function (h, ctx) { 27 | if (!ctx.parent.$ksvuefp.fpLoaded) return h('transition', ctx.data, ctx.children) // don't animate until the plugin is fully loaded 28 | 29 | ctx.data.on = { 30 | enter (el, done) { 31 | const animObj = {} // empty object where we'll push animations 32 | 33 | if (ctx.props.options.parallax) { // if parallax is activated 34 | /** 35 | * Get section background's offset and store it in a constant 36 | * @param {string} action - enter or leave 37 | * @param {string} direction - up or down 38 | * @param {float} offset - the parallax offset defined in options 39 | */ 40 | const bgOffset = utils.bgOffset('enter', ctx.parent.$ksvuefp.sliderDirection, ctx.props.options.parallaxOffset) 41 | 42 | Velocity.hook(el, 'backgroundPositionX', bgOffset * ctx.parent.$ksvuefp.wWidth + 'px') // Positionate the background before triggering the animation 43 | 44 | animObj['backgroundPosition'] = '0% 50%' // Push bgPosition animation to our empty object animObj 45 | } 46 | 47 | const start = ctx.parent.$ksvuefp.sliderDirection === 'up' ? '-100%' : '100%' // Define the full section's translate animation starting offset 48 | Velocity.hook(el, 'translateX', start) // Positionate the full section before triggering the animation 49 | Velocity.hook(el, 'translateY', '0%') // Positionate the full section before triggering the animation 50 | Velocity.hook(el, 'opacity', 1) 51 | 52 | animObj['translateX'] = '0%' 53 | animObj['translateZ'] = 0 // Force 3d rendering 54 | 55 | /** 56 | * Get animations params 57 | * @param {object} ctx - the context 58 | * @param {object} animObj - the animObject 59 | * @param {function} animParams - Velocity's animation options 60 | */ 61 | const animParams = getAnimParams(ctx, el, done) 62 | 63 | /** 64 | * Velocity anim function 65 | * @param el - the element 66 | * @param {object} animObj - the animObject 67 | * @param {function} animParams - Velocity's animation options 68 | */ 69 | Velocity( 70 | el, 71 | animObj, 72 | animParams 73 | ) 74 | }, 75 | leave (el, done) { 76 | const animObj = {} // empty object where we'll push animations 77 | if (ctx.props.options.parallax) { // if parallax is activated 78 | /** 79 | * Get section background's offset and store it in a constant 80 | * @param {string} action - enter or leave 81 | * @param {string} direction - up or down 82 | * @param {float} offset - the parallax offset defined in options 83 | */ 84 | const bgOffset = utils.bgOffset('leave', ctx.parent.$ksvuefp.sliderDirection, ctx.props.options.parallaxOffset) 85 | 86 | animObj['backgroundPositionX'] = bgOffset * ctx.parent.$ksvuefp.wWidth + 'px' // Push bgPosition animation to our empty object animObj 87 | } 88 | 89 | const end = ctx.parent.$ksvuefp.sliderDirection === 'up' ? '100%' : '-100%' // Define the full section's translate animation starting offset 90 | Velocity.hook(el, 'translateX', '0%')// Positionate the full section before triggering the animation 91 | Velocity.hook(el, 'translateY', '0%')// Positionate the full section before triggering the animation 92 | Velocity.hook(el, 'opacity', 1) 93 | 94 | animObj['translateX'] = end // Push translate animation to our object animObj 95 | animObj['translateZ'] = 0 // Force 3d rendering 96 | 97 | /** 98 | * Get animations params 99 | * @param {object} ctx - the context 100 | * @param {object} animObj - the animObject 101 | * @param {function} animParams - Velocity's animation options 102 | */ 103 | const animParams = getAnimParams(ctx, el, done) 104 | 105 | /** 106 | * Velocity anim function 107 | * @param el - the element 108 | * @param {object} animObj - the animObject 109 | * @param {function} animParams - Velocity's animation options 110 | */ 111 | Velocity( 112 | el, 113 | animObj, 114 | animParams 115 | ) 116 | }, 117 | afterLeave (el) { 118 | Velocity.hook(el, 'backgroundPosition', '50% 50%') 119 | } 120 | } 121 | 122 | return h('transition', ctx.data, ctx.children) 123 | } 124 | } 125 | 126 | // component datas for slideY option 127 | export const slideY = { 128 | props: ['options'], 129 | functional: true, 130 | render: function (h, ctx) { 131 | if (!ctx.parent.$ksvuefp.fpLoaded) return h('transition', ctx.data, ctx.children) // If the plugin is not fully loaded, don't animate and return h() directly 132 | ctx.data.on = { 133 | enter: function (el, done) { 134 | const animObj = {} 135 | 136 | if (ctx.props.options.parallax) { 137 | /** 138 | * Get section background's offset and store it in a constant 139 | * @param {string} action - enter or leave 140 | * @param {string} direction - up or down 141 | * @param {float} offset - the parallax offset defined in options 142 | */ 143 | const bgOffset = utils.bgOffset('enter', ctx.parent.$ksvuefp.sliderDirection, ctx.props.options.parallaxOffset) 144 | 145 | Velocity.hook(el, 'backgroundPositionY', bgOffset * ctx.parent.$ksvuefp.wHeight + 'px') 146 | 147 | animObj['backgroundPositionY'] = '0%' 148 | } 149 | 150 | const start = ctx.parent.$ksvuefp.sliderDirection === 'up' ? '-100%' : '100%' 151 | Velocity.hook(el, 'translateY', start) 152 | Velocity.hook(el, 'translateX', '0%') 153 | Velocity.hook(el, 'opacity', 1) 154 | 155 | animObj['translateY'] = '0%' 156 | animObj['translateZ'] = 0 // Force 3d rendering 157 | 158 | /** 159 | * Get animations params 160 | * @param {object} ctx - the context 161 | * @param {object} animObj - the animObject 162 | * @param {function} animParams - Velocity's animation options 163 | */ 164 | const animParams = getAnimParams(ctx, el, done) 165 | 166 | /** 167 | * Velocity anim function 168 | * @param el - the element 169 | * @param {object} animObj - the animObject 170 | * @param {function} animParams - Velocity's animation options 171 | */ 172 | Velocity( 173 | el, 174 | animObj, 175 | animParams 176 | ) 177 | }, 178 | leave: function (el, done) { 179 | const animObj = {} 180 | 181 | if (ctx.props.options.parallax) { 182 | /** 183 | * Get section background's offset and store it in a constant 184 | * @param {string} action - enter or leave 185 | * @param {string} direction - up or down 186 | * @param {float} offset - the parallax offset defined in options 187 | */ 188 | const bgOffset = utils.bgOffset('leave', ctx.parent.$ksvuefp.sliderDirection, ctx.props.options.parallaxOffset) 189 | 190 | animObj['backgroundPositionY'] = bgOffset * ctx.parent.$ksvuefp.wHeight + 'px' 191 | } 192 | 193 | const end = ctx.parent.$ksvuefp.sliderDirection === 'up' ? '100%' : '-100%' 194 | Velocity.hook(el, 'translateY', '0%') 195 | Velocity.hook(el, 'translateX', '0%') 196 | Velocity.hook(el, 'opacity', 1) 197 | 198 | animObj['translateY'] = end 199 | animObj['translateZ'] = 0 // Force 3d rendering 200 | 201 | /** 202 | * Get animations params 203 | * @param {object} ctx - the context 204 | * @param {object} animObj - the animObject 205 | * @param {function} animParams - Velocity's animation options 206 | */ 207 | const animParams = getAnimParams(ctx, el, done) 208 | /** 209 | * Velocity anim function 210 | * @param el - the element 211 | * @param {object} animObj - the animObject 212 | * @param {function} animParams - Velocity's animation options 213 | */ 214 | Velocity( 215 | el, 216 | animObj, 217 | animParams 218 | ) 219 | }, 220 | afterLeave (el) { 221 | Velocity.hook(el, 'backgroundPosition', '50% 50%') 222 | } 223 | } 224 | return h('transition', ctx.data, ctx.children) 225 | } 226 | } 227 | 228 | // component datas for fade option 229 | export const fade = { 230 | props: ['options'], 231 | functional: true, 232 | render: function (h, ctx) { 233 | ctx.data.on = { 234 | enter: function (el, done) { 235 | Velocity.hook(el, 'translateX', '0%') // Positionate the full section before triggering the animation 236 | Velocity.hook(el, 'translateY', '0%') // Positionate the full section before triggering the animation 237 | Velocity.hook(el, 'opacity', 0) 238 | 239 | /** 240 | * Get animations params 241 | * @param {object} ctx - the context 242 | * @param {object} animObj - the animObject 243 | * @param {function} animParams - Velocity's animation options 244 | */ 245 | const animParams = getAnimParams(ctx, el, done) 246 | 247 | /** 248 | * Velocity anim function 249 | * @param el - the element 250 | * @param {object} animObj - the animObject 251 | * @param {function} animParams - Velocity's animation options 252 | */ 253 | Velocity( 254 | el, 255 | { 256 | opacity: 1 257 | }, 258 | animParams 259 | ) 260 | }, 261 | leave: function (el, done) { 262 | /** 263 | * Get animations params 264 | * @param {object} ctx - the context 265 | * @param {object} animObj - the animObject 266 | * @param {function} animParams - Velocity's animation options 267 | */ 268 | const animParams = getAnimParams(ctx, el, done) 269 | 270 | /** 271 | * Velocity anim function 272 | * @param el - the element 273 | * @param {object} - the animObject 274 | * @param {function} animParams - Velocity's animation options 275 | */ 276 | Velocity( 277 | el, 278 | { 279 | opacity: 0 280 | }, 281 | animParams 282 | ) 283 | } 284 | } 285 | 286 | return h('transition', ctx.data, ctx.children) 287 | } 288 | 289 | } 290 | 291 | // component datas for slideX option 292 | export const dotsAnim = { 293 | functional: true, 294 | render: function (h, ctx) { 295 | ctx.props.name = 'dots-anim' 296 | ctx.data.attrs['appear'] = true 297 | ctx.data.on = { 298 | enter (el, done) { 299 | const animObj = {} 300 | switch (ctx.props.currentPos) { 301 | case 'top': 302 | Velocity.hook(el, 'translateY', '-200px') 303 | animObj['translateY'] = '0px' 304 | break; 305 | case 'bottom': 306 | Velocity.hook(el, 'translateY', '200px') 307 | animObj['translateY'] = '0px' 308 | break; 309 | case 'left': 310 | Velocity.hook(el, 'translateX', '-200px') 311 | animObj['translateX'] = '0px' 312 | break; 313 | case 'right': 314 | Velocity.hook(el, 'translateX', '200px') 315 | animObj['translateX'] = '0px' 316 | break; 317 | } 318 | Velocity( 319 | el, 320 | animObj, 321 | { 322 | delay: el.dataset.index * 40, 323 | complete: done 324 | } 325 | ) 326 | }, 327 | leave (el, done) { 328 | done() 329 | } 330 | } 331 | return h('transition-group', ctx.data, ctx.children) 332 | } 333 | } 334 | 335 | // TODO: add prismX and prismY transitions 336 | -------------------------------------------------------------------------------- /src/utils.js: -------------------------------------------------------------------------------- 1 | export default { 2 | bgOffset (action, direction, offset) { 3 | let res 4 | switch (action) { 5 | case 'enter': 6 | res = direction === 'up' ? offset || '0.5' : offset * -1 || '-0.5' 7 | break 8 | case 'leave': 9 | res = direction === 'up' ? offset * -1 || '-0.5' : offset || '0.5' 10 | break 11 | } 12 | 13 | return res 14 | }, 15 | getDirection (e, animType) { 16 | e = e || window.event 17 | switch (e.type) { 18 | case 'mousewheel': 19 | case 'wheel': 20 | const delta = ((e.deltaY || -e.wheelDelta || e.detail) >> 10) || 1 21 | if (delta < 0) return 'up' 22 | return 'down' 23 | case 'keydown': 24 | switch (e.key) { 25 | case 'ArrowDown': 26 | if (animType !== 'slideY') return 'none' 27 | return 'down' 28 | case 'ArrowUp': 29 | if (animType !== 'slideY') return 'none' 30 | return 'up' 31 | case 'ArrowLeft': 32 | if (animType !== 'slideX') return 'none' 33 | return 'up' 34 | case 'ArrowRight': 35 | if (animType !== 'slideX') return 'none' 36 | return 'down' 37 | default: 38 | return 'none' // Quit when this doesn't handle the key event. 39 | } 40 | case 'swipeup': 41 | if (animType === 'slideX') return 'none' 42 | return 'down' 43 | case 'swipeleft': 44 | if (animType !== 'slideX') return 'none' 45 | return 'down' 46 | case 'swipedown': 47 | if (animType === 'slideX') return 'none' 48 | return 'up' 49 | case 'swiperight': 50 | if (animType !== 'slideX') return 'none' 51 | return 'up' 52 | case 'navclick': 53 | if (e.oldIndex < e.nextIndex) { 54 | return 'down' 55 | } else { 56 | return 'up' 57 | } 58 | default: 59 | return 'none' 60 | 61 | } 62 | }, 63 | getWindowDim () { 64 | if (typeof window === 'undefined') global.window = {} 65 | return { 66 | wHeight: window.innerHeight, 67 | wWidth: window.innerWidth 68 | } 69 | }, 70 | getNextIndex (i, direction, length, options) { 71 | switch (direction) { 72 | case 'down': 73 | if (i !== length - 1) { 74 | i++ 75 | } else { 76 | if (options.loopBottom) i = 0 77 | if (!options.loopBottom) i = 'none' 78 | } 79 | break 80 | case 'up': 81 | if (i !== 0) { 82 | i-- 83 | } else { 84 | if (options.loopTop) i = length - 1 85 | if (!options.loopTop) i = 'none' 86 | } 87 | break 88 | default: 89 | } 90 | return i 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /test/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "mocha": true 4 | }, 5 | "globals": { 6 | "expect": true, 7 | "sinon": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/helpers/Test.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 39 | 40 | 108 | -------------------------------------------------------------------------------- /test/helpers/index.js: -------------------------------------------------------------------------------- 1 | import camelcase from 'camelcase' 2 | import { createVM, Vue } from './utils' 3 | import { nextTick } from './wait-for-update' 4 | 5 | export function dataPropagationTest (Component) { 6 | return function () { 7 | const spy = sinon.spy() 8 | const vm = createVM(this, function (h) { 9 | return ( 10 | Hello 11 | ) 12 | }) 13 | spy.should.have.not.been.called 14 | vm.$('.custom').should.exist 15 | vm.$('.custom').click() 16 | spy.should.have.been.calledOnce 17 | } 18 | } 19 | 20 | export function attrTest (it, base, Component, attr) { 21 | const attrs = Array.isArray(attr) ? attr : [attr] 22 | 23 | attrs.forEach(attr => { 24 | it(attr, function (done) { 25 | const vm = createVM(this, function (h) { 26 | const opts = { 27 | props: { 28 | [camelcase(attr)]: this.active 29 | } 30 | } 31 | return ( 32 | {attr} 33 | ) 34 | }, { 35 | data: { active: true } 36 | }) 37 | vm.$(`.${base}`).should.have.class(`${base}--${attr}`) 38 | vm.active = false 39 | nextTick().then(() => { 40 | vm.$(`.${base}`).should.not.have.class(`${base}--${attr}`) 41 | vm.active = true 42 | }).then(done) 43 | }) 44 | }) 45 | } 46 | 47 | export { 48 | createVM, 49 | Vue, 50 | nextTick 51 | } 52 | -------------------------------------------------------------------------------- /test/helpers/utils.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue/dist/vue.js' 2 | import Test from './Test.vue' 3 | 4 | Vue.config.productionTip = false 5 | const isKarma = !!window.__karma__ 6 | 7 | export function createVM (context, template, opts = {}) { 8 | return isKarma 9 | ? createKarmaTest(context, template, opts) 10 | : createVisualTest(context, template, opts) 11 | } 12 | 13 | const emptyNodes = document.querySelectorAll('nonexistant') 14 | Vue.prototype.$$ = function $$ (selector) { 15 | const els = document.querySelectorAll(selector) 16 | const vmEls = this.$el.querySelectorAll(selector) 17 | const fn = vmEls.length 18 | ? el => vmEls.find(el) 19 | : el => this.$el === el 20 | const found = Array.from(els).filter(fn) 21 | return found.length 22 | ? found 23 | : emptyNodes 24 | } 25 | 26 | Vue.prototype.$ = function $ (selector) { 27 | const els = document.querySelectorAll(selector) 28 | const vmEl = this.$el.querySelector(selector) 29 | const fn = vmEl 30 | ? el => el === vmEl 31 | : el => el === this.$el 32 | // Allow should chaining for tests 33 | return Array.from(els).find(fn) || emptyNodes 34 | } 35 | 36 | export function createKarmaTest (context, template, opts) { 37 | const el = document.createElement('div') 38 | document.getElementById('tests').appendChild(el) 39 | const render = typeof template === 'string' 40 | ? { template: `
${template}
` } 41 | : { render: template } 42 | return new Vue({ 43 | el, 44 | name: 'Test', 45 | ...render, 46 | ...opts 47 | }) 48 | } 49 | 50 | export function createVisualTest (context, template, opts) { 51 | let vm 52 | if (typeof template === 'string') { 53 | opts.components = opts.components || {} 54 | // Let the user define a test component 55 | if (!opts.components.Test) { 56 | opts.components.Test = Test 57 | } 58 | vm = new Vue({ 59 | name: 'TestContainer', 60 | el: context.DOMElement, 61 | template: `${template}`, 62 | ...opts 63 | }) 64 | } else { 65 | // TODO allow redefinition of Test component 66 | vm = new Vue({ 67 | name: 'TestContainer', 68 | el: context.DOMElement, 69 | render (h) { 70 | return h(Test, { 71 | attrs: { 72 | id: context.DOMElement.id 73 | } 74 | // render the passed component with this scope 75 | }, [template.call(this, h)]) 76 | }, 77 | ...opts 78 | }) 79 | } 80 | 81 | context.DOMElement.vm = vm 82 | return vm 83 | } 84 | 85 | export function register (name, component) { 86 | Vue.component(name, component) 87 | } 88 | 89 | export { isKarma, Vue } 90 | -------------------------------------------------------------------------------- /test/helpers/wait-for-update.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue/dist/vue.js' 2 | 3 | // Testing helper 4 | // nextTick().then(() => { 5 | // 6 | // Automatically waits for nextTick 7 | // }).then(() => { 8 | // return a promise or value to skip the wait 9 | // }) 10 | function nextTick () { 11 | const jobs = [] 12 | let done 13 | 14 | const chainer = { 15 | then (cb) { 16 | jobs.push(cb) 17 | return chainer 18 | } 19 | } 20 | 21 | function shift (...args) { 22 | const job = jobs.shift() 23 | let result 24 | try { 25 | result = job(...args) 26 | } catch (e) { 27 | jobs.length = 0 28 | done(e) 29 | } 30 | 31 | // wait for nextTick 32 | if (result !== undefined) { 33 | if (result.then) { 34 | result.then(shift) 35 | } else { 36 | shift(result) 37 | } 38 | } else if (jobs.length) { 39 | requestAnimationFrame(() => Vue.nextTick(shift)) 40 | } 41 | } 42 | 43 | // First time 44 | Vue.nextTick(() => { 45 | done = jobs[jobs.length - 1] 46 | if (done.toString().slice(0, 14) !== 'function (err)') { 47 | throw new Error('waitForUpdate chain is missing .then(done)') 48 | } 49 | shift() 50 | }) 51 | 52 | return chainer 53 | } 54 | 55 | exports.nextTick = nextTick 56 | exports.delay = time => new Promise(resolve => setTimeout(resolve, time)) 57 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | // Polyfill fn.bind() for PhantomJS 2 | import bind from 'function-bind' 3 | /* eslint-disable no-extend-native */ 4 | Function.prototype.bind = bind 5 | 6 | // Polyfill Object.assign for PhantomJS 7 | import objectAssign from 'object-assign' 8 | Object.assign = objectAssign 9 | 10 | // require all src files for coverage. 11 | // you can also change this to match only the subset of files that 12 | // you want coverage for. 13 | const srcContext = require.context('../src', true, /^\.\/(?!index(\.js)?$)/) 14 | srcContext.keys().forEach(srcContext) 15 | 16 | // Use a div to insert elements 17 | before(function () { 18 | const el = document.createElement('DIV') 19 | el.id = 'tests' 20 | document.body.appendChild(el) 21 | }) 22 | 23 | // Remove every test html scenario 24 | afterEach(function () { 25 | const el = document.getElementById('tests') 26 | for (let i = 0; i < el.children.length; ++i) { 27 | el.removeChild(el.children[i]) 28 | } 29 | }) 30 | 31 | const specsContext = require.context('./specs', true) 32 | specsContext.keys().forEach(specsContext) 33 | -------------------------------------------------------------------------------- /test/karma.conf.js: -------------------------------------------------------------------------------- 1 | const merge = require('webpack-merge') 2 | const baseConfig = require('../build/webpack.config.dev.js') 3 | 4 | const webpackConfig = merge(baseConfig, { 5 | // use inline sourcemap for karma-sourcemap-loader 6 | devtool: '#inline-source-map' 7 | }) 8 | 9 | webpackConfig.plugins = [] 10 | 11 | const vueRule = webpackConfig.module.rules.find(rule => rule.loader === 'vue-loader') 12 | vueRule.options = vueRule.options || {} 13 | vueRule.options.loaders = vueRule.options.loaders || {} 14 | vueRule.options.loaders.js = 'babel-loader' 15 | 16 | // no need for app entry during tests 17 | delete webpackConfig.entry 18 | 19 | module.exports = function (config) { 20 | config.set({ 21 | // to run in additional browsers: 22 | // 1. install corresponding karma launcher 23 | // http://karma-runner.github.io/0.13/config/browsers.html 24 | // 2. add it to the `browsers` array below. 25 | browsers: ['Chrome'], 26 | frameworks: ['mocha', 'chai-dom', 'sinon-chai'], 27 | reporters: ['spec', 'coverage'], 28 | files: ['./index.js'], 29 | preprocessors: { 30 | './index.js': ['webpack', 'sourcemap'] 31 | }, 32 | webpack: webpackConfig, 33 | webpackMiddleware: { 34 | noInfo: true 35 | }, 36 | coverageReporter: { 37 | dir: './coverage', 38 | reporters: [ 39 | { type: 'lcov', subdir: '.' }, 40 | { type: 'text-summary' } 41 | ] 42 | } 43 | }) 44 | } 45 | -------------------------------------------------------------------------------- /test/specs/Hello-jsx.spec.js: -------------------------------------------------------------------------------- 1 | import HelloJsx from 'src/Hello.jsx' 2 | import { createVM } from '../helpers/utils.js' 3 | 4 | describe('Hello.jsx', function () { 5 | it('should render correct contents', function () { 6 | const vm = createVM(this, ` 7 | 8 | `, { components: { HelloJsx }}) 9 | vm.$el.querySelector('h1').textContent.should.eql('Hello JSX') 10 | }) 11 | 12 | it('renders JSX too', function () { 13 | // You can write your tests in JSX but make sure to use the lower case 14 | // version of your component because otherw 15 | const vm = createVM(this, h => ( 16 | 17 | ), { components: { HelloJsx }}) 18 | vm.$el.querySelector('h1').textContent.should.eql('Hello JSX') 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /test/specs/Hello.spec.js: -------------------------------------------------------------------------------- 1 | import Hello from 'src/Hello.vue' 2 | import { createVM } from '../helpers/utils.js' 3 | 4 | describe('Hello.vue', function () { 5 | it('should render correct contents', function () { 6 | const vm = createVM(this, ` 7 | 8 | `, { components: { Hello }}) 9 | vm.$el.querySelector('.hello h1').textContent.should.eql('Hello World!') 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /test/visual.js: -------------------------------------------------------------------------------- 1 | import 'style-loader!css-loader!mocha-css' 2 | 3 | // create a div where mocha can add its stuff 4 | const mochaDiv = document.createElement('DIV') 5 | mochaDiv.id = 'mocha' 6 | document.body.appendChild(mochaDiv) 7 | 8 | import 'mocha/mocha.js' 9 | import sinon from 'sinon' 10 | import chai from 'chai' 11 | window.mocha.setup({ 12 | ui: 'bdd', 13 | slow: 750, 14 | timeout: 5000, 15 | globals: [ 16 | '__VUE_DEVTOOLS_INSTANCE_MAP__', 17 | 'script', 18 | 'inject', 19 | 'originalOpenFunction' 20 | ] 21 | }) 22 | window.sinon = sinon 23 | chai.use(require('chai-dom')) 24 | chai.use(require('sinon-chai')) 25 | chai.should() 26 | 27 | let vms = [] 28 | let testId = 0 29 | 30 | beforeEach(function () { 31 | this.DOMElement = document.createElement('DIV') 32 | this.DOMElement.id = `test-${++testId}` 33 | document.body.appendChild(this.DOMElement) 34 | }) 35 | 36 | afterEach(function () { 37 | const testReportElements = document.getElementsByClassName('test') 38 | const lastReportElement = testReportElements[testReportElements.length - 1] 39 | 40 | if (!lastReportElement) return 41 | const el = document.getElementById(this.DOMElement.id) 42 | if (el) lastReportElement.appendChild(el) 43 | // Save the vm to hide it later 44 | if (this.DOMElement.vm) vms.push(this.DOMElement.vm) 45 | }) 46 | 47 | // Hide all tests at the end to prevent some weird bugs 48 | before(function () { 49 | vms = [] 50 | testId = 0 51 | }) 52 | after(function () { 53 | requestAnimationFrame(function () { 54 | setTimeout(function () { 55 | vms.forEach(vm => { 56 | // Hide if test passed 57 | if (!vm.$el.parentElement.classList.contains('fail')) { 58 | vm.$children[0].visible = false 59 | } 60 | }) 61 | }, 100) 62 | }) 63 | }) 64 | 65 | const specsContext = require.context('./specs', true) 66 | specsContext.keys().forEach(specsContext) 67 | 68 | window.mocha.checkLeaks() 69 | window.mocha.run() 70 | --------------------------------------------------------------------------------