├── .eslintignore ├── config ├── prod.env.js ├── test.env.js ├── dev.env.js └── index.js ├── static ├── avatar.jpg ├── images │ ├── favicon.png │ ├── logos │ │ ├── css.png │ │ ├── html.png │ │ ├── php.png │ │ ├── nodejs.png │ │ ├── python.png │ │ ├── sketch.png │ │ ├── javascript.png │ │ └── photoshop.png │ ├── designs │ │ ├── logos.png │ │ ├── mockup_mi4.png │ │ └── mockup_jingmei.png │ └── projects │ │ ├── goszu.jpg │ │ ├── goszu_qrcode.png │ │ ├── powerusage.jpg │ │ ├── szucheduleapp.jpg │ │ ├── powerusage_qrcode.png │ │ └── szucheduleapp_qrcode.png ├── background │ └── jingmei.jpg └── svgs │ ├── navigator │ ├── experiences.svg │ ├── introductions.svg │ ├── articles.svg │ ├── index.svg │ ├── projects.svg │ ├── skills.svg │ ├── designs.svg │ ├── contacts.svg │ └── about.svg │ └── info │ ├── email.svg │ ├── phone.svg │ ├── nowCity.svg │ ├── education.svg │ ├── birthday.svg │ └── company.svg ├── .gitignore ├── test └── unit │ ├── .eslintrc │ ├── specs │ └── Hello.spec.js │ ├── index.js │ └── karma.conf.js ├── src ├── vuex │ ├── mutations.js │ ├── actions.js │ ├── index.js │ └── data.js ├── main.js ├── router.js ├── assets │ └── less │ │ ├── entry.less │ │ ├── _reset.less │ │ ├── _variables.less │ │ ├── common.less │ │ ├── animations.less │ │ └── _normailize.less ├── pages │ ├── skills │ │ ├── index.vue │ │ └── index.less │ ├── introductions │ │ ├── index.vue │ │ └── index.less │ ├── articles │ │ ├── index.less │ │ └── index.vue │ ├── designs │ │ ├── index.less │ │ └── index.vue │ ├── index │ │ ├── index.less │ │ └── index.vue │ └── projects │ │ ├── index.less │ │ └── index.vue ├── components │ ├── languageSwitcher.vue │ └── navigator.vue └── App.vue ├── .editorconfig ├── .babelrc ├── README.md ├── .eslintrc.js ├── index.html └── package.json /.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | config/*.js 3 | -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NODE_ENV: '"production"' 3 | } 4 | -------------------------------------------------------------------------------- /static/avatar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas0ncn/resume/HEAD/static/avatar.jpg -------------------------------------------------------------------------------- /static/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas0ncn/resume/HEAD/static/images/favicon.png -------------------------------------------------------------------------------- /static/background/jingmei.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas0ncn/resume/HEAD/static/background/jingmei.jpg -------------------------------------------------------------------------------- /static/images/logos/css.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas0ncn/resume/HEAD/static/images/logos/css.png -------------------------------------------------------------------------------- /static/images/logos/html.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas0ncn/resume/HEAD/static/images/logos/html.png -------------------------------------------------------------------------------- /static/images/logos/php.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas0ncn/resume/HEAD/static/images/logos/php.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log 5 | test/unit/coverage 6 | *.psd 7 | .vscode/ -------------------------------------------------------------------------------- /static/images/designs/logos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas0ncn/resume/HEAD/static/images/designs/logos.png -------------------------------------------------------------------------------- /static/images/logos/nodejs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas0ncn/resume/HEAD/static/images/logos/nodejs.png -------------------------------------------------------------------------------- /static/images/logos/python.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas0ncn/resume/HEAD/static/images/logos/python.png -------------------------------------------------------------------------------- /static/images/logos/sketch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas0ncn/resume/HEAD/static/images/logos/sketch.png -------------------------------------------------------------------------------- /static/images/logos/javascript.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas0ncn/resume/HEAD/static/images/logos/javascript.png -------------------------------------------------------------------------------- /static/images/logos/photoshop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas0ncn/resume/HEAD/static/images/logos/photoshop.png -------------------------------------------------------------------------------- /static/images/projects/goszu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas0ncn/resume/HEAD/static/images/projects/goszu.jpg -------------------------------------------------------------------------------- /static/images/designs/mockup_mi4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas0ncn/resume/HEAD/static/images/designs/mockup_mi4.png -------------------------------------------------------------------------------- /static/images/projects/goszu_qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas0ncn/resume/HEAD/static/images/projects/goszu_qrcode.png -------------------------------------------------------------------------------- /static/images/projects/powerusage.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas0ncn/resume/HEAD/static/images/projects/powerusage.jpg -------------------------------------------------------------------------------- /static/images/designs/mockup_jingmei.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas0ncn/resume/HEAD/static/images/designs/mockup_jingmei.png -------------------------------------------------------------------------------- /static/images/projects/szucheduleapp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas0ncn/resume/HEAD/static/images/projects/szucheduleapp.jpg -------------------------------------------------------------------------------- /static/images/projects/powerusage_qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas0ncn/resume/HEAD/static/images/projects/powerusage_qrcode.png -------------------------------------------------------------------------------- /static/images/projects/szucheduleapp_qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jas0ncn/resume/HEAD/static/images/projects/szucheduleapp_qrcode.png -------------------------------------------------------------------------------- /test/unit/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "mocha": true 4 | }, 5 | "globals": { 6 | "expect": true, 7 | "sinon": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /config/test.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var devEnv = require('./dev.env') 3 | 4 | module.exports = merge(devEnv, { 5 | NODE_ENV: '"testing"' 6 | }) 7 | -------------------------------------------------------------------------------- /config/dev.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var prodEnv = require('./prod.env') 3 | 4 | module.exports = merge(prodEnv, { 5 | NODE_ENV: '"development"' 6 | }) 7 | -------------------------------------------------------------------------------- /src/vuex/mutations.js: -------------------------------------------------------------------------------- 1 | import data from './data' 2 | 3 | export default { 4 | CHANGELANG (state, lang) { 5 | state.lang = lang 6 | state.data = data[lang] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-2"], 3 | "plugins": ["transform-runtime"], 4 | "comments": false, 5 | "env": { 6 | "test": { 7 | "plugins": [ "istanbul" ] 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import store from './vuex' 3 | 4 | import App from './App' 5 | 6 | /* eslint-disable no-new */ 7 | new Vue({ 8 | el: '#app', 9 | store, 10 | render: h => h(App) 11 | }) 12 | -------------------------------------------------------------------------------- /src/vuex/actions.js: -------------------------------------------------------------------------------- 1 | export default { 2 | changeLanguage ({ commit, state }, lang) { 3 | if (state.lang !== lang) { 4 | commit('CHANGELANG', lang) 5 | window.localStorage.setItem('x-language', lang) 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/unit/specs/Hello.spec.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Hello from 'src/components/Hello' 3 | 4 | describe('Hello.vue', () => { 5 | it('should render correct contents', () => { 6 | const vm = new Vue({ 7 | el: document.createElement('div'), 8 | render: (h) => h(Hello) 9 | }) 10 | expect(vm.$el.querySelector('.hello h1').textContent) 11 | .to.equal('Welcome to Your Vue.js App') 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /src/router.js: -------------------------------------------------------------------------------- 1 | export default [{ 2 | path: 'index', 3 | cn: '简介', 4 | en: 'Home' 5 | }, { 6 | path: 'introductions', 7 | cn: '自我介绍', 8 | en: 'About me' 9 | }, { 10 | path: 'skills', 11 | cn: '技能', 12 | en: 'Skills' 13 | }, { 14 | path: 'projects', 15 | cn: '项目经历', 16 | en: 'Projects' 17 | }, { 18 | path: 'designs', 19 | cn: '设计作品', 20 | en: 'Designs' 21 | }, { 22 | path: 'articles', 23 | cn: '个人博客', 24 | en: 'Articles' 25 | }] 26 | -------------------------------------------------------------------------------- /test/unit/index.js: -------------------------------------------------------------------------------- 1 | // Polyfill fn.bind() for PhantomJS 2 | /* eslint-disable no-extend-native */ 3 | Function.prototype.bind = require('function-bind') 4 | 5 | // require all test files (files that ends with .spec.js) 6 | const testsContext = require.context('./specs', true, /\.spec$/) 7 | testsContext.keys().forEach(testsContext) 8 | 9 | // require all src files except main.js for coverage. 10 | // you can also change this to match only the subset of files that 11 | // you want coverage for. 12 | const srcContext = require.context('src', true, /^\.\/(?!main(\.js)?$)/) 13 | srcContext.keys().forEach(srcContext) 14 | -------------------------------------------------------------------------------- /src/vuex/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | import data from './data' 4 | import actions from './actions' 5 | import mutations from './mutations' 6 | 7 | Vue.use(Vuex) 8 | 9 | // load language data to vuex 10 | let language = window.localStorage.getItem('x-language') 11 | if (!language) { 12 | window.localStorage.setItem('x-language', 'cn') 13 | language = 'cn' 14 | } 15 | document.title = data[language].website.title 16 | 17 | // create store 18 | export default new Vuex.Store({ 19 | state: { 20 | lang: language, 21 | data: data[language] 22 | }, 23 | actions, 24 | mutations 25 | }) 26 | 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Jason's resume 2 | 3 | > My resume powered by vue.js and deploy on ijason.cc 4 | 5 | Website: [https://ijason.cc](https://ijason.cc) 6 | 7 | ## Build Setup 8 | 9 | ``` bash 10 | # install dependencies 11 | npm install 12 | 13 | # serve with hot reload at localhost:8080 14 | npm run dev 15 | 16 | # build for production with minification 17 | npm run build 18 | 19 | # run unit tests 20 | npm run unit 21 | 22 | # run all tests 23 | npm test 24 | ``` 25 | 26 | For detailed explanation on how things work, checkout the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 27 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parser: 'babel-eslint', 4 | parserOptions: { 5 | sourceType: 'module' 6 | }, 7 | // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style 8 | extends: 'standard', 9 | // required to lint *.vue files 10 | plugins: [ 11 | 'html' 12 | ], 13 | // add your custom rules here 14 | 'rules': { 15 | // allow paren-less arrow functions 16 | 'arrow-parens': 0, 17 | // allow async-await 18 | 'generator-star-spacing': 0, 19 | // allow debugger during development 20 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/assets/less/entry.less: -------------------------------------------------------------------------------- 1 | .entry { 2 | position: absolute; 3 | left: 0; 4 | top: 0; 5 | width: 100%; 6 | height: 100%; 7 | 8 | display: flex; 9 | flex-direction: column; 10 | justify-content: center; 11 | align-items: center; 12 | 13 | .page { 14 | opacity: 0; 15 | transform: translateY(100%) translateZ(0); 16 | transition: transform 800ms ease, background 300ms ease; 17 | } 18 | 19 | .currentPage { 20 | opacity: 1; 21 | transform: translateY(0) translateZ(0); 22 | } 23 | 24 | .prePage { 25 | opacity: 1; 26 | transform: translateY(-100%) translateZ(0); 27 | } 28 | 29 | .nextPage { 30 | opacity: 1; 31 | transform: translateY(100%) translateZ(0); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/pages/skills/index.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 24 | 25 | 28 | -------------------------------------------------------------------------------- /src/assets/less/_reset.less: -------------------------------------------------------------------------------- 1 | @import './_variables.less'; 2 | 3 | html { 4 | box-sizing: border-box; 5 | } 6 | 7 | *, 8 | *:before, 9 | *:after { 10 | margin: 0; 11 | padding: 0; 12 | box-sizing: inherit; 13 | } 14 | 15 | body { 16 | font-family: @base-font-family; 17 | color: @base-color; 18 | font-size: @base-font-size; 19 | line-height: @base-line-height; 20 | -webkit-font-smoothing: antialiased; 21 | -moz-osx-font-smoothing: grayscale; 22 | padding: 0; 23 | display: flex; 24 | } 25 | 26 | h1 { 27 | font-size: @h1-font-size; 28 | } 29 | 30 | h2 { 31 | font-size: @h2-font-size; 32 | } 33 | 34 | h3 { 35 | font-size: @h3-font-size; 36 | } 37 | 38 | h4 { 39 | font-size: @h4-font-size; 40 | } 41 | 42 | h5 { 43 | font-size: @h5-font-size; 44 | } 45 | 46 | h6 { 47 | font-size: @h6-font-size; 48 | } 49 | 50 | p { 51 | font-size: @base-font-size; 52 | line-height: @base-line-height; 53 | } 54 | -------------------------------------------------------------------------------- /static/svgs/navigator/experiences.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/less/_variables.less: -------------------------------------------------------------------------------- 1 | /* Color */ 2 | @base-color: #222; 3 | @bg-color: #f8f8f8; 4 | 5 | @gray-base-color: #222; 6 | @gray-darker-color: #333; 7 | @gray-dark-color: #666; 8 | @gray-color: #999; 9 | @gray-light-color: #DDD; 10 | @gray-lighter-color: #EEE; 11 | 12 | @primary-color: #9d48d5; 13 | @info-color: #07bcff; 14 | @success-color: #3acf87; 15 | @warning-color: #f18b28; 16 | @danger-color: #f45757; 17 | 18 | @primary-active-color: darken(@primary-color, 30%); 19 | @info-active-color: darken(@info-color, 30%); 20 | @success-active-color: darken(@success-color, 30%); 21 | @warning-active-color: darken(@warning-color, 30%); 22 | @danger-active-color: darken(@danger-color, 30%); 23 | 24 | /* Font Family */ 25 | @base-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; 26 | 27 | /* Font Size */ 28 | @base-font-size: 16px; 29 | 30 | @h1-font-size: @base-font-size * 2.6; 31 | @h2-font-size: @base-font-size * 2.1; 32 | @h3-font-size: @base-font-size * 1.7; 33 | @h4-font-size: @base-font-size * 1.25; 34 | @h5-font-size: @base-font-size; 35 | @h6-font-size: @base-font-size * .85; 36 | 37 | /* Line Height */ 38 | @base-line-height: 1.4; 39 | -------------------------------------------------------------------------------- /src/assets/less/common.less: -------------------------------------------------------------------------------- 1 | body { 2 | width: 100%; 3 | height: 100%; 4 | overflow: hidden; 5 | } 6 | 7 | .page { 8 | position: fixed; 9 | top: 0; 10 | left: 0; 11 | padding: 40px; 12 | width: 100%; 13 | height: 100%; 14 | background: #FFF; 15 | 16 | display: flex; 17 | flex-direction: column; 18 | justify-content: center; 19 | align-items: center; 20 | 21 | transition: transform 800ms ease; 22 | 23 | .title { 24 | line-height: 80px; 25 | text-align: center; 26 | color: rgba(255,255,255,.9); 27 | text-shadow: 0 0 6px rgba(0,0,0,.2); 28 | } 29 | 30 | .pagebody { 31 | width: 100%; 32 | max-width: 1300px; 33 | height: 100%; 34 | 35 | overflow: hidden; 36 | display: flex; 37 | flex-direction: column; 38 | justify-content: center; 39 | align-items: center; 40 | } 41 | } 42 | 43 | .flexRow { 44 | display: flex; 45 | flex-direction: row; 46 | } 47 | 48 | .flexCol { 49 | display: flex; 50 | flex-direction: column; 51 | } 52 | 53 | .allCenter { 54 | justify-content: center; 55 | align-items: center; 56 | } 57 | 58 | /* adapt mobile browser */ 59 | @media (max-width: 430px) { 60 | .page { 61 | padding: 10px 20px; 62 | 63 | .pagebody { 64 | overflow: visible; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | // see http://vuejs-templates.github.io/webpack for documentation. 2 | var path = require('path') 3 | 4 | module.exports = { 5 | build: { 6 | env: require('./prod.env'), 7 | index: path.resolve(__dirname, '../dist/index.html'), 8 | assetsRoot: path.resolve(__dirname, '../dist'), 9 | assetsSubDirectory: 'static', 10 | assetsPublicPath: 'https://cdn.ijason.cc/', 11 | productionSourceMap: true, 12 | // Gzip off by default as many popular static hosts such as 13 | // Surge or Netlify already gzip all static assets for you. 14 | // Before setting to `true`, make sure to: 15 | // npm install --save-dev compression-webpack-plugin 16 | productionGzip: false, 17 | productionGzipExtensions: ['js', 'css'] 18 | }, 19 | dev: { 20 | env: require('./dev.env'), 21 | port: 8080, 22 | assetsSubDirectory: 'static', 23 | assetsPublicPath: '/', 24 | proxyTable: {}, 25 | // CSS Sourcemaps off by default because relative paths are "buggy" 26 | // with this option, according to the CSS-Loader README 27 | // (https://github.com/webpack/css-loader#sourcemaps) 28 | // In our experience, they generally work as expected, 29 | // just be aware of this issue when enabling this option. 30 | cssSourceMap: false 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /static/svgs/navigator/introductions.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/svgs/navigator/articles.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pages/introductions/index.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 39 | 40 | 43 | -------------------------------------------------------------------------------- /static/svgs/navigator/index.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Jason 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 53 |
54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /static/svgs/navigator/projects.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/less/animations.less: -------------------------------------------------------------------------------- 1 | /** 2 | * mix in 3 | */ 4 | .border-radius(@radius: 4px) { 5 | border-radius: @radius; 6 | } 7 | .box-shadow(@color: rgba(0,0,0,.3)) { 8 | box-shadow: 0 0 20px @color; 9 | } 10 | 11 | /** 12 | * slide up in 13 | * for next route 14 | */ 15 | .slideUpIn-enter-active { 16 | .box-shadow(rgba(0,0,0,.4)); 17 | transform: translateY(0) translateZ(0); 18 | opacity: 1; 19 | } 20 | .slideUpIn-leave-active { 21 | .box-shadow(rgba(0,0,0,.4)); 22 | animation: slide-out 800ms ease; 23 | } 24 | .slideDownIn-enter-active { 25 | .box-shadow(rgba(0,0,0,.4)); 26 | animation: slideDownIn-in 800ms ease; 27 | } 28 | .slideDownIn-leave-active { 29 | .box-shadow(rgba(0,0,0,.4)); 30 | animation: slide-out 800ms ease; 31 | } 32 | 33 | /** 34 | * animation 35 | */ 36 | .animation (@name: fade; @duration: 800ms; @timeFunction: ease; @delay: 300ms; @direction: normal; @fillMode: forwards) { 37 | .transitionFromTransparent(@name); 38 | animation: @name @duration @timeFunction @delay @direction @fillMode; 39 | } 40 | 41 | .transitionFromTransparent (@name) when (@name = fade), (@name = fadeIn) { 42 | opacity: 0; 43 | } 44 | 45 | .fade-enter-active, .fade-leave-active { 46 | .animation(); 47 | } 48 | .fade-enter, .fade-leave-active { 49 | opacity: 0; 50 | } 51 | 52 | // Keyframes 53 | @keyframes slideUpIn-in { 54 | 0% { 55 | transform: translateY(100%) translateZ(0); 56 | opacity: .5; 57 | } 58 | 100% { 59 | transform: translateY(0) translateZ(0); 60 | opacity: 1; 61 | } 62 | } 63 | 64 | @keyframes slideDownIn-in { 65 | 0% { 66 | transform: translateY(-100%) translateZ(0); 67 | } 68 | 100% { 69 | transform: translateY(0) translateZ(0); 70 | } 71 | } 72 | 73 | @keyframes slide-out { 74 | 0% { 75 | transform: scale(1) translateZ(0); 76 | opacity: 1; 77 | } 78 | 100% { 79 | transform: scale(.9) translateZ(0); 80 | opacity: .9; 81 | } 82 | } 83 | 84 | @keyframes fade { 85 | 0% { 86 | opacity: 0; 87 | } 88 | 100% { 89 | opacity: 1; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /test/unit/karma.conf.js: -------------------------------------------------------------------------------- 1 | // This is a karma config file. For more details see 2 | // http://karma-runner.github.io/0.13/config/configuration-file.html 3 | // we are also using it with karma-webpack 4 | // https://github.com/webpack/karma-webpack 5 | 6 | var path = require('path') 7 | var merge = require('webpack-merge') 8 | var baseConfig = require('../../build/webpack.base.conf') 9 | var utils = require('../../build/utils') 10 | var webpack = require('webpack') 11 | var projectRoot = path.resolve(__dirname, '../../') 12 | 13 | var webpackConfig = merge(baseConfig, { 14 | // use inline sourcemap for karma-sourcemap-loader 15 | module: { 16 | loaders: utils.styleLoaders() 17 | }, 18 | devtool: '#inline-source-map', 19 | vue: { 20 | loaders: { 21 | js: 'babel-loader' 22 | } 23 | }, 24 | plugins: [ 25 | new webpack.DefinePlugin({ 26 | 'process.env': require('../../config/test.env') 27 | }) 28 | ] 29 | }) 30 | 31 | // no need for app entry during tests 32 | delete webpackConfig.entry 33 | 34 | // Use babel for test files too 35 | webpackConfig.module.loaders.some(function (loader, i) { 36 | if (/^babel(-loader)?$/.test(loader.loader)) { 37 | loader.include.push(path.resolve(projectRoot, 'test/unit')) 38 | return true 39 | } 40 | }) 41 | 42 | module.exports = function (config) { 43 | config.set({ 44 | // to run in additional browsers: 45 | // 1. install corresponding karma launcher 46 | // http://karma-runner.github.io/0.13/config/browsers.html 47 | // 2. add it to the `browsers` array below. 48 | browsers: ['PhantomJS'], 49 | frameworks: ['mocha', 'sinon-chai'], 50 | reporters: ['spec', 'coverage'], 51 | files: ['./index.js'], 52 | preprocessors: { 53 | './index.js': ['webpack', 'sourcemap'] 54 | }, 55 | webpack: webpackConfig, 56 | webpackMiddleware: { 57 | noInfo: true 58 | }, 59 | coverageReporter: { 60 | dir: './coverage', 61 | reporters: [ 62 | { type: 'lcov', subdir: '.' }, 63 | { type: 'text-summary' } 64 | ] 65 | } 66 | }) 67 | } 68 | -------------------------------------------------------------------------------- /static/svgs/info/email.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/svgs/info/phone.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pages/articles/index.less: -------------------------------------------------------------------------------- 1 | .articles { 2 | background: #E0E3DA; 3 | 4 | .title { 5 | color: #566270; 6 | text-shadow: none; 7 | } 8 | 9 | .pagebody { 10 | flex-direction: row; 11 | justify-content: flex-start; 12 | align-items: center; 13 | flex-wrap: wrap; 14 | 15 | .article { 16 | margin-right: 20px; 17 | padding: 20px; 18 | width: 47%; 19 | background: #FFF; 20 | border-radius: 6px; 21 | text-decoration: none; 22 | color: #566270; 23 | box-shadow: 0 3px 10px rgba(0,0,0,.2); 24 | transition: all 300ms ease; 25 | 26 | .articleTitle { 27 | font-size: 24px; 28 | line-height: 28px; 29 | overflow: hidden; 30 | text-overflow: ellipsis; 31 | white-space: nowrap; 32 | } 33 | 34 | .thumb { 35 | margin-top: 10px; 36 | color: #666; 37 | font-size: 16px; 38 | line-height: 22px; 39 | text-align: justify; 40 | 41 | /* for hide long text */ 42 | display: -webkit-box; 43 | -webkit-box-orient: vertical; 44 | -webkit-line-clamp: 3; 45 | overflow: hidden; 46 | } 47 | 48 | .time { 49 | margin-top: 5px; 50 | color: #888; 51 | font-size: 16px; 52 | line-height: 20px; 53 | justify-content: flex-start; 54 | 55 | svg { 56 | fill: #888; 57 | } 58 | 59 | span { 60 | margin-left: 5px; 61 | } 62 | } 63 | 64 | &:hover { 65 | box-shadow: 0 8px 15px rgba(0,0,0,.2); 66 | } 67 | } 68 | } 69 | } 70 | 71 | /* adapt mobile browser */ 72 | @media (max-width: 430px) { 73 | .articles { 74 | .pagebody { 75 | margin-top: 10px; 76 | flex-direction: column; 77 | justify-content: flex-start; 78 | 79 | .article { 80 | margin-right: 0; 81 | width: 100%; 82 | padding: 10px 20px; 83 | border-radius: 0; 84 | box-shadow: none; 85 | border-top: 1px solid #EEE; 86 | 87 | .articleTitle { 88 | font-size: 18px; 89 | } 90 | 91 | .thumb { 92 | display: none; 93 | } 94 | } 95 | 96 | .article:nth-child(1) { 97 | border-radius: 6px 6px 0 0; 98 | } 99 | 100 | .article:last-child { 101 | border-radius: 0 0 6px 6px; 102 | } 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/pages/introductions/index.less: -------------------------------------------------------------------------------- 1 | @import '../../assets/less/animations.less'; 2 | 3 | .introductions { 4 | background: #516395; 5 | 6 | display: flex; 7 | flex-direction: column; 8 | 9 | .pagebody { 10 | justify-content: flex-start; 11 | 12 | .selfIntroduction, 13 | .selfInformations { 14 | margin-top: 40px; 15 | padding: 20px; 16 | 17 | width: 80%; 18 | 19 | background: #FFF; 20 | border-radius: 4px; 21 | box-shadow: 0 5px 5px rgba(0,0,0,.1); 22 | text-align: center; 23 | 24 | display: flex; 25 | flex-direction: column; 26 | flex-wrap: wrap; 27 | 28 | p { 29 | font-size: 14px; 30 | color: #444; 31 | line-height: 1.7; 32 | } 33 | 34 | .infoRow { 35 | margin: 20px 0; 36 | width: 100%; 37 | display: flex; 38 | flex-direction: row; 39 | justify-content: space-around; 40 | 41 | .infoItem { 42 | width: 150px; 43 | display: flex; 44 | flex-direction: column; 45 | justify-content: center; 46 | align-items: center; 47 | } 48 | } 49 | 50 | .infoCol { 51 | margin: 0; 52 | margin-bottom: 10px; 53 | padding-left: 10px; 54 | flex-direction: column; 55 | display: none; 56 | 57 | .infoItem { 58 | width: auto; 59 | margin-top: 10px; 60 | flex-direction: row; 61 | justify-content: flex-start; 62 | 63 | p { 64 | margin-left: 5px; 65 | } 66 | } 67 | } 68 | } 69 | } 70 | } 71 | 72 | /* adapt mobile browser */ 73 | @media (max-width: 430px) { 74 | .introductions { 75 | .pagebody { 76 | justify-content: center; 77 | 78 | .selfIntroduction, 79 | .selfInformations { 80 | margin-top: 10px; 81 | padding: 10px; 82 | 83 | width: 94%; 84 | 85 | .infoRow { 86 | display: none; 87 | } 88 | 89 | .infoCol { 90 | display: block; 91 | } 92 | } 93 | 94 | .selfIntroduction { 95 | margin-top: 0; 96 | } 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/components/languageSwitcher.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 22 | 23 | 113 | -------------------------------------------------------------------------------- /static/svgs/info/nowCity.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/svgs/info/education.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pages/skills/index.less: -------------------------------------------------------------------------------- 1 | .skills { 2 | background: #FF5F6D; 3 | background: linear-gradient(to left, #FF5F6D , #FFC371); 4 | 5 | display: flex; 6 | flex-direction: column; 7 | 8 | .pagebody { 9 | 10 | .cardContainer { 11 | width: 80%; 12 | display: flex; 13 | flex-direction: row; 14 | justify-content: space-around; 15 | align-items: center; 16 | flex-wrap: wrap; 17 | 18 | .card { 19 | position: relative; 20 | margin: 40px 20px; 21 | width: 170px; 22 | height: 170px; 23 | background: linear-gradient(to bottom, #FFF , #F0F0F0); 24 | border-radius: 50%; 25 | box-shadow: 0 5px 10px rgba(0,0,0,.1); 26 | border: 1px solid rgba(255,255,255,.3); 27 | user-select: none; 28 | transition: all 200ms ease; 29 | 30 | display: flex; 31 | flex-direction: column; 32 | justify-content: center; 33 | align-items: center; 34 | 35 | img { 36 | max-height: 80px; 37 | } 38 | 39 | &:hover { 40 | box-shadow: 0 8px 16px rgba(0,0,0,.2); 41 | } 42 | } 43 | 44 | .card:hover::after { 45 | content: attr(data-desc); 46 | position: absolute; 47 | left: 50%; 48 | top: -30px; 49 | width: 120px; 50 | margin-left: -60px; 51 | padding: 12px; 52 | color: #444; 53 | font-size: 14px; 54 | font-weight: bold; 55 | text-align: center; 56 | border-radius: 4px; 57 | border: 1px solid #F0F0F0; 58 | background: linear-gradient(to bottom, #FFF , #F0F0F0); 59 | box-shadow: 0 3px 5px rgba(0,0,0,.2); 60 | text-shadow: 0 1px 0 #FFF; 61 | animation: slideUp 500ms ease forwards; 62 | opacity: 0; 63 | z-index: 0; 64 | } 65 | } 66 | } 67 | } 68 | 69 | /* adapt mobile browser */ 70 | @media (max-width: 430px) { 71 | .skills { 72 | .pagebody { 73 | 74 | .cardContainer { 75 | width: 100%; 76 | 77 | .card { 78 | margin: 0 10px 10px 10px; 79 | width: 110px; 80 | height: 110px; 81 | 82 | img { 83 | max-height: 50px; 84 | } 85 | } 86 | } 87 | } 88 | } 89 | } 90 | 91 | @keyframes slideUp { 92 | from { 93 | opacity: 0; 94 | transform: translateY(0) translateZ(0); 95 | } 96 | to { 97 | opacity: 1; 98 | transform: translateY(-30px) translateZ(0); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /static/svgs/navigator/skills.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/svgs/info/birthday.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/svgs/navigator/designs.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/svgs/navigator/contacts.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "resume", 3 | "version": "1.0.0", 4 | "description": "My resume powered by vue.js and deploy on ijason.cc", 5 | "author": "Jas0ncn ", 6 | "private": true, 7 | "scripts": { 8 | "dev": "node build/dev-server.js", 9 | "build": "node build/build.js", 10 | "unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run", 11 | "test": "npm run unit", 12 | "lint": "eslint --ext .js,.vue src test/unit/specs" 13 | }, 14 | "dependencies": { 15 | "less": "^2.7.2", 16 | "less-loader": "^2.2.3", 17 | "vue": "^2.1.0", 18 | "vue-router": "^2.1.1", 19 | "vuex": "^2.1.1" 20 | }, 21 | "devDependencies": { 22 | "autoprefixer": "^6.4.0", 23 | "babel-core": "^6.0.0", 24 | "babel-eslint": "^7.0.0", 25 | "babel-loader": "^6.0.0", 26 | "babel-plugin-istanbul": "^3.0.0", 27 | "babel-plugin-transform-runtime": "^6.0.0", 28 | "babel-preset-es2015": "^6.0.0", 29 | "babel-preset-stage-2": "^6.0.0", 30 | "babel-register": "^6.0.0", 31 | "chai": "^3.5.0", 32 | "chalk": "^1.1.3", 33 | "connect-history-api-fallback": "^1.1.0", 34 | "cross-env": "^3.1.3", 35 | "css-loader": "^0.25.0", 36 | "eslint": "^3.7.1", 37 | "eslint-config-standard": "^6.1.0", 38 | "eslint-friendly-formatter": "^2.0.5", 39 | "eslint-loader": "^1.5.0", 40 | "eslint-plugin-html": "^1.3.0", 41 | "eslint-plugin-promise": "^3.4.0", 42 | "eslint-plugin-standard": "^2.0.1", 43 | "eventsource-polyfill": "^0.9.6", 44 | "express": "^4.13.3", 45 | "extract-text-webpack-plugin": "^1.0.1", 46 | "file-loader": "^0.9.0", 47 | "friendly-errors-webpack-plugin": "^1.1.2", 48 | "function-bind": "^1.0.2", 49 | "html-webpack-plugin": "^2.8.1", 50 | "http-proxy-middleware": "^0.17.2", 51 | "inject-loader": "^2.0.1", 52 | "json-loader": "^0.5.4", 53 | "karma": "^1.3.0", 54 | "karma-coverage": "^1.1.1", 55 | "karma-mocha": "^1.2.0", 56 | "karma-phantomjs-launcher": "^1.0.0", 57 | "karma-sinon-chai": "^1.2.0", 58 | "karma-sourcemap-loader": "^0.3.7", 59 | "karma-spec-reporter": "0.0.26", 60 | "karma-webpack": "^1.7.0", 61 | "lolex": "^1.4.0", 62 | "mocha": "^3.1.0", 63 | "opn": "^4.0.2", 64 | "ora": "^0.3.0", 65 | "phantomjs-prebuilt": "^2.1.3", 66 | "semver": "^5.3.0", 67 | "shelljs": "^0.7.4", 68 | "sinon": "^1.17.3", 69 | "sinon-chai": "^2.8.0", 70 | "url-loader": "^0.5.7", 71 | "vue-loader": "^10.0.0", 72 | "vue-style-loader": "^1.0.0", 73 | "vue-template-compiler": "^2.1.0", 74 | "webpack": "^1.13.2", 75 | "webpack-dev-middleware": "^1.8.3", 76 | "webpack-hot-middleware": "^2.12.2", 77 | "webpack-merge": "^0.14.1" 78 | }, 79 | "engines": { 80 | "node": ">= 4.0.0", 81 | "npm": ">= 3.0.0" 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /static/svgs/navigator/about.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pages/articles/index.vue: -------------------------------------------------------------------------------- 1 | 33 | 34 | 40 | 41 | 44 | -------------------------------------------------------------------------------- /static/svgs/info/company.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/navigator.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 35 | 36 | 157 | -------------------------------------------------------------------------------- /src/pages/designs/index.less: -------------------------------------------------------------------------------- 1 | .designs { 2 | display: flex; 3 | flex-direction: column; 4 | 5 | .pagebody { 6 | position: relative; 7 | 8 | .section { 9 | position: absolute; 10 | top: 0; 11 | left: 0; 12 | width: 100%; 13 | height: 100%; 14 | opacity: 0; 15 | transform: translateX(100%) translateZ(0); 16 | transition: all 1s ease; 17 | 18 | .desc { 19 | width: 500px; 20 | 21 | .descTitle, .subTitle, .description, .link { 22 | color: #FFF; 23 | text-shadow: 0 2px 2px rgba(0,0,0,.3); 24 | } 25 | 26 | .descTitle { 27 | font-size: 56px; 28 | line-height: 80px; 29 | } 30 | 31 | .subTitle { 32 | font-size: 28px; 33 | line-height: 60px; 34 | font-weight: normal; 35 | } 36 | 37 | .description { 38 | font-size: 18px; 39 | line-height: 30px; 40 | text-align: justify; 41 | } 42 | 43 | .link { 44 | margin-top: 20px; 45 | padding: 10px 0; 46 | width: 300px; 47 | font-size: 18px; 48 | text-decoration: none; 49 | border: 1px solid #FFF; 50 | border-radius: 6px; 51 | transition: all 300ms ease; 52 | 53 | svg { 54 | fill: #FFF; 55 | } 56 | 57 | &:hover { 58 | background: rgba(255,255,255,.2); 59 | } 60 | } 61 | } 62 | 63 | .mockup { 64 | height: 500px; 65 | user-select: none; 66 | } 67 | } 68 | 69 | .currentSection { 70 | opacity: 1; 71 | transform: translateX(0) translateZ(0); 72 | } 73 | 74 | .preSection { 75 | transform: translateX(-100%) translateZ(0); 76 | } 77 | 78 | .prePageBtn, .nextPageBtn { 79 | position: absolute; 80 | bottom: 0; 81 | opacity: .6; 82 | cursor: pointer; 83 | transition: opacity 300ms ease; 84 | 85 | svg { 86 | fill: #FFF; 87 | } 88 | 89 | &:hover { 90 | opacity: 1; 91 | } 92 | } 93 | 94 | .prePageBtn { 95 | left: 0; 96 | } 97 | 98 | .nextPageBtn { 99 | right: 0; 100 | } 101 | } 102 | } 103 | 104 | .logos { 105 | .title { 106 | color: #333; 107 | text-shadow: none; 108 | } 109 | 110 | .pagebody { 111 | .section { 112 | .desc { 113 | .descTitle, .subTitle, .description, .link { 114 | color: #444; 115 | text-shadow: none; 116 | } 117 | 118 | .link { 119 | border: 1px solid #444; 120 | 121 | svg { 122 | fill: #444; 123 | } 124 | 125 | &:hover { 126 | background: rgba(0,0,0,.2); 127 | } 128 | } 129 | } 130 | } 131 | 132 | .prePageBtn, .nextPageBtn { 133 | opacity: .6; 134 | 135 | svg { 136 | fill: #444; 137 | } 138 | 139 | &:hover { 140 | opacity: 1; 141 | } 142 | } 143 | } 144 | } 145 | 146 | /* adapt mobile browser */ 147 | @media (max-width: 430px) { 148 | .designs { 149 | .pagebody { 150 | .section { 151 | flex-direction: column-reverse !important; 152 | justify-content: flex-end; 153 | 154 | .desc { 155 | width: 100%; 156 | 157 | .descTitle { 158 | font-size: 28px; 159 | line-height: 50px; 160 | } 161 | 162 | .subTitle { 163 | font-size: 18px; 164 | line-height: 30px; 165 | } 166 | 167 | .description { 168 | font-size: 12px; 169 | line-height: 20px; 170 | } 171 | } 172 | 173 | .link { 174 | margin: 20px auto; 175 | } 176 | 177 | .mockup { 178 | height: 200px; 179 | user-select: none; 180 | } 181 | } 182 | } 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /src/pages/index/index.less: -------------------------------------------------------------------------------- 1 | @import '../../assets/less/animations.less'; 2 | 3 | .index { 4 | background: radial-gradient(ellipse farthest-corner, #FFFFFF, #EEEEEE); 5 | display: flex; 6 | flex-direction: column; 7 | justify-content: center; 8 | align-items: center; 9 | 10 | .avatar { 11 | width: 150px; 12 | height: 150px; 13 | margin-top: -60px; 14 | 15 | border-radius: 50%; 16 | border: 5px solid #FFF; 17 | box-shadow: 0 5px 10px rgba(0,0,0,.1); 18 | 19 | overflow: hidden; 20 | display: flex; 21 | justify-content: center; 22 | align-items: center; 23 | 24 | img { 25 | width: 100%; 26 | user-select: none; 27 | } 28 | } 29 | 30 | .name { 31 | margin-top: 20px; 32 | 33 | color: #444; 34 | font-size: 32px; 35 | line-height: 60px; 36 | 37 | display: block; 38 | } 39 | 40 | .shortDescription { 41 | color: #777; 42 | line-height: 60px; 43 | } 44 | 45 | .social { 46 | width: 100%; 47 | height: 80px; 48 | 49 | display: flex; 50 | justify-content: center; 51 | align-items: center; 52 | 53 | .blog { 54 | .socialIcon(@color: rgba(0,0,0,.5); @activeColor: #6ca397; blog) 55 | } 56 | .github { 57 | .socialIcon(@color: rgba(0,0,0,.5); @activeColor: #444444; github) 58 | } 59 | .ui { 60 | .socialIcon(@color: rgba(0,0,0,.5); @activeColor: #3498db; ui) 61 | } 62 | .zhihu { 63 | .socialIcon(@color: rgba(0,0,0,.5); @activeColor: #0f88eb; zhihu) 64 | } 65 | .weibo { 66 | .socialIcon(@color: rgba(0,0,0,.5); @activeColor: #fa7d3c; weibo) 67 | } 68 | } 69 | 70 | .footer { 71 | position: absolute; 72 | left: 0; 73 | bottom: 20px; 74 | width: 100%; 75 | text-align: center; 76 | color: #999; 77 | display: flex; 78 | flex-direction: column; 79 | 80 | span { 81 | animation: float 1s infinite ease alternate-reverse; 82 | } 83 | 84 | a { 85 | color: #999; 86 | font-size: 14px; 87 | line-height: 40px; 88 | text-decoration: none; 89 | } 90 | } 91 | } 92 | 93 | /* social icons */ 94 | .socialIcon(@color: #333; @activeColor: #4078c0; @animationName: draw) { 95 | position: relative; 96 | 97 | width: 70px; 98 | height: 70px; 99 | cursor: pointer; 100 | 101 | .svgAndAnimations(@color; @activeColor; @animationName); 102 | 103 | .icon { 104 | position: absolute; 105 | top: 0; 106 | left: 0; 107 | 108 | width: 70px; 109 | height: 70px; 110 | 111 | display: flex; 112 | justify-content: center; 113 | align-items: center; 114 | 115 | svg { 116 | fill: @color; 117 | transition: all 500ms; 118 | } 119 | 120 | &:hover { 121 | svg { 122 | fill: @activeColor; 123 | } 124 | } 125 | } 126 | } 127 | .svgAndAnimations(@color: #333; @activeColor: #4078c0; @animationName: draw) { 128 | .circle { 129 | fill: transparent; 130 | stroke-width: 1px; 131 | stroke: @color; 132 | stroke-dasharray: 0 200; 133 | stroke-dashoffset: -200; 134 | transition: all 300ms; 135 | } 136 | 137 | &:hover .circle { 138 | -webkit-animation: @animationName 500ms ease forwards; 139 | animation: @animationName 500ms ease forwards; 140 | } 141 | 142 | @keyframes @animationName { 143 | 0% { 144 | stroke-dasharray: 0 200; 145 | stroke-dashoffset: -200; 146 | } 147 | 100% { 148 | stroke-dasharray: 200; 149 | stroke-dashoffset: 0; 150 | stroke-width: 1px; 151 | stroke: @activeColor; 152 | } 153 | } 154 | } 155 | /* social icon end*/ 156 | 157 | /* animation */ 158 | @keyframes float { 159 | 0% { 160 | transform: translateY(-5px) 161 | } 162 | 100% { 163 | transform: translateY(5px) 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 55 | 56 | 173 | 174 | 180 | -------------------------------------------------------------------------------- /src/pages/projects/index.less: -------------------------------------------------------------------------------- 1 | .projects { 2 | background: #283048; 3 | background: linear-gradient(to left, #283048 , #859398); 4 | 5 | display: flex; 6 | flex-direction: column; 7 | 8 | .pagebody { 9 | display: flex; 10 | flex-direction: column; 11 | justify-content: center; 12 | align-items: center; 13 | 14 | .cardContainer { 15 | width: 80%; 16 | 17 | display: flex; 18 | flex-direction: row; 19 | justify-content: space-around; 20 | align-items: center; 21 | 22 | .card { 23 | position: relative; 24 | margin: 0 10px; 25 | padding: 10px; 26 | padding-bottom: 60px; 27 | width: 280px; 28 | height: 400px; 29 | background: linear-gradient(to bottom, #FFF , #F0F0F0); 30 | border-radius: 6px; 31 | box-shadow: 0 5px 10px rgba(0,0,0,.1); 32 | border: 1px solid rgba(255,255,255,.3); 33 | transition: all 300ms ease; 34 | 35 | display: flex; 36 | flex-direction: column; 37 | justify-content: space-around; 38 | align-items: center; 39 | 40 | .screenshot { 41 | height: 150px; 42 | border-radius: 4px; 43 | user-select: none; 44 | } 45 | 46 | .description { 47 | margin-top: 6px; 48 | font-size: 16px; 49 | line-height: 28px; 50 | text-indent: 2em; 51 | text-align: justify; 52 | } 53 | 54 | .tool { 55 | position: absolute; 56 | left: 0; 57 | bottom: 0; 58 | width: 100%; 59 | padding: 10px; 60 | 61 | display: flex; 62 | flex-direction: row; 63 | justify-content: space-between; 64 | align-items: center; 65 | 66 | .btn { 67 | width: 48%; 68 | height: 36px; 69 | border: 1px solid #859398; 70 | background: transparent; 71 | border-radius: 4px; 72 | cursor: pointer; 73 | opacity: .6; 74 | transition: all 300ms ease; 75 | outline: 0; 76 | 77 | display: flex; 78 | flex-direction: row; 79 | justify-content: center; 80 | align-items: center; 81 | 82 | svg { 83 | fill: #859398; 84 | } 85 | 86 | &:hover { 87 | opacity: 1; 88 | background: #859398; 89 | 90 | svg { 91 | fill: #FFF; 92 | } 93 | } 94 | } 95 | } 96 | 97 | &:hover { 98 | box-shadow: 0 12px 24px rgba(0,0,0,.3); 99 | } 100 | } 101 | } 102 | 103 | .seeGithub { 104 | margin-top: 50px; 105 | padding: 15px 0; 106 | width: 40%; 107 | color: #FFF; 108 | text-decoration: none; 109 | border: 1px solid #FFF; 110 | border-radius: 6px; 111 | opacity: .7; 112 | transition: all 300ms ease; 113 | 114 | display: flex; 115 | flex-direction: row; 116 | justify-content: center; 117 | align-items: center; 118 | 119 | p { 120 | margin-left: 10px; 121 | } 122 | 123 | &:hover { 124 | opacity: 1; 125 | background: rgba(255,255,255,.2); 126 | } 127 | } 128 | } 129 | 130 | .qrcodeContainerMask { 131 | position: fixed; 132 | top: 0; 133 | left: 0; 134 | width: 100%; 135 | height: 100%; 136 | background: rgba(0,0,0,.6); 137 | transition: opacity 300ms ease; 138 | pointer-events: none; 139 | opacity: 0; 140 | z-index: 30; 141 | 142 | display: flex; 143 | flex-direction: column; 144 | justify-content: center; 145 | align-items: center; 146 | 147 | .qrcodeContainer { 148 | width: 220px; 149 | height: 220px; 150 | padding: 10px; 151 | background: linear-gradient(to bottom, #FFF , #F0F0F0); 152 | border-radius: 6px; 153 | transform: translateY(30px) translateZ(0); 154 | transition: transform 300ms ease; 155 | box-shadow: 0 5px 15px rgba(0,0,0,.3); 156 | 157 | .qrcode { 158 | width: 100%; 159 | height: 100%; 160 | } 161 | } 162 | } 163 | 164 | .showQrcode { 165 | opacity: 1; 166 | pointer-events: auto; 167 | 168 | .qrcodeContainer { 169 | transform: translateY(0) translateZ(0); 170 | } 171 | } 172 | } 173 | 174 | /* adapt mobile browser */ 175 | @media (max-width: 430px) { 176 | .projects { 177 | .pagebody { 178 | .cardContainer { 179 | position: relative; 180 | width: 100%; 181 | height: 420px; 182 | 183 | .card { 184 | margin: 0; 185 | position: absolute; 186 | top: 50%; 187 | left: 50%; 188 | width: 280px; 189 | margin: -200px 0 0 -140px; 190 | transition: all 300ms ease; 191 | 192 | .tool { 193 | .btn { 194 | width: 100%; 195 | } 196 | 197 | .qrcodebtn { 198 | display: none; 199 | } 200 | } 201 | 202 | &:hover { 203 | box-shadow: 0 5px 10px rgba(0,0,0,.1); 204 | } 205 | } 206 | 207 | .currentSection { 208 | transform: translateX(0) translateZ(0); 209 | box-shadow: 0 12px 24px rgba(0,0,0,.3); 210 | } 211 | 212 | .preSection { 213 | transform: translateX(-300px) translateZ(0); 214 | } 215 | 216 | .nextSection { 217 | transform: translateX(300px) translateZ(0); 218 | } 219 | } 220 | 221 | .seeGithub { 222 | margin-top: 10px; 223 | width: 280px; 224 | opacity: 1; 225 | } 226 | } 227 | } 228 | } 229 | -------------------------------------------------------------------------------- /src/pages/designs/index.vue: -------------------------------------------------------------------------------- 1 | 57 | 58 | 81 | 82 | 85 | -------------------------------------------------------------------------------- /src/pages/projects/index.vue: -------------------------------------------------------------------------------- 1 | 50 | 51 | 91 | 92 | 95 | -------------------------------------------------------------------------------- /src/vuex/data.js: -------------------------------------------------------------------------------- 1 | /** 2 | * All data of the website 3 | * In order to support multi-languages 4 | * (Now support Chinese and English) 5 | */ 6 | // import route map 7 | import routeMap from '../router' 8 | 9 | const __RES__ = JSON.parse(JSON.stringify(window.__RES__)) 10 | 11 | const articles = __RES__.contentsSortedByTime.slice(0, 6).map(art => { 12 | art = __RES__.contents[art] 13 | 14 | return { 15 | title: art.title, 16 | thumb: art.desc.slice(0, 200), 17 | url: `https://blog.ijason.cc/article/${art.name}`, 18 | time: art.mtime 19 | } 20 | }) 21 | 22 | const base = { 23 | title: 'Jason 的简历', 24 | name: '陈俊毅', 25 | shortDescription: '大四学生,前端工程师进阶中...', 26 | description: '高中接触 Web 开发和设计,上了大学正式学习前端、PHP、Node.js,大一开始在校不间断负责多个公众号、小程序的开发。目前在腾讯公司 Web 前端开发岗位实习。', 27 | infomations: [{ 28 | icon: 'https://cdn.ijason.cc/static/svgs/info/birthday.svg', 29 | key: '生日', 30 | value: '1996.2.11' 31 | }, { 32 | icon: 'https://cdn.ijason.cc/static/svgs/info/education.svg', 33 | key: '教育经历', 34 | value: '深圳大学 · 通信工程' 35 | }, { 36 | icon: 'https://cdn.ijason.cc/static/svgs/info/nowCity.svg', 37 | key: '居住地', 38 | value: '广东 · 深圳' 39 | }, { 40 | icon: 'https://cdn.ijason.cc/static/svgs/info/email.svg', 41 | key: '邮箱', 42 | value: 'jason@iszu.cn' 43 | }, { 44 | icon: 'https://cdn.ijason.cc/static/svgs/info/phone.svg', 45 | key: '手机号', 46 | value: '+86 13128931074' 47 | }, { 48 | icon: 'https://cdn.ijason.cc/static/svgs/info/company.svg', 49 | key: '公司', 50 | value: '腾讯 · 深圳' 51 | }], 52 | skills: [{ 53 | value: 'HTML', 54 | logo: 'https://cdn.ijason.cc/static/images/logos/html.png' 55 | }, { 56 | value: 'CSS', 57 | logo: 'https://cdn.ijason.cc/static/images/logos/css.png' 58 | }, { 59 | value: 'JavaScript', 60 | logo: 'https://cdn.ijason.cc/static/images/logos/javascript.png', 61 | style: { 62 | background: 'linear-gradient(to bottom, #ffeb0e , #efdd1b)', 63 | 'border-color': '#ffeb0e' 64 | } 65 | }, { 66 | value: 'Node.js', 67 | logo: 'https://cdn.ijason.cc/static/images/logos/nodejs.png', 68 | style: { 69 | background: 'linear-gradient(to bottom, #8ccf00 , #80bd01)', 70 | 'border-color': '#8ccf00' 71 | } 72 | }, { 73 | value: 'PHP', 74 | logo: 'https://cdn.ijason.cc/static/images/logos/php.png', 75 | style: { 76 | background: 'linear-gradient(to bottom, #8093d1 , #7b8ec9)', 77 | 'border-color': '#8093d1' 78 | } 79 | }, { 80 | value: 'Python', 81 | logo: 'https://cdn.ijason.cc/static/images/logos/python.png' 82 | }, { 83 | value: 'Photoshop', 84 | logo: 'https://cdn.ijason.cc/static/images/logos/photoshop.png', 85 | style: { 86 | background: '#001d26', 87 | border: '5px solid #00c8ff' 88 | } 89 | }, { 90 | value: 'Sketch', 91 | logo: 'https://cdn.ijason.cc/static/images/logos/sketch.png', 92 | style: { 93 | background: 'linear-gradient(to bottom, #1d0f4f , #130a33)', 94 | 'border-color': '#1d0f4f' 95 | } 96 | }], 97 | projects: [{ 98 | image: 'https://cdn.ijason.cc/static/images/projects/goszu.jpg', 99 | desc: '一个为深圳大学学生开发的网址导航,收集了大部分学生常用或者难找的网站。前端使用 Vue.js 开发,后端使用 PHP 和 MySQL 搭建,用户首次访问即缓存网站数据在 LocalStorage 里面。', 100 | url: 'http://www.goszu.com/', 101 | qrcode: 'https://cdn.ijason.cc/static/images/projects/goszu_qrcode.png' 102 | }, { 103 | image: 'https://cdn.ijason.cc/static/images/projects/powerusage.jpg', 104 | desc: '这是一个宿舍电费查询工具,每天会自动抓取当天剩余可用电量,并可根据最近一周使用情况计算出剩余可用的天数。同时,在电费不足的时候,会自动通过微信公众号发送模板消息提醒用户。', 105 | url: 'http://www.wacxt.cn/powerusage/', 106 | qrcode: 'https://cdn.ijason.cc/static/images/projects/powerusage_qrcode.png' 107 | }, { 108 | image: 'https://cdn.ijason.cc/static/images/projects/szucheduleapp.jpg', 109 | desc: '一款为深圳大学学生开发的课表查询 App,可以自动同步教务处网站上的课程信息,随时随地查询课程表及课程详细信息。是一款使用 Vue.js 三件套和 Cordove 开发的一款 Hybrid App。', 110 | url: 'https://github.com/heyszu/szuschedule-app', 111 | qrcode: 'https://cdn.ijason.cc/static/images/projects/szucheduleapp_qrcode.png' 112 | }], 113 | projectRefer: '在我的 Github 查看更多项目', 114 | designs: { 115 | jingmei: { 116 | background: `#859398`, 117 | mainImage: 'https://cdn.ijason.cc/static/images/designs/mockup_jingmei.png', 118 | title: '静魅', 119 | subTitle: '魅族 FlymeOS 主题', 120 | desc: '这是 2014 年我参加魅族主题大赛的参赛作品,设计风格采用了无棱角图标,搭配饱和度较低的配色,与山水背景衬托出一种静和清爽的感觉。', 121 | link: 'http://www.ui.cn/detail/26910.html', 122 | linkRefer: '去 ui.cn 查看详情', 123 | posi: 'left' 124 | }, 125 | mi4Mockup: { 126 | background: '#222', 127 | mainImage: 'https://cdn.ijason.cc/static/images/designs/mockup_mi4.png', 128 | title: '小米 4 模型', 129 | subTitle: '手机展示模型 Psd', 130 | desc: '临摹小米官网的小米手机4模型。全矢量绘制,屏幕部分采用智能对象,可嵌入展示图片。', 131 | link: 'http://www.ui.cn/detail/21758.html', 132 | linkRefer: '去 ui.cn 查看详情', 133 | posi: 'left' 134 | }, 135 | logos: { 136 | background: '#F8F8F8', 137 | mainImage: 'https://cdn.ijason.cc/static/images/designs/logos.png', 138 | title: 'LOGO', 139 | subTitle: '', 140 | desc: '为一些公众号的和网站所设计的Logo', 141 | link: '', 142 | linkRefer: '', 143 | posi: 'left' 144 | } 145 | }, 146 | articles 147 | } 148 | 149 | const en = { 150 | title: `Jason's resume`, 151 | name: 'Jason Chen', 152 | shortDescription: 'A student, front-end developer...', 153 | description: `I started learning front-end development and participating in development and maintenance of a number of WeChat public accounts in school when I was a freshman at university. At the same time, I began to follow the open source community and the front-end ecosystem closely. Now work in Tencent as trainee.`, 154 | infomations: [{ 155 | icon: 'https://cdn.ijason.cc/static/svgs/info/birthday.svg', 156 | key: 'Birthday', 157 | value: '1996.2.11' 158 | }, { 159 | icon: 'https://cdn.ijason.cc/static/svgs/info/education.svg', 160 | key: 'Education', 161 | value: 'CIE · SZU' 162 | }, { 163 | icon: 'https://cdn.ijason.cc/static/svgs/info/nowCity.svg', 164 | key: 'Live in', 165 | value: 'Shenzhen, Guangdong' 166 | }, { 167 | icon: 'https://cdn.ijason.cc/static/svgs/info/email.svg', 168 | key: 'Email', 169 | value: 'jason@iszu.cn' 170 | }, { 171 | icon: 'https://cdn.ijason.cc/static/svgs/info/phone.svg', 172 | key: 'Phone Number', 173 | value: '+86 13128931074' 174 | }, { 175 | icon: 'https://cdn.ijason.cc/static/svgs/info/company.svg', 176 | key: 'Company', 177 | value: 'Tencent.Inc' 178 | }], 179 | projects: [{ 180 | image: 'https://cdn.ijason.cc/static/images/projects/goszu.jpg', 181 | desc: 'A website navigation for students of Shenzhen University. It collects many commonly used websites and some websites hard to find. This site is powered by Vue.js and Node.js for backend.', 182 | url: 'http://www.goszu.com/', 183 | qrcode: 'https://cdn.ijason.cc/static/images/projects/goszu_qrcode.png' 184 | }, { 185 | image: 'https://cdn.ijason.cc/static/images/projects/powerusage.jpg', 186 | desc: `It's a website that can query the remaining electricity of dormitory, predict available days based on your usage, and also can push low-power-warning via Wechat.`, 187 | url: 'http://www.wacxt.cn/powerusage/', 188 | qrcode: 'https://cdn.ijason.cc/static/images/projects/powerusage_qrcode.png' 189 | }, { 190 | image: 'https://cdn.ijason.cc/static/images/projects/szucheduleapp.jpg', 191 | desc: `A app can auto sync class schedule from server. You can inquire your class infomations everywhere. It's based on Cordova and Vue.js and Node.js for backend. `, 192 | url: 'https://github.com/heyszu/szuschedule-app', 193 | qrcode: 'https://cdn.ijason.cc/static/images/projects/szucheduleapp_qrcode.png' 194 | }], 195 | projectRefer: 'See more projects in my Github', 196 | designs: { 197 | jingmei: { 198 | background: `#859398`, 199 | mainImage: 'https://cdn.ijason.cc/static/images/designs/mockup_jingmei.png', 200 | title: 'Silence', 201 | subTitle: 'Theme for FlymeOS', 202 | desc: 'This is a theme designing for MEIZU Flyme Theme Competition 2014. No edges and corners icons, with low saturation color and the wallpaper to bring out a quiet feeling.', 203 | link: 'http://www.ui.cn/detail/26910.html', 204 | linkRefer: 'See detail in ui.cn', 205 | posi: 'left' 206 | }, 207 | mi4Mockup: { 208 | background: '#222', 209 | mainImage: 'https://cdn.ijason.cc/static/images/designs/mockup_mi4.png', 210 | title: 'Mi4 Mockup', 211 | subTitle: 'Phone mockup psd', 212 | desc: 'Copy painting from offcial website of Xiaomi 4. Fully vector painting, the screen use intelligent object, can be embedded in the display picture.', 213 | link: 'http://www.ui.cn/detail/21758.html', 214 | linkRefer: 'See detail in ui.cn', 215 | posi: 'left' 216 | }, 217 | logos: { 218 | background: '#F8F8F8', 219 | mainImage: 'https://cdn.ijason.cc/static/images/designs/logos.png', 220 | title: 'Logos', 221 | subTitle: '', 222 | desc: 'Design for some websites and Wechat Public Accounts.', 223 | link: '', 224 | linkRefer: '去 ui.cn 查看详情', 225 | posi: 'left' 226 | } 227 | } 228 | } 229 | 230 | export default { 231 | cn: { 232 | website: base, 233 | route: routeMap.map(v => v.cn) 234 | }, 235 | en: { 236 | website: Object.assign({}, base, en), 237 | route: routeMap.map(v => v.en) 238 | } 239 | } 240 | -------------------------------------------------------------------------------- /src/assets/less/_normailize.less: -------------------------------------------------------------------------------- 1 | /*! normalize.css v4.2.0 | MIT License | github.com/necolas/normalize.css */ 2 | 3 | /** 4 | * 1. Change the default font family in all browsers (opinionated). 5 | * 2. Correct the line height in all browsers. 6 | * 3. Prevent adjustments of font size after orientation changes in IE and iOS. 7 | */ 8 | 9 | /* Document 10 | ========================================================================== */ 11 | 12 | html { 13 | font-family: sans-serif; /* 1 */ 14 | line-height: 1.15; /* 2 */ 15 | -ms-text-size-adjust: 100%; /* 3 */ 16 | -webkit-text-size-adjust: 100%; /* 3 */ 17 | } 18 | 19 | /* Sections 20 | ========================================================================== */ 21 | 22 | /** 23 | * Remove the margin in all browsers (opinionated). 24 | */ 25 | 26 | body { 27 | margin: 0; 28 | } 29 | 30 | /** 31 | * Add the correct display in IE 9-. 32 | */ 33 | 34 | article, 35 | aside, 36 | footer, 37 | header, 38 | nav, 39 | section { 40 | display: block; 41 | } 42 | 43 | /** 44 | * Correct the font size and margin on `h1` elements within `section` and 45 | * `article` contexts in Chrome, Firefox, and Safari. 46 | */ 47 | 48 | h1 { 49 | font-size: 2em; 50 | margin: 0.67em 0; 51 | } 52 | 53 | /* Grouping content 54 | ========================================================================== */ 55 | 56 | /** 57 | * Add the correct display in IE 9-. 58 | * 1. Add the correct display in IE. 59 | */ 60 | 61 | figcaption, 62 | figure, 63 | main { /* 1 */ 64 | display: block; 65 | } 66 | 67 | /** 68 | * Add the correct margin in IE 8. 69 | */ 70 | 71 | figure { 72 | margin: 1em 40px; 73 | } 74 | 75 | /** 76 | * 1. Add the correct box sizing in Firefox. 77 | * 2. Show the overflow in Edge and IE. 78 | */ 79 | 80 | hr { 81 | box-sizing: content-box; /* 1 */ 82 | height: 0; /* 1 */ 83 | overflow: visible; /* 2 */ 84 | } 85 | 86 | /** 87 | * 1. Correct the inheritance and scaling of font size in all browsers. 88 | * 2. Correct the odd `em` font sizing in all browsers. 89 | */ 90 | 91 | pre { 92 | font-family: monospace, monospace; /* 1 */ 93 | font-size: 1em; /* 2 */ 94 | } 95 | 96 | /* Text-level semantics 97 | ========================================================================== */ 98 | 99 | /** 100 | * 1. Remove the gray background on active links in IE 10. 101 | * 2. Remove gaps in links underline in iOS 8+ and Safari 8+. 102 | */ 103 | 104 | a { 105 | background-color: transparent; /* 1 */ 106 | -webkit-text-decoration-skip: objects; /* 2 */ 107 | } 108 | 109 | /** 110 | * Remove the outline on focused links when they are also active or hovered 111 | * in all browsers (opinionated). 112 | */ 113 | 114 | a:active, 115 | a:hover { 116 | outline-width: 0; 117 | } 118 | 119 | /** 120 | * 1. Remove the bottom border in Firefox 39-. 121 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. 122 | */ 123 | 124 | abbr[title] { 125 | border-bottom: none; /* 1 */ 126 | text-decoration: underline; /* 2 */ 127 | text-decoration: underline dotted; /* 2 */ 128 | } 129 | 130 | /** 131 | * Prevent the duplicate application of `bolder` by the next rule in Safari 6. 132 | */ 133 | 134 | b, 135 | strong { 136 | font-weight: inherit; 137 | } 138 | 139 | /** 140 | * Add the correct font weight in Chrome, Edge, and Safari. 141 | */ 142 | 143 | b, 144 | strong { 145 | font-weight: bolder; 146 | } 147 | 148 | /** 149 | * 1. Correct the inheritance and scaling of font size in all browsers. 150 | * 2. Correct the odd `em` font sizing in all browsers. 151 | */ 152 | 153 | code, 154 | kbd, 155 | samp { 156 | font-family: monospace, monospace; /* 1 */ 157 | font-size: 1em; /* 2 */ 158 | } 159 | 160 | /** 161 | * Add the correct font style in Android 4.3-. 162 | */ 163 | 164 | dfn { 165 | font-style: italic; 166 | } 167 | 168 | /** 169 | * Add the correct background and color in IE 9-. 170 | */ 171 | 172 | mark { 173 | background-color: #ff0; 174 | color: #000; 175 | } 176 | 177 | /** 178 | * Add the correct font size in all browsers. 179 | */ 180 | 181 | small { 182 | font-size: 80%; 183 | } 184 | 185 | /** 186 | * Prevent `sub` and `sup` elements from affecting the line height in 187 | * all browsers. 188 | */ 189 | 190 | sub, 191 | sup { 192 | font-size: 75%; 193 | line-height: 0; 194 | position: relative; 195 | vertical-align: baseline; 196 | } 197 | 198 | sub { 199 | bottom: -0.25em; 200 | } 201 | 202 | sup { 203 | top: -0.5em; 204 | } 205 | 206 | /* Embedded content 207 | ========================================================================== */ 208 | 209 | /** 210 | * Add the correct display in IE 9-. 211 | */ 212 | 213 | audio, 214 | video { 215 | display: inline-block; 216 | } 217 | 218 | /** 219 | * Add the correct display in iOS 4-7. 220 | */ 221 | 222 | audio:not([controls]) { 223 | display: none; 224 | height: 0; 225 | } 226 | 227 | /** 228 | * Remove the border on images inside links in IE 10-. 229 | */ 230 | 231 | img { 232 | border-style: none; 233 | } 234 | 235 | /** 236 | * Hide the overflow in IE. 237 | */ 238 | 239 | svg:not(:root) { 240 | overflow: hidden; 241 | } 242 | 243 | /* Forms 244 | ========================================================================== */ 245 | 246 | /** 247 | * 1. Change font properties to `inherit` in all browsers (opinionated). 248 | * 2. Remove the margin in Firefox and Safari. 249 | */ 250 | 251 | button, 252 | input, 253 | optgroup, 254 | select, 255 | textarea { 256 | font: inherit; /* 1 */ 257 | margin: 0; /* 2 */ 258 | } 259 | 260 | /** 261 | * Restore the font weight unset by the previous rule. 262 | */ 263 | 264 | optgroup { 265 | font-weight: bold; 266 | } 267 | 268 | /** 269 | * Show the overflow in IE. 270 | * 1. Show the overflow in Edge. 271 | */ 272 | 273 | button, 274 | input { /* 1 */ 275 | overflow: visible; 276 | } 277 | 278 | /** 279 | * Remove the inheritance of text transform in Edge, Firefox, and IE. 280 | * 1. Remove the inheritance of text transform in Firefox. 281 | */ 282 | 283 | button, 284 | select { /* 1 */ 285 | text-transform: none; 286 | } 287 | 288 | /** 289 | * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video` 290 | * controls in Android 4. 291 | * 2. Correct the inability to style clickable types in iOS and Safari. 292 | */ 293 | 294 | button, 295 | html [type="button"], /* 1 */ 296 | [type="reset"], 297 | [type="submit"] { 298 | -webkit-appearance: button; /* 2 */ 299 | } 300 | 301 | /** 302 | * Remove the inner border and padding in Firefox. 303 | */ 304 | 305 | button::-moz-focus-inner, 306 | [type="button"]::-moz-focus-inner, 307 | [type="reset"]::-moz-focus-inner, 308 | [type="submit"]::-moz-focus-inner { 309 | border-style: none; 310 | padding: 0; 311 | } 312 | 313 | /** 314 | * Restore the focus styles unset by the previous rule. 315 | */ 316 | 317 | button:-moz-focusring, 318 | [type="button"]:-moz-focusring, 319 | [type="reset"]:-moz-focusring, 320 | [type="submit"]:-moz-focusring { 321 | outline: 1px dotted ButtonText; 322 | } 323 | 324 | /** 325 | * Change the border, margin, and padding in all browsers (opinionated). 326 | */ 327 | 328 | fieldset { 329 | border: 1px solid #c0c0c0; 330 | margin: 0 2px; 331 | padding: 0.35em 0.625em 0.75em; 332 | } 333 | 334 | /** 335 | * 1. Correct the text wrapping in Edge and IE. 336 | * 2. Correct the color inheritance from `fieldset` elements in IE. 337 | * 3. Remove the padding so developers are not caught out when they zero out 338 | * `fieldset` elements in all browsers. 339 | */ 340 | 341 | legend { 342 | box-sizing: border-box; /* 1 */ 343 | color: inherit; /* 2 */ 344 | display: table; /* 1 */ 345 | max-width: 100%; /* 1 */ 346 | padding: 0; /* 3 */ 347 | white-space: normal; /* 1 */ 348 | } 349 | 350 | /** 351 | * 1. Add the correct display in IE 9-. 352 | * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. 353 | */ 354 | 355 | progress { 356 | display: inline-block; /* 1 */ 357 | vertical-align: baseline; /* 2 */ 358 | } 359 | 360 | /** 361 | * Remove the default vertical scrollbar in IE. 362 | */ 363 | 364 | textarea { 365 | overflow: auto; 366 | } 367 | 368 | /** 369 | * 1. Add the correct box sizing in IE 10-. 370 | * 2. Remove the padding in IE 10-. 371 | */ 372 | 373 | [type="checkbox"], 374 | [type="radio"] { 375 | box-sizing: border-box; /* 1 */ 376 | padding: 0; /* 2 */ 377 | } 378 | 379 | /** 380 | * Correct the cursor style of increment and decrement buttons in Chrome. 381 | */ 382 | 383 | [type="number"]::-webkit-inner-spin-button, 384 | [type="number"]::-webkit-outer-spin-button { 385 | height: auto; 386 | } 387 | 388 | /** 389 | * 1. Correct the odd appearance in Chrome and Safari. 390 | * 2. Correct the outline style in Safari. 391 | */ 392 | 393 | [type="search"] { 394 | -webkit-appearance: textfield; /* 1 */ 395 | outline-offset: -2px; /* 2 */ 396 | } 397 | 398 | /** 399 | * Remove the inner padding and cancel buttons in Chrome and Safari on OS X. 400 | */ 401 | 402 | [type="search"]::-webkit-search-cancel-button, 403 | [type="search"]::-webkit-search-decoration { 404 | -webkit-appearance: none; 405 | } 406 | 407 | /** 408 | * 1. Correct the inability to style clickable types in iOS and Safari. 409 | * 2. Change font properties to `inherit` in Safari. 410 | */ 411 | 412 | ::-webkit-file-upload-button { 413 | -webkit-appearance: button; /* 1 */ 414 | font: inherit; /* 2 */ 415 | } 416 | 417 | /* Interactive 418 | ========================================================================== */ 419 | 420 | /* 421 | * Add the correct display in IE 9-. 422 | * 1. Add the correct display in Edge, IE, and Firefox. 423 | */ 424 | 425 | details, /* 1 */ 426 | menu { 427 | display: block; 428 | } 429 | 430 | /* 431 | * Add the correct display in all browsers. 432 | */ 433 | 434 | summary { 435 | display: list-item; 436 | } 437 | 438 | /* Scripting 439 | ========================================================================== */ 440 | 441 | /** 442 | * Add the correct display in IE 9-. 443 | */ 444 | 445 | canvas { 446 | display: inline-block; 447 | } 448 | 449 | /** 450 | * Add the correct display in IE. 451 | */ 452 | 453 | template { 454 | display: none; 455 | } 456 | 457 | /* Hidden 458 | ========================================================================== */ 459 | 460 | /** 461 | * Add the correct display in IE 10-. 462 | */ 463 | 464 | [hidden] { 465 | display: none; 466 | } -------------------------------------------------------------------------------- /src/pages/index/index.vue: -------------------------------------------------------------------------------- 1 | 71 | 72 | 77 | 78 | 81 | --------------------------------------------------------------------------------