├── .babelrc
├── .editorconfig
├── .gitignore
├── README.md
├── build
└── gh-pages.js
├── docs
└── images
│ ├── akira.gif
│ ├── haruki.gif
│ ├── hideo.gif
│ ├── hoshi.gif
│ ├── ichiro.gif
│ ├── isao.gif
│ ├── jiro.gif
│ ├── juro.gif
│ ├── kaede.gif
│ ├── kuro.gif
│ ├── kyo.gif
│ ├── madoka.gif
│ ├── minoru.gif
│ └── yoko.gif
├── examples
├── App.vue
├── index.html
├── main.js
├── me.svg
└── themes.json
├── package.json
├── rollup.config.js
├── src
├── components
│ └── EffectInput.vue
├── images
│ └── logo.png
├── index.js
└── styles
│ ├── akira.styl
│ ├── common.styl
│ ├── fonts
│ └── .gitkeep
│ ├── haruki.styl
│ ├── hideo.styl
│ ├── hoshi.styl
│ ├── ichiro.styl
│ ├── index.styl
│ ├── isao.styl
│ ├── jiro.styl
│ ├── juro.styl
│ ├── kaede.styl
│ ├── kuro.styl
│ ├── kyo.styl
│ ├── madoka.styl
│ ├── manami.styl
│ ├── minoru.styl
│ ├── nariko.styl
│ ├── template.styl
│ ├── variables.styl
│ └── yoko.styl
└── webpack.config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["env", { "modules": false }],
4 | "stage-3"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | dist/
4 | sites/
5 | npm-debug.log
6 | yarn-error.log
7 |
8 | # Editor directories and files
9 | .idea
10 | *.suo
11 | *.ntvs*
12 | *.njsproj
13 | *.sln
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # effect-input
2 |
3 | [![NPM version][badge-npm-version]][url-npm]
4 | [![Node version][badge-node-version]][url-npm]
5 | [![NPM download][badge-npm-download]][url-npm]
6 | ![Dependencies][badge-dependencies]
7 | ![License][badge-license]
8 |
9 | 优雅而绚丽的适用于 Vue 2.0 的 `input` 组件。极大提高交互效果和输入愉悦性。
10 |
11 | [![NPM][image-npm]][url-npm]
12 |
13 | > 深受 [TextInputEffects][url-TextInputEffects] 的启发。
14 |
15 |
16 |
17 | ## 概览
18 |
19 | [访问在线示例](https://xbt1.github.io/effect-input)
20 |
21 | ## 安装
22 |
23 | ```bash
24 | $ yarn add effect-input # npm i -S effect-input
25 | ```
26 |
27 | ## 使用
28 |
29 | 一个简单的例子
30 |
31 | ```javascript
32 | import EffectInput from 'effect-input'
33 | import 'effect-input/dist/index.css'
34 |
35 | Vue.use(EffectInput)
36 | ```
37 |
38 | ```html
39 |
40 |
41 |
42 | ```
43 |
44 | ## 主题
45 |
46 | `effect-input` 的 `type` 属性为主题名,目前有如下主题:
47 |
48 | ### `haruki`
49 |
50 | 
51 |
52 | ### `hoshi`
53 |
54 | 
55 |
56 | ### `kuro`
57 |
58 | 
59 |
60 | ### `jiro`
61 |
62 | 
63 |
64 | ### `minoru`
65 |
66 | 
67 |
68 | ### `yoko`
69 |
70 | 
71 |
72 | ### `hideo`
73 |
74 | 
75 |
76 | ### `kyo`
77 |
78 | 
79 |
80 | ### `akira`
81 |
82 | 
83 |
84 | ### `ichiro`
85 |
86 | 
87 |
88 | ### `juro`
89 |
90 | 
91 |
92 | ### `madoka`
93 |
94 | 
95 |
96 | ### `kaede`
97 |
98 | 
99 |
100 | ### `isao`
101 |
102 | 
103 |
104 |
105 | ## 开发
106 |
107 | ```bash
108 | $ npm install
109 | $ npm run dev
110 | ```
111 |
112 | ## 构建
113 |
114 | ```bash
115 | $ npm run build:package # 构建 npm 包
116 | $ npm run build:example # 构建示例站点
117 | $ npm run build # build:package & build:example
118 | ```
119 |
120 | ## TODOs
121 |
122 | - 添加更多主题
123 | - SET 2
124 | - [x] `manami`
125 | - [x] `nariko`
126 | - [ ] `nao`
127 | - [ ] `yoshiko`
128 | - [ ] `shoko`
129 | - [ ] `chisato`
130 | - [ ] `makiko`
131 | - [ ] `sae`
132 | - [ ] `kozakura`
133 | - [ ] `fumi`
134 | - [ ] `ruri`
135 | - [ ] `kohana`
136 |
137 | ## 更新日志
138 |
139 | 详见 [releases][url-releases]
140 |
141 |
142 | [badge-npm-version]: https://img.shields.io/npm/v/effect-input.svg
143 | [badge-node-version]: https://img.shields.io/node/v/effect-input.svg
144 | [badge-npm-download]: https://img.shields.io/npm/dt/effect-input.svg
145 | [badge-license]: https://img.shields.io/github/license/xbt1/effect-input.svg
146 | [badge-dependencies]: https://img.shields.io/david/dev/xbt1/effect-input.svg
147 |
148 | [url-TextInputEffects]: https://tympanus.net/Development/TextInputEffects/index.html
149 | [url-npm]: https://npmjs.org/package/effect-input
150 | [url-dependencies]: https://david-dm.org/vkbansal/effect-input
151 | [url-releases]: https://github.com/XBT1/effect-input/releases
152 |
153 | [image-npm]: https://nodei.co/npm/effect-input.png
154 |
155 |
--------------------------------------------------------------------------------
/build/gh-pages.js:
--------------------------------------------------------------------------------
1 | const ghpages = require('gh-pages')
2 |
3 | ghpages.publish('sites', (err) => {
4 | err && console.log(err)
5 | })
6 |
--------------------------------------------------------------------------------
/docs/images/akira.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CyberNika/effect-input/7c41b3c1d5e7dd0500888bdb4cee32f712764982/docs/images/akira.gif
--------------------------------------------------------------------------------
/docs/images/haruki.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CyberNika/effect-input/7c41b3c1d5e7dd0500888bdb4cee32f712764982/docs/images/haruki.gif
--------------------------------------------------------------------------------
/docs/images/hideo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CyberNika/effect-input/7c41b3c1d5e7dd0500888bdb4cee32f712764982/docs/images/hideo.gif
--------------------------------------------------------------------------------
/docs/images/hoshi.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CyberNika/effect-input/7c41b3c1d5e7dd0500888bdb4cee32f712764982/docs/images/hoshi.gif
--------------------------------------------------------------------------------
/docs/images/ichiro.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CyberNika/effect-input/7c41b3c1d5e7dd0500888bdb4cee32f712764982/docs/images/ichiro.gif
--------------------------------------------------------------------------------
/docs/images/isao.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CyberNika/effect-input/7c41b3c1d5e7dd0500888bdb4cee32f712764982/docs/images/isao.gif
--------------------------------------------------------------------------------
/docs/images/jiro.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CyberNika/effect-input/7c41b3c1d5e7dd0500888bdb4cee32f712764982/docs/images/jiro.gif
--------------------------------------------------------------------------------
/docs/images/juro.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CyberNika/effect-input/7c41b3c1d5e7dd0500888bdb4cee32f712764982/docs/images/juro.gif
--------------------------------------------------------------------------------
/docs/images/kaede.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CyberNika/effect-input/7c41b3c1d5e7dd0500888bdb4cee32f712764982/docs/images/kaede.gif
--------------------------------------------------------------------------------
/docs/images/kuro.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CyberNika/effect-input/7c41b3c1d5e7dd0500888bdb4cee32f712764982/docs/images/kuro.gif
--------------------------------------------------------------------------------
/docs/images/kyo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CyberNika/effect-input/7c41b3c1d5e7dd0500888bdb4cee32f712764982/docs/images/kyo.gif
--------------------------------------------------------------------------------
/docs/images/madoka.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CyberNika/effect-input/7c41b3c1d5e7dd0500888bdb4cee32f712764982/docs/images/madoka.gif
--------------------------------------------------------------------------------
/docs/images/minoru.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CyberNika/effect-input/7c41b3c1d5e7dd0500888bdb4cee32f712764982/docs/images/minoru.gif
--------------------------------------------------------------------------------
/docs/images/yoko.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CyberNika/effect-input/7c41b3c1d5e7dd0500888bdb4cee32f712764982/docs/images/yoko.gif
--------------------------------------------------------------------------------
/examples/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
30 |
31 |
32 |
33 | {{ item.type | upper-case }}
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
50 |
51 |
52 |
53 |
101 |
102 |
181 |
182 |
189 |
190 |
--------------------------------------------------------------------------------
/examples/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | text-input-effects
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/examples/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | import EffectInput from '../src'
5 | import '../src/styles/index.styl'
6 |
7 | // import EffectInput from 'effect-input'
8 | // import 'effect-input/dist/index.css'
9 |
10 | Vue.use(EffectInput)
11 |
12 | new Vue({
13 | el: '#app',
14 | render: h => h(App)
15 | })
16 |
--------------------------------------------------------------------------------
/examples/me.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/themes.json:
--------------------------------------------------------------------------------
1 | [
2 | [
3 | {
4 | "type": "haruki",
5 | "bgColor": "#f0efee"
6 | },
7 | {
8 | "type": "hoshi",
9 | "bgColor": "#f9f7f6"
10 | },
11 | {
12 | "type": "kuro",
13 | "bgColor": "#2f3238",
14 | "color": "#fff"
15 | },
16 | {
17 | "type": "jiro",
18 | "bgColor": "#d0d6d6"
19 | },
20 | {
21 | "type": "minoru",
22 | "bgColor": "#f9f7f6"
23 | },
24 | {
25 | "type": "yoko",
26 | "bgColor": "#dd665c"
27 | },
28 | {
29 | "type": "hideo",
30 | "bgColor": "#f9f7f6"
31 | },
32 | {
33 | "type": "kyo",
34 | "bgColor": "#e8e8e8",
35 | "activeColor": "rgba(11, 43, 205, 0.6)"
36 | },
37 | {
38 | "type": "akira",
39 | "bgColor": "#2f3238",
40 | "color": "#fff"
41 | },
42 | {
43 | "type": "ichiro",
44 | "bgColor": "#f9f7f6"
45 | },
46 | {
47 | "type": "juro",
48 | "color": "#fff",
49 | "bgColor": "#38a9ea"
50 | },
51 | {
52 | "type": "madoka",
53 | "color": "#fff",
54 | "bgColor": "#2f3238"
55 | },
56 | {
57 | "type": "kaede",
58 | "bgColor": "#f9f7f6"
59 | },
60 | {
61 | "type": "isao",
62 | "color": "#fff",
63 | "bgColor": "#3d4444"
64 | }
65 | ],
66 | [
67 | {
68 | "type": "manami",
69 | "bgColor": "#e8e8e8"
70 | },
71 | {
72 | "type": "nariko",
73 | "bgColor": "#d0d6d6"
74 | }
75 | ]
76 | ]
77 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "effect-input",
3 | "description": "Text Input Effects for Vue.js - Simple ideas for enhancing text input interactions",
4 | "version": "0.1.1",
5 | "author": "XBT1 ",
6 | "main": "dist/index.common.js",
7 | "files": [
8 | "src",
9 | "dist"
10 | ],
11 | "keywords": [
12 | "vue",
13 | "input-effects",
14 | "vue-component"
15 | ],
16 | "scripts": {
17 | "start": "npm run dev",
18 | "dev": "cross-env NODE_ENV=development webpack-dev-server --content-base examples/ --hot",
19 | "build": "npm run build:package & npm run build:example",
20 | "build:package": "rm -fr dist && rollup -c && stylus src/styles/index.styl --out dist",
21 | "build:example": "rm -fr sites && cross-env NODE_ENV=production webpack --progress --hide-modules && cp examples/index.html sites",
22 | "ghpages": "npm run build:example && node build/gh-pages.js",
23 | "pb": "npm run build:package && npm publish"
24 | },
25 | "dependencies": {
26 | "vue": "^2.5.0"
27 | },
28 | "browserslist": [
29 | "> 1%",
30 | "last 2 versions",
31 | "not ie <= 8"
32 | ],
33 | "devDependencies": {
34 | "babel-core": "^6.26.0",
35 | "babel-loader": "^7.1.2",
36 | "babel-preset-env": "^1.6.0",
37 | "babel-preset-stage-3": "^6.24.1",
38 | "cross-env": "^5.0.5",
39 | "css-loader": "^0.28.7",
40 | "file-loader": "^1.1.4",
41 | "fs-extra": "^4.0.3",
42 | "gh-pages": "^1.1.0",
43 | "rollup": "^0.52.1",
44 | "rollup-plugin-vue": "^3.0.0",
45 | "style-loader": "^0.19.0",
46 | "stylus": "^0.54.5",
47 | "stylus-loader": "^3.0.1",
48 | "url-loader": "^0.6.2",
49 | "vue-loader": "^13.0.5",
50 | "vue-template-compiler": "^2.4.4",
51 | "webpack": "^3.6.0",
52 | "webpack-dev-server": "^2.9.1"
53 | },
54 | "license": "MIT",
55 | "repository": {
56 | "type": "git",
57 | "url": "https://github.com/XBT1/effect-input.git"
58 | },
59 | "bugs": {
60 | "url": "https://github.com/XBT1/effect-input/issues"
61 | },
62 | "homepage": "https://github.com/XBT1/effect-input",
63 | "engines": {
64 | "node": ">= 4.0.0",
65 | "npm": ">= 3.0.0"
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import vue from 'rollup-plugin-vue'
2 |
3 | export default {
4 | input: 'src/index.js',
5 | output: {
6 | file: 'dist/index.common.js',
7 | format: 'cjs',
8 | exports: 'named',
9 | },
10 | plugins: [
11 | vue(),
12 | ],
13 | }
14 |
--------------------------------------------------------------------------------
/src/components/EffectInput.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
16 |
17 |
18 |
19 |
24 |
25 |
34 |
35 |
36 |
37 |
42 |
43 |
50 |
51 |
52 |
53 |
94 |
--------------------------------------------------------------------------------
/src/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CyberNika/effect-input/7c41b3c1d5e7dd0500888bdb4cee32f712764982/src/images/logo.png
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import EffectInput from './components/EffectInput.vue'
2 |
3 | export { EffectInput }
4 |
5 | export default {
6 | install (Vue) {
7 | Vue.component(EffectInput.name, EffectInput)
8 | },
9 | }
10 |
--------------------------------------------------------------------------------
/src/styles/akira.styl:
--------------------------------------------------------------------------------
1 |
2 | input-color = #747981
3 | input-margin-top = 1.875em
4 |
5 | label-color = #df6589
6 | label-border-width = 0.25em
7 | label-border = label-border-width solid input-color
8 | label-active-translateY = - (input-height + label-font-size + input-margin-top) / 2
9 |
10 | .effect-input--akira
11 | margin-top: input-margin-top
12 | text-align: center
13 |
14 | .effect-input__field
15 | color: input-color
16 | text-align: center
17 |
18 | .effect-input__label
19 | @extend $input__label--vc
20 |
21 | top: 0
22 | color: label-color
23 |
24 | &::after
25 | content: ""
26 | position: absolute
27 | top: 0
28 | left: 0
29 | width: 100%
30 | height: 100%
31 | border: label-border
32 | transition: border-width 0.3s
33 |
34 | .effect-input__label-content
35 | transition: transform 0.3s
36 |
37 | // 激活状态
38 | &.effect-input--filled .effect-input__label,
39 | .effect-input__field:focus + .effect-input__label
40 | &::after
41 | border-width: (label-border-width / 2)
42 |
43 | .effect-input__label-content
44 | transform: translate3d(0, label-active-translateY, 0)
45 |
--------------------------------------------------------------------------------
/src/styles/common.styl:
--------------------------------------------------------------------------------
1 | html *,
2 | html *::before,
3 | html *::after
4 | box-sizing: border-box
5 |
6 | .effect-input
7 | position: relative
8 | display: inline-block
9 | width: input-width
10 | line-height: 1
11 | font-size: input-font-size
12 | text-align: left
13 | z-index: 1
14 |
15 | .effect-input__field
16 | display: block
17 | width: 100%
18 | height: field-height
19 | background: transparent
20 | border: none
21 | color: inherit
22 | font-size: field-font-size
23 | font-weight: bold
24 |
25 | &:focus
26 | outline: none
27 |
28 | .effect-input__label
29 | display: block
30 | width: 100%
31 | font-size: label-font-size
32 | font-weight: bold
33 | color: label-color
34 |
35 | .effect-input__label-content
36 | display: block
37 | width: 100%
38 |
--------------------------------------------------------------------------------
/src/styles/fonts/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CyberNika/effect-input/7c41b3c1d5e7dd0500888bdb4cee32f712764982/src/styles/fonts/.gitkeep
--------------------------------------------------------------------------------
/src/styles/haruki.styl:
--------------------------------------------------------------------------------
1 |
2 | padding-horizontal = 1.2em
3 |
4 | field-font-size = 1.55em
5 |
6 | label-padding-vertical = (input-height - label-font-size) / 2
7 | lebel-decorate-active-translateY = 0.5em
8 | label-active-translateY = -(input-height / 2 + label-font-size * 1.2 + lebel-decorate-active-translateY)
9 |
10 | input-margin-top = (label-font-size + lebel-decorate-active-translateY * 2) * 1.5
11 |
12 | $input__label--vc
13 | position: absolute
14 | padding: label-padding-vertical padding-horizontal
15 | height: input-height
16 | // pointer-events: none
17 | cursor: text
18 |
19 | .effect-input--haruki
20 | margin-top: input-margin-top
21 |
22 | .effect-input__field
23 | position: relative
24 | padding: 0 (padding-horizontal / 2)
25 | color: field-color
26 | font-size: field-font-size
27 |
28 | .effect-input__label
29 | @extend $input__label--vc
30 |
31 | bottom: 0
32 |
33 | &::before,
34 | &::after
35 | content: ""
36 | position: absolute
37 | left: 0
38 | z-index: -1
39 | width: 100%
40 | height: 0.25em
41 | background-color: status-color-primary
42 | transition: transform 0.3s
43 |
44 | &::before
45 | top: 0
46 |
47 | &::after
48 | bottom: 0
49 |
50 | .effect-input__label-content
51 | transition: transform 0.3s
52 |
53 | // 激活状态
54 | &.effect-input--filled .effect-input__label,
55 | .effect-input__field:focus + .effect-input__label
56 | &::before
57 | transform: translate3d(0, -(lebel-decorate-active-translateY), 0)
58 |
59 | &::after
60 | transform: translate3d(0, lebel-decorate-active-translateY, 0)
61 |
62 | .effect-input__label-content
63 | transform: translate3d(0, label-active-translateY, 0)
64 |
--------------------------------------------------------------------------------
/src/styles/hideo.styl:
--------------------------------------------------------------------------------
1 |
2 | label-bgc = #8a9ed8
3 |
4 | field-color = #aaa
5 | active-ratio = 1.5
6 |
7 | .effect-input--hideo
8 |
9 | .effect-input__field
10 | padding-left: field-height + 1
11 | background-color: #fff
12 | color: field-color
13 | transition: padding-left 0.3s
14 |
15 | .effect-input__label
16 | position: absolute
17 | left: 0
18 | top: 0
19 | display: flex
20 | align-items: center
21 | justify-content: center
22 | width: input-height
23 | height: 100%
24 | background-color: label-bgc
25 | transition: all 0.3s
26 |
27 | .effect-input__label-content
28 | width: 1em
29 | height: 1em
30 | font-size: 160%
31 | color: #fff
32 | overflow: hidden
33 |
34 | // 激活状态
35 | // &.effect-input--filled .effect-input__field,
36 | .effect-input__field:focus
37 | padding-left: (field-height / active-ratio) + 1
38 |
39 | // &.effect-input--filled .effect-input__label,
40 | .effect-input__field:focus + .effect-input__label
41 | font-size: (label-font-size / active-ratio)
42 |
--------------------------------------------------------------------------------
/src/styles/hoshi.styl:
--------------------------------------------------------------------------------
1 |
2 | input-margin-top = label-font-size * 1.5
3 | padding-horizontal = 0.3em
4 |
5 | label-active-translateY = -(input-height + label-font-size) / 2
6 | label-padding-top = (input-height - label-font-size) / 2
7 | label-padding-bottom = (input-height - label-font-size) / 2 - 0.6
8 |
9 | .effect-input--hoshi
10 | margin-top: input-margin-top
11 |
12 | .effect-input__field
13 | position: relative
14 | padding: 0 padding-horizontal
15 | height: input-height - 10
16 | color: #595f6e
17 |
18 | .effect-input__label
19 | position: absolute
20 | top: 0
21 | padding: label-padding-top padding-horizontal label-padding-bottom
22 | border-bottom: 1px solid status-color-primary
23 | pointer-events: none
24 |
25 | &::after
26 | content: ""
27 | position: absolute
28 | left: 0
29 | bottom: -0.125em
30 | display: block
31 | width: 0
32 | height: 0.25em
33 | background-color: status-color-info
34 | transition: width 0.3s
35 |
36 | // .effect-input__label-content
37 | // transition: transform 0.3s
38 |
39 | // 激活状态
40 | &.effect-input--filled .effect-input__label,
41 | .effect-input__field:focus + .effect-input__label
42 | &::after
43 | width: 100%
44 |
45 | .effect-input__label-content
46 | animation: animation-hoshi-label 0.3s forwards
47 |
48 | @keyframes animation-hoshi-label
49 | 50%
50 | opacity: 0
51 | transform: translate3d(1em, 0, 0)
52 |
53 | 51%
54 | opacity: 0
55 | transform: translate3d(-1em, label-active-translateY, 0)
56 |
57 | 100%
58 | opacity: 1;
59 | transform: translate3d(0, label-active-translateY, 0);
60 |
--------------------------------------------------------------------------------
/src/styles/ichiro.styl:
--------------------------------------------------------------------------------
1 |
2 | input-padding = 0.25em
3 |
4 | label-padding-vertical = ((input-height - label-font-size) / 2) + input-padding
5 | label-content-active-translateY = -3.15em
6 |
7 | input-margin-top = - label-content-active-translateY / 2 + label-font-size / 2 * 0.8
8 |
9 | .effect-input--ichiro
10 | padding: input-padding
11 | margin-top: input-margin-top
12 |
13 | .effect-input__field
14 | padding: 0 0.55em
15 | background-color: #f0f0f0
16 | color: #7f8994
17 | opacity: 0
18 | transform: scale3d(1, 0, 1)
19 | transform-origin: 50% 100%
20 | transition: transform 0.3s, opacity 0.3s
21 |
22 | .effect-input__label
23 | position: absolute
24 | left: 0
25 | top: 0
26 | height: 100%
27 | padding: label-padding-vertical 1.2em
28 | cursor: text
29 |
30 | &::before
31 | content: ""
32 | position: absolute
33 | top: 0
34 | left: 0
35 | width: 100%
36 | height: 100%
37 | background-color: #fff
38 | transform-origin: 50% 100%
39 | transition: transform 0.3s
40 | z-index: -1
41 |
42 | .effect-input__label-content
43 | transform-origin: left bottom
44 | transition: transform 0.3s
45 |
46 | // 激活状态
47 | &.effect-input--filled .effect-input__field,
48 | .effect-input__field:focus
49 | transform: scale3d(1, 1, 1)
50 | opacity: 1
51 |
52 | &.effect-input--filled .effect-input__label,
53 | .effect-input__field:focus + .effect-input__label
54 |
55 | &::before
56 | transform: scale3d(1, 1.4, 1)
57 |
58 | .effect-input__label-content
59 | transform: translate3d(0, label-content-active-translateY, 0) scale3d(0.8, 0.8, 1) translateZ(1px)
60 |
--------------------------------------------------------------------------------
/src/styles/index.styl:
--------------------------------------------------------------------------------
1 | @import "variables";
2 |
3 | // SET 1
4 | @import "common";
5 | @import "haruki";
6 | @import "hoshi";
7 | @import "kuro";
8 | @import "jiro";
9 | @import "minoru";
10 | @import "yoko";
11 | @import "hideo";
12 | @import "kyo";
13 | @import "akira";
14 | @import "ichiro";
15 | @import "juro";
16 | @import "madoka";
17 | @import "kaede";
18 | @import "isao";
19 |
20 | // SET2
21 | @import "manami";
22 | @import "nariko";
23 |
--------------------------------------------------------------------------------
/src/styles/isao.styl:
--------------------------------------------------------------------------------
1 |
2 | label-content-padding = 0.95em 0.15em 0.75em
3 | isao-transition-timing-function = cubic-bezier(0.2, 1, 0.3, 1)
4 |
5 | .effect-input--isao
6 |
7 | .effect-input__field
8 | padding: 0.75em 0.1em 0
9 | color: #afb3b8
10 |
11 | .effect-input__label
12 | position: relative
13 | color: #dadada
14 | overflow: hidden
15 |
16 | &::before
17 | content: ""
18 | position: absolute
19 | left: 0
20 | top: 0
21 | width: 100%
22 | height: 0.4em
23 | background: #dadada
24 | transform: scale3d(1, 0.4, 1)
25 | transform-origin: 50% 100%
26 | transition: transform 0.3s, background-color 0.3s
27 | transition-timing-function: isao-transition-timing-function
28 |
29 | &::after
30 | content: attr(data-content)
31 | position: absolute
32 | top: 0
33 | left: 0
34 | padding: label-content-padding
35 | color: #da7071
36 | opacity: 0
37 | transform: translate3d(0, 50%, 0)
38 | transition: opacity 0.3s, transform 0.3s
39 | transition-timing-function: isao-transition-timing-function
40 |
41 | .effect-input__label-content
42 | padding: label-content-padding
43 | transition: opacity 0.3s, transform 0.3s
44 | transition-timing-function: isao-transition-timing-function
45 |
46 | // 激活状态
47 | &.effect-input--filled .effect-input__label,
48 | .effect-input__field:focus + .effect-input__label
49 | &::before
50 | background-color: #da7071
51 | transform: scale3d(1, 1, 1)
52 |
53 | &::after
54 | opacity: 1
55 | transform: translate3d(0, 0, 0)
56 |
57 | .effect-input__label-content
58 | opacity: 0
59 | transform: translate3d(0, -50%, 0)
60 |
--------------------------------------------------------------------------------
/src/styles/jiro.styl:
--------------------------------------------------------------------------------
1 |
2 | input-color = #dde2e2
3 | input-margin-top = label-font-size * 2 + 5
4 |
5 | padding-horizontal = 0.95em
6 |
7 | label-active-translateY = -(input-height + label-font-size) / 2 - 0.625em
8 |
9 | $jiro-label-pseudo
10 | content: ""
11 | position: absolute
12 | top: 0
13 | left: 0
14 | width: 100%
15 | height: 100%
16 | transition: transform 0.3s
17 |
18 | .effect-input--jiro
19 | margin-top: input-margin-top
20 |
21 | .effect-input__field
22 | padding: 0 padding-horizontal
23 | color: input-color
24 | background-color: transparent
25 | opacity: 0
26 | transition: opacity 0.3s
27 |
28 | .effect-input__label
29 | @extend $input__label--vc
30 |
31 | top: 0
32 |
33 | &::before
34 | @extend $jiro-label-pseudo
35 |
36 | border-top: 2px solid #6a7989
37 | transform: translate3d(0, 100%, 0) translate3d(0, -2px, 0)
38 | transition-delay: 0.3s
39 |
40 | &::after
41 | @extend $jiro-label-pseudo
42 |
43 | background: #6a7989
44 | transform: scale3d(1, 0, 1)
45 | transform-origin: 50% 0%
46 | z-index: -1
47 |
48 | .effect-input__label-content
49 | transition: transform 0.3s 0.3s
50 |
51 | // 激活状态
52 | &.effect-input--filled .effect-input__field,
53 | .effect-input__field:focus
54 | opacity: 1
55 | transition-delay: 0.3s
56 |
57 | &.effect-input--filled .effect-input__label,
58 | .effect-input__field:focus + .effect-input__label
59 | &::before
60 | transform: translate3d(0, 0, 0)
61 | transition-delay: 0
62 |
63 | &::after
64 | transform: scale3d(1, 1, 1)
65 | transition-delay: 0.3s
66 | transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1)
67 |
68 | .effect-input__label-content
69 | transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1)
70 | transform: translate3d(0, label-active-translateY, 0)
71 |
--------------------------------------------------------------------------------
/src/styles/juro.styl:
--------------------------------------------------------------------------------
1 |
2 | active-label-content-translateY = -1.5em
3 |
4 | input-margin-top = 1em
5 |
6 | juro-color = #1784cd
7 |
8 | .effect-input--juro
9 | margin-top: input-margin-top
10 |
11 | .effect-input__field
12 | position: absolute;
13 | bottom: 0.35em
14 | padding: 0 1em
15 | color: juro-color
16 | font-size: 1em
17 |
18 | .effect-input__label
19 | background: #fff
20 | cursor: text
21 |
22 | &::before
23 | content: ""
24 | position: absolute
25 | top: 0
26 | left: 0
27 | width: 100%
28 | height: 100%
29 | border: 0 solid transparent
30 | transition: border-width 0.3s, border-color 0.3s
31 |
32 | .effect-input__label-content
33 | padding: 2em input-margin-top
34 | transition: transform 0.3s, color 0.3s
35 | text-rendering: geometricPrecision
36 | transform-origin: 0 50%
37 |
38 | // 激活状态
39 | &.effect-input--filled .effect-input__label,
40 | .effect-input__field:focus + .effect-input__label
41 | &::before
42 | border-width: 0.5em
43 | border-color: juro-color
44 | border-top-width: 2em
45 |
46 | .effect-input__label-content
47 | color: #fff
48 | transform: translate3d(0, active-label-content-translateY, 0) scale3d(0.75, 0.75, 1) translateZ(1px)
49 |
--------------------------------------------------------------------------------
/src/styles/kaede.styl:
--------------------------------------------------------------------------------
1 |
2 | kaede-transition-timing-function = cubic-bezier(0.2, 1, 0.3, 1)
3 |
4 | .effect-input--kaede
5 | overflow: hidden
6 |
7 | .effect-input__field
8 | padding: 0 0.8em
9 | width: 60%
10 | background: #fff
11 | color: #9dabba
12 | transform: translate3d(-100%, 0, 0)
13 | transition: transform 0.5s
14 | transition-timing-function: kaede-transition-timing-function
15 |
16 | .effect-input__label
17 | @extend $input__label--vc
18 |
19 | top: 0
20 | background: #efeeee
21 | transition: transform 0.5s
22 | transition-timing-function: kaede-transition-timing-function
23 |
24 | // 激活状态
25 | &.effect-input--filled,
26 | .effect-input__field:focus
27 | transform: translate3d(0, 0, 0)
28 | transition-delay: 0.06s
29 |
30 | &.effect-input--filled .effect-input__label,
31 | .effect-input__field:focus + .effect-input__label
32 | transform: translate3d(60%, 0, 0)
33 |
--------------------------------------------------------------------------------
/src/styles/kuro.styl:
--------------------------------------------------------------------------------
1 |
2 | input-margin-bottom = 1.875em
3 | input-color = #747981
4 |
5 | label-pseudo-border = 0.25em solid input-color
6 | label-color = #df6589
7 | label-active-translateY = (input-height + label-font-size + input-margin-bottom) / 2
8 |
9 | $kuro-label-pseudo
10 | content: ""
11 | position: absolute
12 | top: 0
13 | width: 50%
14 | height: 100%
15 | border: label-pseudo-border
16 | transition: transform 0.3s
17 |
18 | .effect-input--kuro
19 | margin-bottom: input-margin-bottom * 1.5
20 | text-align: center
21 |
22 | .effect-input__field
23 | color: input-color
24 | text-align: center
25 |
26 | .effect-input__label
27 | @extend $input__label--vc
28 |
29 | top: 0
30 | color: label-color
31 |
32 | &::before
33 | @extend $kuro-label-pseudo
34 |
35 | left: 0
36 | border-right: none
37 |
38 | &::after
39 | @extend $kuro-label-pseudo
40 |
41 | right: 0
42 | border-left: none
43 |
44 | // .effect-input__label-content
45 |
46 | // 激活状态
47 | &.effect-input--filled .effect-input__label,
48 | .effect-input__field:focus + .effect-input__label
49 | &::before
50 | transform: translate3d(-10%, 0, 0)
51 |
52 | &::after
53 | transform: translate3d(10%, 0, 0)
54 |
55 | .effect-input__label-content
56 | animation: animation-kuro-label 0.3s forwards
57 |
58 | @keyframes animation-kuro-label
59 | 50%
60 | opacity: 0
61 | transform: scale3d(0.3, 0.3, 1)
62 |
63 | 51%
64 | opacity: 0
65 | transform: translate3d(0, label-active-translateY, 0) scale3d(0.3, 0.3, 1)
66 |
67 | 100%
68 | opacity: 1
69 | transform: translate3d(0, label-active-translateY, 0)
70 |
--------------------------------------------------------------------------------
/src/styles/kyo.styl:
--------------------------------------------------------------------------------
1 |
2 |
3 | .effect-input--kyo
4 | z-index: 100
5 |
6 | .effect-input__field
7 | padding: 0 (field-height / 2)
8 | border-radius: field-height
9 | background-color: #fff
10 | color: #535d92
11 |
12 | .effect-input__label
13 | padding: 0.65em 0 0.65em (field-height / 1.5)
14 |
15 | &::after
16 | content: ""
17 | position: fixed
18 | top: 0
19 | left: 0
20 | width: 100%
21 | height: 100%
22 | background-color: rgba(11, 43, 205, 0.6)
23 | opacity: 0
24 | transition: opacity 0.3s
25 | pointer-events: none
26 | z-index: -1
27 |
28 | // 激活状态
29 | .effect-input__field:focus
30 | & + .effect-input__label
31 | color: #fff
32 |
33 | &::after
34 | opacity: 1
35 |
--------------------------------------------------------------------------------
/src/styles/madoka.styl:
--------------------------------------------------------------------------------
1 |
2 | input-margin-bottom = 1em + label-font-size
3 | active-label-content-translateY = input-height - label-font-size + input-margin-bottom / 2
4 |
5 | .effect-input--madoka
6 | margin-bottom: input-margin-bottom
7 | color: #7a7593
8 |
9 | // .effect-input__field
10 |
11 | .effect-input__label
12 | @extend $input__label--vc
13 |
14 | top: 0
15 |
16 | .graphic
17 | position: absolute
18 | top: 0
19 | left: 0
20 | fill: none
21 | transform: scale3d(1, -1, 1)
22 | transition: stroke-dashoffset 0.3s
23 | pointer-events: none
24 | stroke: #7A7593
25 | stroke-width: 4px
26 | stroke-dasharray: 962
27 | stroke-dashoffset: 558
28 |
29 | .effect-input__label-content
30 | transform-origin: 0 50%
31 | transition: transform 0.3s
32 |
33 | // 激活状态
34 | &.effect-input--filled .effect-input__label,
35 | .effect-input__field:focus + .effect-input__label
36 |
37 | .graphic
38 | stroke-dashoffset: 0
39 |
40 | .effect-input__label-content
41 | transform: scale3d(0.81, 0.81, 1) translate3d(0, active-label-content-translateY, 0)
42 |
--------------------------------------------------------------------------------
/src/styles/manami.styl:
--------------------------------------------------------------------------------
1 |
2 | active-label-content-translateY = input-height - label-font-size * 1.5
3 | input-padding-bottom = label-font-size * 2
4 |
5 | manami-transition-timing-function = cubic-bezier(0, 0.25, 0.5, 1)
6 |
7 | $manami-label-pseudo
8 | content: ""
9 | position: absolute
10 | left: 0
11 | width: 100%
12 | background-color: #a8a8a8
13 | transition-timing-function: manami-transition-timing-function
14 |
15 | .effect-input--manami
16 | padding-bottom: input-padding-bottom
17 | height: input-height + input-padding-bottom
18 | overflow: hidden
19 |
20 | .effect-input__field
21 | padding: 0.5em
22 | color: #f9f7f6
23 |
24 | .effect-input__label
25 | @extend $input__label--vc
26 |
27 | top: 0
28 | padding-left: 0.2em
29 | padding-right: 0.2em
30 |
31 | &::before
32 | @extend $manami-label-pseudo
33 |
34 | top: -100%
35 | height: 100%
36 | transition: top 0.2s
37 | z-index: -1
38 |
39 | &::after
40 | @extend $manami-label-pseudo
41 |
42 | bottom: 0
43 | height: 0.1em
44 | opacity: 1
45 | transition: opacity 0.2s
46 |
47 | .effect-input__label-content
48 | font-size: 1.25em
49 | transition-timing-function: manami-transition-timing-function
50 | transition: transform 0.2s, color 0.2s
51 | transform-origin: 0 0
52 |
53 | // 激活状态
54 | &.effect-input--filled .effect-input__field,
55 | .effect-input__field:focus
56 | // transform: scale3d(1, 1, 1)
57 |
58 | &.effect-input--filled .effect-input__label,
59 | .effect-input__field:focus + .effect-input__label
60 | &::before
61 | top: 0
62 |
63 | &::after
64 | opacity: 0
65 |
66 | .effect-input__label-content
67 | color: #cbc4c6
68 | transform: translate3d(0, active-label-content-translateY, 0) scale3d(0.65, 0.65, 1)
69 |
--------------------------------------------------------------------------------
/src/styles/minoru.styl:
--------------------------------------------------------------------------------
1 |
2 |
3 | .effect-input--minoru
4 |
5 | .effect-input__field
6 | padding: 0 0.95em
7 | color: #eca29b
8 | background: #fff
9 | box-shadow: 0 0 0 2px transparent
10 | transition: box-shadow 0.3s
11 |
12 | .effect-input__label
13 | padding: 0.9em 0.35em
14 |
15 | &::after
16 | content: ""
17 | position: absolute
18 | top: 0
19 | z-index: -1
20 | width: 100%
21 | height: input-height
22 | box-shadow: 0 0 0 0
23 | color: rgba(199, 152, 157, 0.6)
24 |
25 | // 激活状态
26 | &.effect-input--filled .effect-input__field,
27 | .effect-input__field:focus
28 | box-shadow: 0 0 0 2px #eca29b
29 |
30 | &.effect-input--filled .effect-input__label,
31 | .effect-input__field:focus + .effect-input__label
32 | &::after
33 | animation: animation-minoru-label-pseudo 0.3s forwards
34 |
35 |
36 | @keyframes animation-minoru-label-pseudo
37 | to
38 | box-shadow: 0 0 100px 50px
39 | opacity: 0
40 |
--------------------------------------------------------------------------------
/src/styles/nariko.styl:
--------------------------------------------------------------------------------
1 |
2 | active-label-content-translateY = - (input-height - label-font-size)
3 |
4 | input-padding-top = label-font-size * 2
5 |
6 | nariko-transition-timing-function = cubic-bezier(0.7, 0, 0.3, 1)
7 |
8 | $nariko-label-pseudo
9 | content: ""
10 | position: absolute
11 | left: 0
12 | width: 100%
13 | transition-timing-function: nariko-transition-timing-function
14 |
15 | .effect-input--nariko
16 | padding-top: input-padding-top
17 | height: input-height + input-padding-top
18 | overflow: hidden
19 |
20 | .effect-input__field
21 | padding: 0.5em
22 | color: #f18292
23 | opacity: 0
24 |
25 | .effect-input__label
26 | @extend $input__label--vc
27 |
28 | bottom: 0
29 | padding-left: 0.5em
30 | padding-right: 0.5em
31 |
32 | &::before
33 | @extend $nariko-label-pseudo
34 |
35 | bottom: -100%
36 | height: 100%
37 | border-top: 0.2em solid #9b9f9f
38 | background-color: #fff
39 | transition: bottom transition-time
40 | transform: translate3d(0, -0.2em, 0)
41 | z-index: -1
42 |
43 | .effect-input__label-content
44 | color: #8e9191
45 | transition-timing-function: nariko-transition-timing-function
46 | transition: transform transition-time, color transition-time
47 | transform-origin: 0 0
48 |
49 | // 激活状态
50 | &.effect-input--filled .effect-input__field,
51 | .effect-input__field:focus
52 | opacity: 1
53 | transition: opacity 0s transition-time
54 |
55 | &.effect-input--filled .effect-input__label,
56 | .effect-input__field:focus + .effect-input__label
57 | &::before
58 | bottom: 0
59 |
60 | .effect-input__label-content
61 | color: #6b6e6e
62 | transform: translate3d(0, active-label-content-translateY, 0) scale3d(0.9, 0.9, 1)
63 |
--------------------------------------------------------------------------------
/src/styles/template.styl:
--------------------------------------------------------------------------------
1 |
2 |
3 | .effect-input--hoshi
4 |
5 | .effect-input__field
6 |
7 | .effect-input__label
8 |
9 | .effect-input__label-content
10 |
11 | // 激活状态
12 | &.effect-input--filled .effect-input__label,
13 | .effect-input__field:focus + .effect-input__label
14 |
15 | .effect-input__label-content
16 |
--------------------------------------------------------------------------------
/src/styles/variables.styl:
--------------------------------------------------------------------------------
1 | input-width = 320px
2 | input-width = 20em
3 | input-height = 4.125em
4 | input-font-size = 1em
5 |
6 | label-font-size = input-font-size
7 | label-color = #6a7989
8 |
9 | field-font-size = 1.5em
10 | field-color = #afb5bb
11 | field-height = input-height * input-font-size / field-font-size
12 |
13 | status-color-primary = #6a7989
14 | status-color-info = #1dacfc
15 | status-color-success = #2bfdac
16 | status-color-danger = #fc561f
17 |
18 | transition-time = 0.3s
19 |
20 |
--------------------------------------------------------------------------------
/src/styles/yoko.styl:
--------------------------------------------------------------------------------
1 |
2 | pseudo-background-color = #c5564a
3 |
4 | $yoko-label-pseudo
5 | content: ""
6 | position: absolute
7 | left: 0
8 | width: 100%
9 | transition: transform 0.3s
10 |
11 | .effect-input--yoko
12 |
13 | .effect-input__field
14 | padding: 0 15px
15 | color: #f5f5f5
16 | opacity: 0
17 | transition: opacity 0.3s
18 |
19 | .effect-input__label
20 | position: relative
21 | color: #b04b40
22 |
23 | &::before
24 | @extend $yoko-label-pseudo
25 |
26 | bottom: 100%
27 | height: input-height
28 | background-color: pseudo-background-color
29 | transform: perspective(1000px) rotate3d(1, 0, 0, 90deg)
30 | transform-origin: 50% 100%
31 | z-index: -1
32 |
33 | &::after
34 | @extend $yoko-label-pseudo
35 |
36 | top: 0
37 | height: 4px
38 | background: #ad473c
39 | transform-origin: 50% 0%
40 |
41 | .effect-input__label-content
42 | padding: 1.2em 0.95em
43 |
44 | // 激活状态
45 | &.effect-input--filled .effect-input__label,
46 | .effect-input__field:focus + .effect-input__label
47 | &::before
48 | transform: perspective(1000px) rotate3d(1, 0, 0, 0)
49 |
50 | &::after
51 | transform: perspective(1000px) rotate3d(1, 0, 0, -90deg)
52 |
53 | &.effect-input--filled .effect-input__field,
54 | .effect-input__field:focus
55 | opacity: 1
56 | transition-delay: 0.3s
57 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var webpack = require('webpack')
3 |
4 | module.exports = {
5 | entry: './examples/main.js',
6 | output: {
7 | path: path.resolve(__dirname, 'sites'),
8 | publicPath: '',
9 | filename: 'build.js'
10 | },
11 | module: {
12 | rules: [
13 | {
14 | test: /\.css$/,
15 | use: [
16 | 'vue-style-loader',
17 | 'css-loader'
18 | ],
19 | },
20 | {
21 | test: /\.styl$/,
22 | loader: 'style-loader!css-loader!stylus-loader',
23 | exclude: /node_modules/
24 | },
25 | {
26 | test: /\.vue$/,
27 | loader: 'vue-loader',
28 | options: {
29 | loaders: {
30 | }
31 | // other vue-loader options go here
32 | }
33 | },
34 | {
35 | test: /\.js$/,
36 | loader: 'babel-loader',
37 | exclude: /node_modules/
38 | },
39 | {
40 | test: /\.(png|jpg|gif|svg)$/,
41 | loader: 'file-loader',
42 | options: {
43 | name: '[name].[ext]?[hash]'
44 | }
45 | },
46 | {
47 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
48 | loader: 'url-loader',
49 | query: {
50 | limit: 10000,
51 | name: 'fonts/[name].[hash:7].[ext]'
52 | }
53 | }
54 | ]
55 | },
56 | resolve: {
57 | alias: {
58 | 'vue$': 'vue/dist/vue.esm.js'
59 | },
60 | extensions: ['*', '.js', '.vue', '.json']
61 | },
62 | devServer: {
63 | historyApiFallback: true,
64 | noInfo: true,
65 | overlay: true
66 | },
67 | performance: {
68 | hints: false
69 | },
70 | devtool: '#eval-source-map'
71 | }
72 |
73 | if (process.env.NODE_ENV === 'production') {
74 | module.exports.devtool = '#source-map'
75 | // http://vue-loader.vuejs.org/en/workflow/production.html
76 | module.exports.plugins = (module.exports.plugins || []).concat([
77 | new webpack.DefinePlugin({
78 | 'process.env': {
79 | NODE_ENV: '"production"'
80 | }
81 | }),
82 | new webpack.optimize.UglifyJsPlugin({
83 | sourceMap: true,
84 | compress: {
85 | warnings: false
86 | }
87 | }),
88 | new webpack.LoaderOptionsPlugin({
89 | minimize: true
90 | })
91 | ])
92 | }
93 |
--------------------------------------------------------------------------------