├── .babelrc
├── .csscomb.json
├── .editorconfig
├── .eslintrc
├── .gitignore
├── .node-version
├── LICENSE
├── circle.yml
├── css
├── smartphoto.css
└── smartphoto.min.css
├── examples
├── assets
│ ├── bear.jpg
│ ├── camel.jpg
│ ├── castle.jpg
│ ├── hippo.jpg
│ ├── koala.jpg
│ ├── large-bear.jpg
│ ├── large-camel.jpg
│ ├── large-hippo.jpg
│ ├── large-koala.jpg
│ ├── large-lion.jpg
│ ├── large-rhino.jpg
│ ├── lion.jpg
│ ├── rhino.jpg
│ ├── sample.png
│ ├── style.css
│ └── test.png
├── event.html
├── jquery.html
├── lazy.html
├── multiple.html
├── noimage.html
├── resizeFit.html
└── vanilla.html
├── images
├── icon_arrow_next.svg
├── icon_arrow_prev.svg
└── icon_close.svg
├── index.d.ts
├── js
├── jquery-smartphoto.js
├── jquery-smartphoto.min.js
├── smartphoto.js
└── smartphoto.min.js
├── lib
├── adaptor
│ └── jquery.js
├── core
│ └── index.js
├── index.js
└── lib
│ └── util.js
├── package-lock.json
├── package.json
├── readme.md
├── scss
└── smartphoto.scss
├── src
├── .DS_Store
├── adaptor
│ └── jquery.js
├── core
│ ├── index.js
│ └── viwer.html
├── index.js
└── lib
│ └── util.js
├── test
├── preload.js
└── test.js
└── tools
└── index.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "@babel/preset-env"
4 | ],
5 | "plugins": [
6 | "transform-html-import-to-string",
7 | "add-module-exports"
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/.csscomb.json:
--------------------------------------------------------------------------------
1 | {
2 | "remove-empty-rulesets": true,
3 | "always-semicolon": true,
4 | "color-case": "upper",
5 | "block-indent": " ",
6 | "color-shorthand": true,
7 | "element-case": "lower",
8 | "eof-newline": false,
9 | "leading-zero": false,
10 | "quotes": "double",
11 | "sort-order-fallback": "abc",
12 | "space-before-colon": "",
13 | "space-after-colon": " ",
14 | "space-before-combinator": " ",
15 | "space-after-combinator": " ",
16 | "space-between-declarations": "\n",
17 | "space-before-opening-brace": " ",
18 | "space-after-opening-brace": "\n",
19 | "space-after-selector-delimiter": "\n",
20 | "space-before-selector-delimiter": "",
21 | "space-before-closing-brace": "\n",
22 | "strip-spaces": true,
23 | "tab-size": true,
24 | "unitless-zero": true,
25 | "vendor-prefix-align": true,
26 | "sort-order": [
27 | [
28 | "display",
29 | "visibility",
30 | "overflow",
31 | "overflow-x",
32 | "overflow-y",
33 | "-ms-overflow-x",
34 | "-ms-overflow-y",
35 | "flex-direction",
36 | "flex-order",
37 | "flex-pack",
38 | "flex-align",
39 | "-webkit-box-sizing",
40 | "-moz-box-sizing",
41 | "box-sizing",
42 | "table-layout",
43 | "empty-cells",
44 | "caption-side",
45 | "border-spacing",
46 | "border-collapse",
47 | "list-style",
48 | "list-style-position",
49 | "list-style-type",
50 | "list-style-image",
51 | "position",
52 | "z-index",
53 | "top",
54 | "right",
55 | "bottom",
56 | "left",
57 | "float",
58 | "clear",
59 | "min-width",
60 | "max-width",
61 | "width",
62 | "min-height",
63 | "max-height",
64 | "height",
65 | "margin",
66 | "margin-top",
67 | "margin-right",
68 | "margin-bottom",
69 | "margin-left",
70 | "padding",
71 | "padding-top",
72 | "padding-right",
73 | "padding-bottom",
74 | "padding-left",
75 | "border",
76 | "border-width",
77 | "border-style",
78 | "border-color",
79 | "border-top",
80 | "border-top-width",
81 | "border-top-style",
82 | "border-top-color",
83 | "border-right",
84 | "border-right-width",
85 | "border-right-style",
86 | "border-right-color",
87 | "border-bottom",
88 | "border-bottom-width",
89 | "border-bottom-style",
90 | "border-bottom-color",
91 | "border-left",
92 | "border-left-width",
93 | "border-left-style",
94 | "border-left-color",
95 | "-webkit-border-radius",
96 | "-moz-border-radius",
97 | "border-radius",
98 | "-webkit-border-top-left-radius",
99 | "-moz-border-radius-topleft",
100 | "border-top-left-radius",
101 | "-webkit-border-top-right-radius",
102 | "-moz-border-radius-topright",
103 | "border-top-right-radius",
104 | "-webkit-border-bottom-right-radius",
105 | "-moz-border-radius-bottomright",
106 | "border-bottom-right-radius",
107 | "-webkit-border-bottom-left-radius",
108 | "-moz-border-radius-bottomleft",
109 | "border-bottom-left-radius",
110 | "-webkit-border-image",
111 | "-moz-border-image",
112 | "-o-border-image",
113 | "border-image",
114 | "-webkit-border-image-source",
115 | "-moz-border-image-source",
116 | "-o-border-image-source",
117 | "border-image-source",
118 | "-webkit-border-image-slice",
119 | "-moz-border-image-slice",
120 | "-o-border-image-slice",
121 | "border-image-slice",
122 | "-webkit-border-image-width",
123 | "-moz-border-image-width",
124 | "-o-border-image-width",
125 | "border-image-width",
126 | "-webkit-border-image-outset",
127 | "-moz-border-image-outset",
128 | "-o-border-image-outset",
129 | "border-image-outset",
130 | "-webkit-border-image-repeat",
131 | "-moz-border-image-repeat",
132 | "-o-border-image-repeat",
133 | "border-image-repeat",
134 | "background",
135 | "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader",
136 | "background-color",
137 | "background-image",
138 | "background-repeat",
139 | "background-attachment",
140 | "background-position",
141 | "background-position-x",
142 | "-ms-background-position-x",
143 | "background-position-y",
144 | "-ms-background-position-y",
145 | "-webkit-background-clip",
146 | "-moz-background-clip",
147 | "background-clip",
148 | "background-origin",
149 | "-webkit-background-size",
150 | "-moz-background-size",
151 | "-o-background-size",
152 | "background-size",
153 | "opacity",
154 | "filter:progid:DXImageTransform.Microsoft.Alpha(Opacity",
155 | "-ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha",
156 | "-ms-interpolation-mode",
157 | "outline",
158 | "outline-width",
159 | "outline-style",
160 | "outline-color",
161 | "outline-offset",
162 | "box-decoration-break",
163 | "-webkit-box-shadow",
164 | "-moz-box-shadow",
165 | "box-shadow",
166 | "filter:progid:DXImageTransform.Microsoft.gradient",
167 | "-ms-filter:\\'progid:DXImageTransform.Microsoft.gradient",
168 | "text-shadow",
169 | "color",
170 | "font",
171 | "font-family",
172 | "font-size",
173 | "font-weight",
174 | "font-style",
175 | "font-variant",
176 | "font-size-adjust",
177 | "font-stretch",
178 | "font-effect",
179 | "font-emphasize",
180 | "font-emphasize-position",
181 | "font-emphasize-style",
182 | "font-smooth",
183 | "text-decoration",
184 | "text-emphasis",
185 | "text-emphasis-color",
186 | "text-emphasis-style",
187 | "text-emphasis-position",
188 | "text-indent",
189 | "text-align",
190 | "-webkit-text-align-last",
191 | "-moz-text-align-last",
192 | "-ms-text-align-last",
193 | "text-align-last",
194 | "vertical-align",
195 | "line-height",
196 | "white-space",
197 | "-ms-text-justify",
198 | "text-justify",
199 | "letter-spacing",
200 | "word-spacing",
201 | "-ms-writing-mode",
202 | "text-outline",
203 | "text-transform",
204 | "text-wrap",
205 | "text-overflow",
206 | "-ms-text-overflow",
207 | "text-overflow-ellipsis",
208 | "text-overflow-mode",
209 | "-ms-word-wrap",
210 | "word-wrap",
211 | "word-break",
212 | "-ms-word-break",
213 | "-moz-tab-size",
214 | "-o-tab-size",
215 | "tab-size",
216 | "-webkit-hyphens",
217 | "-moz-hyphens",
218 | "hyphens",
219 | "pointer-events",
220 | "content",
221 | "quotes",
222 | "counter-reset",
223 | "counter-increment",
224 | "resize",
225 | "cursor",
226 | "-webkit-user-select",
227 | "-moz-user-select",
228 | "-ms-user-select",
229 | "user-select",
230 | "nav-index",
231 | "nav-up",
232 | "nav-right",
233 | "nav-down",
234 | "nav-left",
235 | "-webkit-transition",
236 | "-moz-transition",
237 | "-ms-transition",
238 | "-o-transition",
239 | "transition",
240 | "-webkit-transition-delay",
241 | "-moz-transition-delay",
242 | "-ms-transition-delay",
243 | "-o-transition-delay",
244 | "transition-delay",
245 | "-webkit-transition-timing-function",
246 | "-moz-transition-timing-function",
247 | "-ms-transition-timing-function",
248 | "-o-transition-timing-function",
249 | "transition-timing-function",
250 | "-webkit-transition-duration",
251 | "-moz-transition-duration",
252 | "-ms-transition-duration",
253 | "-o-transition-duration",
254 | "transition-duration",
255 | "-webkit-transition-property",
256 | "-moz-transition-property",
257 | "-ms-transition-property",
258 | "-o-transition-property",
259 | "transition-property",
260 | "-webkit-transform",
261 | "-moz-transform",
262 | "-ms-transform",
263 | "-o-transform",
264 | "transform",
265 | "-webkit-transform-origin",
266 | "-moz-transform-origin",
267 | "-ms-transform-origin",
268 | "-o-transform-origin",
269 | "transform-origin",
270 | "-webkit-animation",
271 | "-moz-animation",
272 | "-ms-animation",
273 | "-o-animation",
274 | "animation",
275 | "-webkit-animation-name",
276 | "-moz-animation-name",
277 | "-ms-animation-name",
278 | "-o-animation-name",
279 | "animation-name",
280 | "-webkit-animation-duration",
281 | "-moz-animation-duration",
282 | "-ms-animation-duration",
283 | "-o-animation-duration",
284 | "animation-duration",
285 | "-webkit-animation-play-state",
286 | "-moz-animation-play-state",
287 | "-ms-animation-play-state",
288 | "-o-animation-play-state",
289 | "animation-play-state",
290 | "-webkit-animation-timing-function",
291 | "-moz-animation-timing-function",
292 | "-ms-animation-timing-function",
293 | "-o-animation-timing-function",
294 | "animation-timing-function",
295 | "-webkit-animation-delay",
296 | "-moz-animation-delay",
297 | "-ms-animation-delay",
298 | "-o-animation-delay",
299 | "animation-delay",
300 | "-webkit-animation-iteration-count",
301 | "-moz-animation-iteration-count",
302 | "-ms-animation-iteration-count",
303 | "-o-animation-iteration-count",
304 | "animation-iteration-count",
305 | "-webkit-animation-direction",
306 | "-moz-animation-direction",
307 | "-ms-animation-direction",
308 | "-o-animation-direction",
309 | "animation-direction",
310 | "clip",
311 | "zoom"
312 | ]
313 | ]
314 | }
315 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*.js,*.json]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.html]
13 | # すべてのファイルに適用する
14 | charset = utf-8
15 | # 文字コードを統一
16 | indent_style = tab
17 | #インデントを統一する。「tab」か「 space」
18 | indent_size = 2
19 | # インデントの数を統一
20 | trim_trailing_whitespace = true
21 | # 行末のホワイトスペースを削除
22 | insert_final_newline = true
23 | # フォルダの最後の行に改行
24 | end_of_line = lf
25 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "airbnb/base"
4 | ],
5 | "env": {
6 | "browser": true
7 | },
8 | "globals": {
9 | "document": true,
10 | "window": true,
11 | "event": true
12 | },
13 | "rules":{
14 | "comma-dangle": 0,
15 | "no-underscore-dangle": 0,
16 | "class-methods-use-this": 0,
17 | "no-param-reassign": 0,
18 | "no-mixed-operators": 0,
19 | "max-len": 0,
20 | "no-continue": 0,
21 | "no-undef": ["error", { "typeof": true }],
22 | "no-restricted-properties": 0
23 | }
24 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .DS_Store
--------------------------------------------------------------------------------
/.node-version:
--------------------------------------------------------------------------------
1 | v8.9.4
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 appleple
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/circle.yml:
--------------------------------------------------------------------------------
1 | machine:
2 | node:
3 | version: 6.9.2
4 | post:
5 | general:
6 | branches:
7 | ignore:
8 | - gh-pages
9 | dependencies:
10 | override:
11 | - "npm install extract-zip@1.6.0"
12 | - "npm install"
13 | test:
14 | override:
15 | - "npm run test"
--------------------------------------------------------------------------------
/css/smartphoto.css:
--------------------------------------------------------------------------------
1 | @keyframes smartphoto {
2 | from {
3 | opacity: 0;
4 | }
5 | to {
6 | opacity: 1;
7 | }
8 | }
9 |
10 | @keyframes smartphoto-img-wrap {
11 | from {
12 | opacity: 0;
13 | }
14 | to {
15 | opacity: 1;
16 | }
17 | }
18 |
19 | @keyframes smartphoto-inner {
20 | from {
21 | transform: translate(0, 100px);
22 | }
23 | to {
24 | transform: translate(0, 0);
25 | }
26 | }
27 |
28 | @keyframes smartphoto-loader {
29 | 0% {
30 | opacity: .4;
31 | transform: rotate(0deg);
32 | }
33 | 50% {
34 | opacity: 1;
35 | transform: rotate(180deg);
36 | }
37 | 100% {
38 | opacity: .4;
39 | transform: rotate(360deg);
40 | }
41 | }
42 |
43 | @keyframes smartphoto-appear {
44 | 0% {
45 | display: none;
46 | opacity: 0;
47 | }
48 | 1% {
49 | display: block;
50 | opacity: 0;
51 | }
52 | 100% {
53 | display: block;
54 | opacity: 1;
55 | }
56 | }
57 |
58 | @keyframes smartphoto-hide {
59 | 0% {
60 | display: block;
61 | opacity: 1;
62 | }
63 | 99% {
64 | display: block;
65 | opacity: 0;
66 | }
67 | 100% {
68 | display: none;
69 | opacity: 0;
70 | }
71 | }
72 |
73 | .smartphoto {
74 | position: fixed;
75 | z-index: 100;
76 | top: 0;
77 | left: 0;
78 | width: 100%;
79 | height: 100%;
80 | overflow: hidden;
81 | background-color: black;
82 | opacity: 1;
83 | font-family: sans-serif;
84 | cursor: pointer;
85 | -webkit-transition: opacity 0.3s ease-out;
86 | -moz-transition: opacity 0.3s ease-out;
87 | -ms-transition: opacity 0.3s ease-out;
88 | -o-transition: opacity 0.3s ease-out;
89 | transition: opacity 0.3s ease-out;
90 | transition: all 0.3s ease-out;
91 | animation-name: smartphoto;
92 | animation-duration: 0.3s;
93 | animation-timing-function: ease-out;
94 | }
95 |
96 | .smartphoto[aria-hidden="true"] {
97 | display: none;
98 | }
99 |
100 | .smartphoto-close {
101 | opacity: 0;
102 | }
103 |
104 | .smartphoto-count {
105 | display: inline-block;
106 | color: #FFF;
107 | font-size: 16px;
108 | }
109 |
110 | .smartphoto-header {
111 | display: block;
112 | box-sizing: border-box;
113 | position: fixed;
114 | z-index: 102;
115 | top: 0;
116 | left: 0;
117 | width: 100%;
118 | height: 50px;
119 | padding: 15px;
120 | background-color: rgba(0, 0, 0, 0.2);
121 | }
122 |
123 | .smartphoto-content {
124 | display: block;
125 | position: absolute;
126 | top: 0;
127 | left: 0;
128 | width: 100%;
129 | height: 100%;
130 | }
131 |
132 | .smartphoto-dismiss {
133 | display: block;
134 | position: absolute;
135 | top: 15px;
136 | right: 10px;
137 | width: 20px;
138 | height: 20px;
139 | padding: 0;
140 | border: none;
141 | background-color: transparent;
142 | background-image: url(data:image/svg+xml;base64,PHN2ZyBpZD0i44Os44Kk44Ok44O8XzEiIGRhdGEtbmFtZT0i44Os44Kk44Ok44O8IDEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDI4MzQuNjUgMjgzNC42NSIgZmlsbD0iI0ZGRiI+PHRpdGxlPmljb248L3RpdGxlPjxwYXRoIGQ9Ik0xNTc2LjQyLDE0MDYuNzYsMjc4NCwxOTkuMTlhNTYuODYsNTYuODYsMCwwLDAsMC04MC4xOGwtNzguOTItNzguOTJhNTYuODYsNTYuODYsMCwwLDAtODAuMTgsMEwxNDE3LjMyLDEyNDcuNjYsMjA5Ljc1LDQwLjA5YTU2Ljg2LDU2Ljg2LDAsMCwwLTgwLjE4LDBMNTAuNjUsMTE5YTU2Ljg2LDU2Ljg2LDAsMCwwLDAsODAuMThMMTI1OC4yMywxNDA2Ljc2LDUwLjY1LDI2MTQuMzRhNTYuODYsNTYuODYsMCwwLDAsMCw4MC4xOGw3OC45Miw3OC45MmE1Ni44Niw1Ni44NiwwLDAsMCw4MC4xOCwwTDE0MTcuMzIsMTU2NS44NiwyNjI0LjksMjc3My40NGE1Ni44Niw1Ni44NiwwLDAsMCw4MC4xOCwwbDc4LjkyLTc4LjkyYTU2Ljg2LDU2Ljg2LDAsMCwwLDAtODAuMThaIi8+PC9zdmc+);
143 | text-shadow: 0 1px 0 #FFF;
144 | color: #FFF;
145 | font-size: 30px;
146 | text-decoration: none;
147 | cursor: pointer;
148 | line-height: 1;
149 | }
150 |
151 | .smartphoto-body {
152 | position: relative;
153 | z-index: 102;
154 | width: 100%;
155 | height: 100%;
156 | margin: 0 auto;
157 | }
158 |
159 | .smartphoto-inner {
160 | position: relative;
161 | width: 100%;
162 | height: 100%;
163 | vertical-align: top;
164 | }
165 |
166 | .smartphoto-img {
167 | display: none;
168 | max-width: none;
169 | width: auto;
170 | height: auto;
171 | cursor: zoom-in;
172 | -webkit-user-select: none;
173 | -moz-user-select: none;
174 | -ms-user-select: none;
175 | user-select: none;
176 | transition: transform 0.3s ease-out;
177 | -webkit-user-drag: none;
178 | }
179 |
180 | .smartphoto-img.active {
181 | display: block;
182 | }
183 |
184 | .smartphoto-img-onmove {
185 | cursor: grab;
186 | cursor: -webkit-grab;
187 | transition: none;
188 | }
189 |
190 | .smartphoto-img-elasticmove {
191 | transition: transform 0.3s ease-out;
192 | }
193 |
194 | .smartphoto-img-wrap {
195 | display: inline-block;
196 | opacity: 1;
197 | -webkit-transition: opacity 0.3s ease-out;
198 | -moz-transition: opacity 0.3s ease-out;
199 | -ms-transition: opacity 0.3s ease-out;
200 | -o-transition: opacity 0.3s ease-out;
201 | transition: opacity 0.3s ease-out;
202 | animation-name: smartphoto-img-wrap;
203 | animation-duration: 0.3s;
204 | animation-timing-function: ease-out;
205 | }
206 |
207 | .smartphoto-img-left {
208 | transform: translateX(150%) !important;
209 | }
210 |
211 | .smartphoto-img-right {
212 | transform: translateX(-150%) !important;
213 | }
214 |
215 | .smartphoto-arrows {
216 | list-style-type: none;
217 | margin: 0;
218 | padding: 0;
219 | position: relative;
220 | z-index: 1002;
221 | top: 50%;
222 | left: 0;
223 | opacity: 1;
224 | animation-name: smartphoto-appear;
225 | animation-duration: 0.3s;
226 | animation-timing-function: ease-out;
227 | }
228 |
229 | .smartphoto-arrows[aria-hidden="true"] {
230 | animation-name: smartphoto-hide;
231 | display: none;
232 | }
233 |
234 | .smartphoto-arrows li {
235 | display: block;
236 | position: absolute;
237 | top: 50%;
238 | width: 30px;
239 | height: 30px;
240 | margin-top: -20px;
241 | box-sizing: content-box;
242 | animation-duration: 0.3s;
243 | animation-timing-function: ease-out;
244 | animation-name: smartphoto-appear;
245 | }
246 |
247 | .smartphoto-arrows li:focus {
248 | outline: none;
249 | }
250 |
251 | .smartphoto-arrows [aria-hidden="true"] {
252 | animation-name: smartphoto-hide;
253 | display: none;
254 | }
255 |
256 | .smartphoto-arrows a {
257 | display: block;
258 | width: 100%;
259 | height: 100%;
260 | text-decoration: none;
261 | }
262 |
263 | .smartphoto-arrow-right {
264 | right: 0;
265 | padding: 5px 0;
266 | background-color: rgba(0, 0, 0, 0.5);
267 | }
268 |
269 | .smartphoto-arrow-right a {
270 | background-image: url(data:image/svg+xml;base64,PHN2ZyBpZD0i44Os44Kk44Ok44O8XzEiIGRhdGEtbmFtZT0i44Os44Kk44Ok44O8IDEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDI4MzQuNjUgMjgzNC42NSIgZmlsbD0iI0ZGRiAiPjx0aXRsZT5pY29uPC90aXRsZT48cGF0aCBkPSJNMTgzNy44OCwxNDE3LjMyLDY0My41OSwyMjNhNzIuMjEsNzIuMjEsMCwwLDEsMC0xMDEuODJMNzQzLjgyLDIxYTcyLjIxLDcyLjIxLDAsMCwxLDEwMS44MiwwTDIwOTAuODMsMTI2Ni4xOWwxMDAuMjMsMTAwLjIzYTcyLjIxLDcyLjIxLDAsMCwxLDAsMTAxLjgyTDg0NS42NCwyODEzLjY1YTcyLjIxLDcyLjIxLDAsMCwxLTEwMS44MiwwTDY0My41OSwyNzEzLjQyYTcyLjIxLDcyLjIxLDAsMCwxLDAtMTAxLjgyWiIvPjwvc3ZnPg==);
271 | }
272 |
273 | .smartphoto-arrow-left {
274 | left: 0;
275 | padding: 5px 0;
276 | background-color: rgba(0, 0, 0, 0.5);
277 | }
278 |
279 | .smartphoto-arrow-left a {
280 | background-image: url(data:image/svg+xml;base64,PHN2ZyBpZD0i44Os44Kk44Ok44O8XzEiIGRhdGEtbmFtZT0i44Os44Kk44Ok44O8IDEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDI4MzQuNjUgMjgzNC42NSIgZmlsbD0iI0ZGRiI+PHRpdGxlPmljb248L3RpdGxlPjxwYXRoIGQ9Ik05OTYuNzcsMTQxNy4zMiwyMTkxLjA2LDIyM2E3Mi4yMSw3Mi4yMSwwLDAsMCwwLTEwMS44MkwyMDkwLjgzLDIxQTcyLjIxLDcyLjIxLDAsMCwwLDE5ODksMjFMNzQzLjgyLDEyNjYuMTksNjQzLjU5LDEzNjYuNDJhNzIuMjEsNzIuMjEsMCwwLDAsMCwxMDEuODJMMTk4OSwyODEzLjY1YTcyLjIxLDcyLjIxLDAsMCwwLDEwMS44MiwwbDEwMC4yMy0xMDAuMjNhNzIuMjEsNzIuMjEsMCwwLDAsMC0xMDEuODJaIi8+PC9zdmc+);
281 | }
282 |
283 | .smartPhotoArrowHideIcon {
284 | display: none;
285 | }
286 |
287 | .smartphoto-nav {
288 | position: absolute;
289 | bottom: 0;
290 | left: 0;
291 | width: 100%;
292 | opacity: 1;
293 | animation-name: smartphoto-appear;
294 | animation-duration: 0.3s;
295 | animation-timing-function: ease-out;
296 | }
297 |
298 | .smartphoto-nav[aria-hidden="true"] {
299 | animation-name: smartphoto-hide;
300 | display: none;
301 | }
302 |
303 | .smartphoto-nav ul {
304 | display: block;
305 | overflow-x: auto;
306 | list-style: none;
307 | margin: 0;
308 | padding: 0;
309 | text-align: center;
310 | white-space: nowrap;
311 | -webkit-overflow-scrolling: touch;
312 | }
313 |
314 | .smartphoto-nav li {
315 | display: inline-block;
316 | overflow: hidden;
317 | width: 50px;
318 | height: 50px;
319 | }
320 |
321 | .smartphoto-nav a {
322 | display: block;
323 | width: 100%;
324 | height: 100%;
325 | background-color: #FFF;
326 | background-position: center center;
327 | background-size: cover;
328 | opacity: .5;
329 | }
330 |
331 | .smartphoto-nav a:focus {
332 | opacity: .8;
333 | }
334 |
335 | .smartphoto-nav a.current {
336 | opacity: 1;
337 | }
338 |
339 | .smartphoto-nav img {
340 | width: auto;
341 | height: 100%;
342 | }
343 |
344 | .smartphoto-list {
345 | list-style-type: none;
346 | position: absolute;
347 | z-index: 101;
348 | top: 0;
349 | left: 0;
350 | margin: 0;
351 | padding: 0;
352 | white-space: nowrap;
353 | }
354 |
355 | .smartphoto-list li {
356 | display: block;
357 | position: absolute;
358 | top: 0;
359 | left: 0;
360 | width: 100%;
361 | height: 100%;
362 | transition: all 0.3s ease-out;
363 | }
364 |
365 | .smartphoto-list li:focus {
366 | outline: none;
367 | }
368 |
369 | .smartphoto-list-onmove {
370 | transition: all 0.3s ease-out;
371 | }
372 |
373 | .smartphoto-caption {
374 | overflow: hidden;
375 | box-sizing: border-box;
376 | position: absolute;
377 | top: 0;
378 | left: 0;
379 | width: 100%;
380 | height: 50px;
381 | padding: 0 50px;
382 | color: #FFF;
383 | font-size: 12px;
384 | text-align: center;
385 | line-height: 50px;
386 | white-space: nowrap;
387 | text-overflow: ellipsis;
388 | }
389 |
390 | .smartphoto-caption:focus {
391 | outline: none;
392 | }
393 |
394 | .smartphoto-loader-wrap {
395 | display: block;
396 | position: relative;
397 | z-index: 103;
398 | width: 0;
399 | height: 0;
400 | transform: translate(50vw, 50vh);
401 | }
402 |
403 | .smartphoto-loader {
404 | position: absolute;
405 | z-index: 101;
406 | top: 0;
407 | left: 0;
408 | width: 30px;
409 | height: 30px;
410 | margin-top: -25px;
411 | margin-left: -25px;
412 | border: 8px solid #17CDDD;
413 | border-right-color: transparent;
414 | border-radius: 50%;
415 | animation: smartphoto-loader .5s infinite linear;
416 | }
417 |
418 | .smartphoto-img-clone {
419 | position: fixed;
420 | z-index: 100;
421 | top: 0;
422 | left: 0;
423 | transition: all 0.3s ease-out;
424 | }
425 |
426 | .smartphoto-sr-only {
427 | overflow: hidden;
428 | position: absolute;
429 | width: 1px;
430 | height: 1px;
431 | margin: -1px;
432 | padding: 0;
433 | border: 0;
434 | clip: rect(0, 0, 0, 0);
435 | }
436 |
--------------------------------------------------------------------------------
/css/smartphoto.min.css:
--------------------------------------------------------------------------------
1 | @keyframes smartphoto{from{opacity:0}to{opacity:1}}@keyframes smartphoto-img-wrap{from{opacity:0}to{opacity:1}}@keyframes smartphoto-inner{from{transform:translate(0, 100px)}to{transform:translate(0, 0)}}@keyframes smartphoto-loader{0%{opacity:.4;transform:rotate(0deg)}50%{opacity:1;transform:rotate(180deg)}100%{opacity:.4;transform:rotate(360deg)}}@keyframes smartphoto-appear{0%{display:none;opacity:0}1%{display:block;opacity:0}100%{display:block;opacity:1}}@keyframes smartphoto-hide{0%{display:block;opacity:1}99%{display:block;opacity:0}100%{display:none;opacity:0}}.smartphoto{position:fixed;z-index:100;top:0;left:0;width:100%;height:100%;overflow:hidden;background-color:#000;opacity:1;font-family:sans-serif;cursor:pointer;-webkit-transition:opacity .3s ease-out;-moz-transition:opacity .3s ease-out;-ms-transition:opacity .3s ease-out;-o-transition:opacity .3s ease-out;transition:opacity .3s ease-out;transition:all 0.3s ease-out;animation-name:smartphoto;animation-duration:.3s;animation-timing-function:ease-out}.smartphoto[aria-hidden="true"]{display:none}.smartphoto-close{opacity:0}.smartphoto-count{display:inline-block;color:#FFF;font-size:16px}.smartphoto-header{display:block;box-sizing:border-box;position:fixed;z-index:102;top:0;left:0;width:100%;height:50px;padding:15px;background-color:rgba(0,0,0,0.2)}.smartphoto-content{display:block;position:absolute;top:0;left:0;width:100%;height:100%}.smartphoto-dismiss{display:block;position:absolute;top:15px;right:10px;width:20px;height:20px;padding:0;border:none;background-color:transparent;background-image:url(data:image/svg+xml;base64,PHN2ZyBpZD0i44Os44Kk44Ok44O8XzEiIGRhdGEtbmFtZT0i44Os44Kk44Ok44O8IDEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDI4MzQuNjUgMjgzNC42NSIgZmlsbD0iI0ZGRiI+PHRpdGxlPmljb248L3RpdGxlPjxwYXRoIGQ9Ik0xNTc2LjQyLDE0MDYuNzYsMjc4NCwxOTkuMTlhNTYuODYsNTYuODYsMCwwLDAsMC04MC4xOGwtNzguOTItNzguOTJhNTYuODYsNTYuODYsMCwwLDAtODAuMTgsMEwxNDE3LjMyLDEyNDcuNjYsMjA5Ljc1LDQwLjA5YTU2Ljg2LDU2Ljg2LDAsMCwwLTgwLjE4LDBMNTAuNjUsMTE5YTU2Ljg2LDU2Ljg2LDAsMCwwLDAsODAuMThMMTI1OC4yMywxNDA2Ljc2LDUwLjY1LDI2MTQuMzRhNTYuODYsNTYuODYsMCwwLDAsMCw4MC4xOGw3OC45Miw3OC45MmE1Ni44Niw1Ni44NiwwLDAsMCw4MC4xOCwwTDE0MTcuMzIsMTU2NS44NiwyNjI0LjksMjc3My40NGE1Ni44Niw1Ni44NiwwLDAsMCw4MC4xOCwwbDc4LjkyLTc4LjkyYTU2Ljg2LDU2Ljg2LDAsMCwwLDAtODAuMThaIi8+PC9zdmc+);text-shadow:0 1px 0 #FFF;color:#FFF;font-size:30px;text-decoration:none;cursor:pointer;line-height:1}.smartphoto-body{position:relative;z-index:102;width:100%;height:100%;margin:0 auto}.smartphoto-inner{position:relative;width:100%;height:100%;vertical-align:top}.smartphoto-img{display:none;max-width:none;width:auto;height:auto;cursor:zoom-in;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;transition:transform 0.3s ease-out;-webkit-user-drag:none}.smartphoto-img.active{display:block}.smartphoto-img-onmove{cursor:grab;cursor:-webkit-grab;transition:none}.smartphoto-img-elasticmove{transition:transform 0.3s ease-out}.smartphoto-img-wrap{display:inline-block;opacity:1;-webkit-transition:opacity .3s ease-out;-moz-transition:opacity .3s ease-out;-ms-transition:opacity .3s ease-out;-o-transition:opacity .3s ease-out;transition:opacity .3s ease-out;animation-name:smartphoto-img-wrap;animation-duration:.3s;animation-timing-function:ease-out}.smartphoto-img-left{transform:translateX(150%) !important}.smartphoto-img-right{transform:translateX(-150%) !important}.smartphoto-arrows{list-style-type:none;margin:0;padding:0;position:relative;z-index:1002;top:50%;left:0;opacity:1;animation-name:smartphoto-appear;animation-duration:.3s;animation-timing-function:ease-out}.smartphoto-arrows[aria-hidden="true"]{animation-name:smartphoto-hide;display:none}.smartphoto-arrows li{display:block;position:absolute;top:50%;width:30px;height:30px;margin-top:-20px;box-sizing:content-box;animation-duration:.3s;animation-timing-function:ease-out;animation-name:smartphoto-appear}.smartphoto-arrows li:focus{outline:none}.smartphoto-arrows [aria-hidden="true"]{animation-name:smartphoto-hide;display:none}.smartphoto-arrows a{display:block;width:100%;height:100%;text-decoration:none}.smartphoto-arrow-right{right:0;padding:5px 0;background-color:rgba(0,0,0,0.5)}.smartphoto-arrow-right a{background-image:url(data:image/svg+xml;base64,PHN2ZyBpZD0i44Os44Kk44Ok44O8XzEiIGRhdGEtbmFtZT0i44Os44Kk44Ok44O8IDEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDI4MzQuNjUgMjgzNC42NSIgZmlsbD0iI0ZGRiAiPjx0aXRsZT5pY29uPC90aXRsZT48cGF0aCBkPSJNMTgzNy44OCwxNDE3LjMyLDY0My41OSwyMjNhNzIuMjEsNzIuMjEsMCwwLDEsMC0xMDEuODJMNzQzLjgyLDIxYTcyLjIxLDcyLjIxLDAsMCwxLDEwMS44MiwwTDIwOTAuODMsMTI2Ni4xOWwxMDAuMjMsMTAwLjIzYTcyLjIxLDcyLjIxLDAsMCwxLDAsMTAxLjgyTDg0NS42NCwyODEzLjY1YTcyLjIxLDcyLjIxLDAsMCwxLTEwMS44MiwwTDY0My41OSwyNzEzLjQyYTcyLjIxLDcyLjIxLDAsMCwxLDAtMTAxLjgyWiIvPjwvc3ZnPg==)}.smartphoto-arrow-left{left:0;padding:5px 0;background-color:rgba(0,0,0,0.5)}.smartphoto-arrow-left a{background-image:url(data:image/svg+xml;base64,PHN2ZyBpZD0i44Os44Kk44Ok44O8XzEiIGRhdGEtbmFtZT0i44Os44Kk44Ok44O8IDEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDI4MzQuNjUgMjgzNC42NSIgZmlsbD0iI0ZGRiI+PHRpdGxlPmljb248L3RpdGxlPjxwYXRoIGQ9Ik05OTYuNzcsMTQxNy4zMiwyMTkxLjA2LDIyM2E3Mi4yMSw3Mi4yMSwwLDAsMCwwLTEwMS44MkwyMDkwLjgzLDIxQTcyLjIxLDcyLjIxLDAsMCwwLDE5ODksMjFMNzQzLjgyLDEyNjYuMTksNjQzLjU5LDEzNjYuNDJhNzIuMjEsNzIuMjEsMCwwLDAsMCwxMDEuODJMMTk4OSwyODEzLjY1YTcyLjIxLDcyLjIxLDAsMCwwLDEwMS44MiwwbDEwMC4yMy0xMDAuMjNhNzIuMjEsNzIuMjEsMCwwLDAsMC0xMDEuODJaIi8+PC9zdmc+)}.smartPhotoArrowHideIcon{display:none}.smartphoto-nav{position:absolute;bottom:0;left:0;width:100%;opacity:1;animation-name:smartphoto-appear;animation-duration:.3s;animation-timing-function:ease-out}.smartphoto-nav[aria-hidden="true"]{animation-name:smartphoto-hide;display:none}.smartphoto-nav ul{display:block;overflow-x:auto;list-style:none;margin:0;padding:0;text-align:center;white-space:nowrap;-webkit-overflow-scrolling:touch}.smartphoto-nav li{display:inline-block;overflow:hidden;width:50px;height:50px}.smartphoto-nav a{display:block;width:100%;height:100%;background-color:#FFF;background-position:center center;background-size:cover;opacity:.5}.smartphoto-nav a:focus{opacity:.8}.smartphoto-nav a.current{opacity:1}.smartphoto-nav img{width:auto;height:100%}.smartphoto-list{list-style-type:none;position:absolute;z-index:101;top:0;left:0;margin:0;padding:0;white-space:nowrap}.smartphoto-list li{display:block;position:absolute;top:0;left:0;width:100%;height:100%;transition:all 0.3s ease-out}.smartphoto-list li:focus{outline:none}.smartphoto-list-onmove{transition:all 0.3s ease-out}.smartphoto-caption{overflow:hidden;box-sizing:border-box;position:absolute;top:0;left:0;width:100%;height:50px;padding:0 50px;color:#FFF;font-size:12px;text-align:center;line-height:50px;white-space:nowrap;text-overflow:ellipsis}.smartphoto-caption:focus{outline:none}.smartphoto-loader-wrap{display:block;position:relative;z-index:103;width:0;height:0;transform:translate(50vw, 50vh)}.smartphoto-loader{position:absolute;z-index:101;top:0;left:0;width:30px;height:30px;margin-top:-25px;margin-left:-25px;border:8px solid #17CDDD;border-right-color:transparent;border-radius:50%;animation:smartphoto-loader .5s infinite linear}.smartphoto-img-clone{position:fixed;z-index:100;top:0;left:0;transition:all .3s ease-out}.smartphoto-sr-only{overflow:hidden;position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;clip:rect(0, 0, 0, 0)}
2 |
--------------------------------------------------------------------------------
/examples/assets/bear.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appleple/SmartPhoto/abfd4f071f50b3c170c5ddcbed8c8e966c965eec/examples/assets/bear.jpg
--------------------------------------------------------------------------------
/examples/assets/camel.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appleple/SmartPhoto/abfd4f071f50b3c170c5ddcbed8c8e966c965eec/examples/assets/camel.jpg
--------------------------------------------------------------------------------
/examples/assets/castle.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appleple/SmartPhoto/abfd4f071f50b3c170c5ddcbed8c8e966c965eec/examples/assets/castle.jpg
--------------------------------------------------------------------------------
/examples/assets/hippo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appleple/SmartPhoto/abfd4f071f50b3c170c5ddcbed8c8e966c965eec/examples/assets/hippo.jpg
--------------------------------------------------------------------------------
/examples/assets/koala.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appleple/SmartPhoto/abfd4f071f50b3c170c5ddcbed8c8e966c965eec/examples/assets/koala.jpg
--------------------------------------------------------------------------------
/examples/assets/large-bear.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appleple/SmartPhoto/abfd4f071f50b3c170c5ddcbed8c8e966c965eec/examples/assets/large-bear.jpg
--------------------------------------------------------------------------------
/examples/assets/large-camel.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appleple/SmartPhoto/abfd4f071f50b3c170c5ddcbed8c8e966c965eec/examples/assets/large-camel.jpg
--------------------------------------------------------------------------------
/examples/assets/large-hippo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appleple/SmartPhoto/abfd4f071f50b3c170c5ddcbed8c8e966c965eec/examples/assets/large-hippo.jpg
--------------------------------------------------------------------------------
/examples/assets/large-koala.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appleple/SmartPhoto/abfd4f071f50b3c170c5ddcbed8c8e966c965eec/examples/assets/large-koala.jpg
--------------------------------------------------------------------------------
/examples/assets/large-lion.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appleple/SmartPhoto/abfd4f071f50b3c170c5ddcbed8c8e966c965eec/examples/assets/large-lion.jpg
--------------------------------------------------------------------------------
/examples/assets/large-rhino.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appleple/SmartPhoto/abfd4f071f50b3c170c5ddcbed8c8e966c965eec/examples/assets/large-rhino.jpg
--------------------------------------------------------------------------------
/examples/assets/lion.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appleple/SmartPhoto/abfd4f071f50b3c170c5ddcbed8c8e966c965eec/examples/assets/lion.jpg
--------------------------------------------------------------------------------
/examples/assets/rhino.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appleple/SmartPhoto/abfd4f071f50b3c170c5ddcbed8c8e966c965eec/examples/assets/rhino.jpg
--------------------------------------------------------------------------------
/examples/assets/sample.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appleple/SmartPhoto/abfd4f071f50b3c170c5ddcbed8c8e966c965eec/examples/assets/sample.png
--------------------------------------------------------------------------------
/examples/assets/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: Arial, Helvetica, sans-serif;
3 | background-color: #eee;
4 | }
5 | .title {
6 | text-align: center;
7 | font-weight: bold;
8 | font-size: 48px;
9 | color: #333;
10 | }
11 | .wrapper{
12 | max-width: 940px;
13 | margin: 0 auto;
14 | }
15 | .masonry {
16 | -moz-transition: all .5s ease-in-out;
17 | -webkit-transition: all .5s ease-in-out;
18 | transition: all .5s ease-in-out;
19 | -moz-column-gap: 30px;
20 | -webkit-column-gap: 30px;
21 | column-gap: 30px;
22 | -moz-column-fill: initial;
23 | -webkit-column-fill: initial;
24 | column-fill: initial;
25 | }
26 | .masonry .brick {
27 | margin-bottom: 30px;
28 | overflow: hidden;
29 | }
30 | .masonry .brick img {
31 | -moz-transition: all .5s ease-in-out;
32 | -webkit-transition: all .5s ease-in-out;
33 | transition: all .5s ease-in-out;
34 | }
35 | .masonry .brick:hover img {
36 | opacity: .75;
37 | }
38 | .masonry.bordered {
39 | -moz-column-rule: 1px solid #eee;
40 | -webkit-column-rule: 1px solid #eee;
41 | column-rule: 1px solid #eee;
42 | -moz-column-gap: 50px;
43 | -webkit-column-gap: 50px;
44 | column-gap: 50px;
45 | }
46 | .masonry.bordered .brick {
47 | padding-bottom: 25px;
48 | margin-bottom: 25px;
49 | border-bottom: 1px solid #eee;
50 | }
51 | .masonry.gutterless {
52 | -moz-column-gap: 0;
53 | -webkit-column-gap: 0;
54 | column-gap: 0;
55 | }
56 | .masonry.gutterless .brick {
57 | margin-bottom: 0;
58 | }
59 |
60 | .span {
61 | -moz-column-span: all;
62 | -webkit-column-span: all;
63 | column-span: all;
64 | *margin: 30px 0;
65 | }
66 |
67 | @media only screen and (min-width: 1024px) {
68 | .desc {
69 | font-size: 1.25em;
70 | }
71 |
72 | .intro {
73 | letter-spacing: 1px;
74 | }
75 |
76 | .wrapper {
77 | width: 80%;
78 | padding: 2em;
79 | }
80 |
81 | .masonry {
82 | -moz-column-count: 3;
83 | -webkit-column-count: 3;
84 | column-count: 3;
85 | }
86 | }
87 | @media only screen and (min-width: 768px) and (max-width: 1023px) {
88 | .wrapper {
89 | width: 85%;
90 | padding: 1.5em;
91 | }
92 |
93 | .masonry {
94 | -moz-column-count: 2;
95 | -webkit-column-count: 2;
96 | column-count: 2;
97 | }
98 | }
--------------------------------------------------------------------------------
/examples/assets/test.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appleple/SmartPhoto/abfd4f071f50b3c170c5ddcbed8c8e966c965eec/examples/assets/test.png
--------------------------------------------------------------------------------
/examples/event.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | SmartPhoto.js
9 |
10 |
11 |
12 |
13 |
SmartPhoto.js
14 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
46 |
47 |
48 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/examples/jquery.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | jquery-smartphoto.js
10 |
11 |
12 |
13 |
jquery-smartphoto.js
14 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
66 |
67 |
68 |
69 |
73 |
74 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/examples/lazy.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | jquery-smartphoto.js
9 |
15 |
16 |
17 |
18 |
23 |
28 |
33 |
38 |
43 |
48 |
53 |
58 |
63 |
68 |
69 |
70 |
71 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/examples/multiple.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | SmartPhoto.js
10 |
11 |
12 |
13 |
SmartPhoto.js
14 |
resizeStyle = Fill
15 |
16 |
21 |
26 |
31 |
36 |
41 |
46 |
47 |
resizeStyle = Fit
48 |
49 |
54 |
59 |
64 |
69 |
74 |
79 |
80 |
81 |
82 |
83 |
84 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/examples/noimage.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | SmartPhoto.js
9 |
10 |
11 |
12 |
13 |
SmartPhoto.js
14 |
15 |
16 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/examples/resizeFit.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | SmartPhoto.js
10 |
11 |
12 |
13 |
SmartPhoto.js
14 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
46 |
47 |
48 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/examples/vanilla.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | SmartPhoto.js
9 |
10 |
11 |
12 |
13 |
SmartPhoto.js
14 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
46 |
47 |
48 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/images/icon_arrow_next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/icon_arrow_prev.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/icon_close.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/index.d.ts:
--------------------------------------------------------------------------------
1 | declare module "smartphoto" {
2 |
3 | type SmartPhotoEvent = 'open'|'close'|'change'|'swipestart'|'swipeend'|'zoomin'|'zoomout'|'gesturestart'|'gestureend';
4 |
5 | interface SmartPhotoOption {
6 | classNames?: {
7 | smartPhoto: string,
8 | smartPhotoClose: string,
9 | smartPhotoBody: string,
10 | smartPhotoInner: string,
11 | smartPhotoContent: string,
12 | smartPhotoImg: string,
13 | smartPhotoImgOnMove: string,
14 | smartPhotoImgElasticMove: string,
15 | smartPhotoImgWrap: string,
16 | smartPhotoArrows: string,
17 | smartPhotoNav: string,
18 | smartPhotoArrowRight: string,
19 | smartPhotoArrowLeft: string,
20 | smartPhotoImgLeft: string,
21 | smartPhotoImgRight: string,
22 | smartPhotoList: string,
23 | smartPhotoListOnMove: string,
24 | smartPhotoHeader: string,
25 | smartPhotoCount: string,
26 | smartPhotoCaption: string,
27 | smartPhotoDismiss: string,
28 | smartPhotoLoader: string,
29 | smartPhotoLoaderWrap: string,
30 | smartPhotoImgClone: string
31 | },
32 | message?: {
33 | gotoNextImage: string,
34 | gotoPrevImage: string,
35 | closeDialog: string
36 | },
37 | arrows?: boolean,
38 | nav?: boolean,
39 | showAnimation?: boolean,
40 | verticalGravity?: boolean,
41 | useOrientationApi?: boolean,
42 | useHistoryApi?: boolean,
43 | swipeTopToClose?: boolean,
44 | swipeBottomToClose?: boolean,
45 | swipeOffset?: number,
46 | headerHeight?: number,
47 | footerHeight?: number,
48 | forceInterval?: number,
49 | registance?: number,
50 | loadOffset?: number,
51 | resizeStyle?: 'fit'|'cover',
52 | }
53 |
54 | export default class SmartPhoto {
55 | constructor(selector: string | NodeListOf, option?:SmartPhotoOption);
56 | on(event: SmartPhotoEvent, eventListener: EventListenerOrEventListenerObject) :void;
57 | destroy(): void;
58 | addNewItem(element: HTMLElement): void;
59 | hidePhoto(dir: 'bottom'|'top'): void;
60 | gotoSlide(index: number): void;
61 | zoomPhoto(): void;
62 | zoomOutPhoto(): void;
63 | }
64 | }
--------------------------------------------------------------------------------
/js/smartphoto.min.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Modules in this bundle
3 | * @license
4 | *
5 | * smartphoto:
6 | * license: MIT (http://opensource.org/licenses/MIT)
7 | * author: appleple
8 | * homepage: http://developer.a-blogcms.jp
9 | * version: 1.6.4
10 | *
11 | * a-template:
12 | * license: MIT (http://opensource.org/licenses/MIT)
13 | * author: steelydylan
14 | * version: 0.6.1
15 | *
16 | * custom-event-polyfill:
17 | * license: MIT (http://opensource.org/licenses/MIT)
18 | * contributors: Frank Panetta, Mikhail Reenko , Joscha Feth
19 | * homepage: https://github.com/krambuhl/custom-event-polyfill#readme
20 | * version: 0.3.0
21 | *
22 | * es6-promise-polyfill:
23 | * license: MIT (http://opensource.org/licenses/MIT)
24 | * author: Roman Dvornov
25 | * homepage: https://github.com/lahmatiy/es6-promise-polyfill#readme
26 | * version: 1.2.0
27 | *
28 | * ie-array-find-polyfill:
29 | * license: MIT (http://opensource.org/licenses/MIT)
30 | * author: Carlos Abdalla
31 | * homepage: https://github.com/abdalla/ie-array-find-polyfill#readme
32 | * version: 1.1.0
33 | *
34 | * morphdom:
35 | * license: MIT (http://opensource.org/licenses/MIT)
36 | * author: Patrick Steele-Idem
37 | * homepage: https://github.com/patrick-steele-idem/morphdom#readme
38 | * version: 2.5.12
39 | *
40 | * process:
41 | * license: MIT (http://opensource.org/licenses/MIT)
42 | * author: Roman Shtylman
43 | * homepage: https://github.com/shtylman/node-process#readme
44 | * version: 0.11.10
45 | *
46 | * timers-browserify:
47 | * licenses: MIT (http://opensource.org/licenses/MIT)
48 | * author: J. Ryan Stinnett
49 | * contributors: Guy Bedford , Ionut-Cristian Florescu , James Halliday , Jan Schär , Johannes Ewald , Jonathan Prins , Matt Esch
50 | * homepage: https://github.com/jryans/timers-browserify
51 | * version: 1.4.2
52 | *
53 | * This header is generated by licensify (https://github.com/twada/licensify)
54 | */
55 | !function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.SmartPhoto=t()}}(function(){var t;return function(){function t(e,a,o){function n(r,s){if(!a[r]){if(!e[r]){var c="function"==typeof require&&require;if(!s&&c)return c(r,!0);if(i)return i(r,!0);var d=new Error("Cannot find module '"+r+"'");throw d.code="MODULE_NOT_FOUND",d}var u=a[r]={exports:{}};e[r][0].call(u.exports,function(t){return n(e[r][1][t]||t)},u,u.exports,t,e,a,o)}return a[r].exports}for(var i="function"==typeof require&&require,r=0;r1;)a=a[o.shift()];a[o.shift()]=e}},{key:"removeDataByString",value:function(t){for(var e=this.data,a=t.split(".");a.length>1;)e=e[a.shift()];var o=a.shift();o.match(/^\d+$/)?e.splice(Number(o),1):delete e[o]}},{key:"resolveBlock",value:function(t,e,a){var o=this,n=t.match(//g),i=t.match(//g),r=t.match(//g),s=t.match(//g);if(n)for(var c=0,d=n.length;c/g;return t=t.replace(e,function(t,e){return(0,c.selector)("#"+e).innerHTML})}},{key:"resolveWith",value:function(t){var e=/(([\n\r\t]|.)*?)/g;return t=t.replace(e,function(t,e){return t=t.replace(/data\-bind=['"](.*?)['"]/g,"data-bind='"+e+".$1'")})}},{key:"resolveLoop",value:function(t){var e=/(([\n\r\t]|.)*?)/g,a=this;return t=t.replace(e,function(t,e,o){var n=a.getDataByString(e),i=[];i="function"==typeof n?n.apply(a):n;var r="";if(i instanceof Array)for(var s=0,c=i.length;s(([\n\r\t]|.)*?)/g;return!!t.match(e)}},{key:"getHtml",value:function(t,e){var a=this.atemplate.find(function(e){return e.id===t}),o="";if(a&&a.html&&(o=a.html),e&&(o=t),!o)return"";var n=this.data;for(o=this.resolveInclude(o),o=this.resolveWith(o);this.hasLoop(o);)o=this.resolveLoop(o);return o=this.resolveBlock(o,n),o=o.replace(/\\([^\\])/g,"$1"),o=this.resolveAbsBlock(o),o.replace(/^([\t ])*\n/gm,"")}},{key:"update",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"html",a=arguments[1],o=this.templates;this.beforeUpdated&&this.beforeUpdated();for(var n=0,i=o.length;n"+u+"");else(0,c.selector)(d).insertAdjacentHTML("afterend",''),"text"===e?(0,c.selector)("[data-id='"+r+"']").innerText=u:(0,c.selector)("[data-id='"+r+"']").innerHTML=u;var p=t.atemplate.find(function(t){return t.id===r});p.binded||(p.binded=!0,t.addDataBind((0,c.selector)("[data-id='"+r+"']")),t.addActionBind((0,c.selector)("[data-id='"+r+"']")))}(n);return this.updateBindingData(a),this.onUpdated&&this.onUpdated(a),this}},{key:"updateBindingData",value:function(t){for(var e=this,a=this.templates,o=0,n=a.length;o1?a-1:0),n=1;n1;)e=e[a.shift()];var o=a.shift();return o.match(/^\d+$/)?e.splice(Number(o),1):delete e[o],this}}]),t}();a.default=h,e.exports=a.default},{"./util":2,"ie-array-find-polyfill":5,morphdom:6}],2:[function(t,e,a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});var o=a.matches=function(t,e){for(var a=(t.document||t.ownerDocument).querySelectorAll(e),o=a.length;--o>=0&&a.item(o)!==t;);return o>-1},n=(a.selector=function(t){return document.querySelector(t)},a.findAncestor=function(t,e){if("function"==typeof t.closest)return t.closest(e)||null;for(;t&&t!==document;){if(o(t,e))return t;t=t.parentElement}return null}),i=[];a.on=function(t,e,a,o){var r=arguments.length>4&&void 0!==arguments[4]&&arguments[4];a.split(" ").forEach(function(a){var s=function(t){var a=n(t.target,e);a&&(t.delegateTarget=a,o(t))};i.push({listener:s,element:t,query:e,event:a,capture:r}),t.addEventListener(a,s,r)})},a.off=function(t,e,a){a.split(" ").forEach(function(a){i.forEach(function(o,n){o.element===t&&o.query===e&&o.event===a&&(t.removeEventListener(a,o.listener,o.capture),i.splice(n,1))})})}},{}],3:[function(t,e,a){try{var o=new window.CustomEvent("test");if(o.preventDefault(),!0!==o.defaultPrevented)throw new Error("Could not prevent default")}catch(t){var n=function(t,e){var a,o;return e=e||{bubbles:!1,cancelable:!1,detail:void 0},a=document.createEvent("CustomEvent"),a.initCustomEvent(t,e.bubbles,e.cancelable,e.detail),o=a.preventDefault,a.preventDefault=function(){o.call(this);try{Object.defineProperty(this,"defaultPrevented",{get:function(){return!0}})}catch(t){this.defaultPrevented=!0}},a};n.prototype=window.Event.prototype,window.CustomEvent=n}},{}],4:[function(e,a,o){(function(e,a){!function(e){function n(t){return"[object Array]"===Object.prototype.toString.call(t)}function i(){for(var t=0;t>>0;if("function"!=typeof t)throw new TypeError("predicate must be a function");for(var o=arguments[1],n=0;n=0;s--)a=r[s],o=a.name,n=a.namespaceURI,i=a.value,n?(o=a.localName||o,t.getAttributeNS(n,o)!==i&&("xmlns"===a.prefix&&(o=a.name),t.setAttributeNS(n,o,i))):t.getAttribute(o)!==i&&t.setAttribute(o,i);for(var c=t.attributes,d=c.length-1;d>=0;d--)a=c[d],o=a.name,n=a.namespaceURI,n?(o=a.localName||o,e.hasAttributeNS(n,o)||t.removeAttributeNS(n,o)):e.hasAttribute(o)||t.removeAttribute(o)}}function n(t){var e=g.createElement("template");return e.innerHTML=t,e.content.childNodes[0]}function i(t){return p||(p=g.createRange(),p.selectNode(g.body)),p.createContextualFragment(t).childNodes[0]}function r(t){var e=g.createElement("body");return e.innerHTML=t,e.childNodes[0]}function s(t){return t=t.trim(),y?n(t):x?i(t):r(t)}function c(t,e){var a=t.nodeName,o=e.nodeName;return a===o||!!(e.actualize&&a.charCodeAt(0)<91&&o.charCodeAt(0)>90)&&a===o.toUpperCase()}function d(t,e){return e&&e!==v?g.createElementNS(e,t):g.createElement(t)}function u(t,e){for(var a=t.firstChild;a;){var o=a.nextSibling;e.appendChild(a),a=o}return e}function l(t,e,a){t[a]!==e[a]&&(t[a]=e[a],t[a]?t.setAttribute(a,""):t.removeAttribute(a))}function h(){}function f(t){if(t)return t.getAttribute&&t.getAttribute("id")||t.id}var p,m=11,v="http://www.w3.org/1999/xhtml",g="undefined"==typeof document?void 0:document,y=!!g&&"content"in g.createElement("template"),x=!!g&&g.createRange&&"createContextualFragment"in g.createRange(),w={OPTION:function(t,e){var a=t.parentNode;if(a){var o=a.nodeName.toUpperCase();"OPTGROUP"===o&&(a=a.parentNode,o=a&&a.nodeName.toUpperCase()),"SELECT"!==o||a.hasAttribute("multiple")||(t.hasAttribute("selected")&&!e.selected&&(t.setAttribute("selected","selected"),t.removeAttribute("selected")),a.selectedIndex=-1)}l(t,e,"selected")},INPUT:function(t,e){l(t,e,"checked"),l(t,e,"disabled"),t.value!==e.value&&(t.value=e.value),e.hasAttribute("value")||t.removeAttribute("value")},TEXTAREA:function(t,e){var a=e.value;t.value!==a&&(t.value=a);var o=t.firstChild;if(o){var n=o.nodeValue;if(n==a||!a&&n==t.placeholder)return;o.nodeValue=a}},SELECT:function(t,e){if(!e.hasAttribute("multiple")){for(var a,o,n=-1,i=0,r=t.firstChild;r;)if("OPTGROUP"===(o=r.nodeName&&r.nodeName.toUpperCase()))a=r,r=a.firstChild;else{if("OPTION"===o){if(r.hasAttribute("selected")){n=i;break}i++}r=r.nextSibling,!r&&a&&(r=a.nextSibling,a=null)}t.selectedIndex=n}}},P=1,E=11,b=3,_=8,I=function(t){return function(e,a,o){function n(t){G.push(t)}function i(t,e){if(t.nodeType===P)for(var a=t.firstChild;a;){var o=void 0;e&&(o=I(a))?n(o):(T(a),a.firstChild&&i(a,e)),a=a.nextSibling}}function r(t,e,a){!1!==B(t)&&(e&&e.removeChild(t),T(t),i(t,a))}function l(t){if(t.nodeType===P||t.nodeType===E)for(var e=t.firstChild;e;){var a=I(e);a&&(C[a]=e),l(e),e=e.nextSibling}}function p(t){S(t);for(var e=t.firstChild;e;){var a=e.nextSibling,o=I(e);if(o){var n=C[o];n&&c(e,n)&&(e.parentNode.replaceChild(n,e),v(n,e))}p(e),e=a}}function m(t,e,a){for(;e;){var o=e.nextSibling;(a=I(e))?n(a):r(e,t,!0),e=o}}function v(e,a,o){var n=I(a);if(n&&delete C[n],!o){if(!1===k(e,a))return;if(t(e,a),A(e),!1===D(e,a))return}"TEXTAREA"!==e.nodeName?y(e,a):w.TEXTAREA(e,a)}function y(t,e){var a,o,i,s,d,u=e.firstChild,l=t.firstChild;t:for(;u;){for(s=u.nextSibling,a=I(u);l;){if(i=l.nextSibling,u.isSameNode&&u.isSameNode(l)){u=s,l=i;continue t}o=I(l);var h=l.nodeType,f=void 0;if(h===u.nodeType&&(h===P?(a?a!==o&&((d=C[a])?i===d?f=!1:(t.insertBefore(d,l),o?n(o):r(l,t,!0),l=d):f=!1):o&&(f=!1),(f=!1!==f&&c(l,u))&&v(l,u)):h!==b&&h!=_||(f=!0,l.nodeValue!==u.nodeValue&&(l.nodeValue=u.nodeValue))),f){u=s,l=i;continue t}o?n(o):r(l,t,!0),l=i}if(a&&(d=C[a])&&c(d,u))t.appendChild(d),v(d,u);else{var y=N(u);!1!==y&&(y&&(u=y),u.actualize&&(u=u.actualize(t.ownerDocument||g)),t.appendChild(u),p(u))}u=s,l=i}m(t,l,o);var x=w[t.nodeName];x&&x(t,e)}if(o||(o={}),"string"==typeof a)if("#document"===e.nodeName||"HTML"===e.nodeName){var x=a;a=g.createElement("html"),a.innerHTML=x}else a=s(a);var I=o.getNodeKey||f,N=o.onBeforeNodeAdded||h,S=o.onNodeAdded||h,k=o.onBeforeElUpdated||h,A=o.onElUpdated||h,B=o.onBeforeNodeDiscarded||h,T=o.onNodeDiscarded||h,D=o.onBeforeElChildrenUpdated||h,O=!0===o.childrenOnly,C=Object.create(null),G=[];l(e);var L=e,z=L.nodeType,X=a.nodeType;if(!O)if(z===P)X===P?c(e,a)||(T(e),L=u(e,d(a.nodeName,a.namespaceURI))):L=a;else if(z===b||z===_){if(X===z)return L.nodeValue!==a.nodeValue&&(L.nodeValue=a.nodeValue),L;L=a}if(L===a)T(e);else{if(a.isSameNode&&a.isSameNode(L))return;if(v(L,a,O),G)for(var M=0,Y=G.length;M1)for(var a=1;a=0&&(t._idleTimeoutId=setTimeout(function(){t._onTimeout&&t._onTimeout()},e))},a.setImmediate="function"==typeof e?e:function(t){var e=d++,o=!(arguments.length<2)&&s.call(arguments,1);return c[e]=!0,i(function(){c[e]&&(o?t.apply(null,o):t.call(null),a.clearImmediate(e))}),e},a.clearImmediate="function"==typeof o?o:function(t){delete c[t]}}).call(this,t("timers").setImmediate,t("timers").clearImmediate)},{"process/browser.js":7,timers:8}],9:[function(t,e,a){"use strict";function o(t){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){for(var a=0;ago to {caption}\n\t\t\t\t\t\t\x3c!-- END groupItems:loop --\x3e\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\x3c!-- END nav:exist --\x3e\n\t\t\n\t\t\x3c!-- BEGIN appearEffect:exist --\x3e\n\t\t
\n\t\t\x3c!-- END appearEffect:exist --\x3e\n\t\n\n',p=t("../lib/util"),m=t("es6-promise-polyfill"),v=m.Promise,g={classNames:{smartPhoto:"smartphoto",smartPhotoClose:"smartphoto-close",smartPhotoBody:"smartphoto-body",smartPhotoInner:"smartphoto-inner",smartPhotoContent:"smartphoto-content",smartPhotoImg:"smartphoto-img",smartPhotoImgOnMove:"smartphoto-img-onmove",smartPhotoImgElasticMove:"smartphoto-img-elasticmove",smartPhotoImgWrap:"smartphoto-img-wrap",smartPhotoArrows:"smartphoto-arrows",smartPhotoNav:"smartphoto-nav",smartPhotoArrowRight:"smartphoto-arrow-right",smartPhotoArrowLeft:"smartphoto-arrow-left",smartPhotoArrowHideIcon:"smartphoto-arrow-hide",smartPhotoImgLeft:"smartphoto-img-left",smartPhotoImgRight:"smartphoto-img-right",smartPhotoList:"smartphoto-list",smartPhotoListOnMove:"smartphoto-list-onmove",smartPhotoHeader:"smartphoto-header",smartPhotoCount:"smartphoto-count",smartPhotoCaption:"smartphoto-caption",smartPhotoDismiss:"smartphoto-dismiss",smartPhotoLoader:"smartphoto-loader",smartPhotoLoaderWrap:"smartphoto-loader-wrap",smartPhotoImgClone:"smartphoto-img-clone"},message:{gotoNextImage:"go to the next image",gotoPrevImage:"go to the previous image",closeDialog:"close the image dialog"},arrows:!0,nav:!0,showAnimation:!0,verticalGravity:!1,useOrientationApi:!1,useHistoryApi:!0,swipeTopToClose:!1,swipeBottomToClose:!0,swipeOffset:100,headerHeight:60,footerHeight:60,forceInterval:10,registance:.5,loadOffset:2,resizeStyle:"fit",lazyAttribute:"data-src"},y=function(t){function e(t,a){var o;n(this,e),o=s(this,d(e).call(this)),o.data=p.extend({},g,a),o.data.currentIndex=0,o.data.oldIndex=0,o.data.hide=!0,o.data.group={},o.data.scaleSize=1,o.data.scale=!1,o.pos={x:0,y:0},o.data.photoPosX=0,o.data.photoPosY=0,o.handlers=[],o.convert={increment:o.increment,virtualPos:o.virtualPos,round:o.round},o.data.groupItems=o.groupItems,o.elements="string"==typeof t?document.querySelectorAll(t):t;var i=new Date;o.tapSecond=i.getTime(),o.onListMove=!1,o.clicked=!1,o.id=o._getUniqId(),o.vx=0,o.vy=0,o.data.appearEffect=null,o.addTemplate(o.id,f),o.data.isSmartPhone=o._isSmartPhone();var r=document.querySelector("body");p.append(r,"")),[].forEach.call(o.elements,function(t){o.addNewItem(t)}),o.update();var c=o._getCurrentItemByHash();if(c&&p.triggerEvent(c.element,"click"),
56 | o.interval=setInterval(function(){o._doAnim()},o.data.forceInterval),!o.data.isSmartPhone){var u=function(){o.groupItems()&&(o._resetTranslate(),o._setPosByCurrentIndex(),o._setSizeByScreen(),o.update())},l=function(t){var e=t.keyCode||t.which;!0!==o.data.hide&&(37===e?o.gotoSlide(o.data.prev):39===e?o.gotoSlide(o.data.next):27===e&&o.hidePhoto())};return window.addEventListener("resize",u),window.addEventListener("keydown",l),o._registerRemoveEvent(window,"resize",u),o._registerRemoveEvent(window,"keydown",l),s(o)}var h=function(){if(o.groupItems()){o._resetTranslate(),o._setPosByCurrentIndex(),o._setHashByCurrentIndex(),o._setSizeByScreen(),o.update();var t=o._getWindowWidth();!function e(a){new v(function(t){setTimeout(function(){t()},25)}).then(function(){t!==o._getWindowWidth()?(o._resetTranslate(),o._setPosByCurrentIndex(),o._setHashByCurrentIndex(),o._setSizeByScreen(),o.update()):a<=500&&e(a+25)})}(0)}};if(window.addEventListener("orientationchange",h),o._registerRemoveEvent(window,"orientationchange",h),!o.data.useOrientationApi)return s(o);var m=function(t){var e=window,a=e.orientation;t&&t.gamma&&!o.data.appearEffect&&(o.isBeingZoomed||o.photoSwipable||o.data.elastic||!o.data.scale||(0===a?o._calcGravity(t.gamma,t.beta):90===a?o._calcGravity(t.beta,t.gamma):-90===a?o._calcGravity(-t.beta,-t.gamma):180===a&&o._calcGravity(-t.gamma,-t.beta)))};return window.addEventListener("deviceorientation",m),o._registerRemoveEvent(window,"deviceorientation",m),o}return u(e,t),r(e,[{key:"on",value:function(t,e){var a=this._getElementByClass(this.data.classNames.smartPhoto),o=function(t){e.call(a,t)};a.addEventListener(t,o),this._registerRemoveEvent(a,t,o)}},{key:"_registerRemoveEvent",value:function(t,e,a){this.handlers.push({target:t,event:e,handler:a})}},{key:"destroy",value:function(){this.handlers.forEach(function(t){t.target.removeEventListener(t.event,t.handler)});var t=document.querySelector('[data-id="'.concat(this.id,'"]'));p.removeElement(t),clearInterval(this.interval),this.removeTemplateEvents()}},{key:"increment",value:function(t){return t+1}},{key:"round",value:function(t){return Math.round(t)}},{key:"virtualPos",value:function(t){return(t=parseInt(t,10))/this._getSelectedItem().scale/this.data.scaleSize}},{key:"groupItems",value:function(){return this.data.group[this.data.currentGroup]}},{key:"_resetTranslate",value:function(){var t=this;this.groupItems().forEach(function(e,a){e.translateX=t._getWindowWidth()*a})}},{key:"addNewItem",value:function(t){var e=this,a=t.getAttribute("data-group")||"nogroup",o=this.data.group;"nogroup"===a&&t.setAttribute("data-group","nogroup"),o[a]||(o[a]=[]);var n=o[a].length,i=document.querySelector("body"),r=t.getAttribute("href"),s=t.querySelector("img"),c=r;s&&(c=s.getAttribute(this.data.lazyAttribute)?s.getAttribute(this.data.lazyAttribute):s.currentSrc?s.currentSrc:s.src);var d={src:r,thumb:c,caption:t.getAttribute("data-caption"),groupId:a,translateX:this._getWindowWidth()*n,index:n,translateY:0,width:50,height:50,id:t.getAttribute("data-id")||n,loaded:!1,processed:!1,element:t};o[a].push(d),this.data.currentGroup=a,t.getAttribute("data-id")||t.setAttribute("data-id",n),t.setAttribute("data-index",n);var u=function(a){a.preventDefault(),e.data.currentGroup=t.getAttribute("data-group"),e.data.currentIndex=parseInt(t.getAttribute("data-index"),10),e._setHashByCurrentIndex();var o=e._getSelectedItem();o.loaded?(e._initPhoto(),e.addAppearEffect(t,o),e.clicked=!0,e.update(),i.style.overflow="hidden",e._fireEvent("open")):e._loadItem(o).then(function(){e._initPhoto(),e.addAppearEffect(t,o),e.clicked=!0,e.update(),i.style.overflow="hidden",e._fireEvent("open")})};t.addEventListener("click",u),this._registerRemoveEvent(t,"click",u)}},{key:"_initPhoto",value:function(){this.data.total=this.groupItems().length,this.data.hide=!1,this.data.photoPosX=0,this.data.photoPosY=0,this._setPosByCurrentIndex(),this._setSizeByScreen(),this.setArrow(),"fill"===this.data.resizeStyle&&this.data.isSmartPhone&&(this.data.scale=!0,this.data.hideUi=!0,this.data.scaleSize=this._getScaleBoarder())}},{key:"onUpdated",value:function(){var t=this;if(this.data.appearEffect&&this.data.appearEffect.once&&(this.data.appearEffect.once=!1,this.execEffect().then(function(){t.data.appearEffect=null,t.data.appear=!0,t.update()})),this.clicked){this.clicked=!1;var e=this.data.classNames;this._getElementByClass(e.smartPhotoCaption).focus()}}},{key:"execEffect",value:function(){var t=this;return new v(function(e){p.isOldIE()&&e();var a=t.data,o=a.appearEffect,n=a.classNames,i=t._getElementByClass(n.smartPhotoImgClone),r=function t(){i.removeEventListener("transitionend",t,!0),e()};i.addEventListener("transitionend",r,!0),setTimeout(function(){i.style.transform="translate(".concat(o.afterX,"px, ").concat(o.afterY,"px) scale(").concat(o.scale,")")},10)})}},{key:"addAppearEffect",value:function(t,e){if(!1===this.data.showAnimation)return void(this.data.appear=!0);var a=t.querySelector("img"),o=p.getViewPos(a),n={},i=1;n.width=a.offsetWidth,n.height=a.offsetHeight,n.top=o.top,n.left=o.left,n.once=!0,a.getAttribute(this.data.lazyAttribute)?n.img=a.getAttribute(this.data.lazyAttribute):n.img=e.src;var r=this._getWindowWidth(),s=this._getWindowHeight(),c=s-this.data.headerHeight-this.data.footerHeight;"fill"===this.data.resizeStyle&&this.data.isSmartPhone?i=a.offsetWidth>a.offsetHeight?s/a.offsetHeight:r/a.offsetWidth:(n.width>=n.height?i=e.heightn.width&&(i=e.heightr&&(i=r/n.width));var d=(i-1)/2*a.offsetWidth+(r-a.offsetWidth*i)/2,u=(i-1)/2*a.offsetHeight+(s-a.offsetHeight*i)/2;n.afterX=d,n.afterY=u,n.scale=i,this.data.appearEffect=n}},{key:"hidePhoto",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"bottom";this.data.hide=!0,this.data.appear=!1,this.data.appearEffect=null,this.data.hideUi=!1,this.data.scale=!1,this.data.scaleSize=1;var a=void 0!==window.pageXOffset?window.pageXOffset:(document.documentElement||document.body.parentNode||document.body).scrollLeft,o=void 0!==window.pageYOffset?window.pageYOffset:(document.documentElement||document.body.parentNode||document.body).scrollTop,n=document.querySelector("body");window.location.hash&&this._setHash(""),window.scroll(a,o),this._doHideEffect(e).then(function(){t.update(),n.style.overflow="",t._fireEvent("close")})}},{key:"_doHideEffect",value:function(t){var e=this;return new v(function(a){p.isOldIE()&&a();var o=e.data.classNames,n=e._getElementByClass(o.smartPhoto),i=e._getElementByQuery(".current .".concat(o.smartPhotoImg)),r=e._getWindowHeight(),s=function t(){n.removeEventListener("transitionend",t,!0),a()};n.style.opacity=0,"bottom"===t?i.style.transform="translateY(".concat(r,"px)"):"top"===t&&(i.style.transform="translateY(-".concat(r,"px)")),n.addEventListener("transitionend",s,!0)})}},{key:"_getElementByClass",value:function(t){return document.querySelector('[data-id="'.concat(this.id,'"] .').concat(t))}},{key:"_getElementByQuery",value:function(t){return document.querySelector('[data-id="'.concat(this.id,'"] ').concat(t))}},{key:"_getTouchPos",value:function(){var t=0,e=0,a="undefined"==typeof event?this.e:event;return this._isTouched(a)?(t=a.touches[0].pageX,e=a.touches[0].pageY):a.pageX&&(t=a.pageX,e=a.pageY),{x:t,y:e}}},{key:"_getGesturePos",value:function(t){var e=t.touches;return[{x:e[0].pageX,y:e[0].pageY},{x:e[1].pageX,y:e[1].pageY}]}},{key:"_setPosByCurrentIndex",value:function(){var t=this,e=this.groupItems(),a=-1*e[this.data.currentIndex].translateX;this.pos.x=a,setTimeout(function(){t.data.translateX=a,t.data.translateY=0,t._listUpdate()},1)}},{key:"_setHashByCurrentIndex",value:function(){var t=void 0!==window.pageXOffset?window.pageXOffset:(document.documentElement||document.body.parentNode||document.body).scrollLeft,e=void 0!==window.pageYOffset?window.pageYOffset:(document.documentElement||document.body.parentNode||document.body).scrollTop,a=this.groupItems(),o=a[this.data.currentIndex].id,n=this.data.currentGroup,i="group=".concat(n,"&photo=").concat(o);this._setHash(i),window.scroll(t,e)}},{key:"_setHash",value:function(t){window.history&&window.history.pushState&&this.data.useHistoryApi&&(t?window.history.replaceState(null,null,"".concat(location.pathname).concat(location.search,"#").concat(t)):window.history.replaceState(null,null,"".concat(location.pathname).concat(location.search)))}},{key:"_getCurrentItemByHash",value:function(){var t=this.data.group,e=location.hash.substr(1),a=p.parseQuery(e),o=null,n=function(t){a.group===t.groupId&&a.photo===t.id&&(o=t)};return Object.keys(t).forEach(function(e){t[e].forEach(n)}),o}},{key:"_loadItem",value:function(t){return new v(function(e){var a=new Image;a.onload=function(){t.width=a.width,t.height=a.height,t.loaded=!0,e()},a.onerror=function(){e()},a.src=t.src})}},{key:"_getItemByIndex",value:function(t){var e=this.data;return e.group[e.currentGroup][t]?e.group[e.currentGroup][t]:null}},{key:"_loadNeighborItems",value:function(){for(var t=this,e=this.data.currentIndex,a=this.data.loadOffset,o=e-a,n=e+a,i=[],r=o;rt&&(a.scale=t/a.width,a.x=(a.scale-1)/2*a.width))})}},{key:"_slideList",value:function(){var t=this;this.data.scaleSize=1,this.isBeingZoomed=!1,this.data.hideUi=!1,this.data.scale=!1,this.data.photoPosX=0,this.data.photoPosY=0,this.data.onMoveClass=!0,this._setPosByCurrentIndex(),this._setHashByCurrentIndex(),this._setSizeByScreen(),setTimeout(function(){var e=t._getSelectedItem();t.data.onMoveClass=!1,t.setArrow(),t.update(),t.data.oldIndex!==t.data.currentIndex&&t._fireEvent("change"),t.data.oldIndex=t.data.currentIndex,t._loadNeighborItems(),e.loaded||t._loadItem(e).then(function(){t._initPhoto(),t.update()})},200)}},{key:"gotoSlide",value:function(t){this.e&&this.e.preventDefault&&this.e.preventDefault(),this.data.currentIndex=parseInt(t,10),this.data.currentIndex||(this.data.currentIndex=0),this._slideList()}},{key:"setArrow",value:function(){var t=this.groupItems(),e=t.length,a=this.data.currentIndex+1,o=this.data.currentIndex-1;this.data.showNextArrow=!1,this.data.showPrevArrow=!1,a!==e&&(this.data.next=a,this.data.showNextArrow=!0),-1!==o&&(this.data.prev=o,this.data.showPrevArrow=!0)}},{key:"beforeDrag",value:function(){if(this._isGestured(this.e))return void this.beforeGesture();if(this.isBeingZoomed=!1,this.data.scale)return void this.beforePhotoDrag();var t=this._getTouchPos();this.isSwipable=!0,this.dragStart=!0,this.firstPos=t,this.oldPos=t}},{key:"afterDrag",value:function(){var t=this.groupItems(),e=new Date,a=e.getTime(),o=this.tapSecond-a,n=0,i=0;return this.isSwipable=!1,this.onListMove=!1,this.oldPos&&(n=this.oldPos.x-this.firstPos.x,i=this.oldPos.y-this.firstPos.y),this.isBeingZoomed?void this.afterGesture():this.data.scale?void this.afterPhotoDrag():p.isSmartPhone()||0!==n||0!==i?Math.abs(o)<=500&&0===n&&0===i?(this.e.preventDefault(),void this.zoomPhoto()):(this.tapSecond=a,this._fireEvent("swipeend"),"horizontal"===this.moveDir&&(n>=this.data.swipeOffset&&0!==this.data.currentIndex?this.data.currentIndex-=1:n<=-this.data.swipeOffset&&this.data.currentIndex!==t.length-1&&(this.data.currentIndex+=1),this._slideList()),void("vertical"===this.moveDir&&(this.data.swipeBottomToClose&&i>=this.data.swipeOffset?this.hidePhoto("bottom"):this.data.swipeTopToClose&&i<=-this.data.swipeOffset?this.hidePhoto("top"):(this.data.translateY=0,this._slideList())))):void this.zoomPhoto()}},{key:"onDrag",value:function(){if(this.e.preventDefault(),this._isGestured(this.e)&&!1===this.onListMove)return void this.onGesture();if(!this.isBeingZoomed){if(this.data.scale)return void this.onPhotoDrag();if(this.isSwipable){var t=this._getTouchPos(),e=t.x-this.oldPos.x,a=t.y-this.firstPos.y;this.dragStart&&(this._fireEvent("swipestart"),this.dragStart=!1,Math.abs(e)>Math.abs(a)?this.moveDir="horizontal":this.moveDir="vertical"),"horizontal"===this.moveDir?(this.pos.x+=e,this.data.translateX=this.pos.x):this.data.translateY=a,this.onListMove=!0,this.oldPos=t,this._listUpdate()}}}},{key:"zoomPhoto",value:function(){var t=this;this.data.hideUi=!0,this.data.scaleSize=this._getScaleBoarder(),this.data.scaleSize<=1||(this.data.photoPosX=0,this.data.photoPosY=0,this._photoUpdate(),setTimeout(function(){t.data.scale=!0,t._photoUpdate(),t._fireEvent("zoomin")},300))}},{key:"zoomOutPhoto",value:function(){this.data.scaleSize=1,this.isBeingZoomed=!1,this.data.hideUi=!1,this.data.scale=!1,this.data.photoPosX=0,this.data.photoPosY=0,this._photoUpdate(),this._fireEvent("zoomout")}},{key:"beforePhotoDrag",value:function(){var t=this._getTouchPos();this.photoSwipable=!0,this.data.photoPosX||(this.data.photoPosX=0),this.data.photoPosY||(this.data.photoPosY=0),this.oldPhotoPos=t,this.firstPhotoPos=t}},{key:"onPhotoDrag",value:function(){if(this.photoSwipable){this.e.preventDefault();var t=this._getTouchPos(),e=t.x-this.oldPhotoPos.x,a=t.y-this.oldPhotoPos.y,o=this._round(this.data.scaleSize*e,6),n=this._round(this.data.scaleSize*a,6);"number"==typeof o&&(this.data.photoPosX+=o,this.photoVX=o),"number"==typeof n&&(this.data.photoPosY+=n,this.photoVY=n),this.oldPhotoPos=t,this._photoUpdate()}}},{key:"afterPhotoDrag",value:function(){if(this.oldPhotoPos.x===this.firstPhotoPos.x&&this.photoSwipable)this.photoSwipable=!1,this.zoomOutPhoto();else{this.photoSwipable=!1;var t=this._getSelectedItem(),e=this._makeBound(t),a=this.data.swipeOffset*this.data.scaleSize,o=0,n=0;if(this.data.photoPosX>e.maxX?o=-1:this.data.photoPosXe.maxY?n=-1:this.data.photoPosYa&&0!==this.data.currentIndex)return void this.gotoSlide(this.data.prev);if(e.minX-this.data.photoPosX>a&&this.data.currentIndex+1!==this.data.total)return void this.gotoSlide(this.data.next);0===o&&0===n?(this.vx=this.photoVX/5,this.vy=this.photoVY/5):this._registerElasticForce(o,n)}}},{key:"beforeGesture",value:function(){this._fireEvent("gesturestart");var t=this._getGesturePos(this.e),e=this._getDistance(t[0],t[1]);this.isBeingZoomed=!0,this.oldDistance=e,this.data.scale=!0,this.e.preventDefault()}},{key:"onGesture",value:function(){var t=this._getGesturePos(this.e),e=this._getDistance(t[0],t[1]),a=(e-this.oldDistance)/100,o=this.data.scaleSize,n=this.data.photoPosX,i=this.data.photoPosY;this.isBeingZoomed=!0,this.data.scaleSize+=this._round(a,6),this.data.scaleSize<.2&&(this.data.scaleSize=.2),this.data.scaleSizethis._getScaleBoarder()?this.data.hideUi=!0:this.data.hideUi=!1,this.oldDistance=e,this.e.preventDefault(),this._photoUpdate()}},{key:"afterGesture",value:function(){this.data.scaleSize>this._getScaleBoarder()||(this.data.photoPosX=0,this.data.photoPosY=0,this.data.scale=!1,this.data.scaleSize=1,this.data.hideUi=!1,this._fireEvent("gestureend"),this._photoUpdate())}},{key:"_getForceAndTheta",value:function(t,e){return{force:Math.sqrt(t*t+e*e),theta:Math.atan2(e,t)}}},{key:"_getScaleBoarder",value:function(){var t=this._getSelectedItem(),e=this._getWindowWidth(),a=this._getWindowHeight();return p.isSmartPhone()?t.width>t.height?a/(t.height*t.scale):e/(t.width*t.scale):1/t.scale}},{key:"_makeBound",value:function(t){var e,a,o,n,i=t.width*t.scale*this.data.scaleSize,r=t.height*t.scale*this.data.scaleSize,s=this._getWindowWidth(),c=this._getWindowHeight();return s>i?(o=(s-i)/2,e=-1*o):(o=(i-s)/2,e=-1*o),c>r?(n=(c-r)/2,a=-1*n):(n=(r-c)/2,a=-1*n),{minX:this._round(e,6)*this.data.scaleSize,minY:this._round(a,6)*this.data.scaleSize,maxX:this._round(o,6)*this.data.scaleSize,maxY:this._round(n,6)*this.data.scaleSize}}},{key:"_registerElasticForce",value:function(t,e){var a=this,o=this._getSelectedItem(),n=this._makeBound(o);this.data.elastic=!0,1===t?this.data.photoPosX=n.minX:-1===t&&(this.data.photoPosX=n.maxX),1===e?this.data.photoPosY=n.minY:-1===e&&(this.data.photoPosY=n.maxY),this._photoUpdate(),setTimeout(function(){a.data.elastic=!1,a._photoUpdate()},300)}},{key:"_getSelectedItem",value:function(){var t=this.data,e=t.currentIndex;return t.group[t.currentGroup][e]}},{key:"_getUniqId",value:function(){return(Date.now().toString(36)+Math.random().toString(36).substr(2,5)).toUpperCase()}},{key:"_getDistance",value:function(t,e){var a=t.x-e.x,o=t.y-e.y;return Math.sqrt(a*a+o*o)}},{key:"_round",value:function(t,e){var a=Math.pow(10,e);return t*=a,t=Math.round(t),t/=a}},{key:"_isTouched",value:function(t){return!(!t||!t.touches)}},{key:"_isGestured",value:function(t){return!!(t&&t.touches&&t.touches.length>1)}},{key:"_isSmartPhone",value:function(){var t=navigator.userAgent;return t.indexOf("iPhone")>0||t.indexOf("iPad")>0||t.indexOf("ipod")>0||t.indexOf("Android")>0}},{key:"_calcGravity",value:function(t,e){(t>5||t<-5)&&(this.vx+=.05*t),!1!==this.data.verticalGravity&&(e>5||e<-5)&&(this.vy+=.05*e)}},{key:"_photoUpdate",value:function(){var t=this.data.classNames,e=this._getElementByQuery(".current"),a=e.querySelector(".".concat(t.smartPhotoImg)),o=this._getElementByQuery(".".concat(t.smartPhotoNav)),n=this._getElementByQuery(".".concat(t.smartPhotoArrows)),i=this.virtualPos(this.data.photoPosX),r=this.virtualPos(this.data.photoPosY),s=this.data.scaleSize,c="translate(".concat(i,"px,").concat(r,"px) scale(").concat(s,")");a.style.transform=c,this.data.scale?p.addClass(a,t.smartPhotoImgOnMove):p.removeClass(a,t.smartPhotoImgOnMove),this.data.elastic?p.addClass(a,t.smartPhotoImgElasticMove):p.removeClass(a,t.smartPhotoImgElasticMove),this.data.hideUi?(o&&o.setAttribute("aria-hidden","true"),n&&n.setAttribute("aria-hidden","true")):(o&&o.setAttribute("aria-hidden","false"),n&&n.setAttribute("aria-hidden","false"))}},{key:"_getWindowWidth",value:function(){return document&&document.documentElement?document.documentElement.clientWidth:window&&window.innerWidth?window.innerWidth:0}},{key:"_getWindowHeight",value:function(){return document&&document.documentElement?document.documentElement.clientHeight:window&&window.innerHeight?window.innerHeight:0}},{key:"_listUpdate",value:function(){var t=this.data.classNames,e=this._getElementByQuery(".".concat(t.smartPhotoList)),a="translate(".concat(this.data.translateX,"px,").concat(this.data.translateY,"px)");e.style.transform=a,this.data.onMoveClass?p.addClass(e,t.smartPhotoListOnMove):p.removeClass(e,t.smartPhotoListOnMove)}},{key:"_fireEvent",value:function(t){var e=this._getElementByClass(this.data.classNames.smartPhoto);p.triggerEvent(e,t)}},{key:"_doAnim",value:function(){if(!(this.isBeingZoomed||this.isSwipable||this.photoSwipable||this.data.elastic)&&this.data.scale){this.data.photoPosX+=this.vx,this.data.photoPosY+=this.vy;var t=this._getSelectedItem(),e=this._makeBound(t);this.data.photoPosXe.maxX&&(this.data.photoPosX=e.maxX,this.vx*=-.2),this.data.photoPosYe.maxY&&(this.data.photoPosY=e.maxY,this.vy*=-.2);var a=this._getForceAndTheta(this.vx,this.vy),o=a.force,n=a.theta;o-=this.data.registance,Math.abs(o)<.5||(this.vx=Math.cos(n)*o,this.vy=Math.sin(n)*o,this._photoUpdate())}}}]),e}(h.default);a.default=y,e.exports=a.default},{"../lib/util":11,"a-template":1,"custom-event-polyfill":3,"es6-promise-polyfill":4}],10:[function(t,e,a){"use strict";e.exports=t("./core/")},{"./core/":9}],11:[function(t,e,a){"use strict";function o(t){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function n(t){t=t||{};for(var e=1;e0||t.indexOf("iPad")>0||t.indexOf("ipod")>0||t.indexOf("Android")>0};a.isSmartPhone=i;var r=n;a.extend=r;var s=function(t,e,a){var o;window.CustomEvent?o=new CustomEvent(e,{cancelable:!0}):(o=document.createEvent("CustomEvent"),o.initCustomEvent(e,!1,!1,a)),t.dispatchEvent(o)};a.triggerEvent=s;var c=function(t){for(var e,a,o,n=t.split("&"),i={},r=0,s=n.length;r0;)t.appendChild(a.children[0])};a.append=l;var h=function(t,e){t.classList?t.classList.add(e):t.className+=" ".concat(e)};a.addClass=h;var f=function(t,e){t.classList?t.classList.remove(e):t.className=t.className.replace(new RegExp("(^|\\b)"+e.split(" ").join("|")+"(\\b|$)","gi")," ")};a.removeClass=f;var p=function(){var t=window.navigator.userAgent.toLowerCase(),e=window.navigator.appVersion.toLowerCase(),a="unknown";return-1!=t.indexOf("msie")?a=-1!=e.indexOf("msie 6.")?"ie6":-1!=e.indexOf("msie 7.")?"ie7":-1!=e.indexOf("msie 8.")?"ie8":-1!=e.indexOf("msie 9.")?"ie9":-1!=e.indexOf("msie 10.")?"ie10":"ie":-1!=t.indexOf("trident/7")?a="ie11":-1!=t.indexOf("chrome")?a="chrome":-1!=t.indexOf("safari")?a="safari":-1!=t.indexOf("opera")?a="opera":-1!=t.indexOf("firefox")&&(a="firefox"),a};a.getBrowser=p;var m=function(){var t=p();return-1!==t.indexOf("ie")&&parseInt(t.replace(/[^0-9]/g,""))<=10};a.isOldIE=m},{}]},{},[10])(10)});
--------------------------------------------------------------------------------
/lib/adaptor/jquery.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var SmartPhoto = require('../index');
4 |
5 | var applyJQuery = function applyJQuery(jQuery) {
6 | jQuery.fn.SmartPhoto = function (settings) {
7 | if (typeof settings === 'strings') {} else {
8 | new SmartPhoto(this, settings);
9 | }
10 |
11 | return this;
12 | };
13 | };
14 |
15 | if (typeof define === 'function' && define.amd) {
16 | define(['jquery'], applyJQuery);
17 | } else {
18 | var jq = window.jQuery ? window.jQuery : window.$;
19 |
20 | if (typeof jq !== 'undefined') {
21 | applyJQuery(jq);
22 | }
23 | }
24 |
25 | module.exports = applyJQuery;
--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = require('./core/');
--------------------------------------------------------------------------------
/lib/lib/util.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.isOldIE = exports.getBrowser = exports.removeClass = exports.addClass = exports.append = exports.removeElement = exports.getViewPos = exports.parseQuery = exports.triggerEvent = exports.extend = exports.isSmartPhone = void 0;
7 |
8 | function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
9 |
10 | var isSmartPhone = function isSmartPhone() {
11 | var agent = navigator.userAgent;
12 |
13 | if (agent.indexOf('iPhone') > 0 || agent.indexOf('iPad') > 0 || agent.indexOf('ipod') > 0 || agent.indexOf('Android') > 0) {
14 | return true;
15 | } else {
16 | return false;
17 | }
18 | };
19 |
20 | exports.isSmartPhone = isSmartPhone;
21 |
22 | function deepExtend(out) {
23 | out = out || {};
24 |
25 | for (var i = 1; i < arguments.length; i++) {
26 | var obj = arguments[i];
27 |
28 | if (!obj) {
29 | continue;
30 | }
31 |
32 | for (var key in obj) {
33 | if (obj.hasOwnProperty(key)) {
34 | if (_typeof(obj[key]) === 'object') out[key] = deepExtend(out[key], obj[key]);else out[key] = obj[key];
35 | }
36 | }
37 | }
38 |
39 | return out;
40 | }
41 |
42 | ;
43 | var extend = deepExtend;
44 | exports.extend = extend;
45 |
46 | var triggerEvent = function triggerEvent(el, eventName, options) {
47 | var event;
48 |
49 | if (window.CustomEvent) {
50 | event = new CustomEvent(eventName, {
51 | cancelable: true
52 | });
53 | } else {
54 | event = document.createEvent('CustomEvent');
55 | event.initCustomEvent(eventName, false, false, options);
56 | }
57 |
58 | el.dispatchEvent(event);
59 | };
60 |
61 | exports.triggerEvent = triggerEvent;
62 |
63 | var parseQuery = function parseQuery(query) {
64 | var s = query.split('&'),
65 | data = {},
66 | i = 0,
67 | iz = s.length,
68 | param,
69 | key,
70 | value;
71 |
72 | for (; i < iz; i++) {
73 | param = s[i].split('=');
74 |
75 | if (param[0] !== void 0) {
76 | key = param[0];
77 | value = param[1] !== void 0 ? param.slice(1).join('=') : key;
78 | data[key] = decodeURIComponent(value);
79 | }
80 | }
81 |
82 | return data;
83 | };
84 |
85 | exports.parseQuery = parseQuery;
86 |
87 | var getViewPos = function getViewPos(element) {
88 | return {
89 | left: element.getBoundingClientRect().left,
90 | top: element.getBoundingClientRect().top
91 | };
92 | };
93 |
94 | exports.getViewPos = getViewPos;
95 |
96 | var removeElement = function removeElement(element) {
97 | if (element && element.parentNode) {
98 | element.parentNode.removeChild(element);
99 | }
100 | };
101 |
102 | exports.removeElement = removeElement;
103 |
104 | var append = function append(element, string) {
105 | var div = document.createElement('div');
106 | div.innerHTML = string;
107 |
108 | while (div.children.length > 0) {
109 | element.appendChild(div.children[0]);
110 | }
111 | };
112 |
113 | exports.append = append;
114 |
115 | var addClass = function addClass(element, className) {
116 | if (element.classList) {
117 | element.classList.add(className);
118 | } else {
119 | element.className += " ".concat(className);
120 | }
121 | };
122 |
123 | exports.addClass = addClass;
124 |
125 | var removeClass = function removeClass(element, className) {
126 | if (element.classList) {
127 | element.classList.remove(className);
128 | } else {
129 | element.className = element.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
130 | }
131 | };
132 |
133 | exports.removeClass = removeClass;
134 |
135 | var getBrowser = function getBrowser() {
136 | var ua = window.navigator.userAgent.toLowerCase();
137 | var ver = window.navigator.appVersion.toLowerCase();
138 | var name = 'unknown';
139 |
140 | if (ua.indexOf('msie') != -1) {
141 | if (ver.indexOf('msie 6.') != -1) {
142 | name = 'ie6';
143 | } else if (ver.indexOf('msie 7.') != -1) {
144 | name = 'ie7';
145 | } else if (ver.indexOf('msie 8.') != -1) {
146 | name = 'ie8';
147 | } else if (ver.indexOf('msie 9.') != -1) {
148 | name = 'ie9';
149 | } else if (ver.indexOf('msie 10.') != -1) {
150 | name = 'ie10';
151 | } else {
152 | name = 'ie';
153 | }
154 | } else if (ua.indexOf('trident/7') != -1) {
155 | name = 'ie11';
156 | } else if (ua.indexOf('chrome') != -1) {
157 | name = 'chrome';
158 | } else if (ua.indexOf('safari') != -1) {
159 | name = 'safari';
160 | } else if (ua.indexOf('opera') != -1) {
161 | name = 'opera';
162 | } else if (ua.indexOf('firefox') != -1) {
163 | name = 'firefox';
164 | }
165 |
166 | return name;
167 | };
168 |
169 | exports.getBrowser = getBrowser;
170 |
171 | var isOldIE = function isOldIE() {
172 | var browser = getBrowser();
173 |
174 | if (browser.indexOf('ie') !== -1) {
175 | if (parseInt(browser.replace(/[^0-9]/g, '')) <= 10) {
176 | return true;
177 | }
178 | }
179 |
180 | return false;
181 | };
182 |
183 | exports.isOldIE = isOldIE;
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "smartphoto",
3 | "version": "1.6.5",
4 | "description": "smartphoto",
5 | "homepage": "http://developer.a-blogcms.jp",
6 | "main": "lib/index.js",
7 | "scripts": {
8 | "test": "mocha ./test/test.js --timeout 1000000 --exit",
9 | "lint": "eslint ./src/core/index.js --fix",
10 | "build:js": "npm-run-all -p build:lib build:jquery build:global",
11 | "build:lib": "npm run babel",
12 | "build:jquery": "browserify ./src/adaptor/jquery.js -t babelify -p licensify -o ./js/jquery-smartphoto.js && npm run build:jquery:min",
13 | "build:global": "browserify ./src/index.js -t babelify -p licensify --standalone SmartPhoto -o ./js/smartphoto.js && npm run build:global:min",
14 | "build:jquery:min": "uglifyjs ./js/jquery-smartphoto.js -m -c --comments -o ./js/jquery-smartphoto.min.js",
15 | "build:global:min": "uglifyjs ./js/smartphoto.js -m -c --comments -o ./js/smartphoto.min.js",
16 | "build:sass": "npm-run-all -p sass sass:min",
17 | "babel": "babel src --out-dir lib",
18 | "sass": "node-sass ./scss/smartphoto.scss ./css/smartphoto.css --output-style expanded",
19 | "sass:min": "node-sass ./scss/smartphoto.scss ./css/smartphoto.min.css --output-style compressed",
20 | "watch:js": "onchange \"src/\" -- npm run build:js",
21 | "watch:sass": "onchange \"scss\" -- npm run build:sass",
22 | "sync": "browser-sync start --server './' --files './js/*.js' './css/*.css' --startPath '/examples/jquery.html'",
23 | "start": "npm-run-all -p watch:js watch:sass sync",
24 | "deploy": "np --no-cleanup"
25 | },
26 | "repository": {
27 | "type": "git",
28 | "url": "https://github.com/appleple/SmartPhoto/"
29 | },
30 | "author": "appleple",
31 | "license": "MIT",
32 | "devDependencies": {
33 | "@babel/cli": "^7.5.5",
34 | "@babel/core": "^7.5.5",
35 | "@babel/preset-env": "^7.5.5",
36 | "babel-plugin-add-module-exports": "^0.2.1",
37 | "babel-plugin-transform-html-import-to-string": "^0.0.1",
38 | "babelify": "^10.0.0",
39 | "browser-sync": "^2.26.7",
40 | "browserify": "^16.5.0",
41 | "chokidar": "^2.0.4",
42 | "co": "^4.6.0",
43 | "eslint": "^6.2.0",
44 | "eslint-config-airbnb": "^14.1.0",
45 | "eslint-plugin-import": "^2.2.0",
46 | "fs-extra": "^2.1.2",
47 | "http-server": "^0.11.1",
48 | "licensify": "^3.1.2",
49 | "mocha": "^6.2.0",
50 | "nightmare": "^2.8.1",
51 | "node-cmd": "^2.0.0",
52 | "node-sass": "^4.12.0",
53 | "nodemon": "^1.11.0",
54 | "np": "^2.16.0",
55 | "npm-run-all": "^4.0.2",
56 | "onchange": "^6.0.0",
57 | "power-assert": "^1.4.2",
58 | "uglify-js": "^2.8.22",
59 | "watchify": "^3.11.1"
60 | },
61 | "dependencies": {
62 | "a-template": "^0.6.1",
63 | "custom-event-polyfill": "^0.3.0",
64 | "es6-promise-polyfill": "^1.2.0"
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # SmartPhoto
2 | [](https://badge.fury.io/js/smartphoto)
3 | [](https://circleci.com/gh/appleple/SmartPhoto/tree/master)
4 | [](https://www.npmjs.com/package/smartphoto)
5 | [](https://raw.githubusercontent.com/appleple/SmartPhoto/master/LICENSE)
6 |
7 | The most easy to use responsive image viewer especially for mobile devices
8 |
9 | See [https://appleple.github.io/SmartPhoto/](https://appleple.github.io/SmartPhoto/) for complete docs and demos
10 | If you are Japasese, See here [https://www.appleple.com/blog/javascript/smartphoto-js.html](https://www.appleple.com/blog/javascript/smartphoto-js.html) instead.
11 |
12 | ## Feature
13 | - Intuitive gestures such as pinch-in/pinch-out/drag/swipe
14 | - Use Accelerometer to move images
15 | - Accessible from keyboards and screen-readers
16 | - Show pictures via URL hash
17 | - Can make photo groups
18 |
19 | ## Installation
20 | - [npm](https://www.npmjs.com/package/smartphoto)
21 | - [standalone](https://raw.githubusercontent.com/appleple/smart-photo/master/js/smartphoto.js)
22 |
23 | via npm
24 | ```shell
25 | npm install smartphoto --save
26 | ```
27 |
28 | or yarn
29 |
30 | ```shell
31 | yarn add smartphoto
32 | ```
33 |
34 | ## Usage
35 | require
36 | ```js
37 | const SmartPhoto = require('smartphoto');
38 | ```
39 |
40 | smartphoto.js
41 | ```js
42 | document.addEventListener('DOMContentLoaded',function(){
43 | new SmartPhoto(".js-smartphoto");
44 | });
45 | ```
46 |
47 | jquery-smartphoto.js
48 | ```js
49 | $(function(){
50 | $(".js-smartphoto").SmartPhoto();
51 | });
52 | ```
53 |
54 | ### Basic Standalone Usage
55 |
56 | ```html
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
73 | ```
74 |
75 | ### Option
76 |
77 |
78 |
79 | variable |
80 | description |
81 | default |
82 |
83 |
84 | arrows |
85 | prev/next arrows |
86 | true |
87 |
88 |
89 | nav |
90 | navigation images at the bottom |
91 | true |
92 |
93 |
94 | useOrientationApi |
95 | use accelerometer to move images |
96 | true |
97 |
98 |
99 | resizeStyle |
100 | resize images to fill/fit on the screen |
101 | 'fill' |
102 |
103 |
104 | animationSpeed |
105 | animation speed when switching images |
106 | 300 |
107 |
108 |
109 | forceInterval |
110 | frequency to apply force to images |
111 | 10 |
112 |
113 |
114 |
115 | #### Hide parts
116 | ```js
117 | document.addEventListener('DOMContentLoaded',function(){
118 | new SmartPhoto(".js-smartphoto",{
119 | arrows: false,
120 | nav: false
121 | });
122 | });
123 | ```
124 |
125 | #### Fit/Fill Option
126 |
127 | You can choose if you want to scale images to fit/fill
128 |
129 | ```js
130 | document.addEventListener('DOMContentLoaded',function(){
131 | new SmartPhoto(".js-smartphoto",{
132 | resizeStyle: 'fit'
133 | });
134 | });
135 | ```
136 |
137 | ### Event
138 |
139 | ```js
140 | // when the modal opened
141 | photo.on('open',function(){
142 | console.log('open');
143 | });
144 | // when the modal closed
145 | photo.on('close',function(){
146 | console.log('close');
147 | });
148 | // when all images are loaded
149 | photo.on('loadall',function(){
150 | console.log('loadall');
151 | });
152 | // when photo is changed
153 | photo.on('change',function(){
154 | console.log('change');
155 | });
156 | // when swipe started
157 | photo.on('swipestart',function(){
158 | console.log('swipestart');
159 | });
160 | // when swipe ended
161 | photo.on('swipeend',function(){
162 | console.log('swipeend');
163 | });
164 | // when zoomed in
165 | photo.on('zoomin',function(){
166 | console.log('zoomin');
167 | });
168 | // when zoomed out
169 | photo.on('zoomout',function(){
170 | console.log('zoomout');
171 | });
172 | ```
173 |
174 | ### SCSS
175 |
176 |
177 |
178 | variable |
179 | description |
180 | default |
181 |
182 |
183 | $animation-speed |
184 | animation speed when switching images |
185 | .3s |
186 |
187 |
188 | $backdrop-color |
189 | backdrop color when viewing images |
190 | rgba(0, 0, 0, 1) |
191 |
192 |
193 | $header-color |
194 | header color |
195 | rgba(0, 0, 0, .2) |
196 |
197 |
198 |
199 |
200 | ## Download
201 | [Download ZIP](https://github.com/appleple/SmartPhoto/archive/master.zip)
202 |
203 | ## Github
204 | [https://github.com/appleple/SmartPhoto](https://github.com/appleple/SmartPhoto)
205 |
206 | ## Contributor
207 | [@steelydylan](https://github.com/steelydylan)
208 |
209 | ## License
210 | Code and documentation copyright 2017 by appleple, Inc. Code released under the [MIT License](https://github.com/appleple/SmartPhoto/blob/master/LICENSE).
211 |
--------------------------------------------------------------------------------
/scss/smartphoto.scss:
--------------------------------------------------------------------------------
1 | $animation-speed: .3s !default;
2 | $animation-function: ease-out !default;
3 | $backdrop-color: rgba(0, 0, 0, 1) !default;
4 | $header-color: rgba(0, 0, 0, .2) !default;
5 |
6 | @keyframes smartphoto {
7 | from {
8 | opacity: 0;
9 | }
10 |
11 | to {
12 | opacity: 1;
13 | }
14 | }
15 |
16 | @keyframes smartphoto-img-wrap {
17 | from {
18 | opacity: 0;
19 | }
20 |
21 | to {
22 | opacity: 1;
23 | }
24 | }
25 |
26 | @keyframes smartphoto-inner {
27 | from {
28 | transform: translate(0, 100px);
29 | }
30 |
31 | to {
32 | transform: translate(0, 0);
33 | }
34 | }
35 |
36 | @keyframes smartphoto-loader {
37 | 0% {
38 | opacity: .4;
39 | transform: rotate(0deg);
40 | }
41 | 50% {
42 | opacity: 1;
43 | transform: rotate(180deg);
44 | }
45 | 100% {
46 | opacity: .4;
47 | transform: rotate(360deg);
48 | }
49 | }
50 |
51 | @keyframes smartphoto-appear {
52 | 0% {
53 | display: none;
54 | opacity: 0;
55 | }
56 |
57 | 1% {
58 | display: block;
59 | opacity: 0;
60 | }
61 |
62 | 100% {
63 | display: block;
64 | opacity: 1;
65 | }
66 | }
67 |
68 | @keyframes smartphoto-hide {
69 | 0% {
70 | display: block;
71 | opacity: 1;
72 | }
73 | 99% {
74 | display: block;
75 | opacity: 0;
76 | }
77 | 100% {
78 | display: none;
79 | opacity: 0;
80 | }
81 | }
82 |
83 | .smartphoto {
84 | position: fixed;
85 | z-index: 100;
86 | top: 0;
87 | left: 0;
88 | width: 100%;
89 | height: 100%;
90 | overflow: hidden;
91 | background-color: $backdrop-color;
92 | opacity: 1;
93 | font-family: sans-serif;
94 | cursor: pointer;
95 | -webkit-transition: opacity $animation-speed $animation-function;
96 | -moz-transition: opacity $animation-speed $animation-function;
97 | -ms-transition: opacity $animation-speed $animation-function;
98 | -o-transition: opacity $animation-speed $animation-function;
99 | transition: opacity $animation-speed $animation-function;
100 | transition: all .3s $animation-function;
101 | animation-name: smartphoto;
102 | animation-duration: $animation-speed;
103 | animation-timing-function: $animation-function;
104 | }
105 |
106 | .smartphoto[aria-hidden="true"] {
107 | display: none;
108 | }
109 |
110 | .smartphoto-close {
111 | opacity: 0;
112 | }
113 |
114 | .smartphoto-count {
115 | display: inline-block;
116 | color: #FFF;
117 | font-size: 16px;
118 | }
119 |
120 | .smartphoto-header {
121 | display: block;
122 | box-sizing: border-box;
123 | position: fixed;
124 | z-index: 102;
125 | top: 0;
126 | left: 0;
127 | width: 100%;
128 | height: 50px;
129 | padding: 15px;
130 | background-color: $header-color;
131 | }
132 |
133 | .smartphoto-content {
134 | display: block;
135 | position: absolute;
136 | top: 0;
137 | left: 0;
138 | width: 100%;
139 | height: 100%;
140 | }
141 |
142 | .smartphoto-dismiss {
143 | display: block;
144 | position: absolute;
145 | top: 15px;
146 | right: 10px;
147 | width: 20px;
148 | height: 20px;
149 | padding: 0;
150 | border: none;
151 | background-color: transparent;
152 | background-image: url(data:image/svg+xml;base64,PHN2ZyBpZD0i44Os44Kk44Ok44O8XzEiIGRhdGEtbmFtZT0i44Os44Kk44Ok44O8IDEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDI4MzQuNjUgMjgzNC42NSIgZmlsbD0iI0ZGRiI+PHRpdGxlPmljb248L3RpdGxlPjxwYXRoIGQ9Ik0xNTc2LjQyLDE0MDYuNzYsMjc4NCwxOTkuMTlhNTYuODYsNTYuODYsMCwwLDAsMC04MC4xOGwtNzguOTItNzguOTJhNTYuODYsNTYuODYsMCwwLDAtODAuMTgsMEwxNDE3LjMyLDEyNDcuNjYsMjA5Ljc1LDQwLjA5YTU2Ljg2LDU2Ljg2LDAsMCwwLTgwLjE4LDBMNTAuNjUsMTE5YTU2Ljg2LDU2Ljg2LDAsMCwwLDAsODAuMThMMTI1OC4yMywxNDA2Ljc2LDUwLjY1LDI2MTQuMzRhNTYuODYsNTYuODYsMCwwLDAsMCw4MC4xOGw3OC45Miw3OC45MmE1Ni44Niw1Ni44NiwwLDAsMCw4MC4xOCwwTDE0MTcuMzIsMTU2NS44NiwyNjI0LjksMjc3My40NGE1Ni44Niw1Ni44NiwwLDAsMCw4MC4xOCwwbDc4LjkyLTc4LjkyYTU2Ljg2LDU2Ljg2LDAsMCwwLDAtODAuMThaIi8+PC9zdmc+);
153 | text-shadow: 0 1px 0 #FFF;
154 | color: #FFF;
155 | font-size: 30px;
156 | text-decoration: none;
157 | cursor: pointer;
158 | line-height: 1;
159 | }
160 |
161 |
162 | .smartphoto-body {
163 | position: relative;
164 | z-index: 102;
165 | width: 100%;
166 | height: 100%;
167 | margin: 0 auto;
168 | }
169 |
170 | .smartphoto-inner {
171 | position: relative;
172 | width: 100%;
173 | height: 100%;
174 | // display: table-cell;
175 | vertical-align: top;
176 | }
177 |
178 | .smartphoto-img {
179 | display: none;
180 | max-width: none;
181 | width: auto;
182 | height: auto;
183 | cursor: zoom-in;
184 | -webkit-user-select: none;
185 | -moz-user-select: none;
186 | -ms-user-select: none;
187 | user-select: none;
188 | transition: transform .3s $animation-function;
189 |
190 | -webkit-user-drag: none;
191 | }
192 |
193 | .smartphoto-img.active {
194 | display: block;
195 | }
196 |
197 | .smartphoto-img-onmove {
198 | cursor: grab;
199 | cursor: -webkit-grab;
200 | transition: none;
201 | }
202 |
203 | .smartphoto-img-elasticmove {
204 | transition: transform .3s $animation-function;
205 | }
206 |
207 | .smartphoto-img-wrap {
208 | display: inline-block;
209 | opacity: 1;
210 | -webkit-transition: opacity $animation-speed $animation-function;
211 | -moz-transition: opacity $animation-speed $animation-function;
212 | -ms-transition: opacity $animation-speed $animation-function;
213 | -o-transition: opacity $animation-speed $animation-function;
214 | transition: opacity $animation-speed $animation-function;
215 | animation-name: smartphoto-img-wrap;
216 | animation-duration: $animation-speed;
217 | animation-timing-function: $animation-function;
218 | }
219 |
220 | .smartphoto-img-left {
221 | transform: translateX(150%) !important;
222 | }
223 |
224 | .smartphoto-img-right {
225 | transform: translateX(-150%) !important;
226 | }
227 |
228 | .smartphoto-arrows {
229 | list-style-type: none;
230 | margin: 0;
231 | padding: 0;
232 | position: relative;
233 | z-index: 1002;
234 | top: 50%;
235 | left: 0;
236 | opacity: 1;
237 | animation-name: smartphoto-appear;
238 | animation-duration: $animation-speed;
239 | animation-timing-function: $animation-function;
240 | }
241 |
242 | .smartphoto-arrows[aria-hidden="true"] {
243 | animation-name: smartphoto-hide;
244 | display: none;
245 | }
246 |
247 | .smartphoto-arrows li {
248 | display: block;
249 | position: absolute;
250 | top: 50%;
251 | width: 30px;
252 | height: 30px;
253 | margin-top: -20px;
254 | box-sizing: content-box;
255 | animation-duration: $animation-speed;
256 | animation-timing-function: $animation-function;
257 | animation-name: smartphoto-appear;
258 | &:focus {
259 | outline: none;
260 | }
261 | }
262 |
263 | .smartphoto-arrows [aria-hidden="true"] {
264 | animation-name: smartphoto-hide;
265 | display: none;
266 | }
267 |
268 | .smartphoto-arrows a {
269 | display: block;
270 | width: 100%;
271 | height: 100%;
272 | text-decoration: none;
273 | }
274 |
275 | .smartphoto-arrow-right {
276 | right: 0;
277 | padding: 5px 0;
278 | background-color: rgba(0, 0, 0, .5);
279 | a {
280 | background-image: url(data:image/svg+xml;base64,PHN2ZyBpZD0i44Os44Kk44Ok44O8XzEiIGRhdGEtbmFtZT0i44Os44Kk44Ok44O8IDEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDI4MzQuNjUgMjgzNC42NSIgZmlsbD0iI0ZGRiAiPjx0aXRsZT5pY29uPC90aXRsZT48cGF0aCBkPSJNMTgzNy44OCwxNDE3LjMyLDY0My41OSwyMjNhNzIuMjEsNzIuMjEsMCwwLDEsMC0xMDEuODJMNzQzLjgyLDIxYTcyLjIxLDcyLjIxLDAsMCwxLDEwMS44MiwwTDIwOTAuODMsMTI2Ni4xOWwxMDAuMjMsMTAwLjIzYTcyLjIxLDcyLjIxLDAsMCwxLDAsMTAxLjgyTDg0NS42NCwyODEzLjY1YTcyLjIxLDcyLjIxLDAsMCwxLTEwMS44MiwwTDY0My41OSwyNzEzLjQyYTcyLjIxLDcyLjIxLDAsMCwxLDAtMTAxLjgyWiIvPjwvc3ZnPg==);
281 | }
282 | }
283 |
284 | .smartphoto-arrow-left {
285 | left: 0;
286 | padding: 5px 0;
287 | background-color: rgba(0, 0, 0, .5);
288 | a {
289 | background-image: url(data:image/svg+xml;base64,PHN2ZyBpZD0i44Os44Kk44Ok44O8XzEiIGRhdGEtbmFtZT0i44Os44Kk44Ok44O8IDEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDI4MzQuNjUgMjgzNC42NSIgZmlsbD0iI0ZGRiI+PHRpdGxlPmljb248L3RpdGxlPjxwYXRoIGQ9Ik05OTYuNzcsMTQxNy4zMiwyMTkxLjA2LDIyM2E3Mi4yMSw3Mi4yMSwwLDAsMCwwLTEwMS44MkwyMDkwLjgzLDIxQTcyLjIxLDcyLjIxLDAsMCwwLDE5ODksMjFMNzQzLjgyLDEyNjYuMTksNjQzLjU5LDEzNjYuNDJhNzIuMjEsNzIuMjEsMCwwLDAsMCwxMDEuODJMMTk4OSwyODEzLjY1YTcyLjIxLDcyLjIxLDAsMCwwLDEwMS44MiwwbDEwMC4yMy0xMDAuMjNhNzIuMjEsNzIuMjEsMCwwLDAsMC0xMDEuODJaIi8+PC9zdmc+);
290 | }
291 | }
292 |
293 | .smartPhotoArrowHideIcon {
294 | display: none;
295 | }
296 |
297 | .smartphoto-nav {
298 | position: absolute;
299 | bottom: 0;
300 | left: 0;
301 | width: 100%;
302 | opacity: 1;
303 | animation-name: smartphoto-appear;
304 | animation-duration: $animation-speed;
305 | animation-timing-function: $animation-function;
306 | }
307 |
308 | .smartphoto-nav[aria-hidden="true"] {
309 | animation-name: smartphoto-hide;
310 | display: none;
311 | }
312 |
313 | .smartphoto-nav ul {
314 | display: block;
315 | overflow-x: auto;
316 | list-style: none;
317 | margin: 0;
318 | padding: 0;
319 | text-align: center;
320 | white-space: nowrap;
321 |
322 | -webkit-overflow-scrolling: touch;
323 | }
324 |
325 | .smartphoto-nav li {
326 | display: inline-block;
327 | overflow: hidden;
328 | width: 50px;
329 | height: 50px;
330 | }
331 |
332 | .smartphoto-nav a {
333 | display: block;
334 | width: 100%;
335 | height: 100%;
336 | background-color: #FFF;
337 | background-position: center center;
338 | background-size: cover;
339 | opacity: .5;
340 | &:focus {
341 | opacity: .8;
342 | }
343 | }
344 |
345 | .smartphoto-nav a.current {
346 | opacity: 1;
347 | }
348 |
349 | .smartphoto-nav img {
350 | width: auto;
351 | height: 100%;
352 | }
353 |
354 | .smartphoto-list {
355 | list-style-type: none;
356 | position: absolute;
357 | z-index: 101;
358 | top: 0;
359 | left: 0;
360 | margin: 0;
361 | padding: 0;
362 | white-space: nowrap;
363 | li {
364 | display: block;
365 | position: absolute;
366 | top: 0;
367 | left: 0;
368 | width: 100%;
369 | height: 100%;
370 | transition: all .3s $animation-function;
371 | &:focus {
372 | outline: none;
373 | }
374 | }
375 | }
376 |
377 | .smartphoto-list-onmove {
378 | transition: all .3s $animation-function;
379 | }
380 |
381 | .smartphoto-caption {
382 | overflow: hidden;
383 | box-sizing: border-box;
384 | position: absolute;
385 | top: 0;
386 | left: 0;
387 | width: 100%;
388 | height: 50px;
389 | padding: 0 50px;
390 | color: #FFF;
391 | font-size: 12px;
392 | text-align: center;
393 | line-height: 50px;
394 | white-space: nowrap;
395 | text-overflow: ellipsis;
396 | &:focus {
397 | outline: none;
398 | }
399 | }
400 |
401 | .smartphoto-loader-wrap {
402 | display: block;
403 | position: relative;
404 | z-index: 103;
405 | width: 0;
406 | height: 0;
407 | transform: translate(50vw,50vh);
408 | }
409 |
410 | .smartphoto-loader {
411 | position: absolute;
412 | z-index: 101;
413 | top: 0;
414 | left: 0;
415 | width: 30px;
416 | height: 30px;
417 | margin-top: -25px;
418 | margin-left: -25px;
419 | border: 8px solid #17CDDD;
420 | border-right-color: transparent;
421 | border-radius: 50%;
422 | animation: smartphoto-loader .5s infinite linear;
423 | }
424 |
425 | .smartphoto-img-clone {
426 | position: fixed;
427 | z-index: 100;
428 | top: 0;
429 | left: 0;
430 | transition: all $animation-speed $animation-function;
431 | }
432 |
433 | .smartphoto-sr-only {
434 | overflow: hidden;
435 | position: absolute;
436 | width: 1px;
437 | height: 1px;
438 | margin: -1px;
439 | padding: 0;
440 | border: 0;
441 | clip: rect(0,0,0,0);
442 | }
443 |
--------------------------------------------------------------------------------
/src/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appleple/SmartPhoto/abfd4f071f50b3c170c5ddcbed8c8e966c965eec/src/.DS_Store
--------------------------------------------------------------------------------
/src/adaptor/jquery.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const SmartPhoto = require('../index');
4 |
5 | const applyJQuery = (jQuery) => {
6 | jQuery.fn.SmartPhoto = function(settings) {
7 | if (typeof settings === 'strings'){
8 | } else {
9 | new SmartPhoto(this, settings);
10 | }
11 | return this;
12 | }
13 | }
14 |
15 | if (typeof define === 'function' && define.amd) {
16 | define(['jquery'], applyJQuery);
17 | } else {
18 | var jq = window.jQuery ? window.jQuery : window.$;
19 | if (typeof jq !== 'undefined') {
20 | applyJQuery(jq);
21 | }
22 | }
23 |
24 | module.exports = applyJQuery;
25 |
--------------------------------------------------------------------------------
/src/core/index.js:
--------------------------------------------------------------------------------
1 | import ATemplate from 'a-template';
2 | import 'custom-event-polyfill';
3 |
4 | import template from './viwer.html';
5 |
6 | const util = require('../lib/util');
7 | const { Promise } = require('es6-promise-polyfill');
8 |
9 | const defaults = {
10 | classNames: {
11 | smartPhoto: 'smartphoto',
12 | smartPhotoClose: 'smartphoto-close',
13 | smartPhotoBody: 'smartphoto-body',
14 | smartPhotoInner: 'smartphoto-inner',
15 | smartPhotoContent: 'smartphoto-content',
16 | smartPhotoImg: 'smartphoto-img',
17 | smartPhotoImgOnMove: 'smartphoto-img-onmove',
18 | smartPhotoImgElasticMove: 'smartphoto-img-elasticmove',
19 | smartPhotoImgWrap: 'smartphoto-img-wrap',
20 | smartPhotoArrows: 'smartphoto-arrows',
21 | smartPhotoNav: 'smartphoto-nav',
22 | smartPhotoArrowRight: 'smartphoto-arrow-right',
23 | smartPhotoArrowLeft: 'smartphoto-arrow-left',
24 | smartPhotoArrowHideIcon: 'smartphoto-arrow-hide',
25 | smartPhotoImgLeft: 'smartphoto-img-left',
26 | smartPhotoImgRight: 'smartphoto-img-right',
27 | smartPhotoList: 'smartphoto-list',
28 | smartPhotoListOnMove: 'smartphoto-list-onmove',
29 | smartPhotoHeader: 'smartphoto-header',
30 | smartPhotoCount: 'smartphoto-count',
31 | smartPhotoCaption: 'smartphoto-caption',
32 | smartPhotoDismiss: 'smartphoto-dismiss',
33 | smartPhotoLoader: 'smartphoto-loader',
34 | smartPhotoLoaderWrap: 'smartphoto-loader-wrap',
35 | smartPhotoImgClone: 'smartphoto-img-clone'
36 | },
37 | message: {
38 | gotoNextImage: 'go to the next image',
39 | gotoPrevImage: 'go to the previous image',
40 | closeDialog: 'close the image dialog'
41 | },
42 | arrows: true,
43 | nav: true,
44 | showAnimation: true,
45 | verticalGravity: false,
46 | useOrientationApi: false,
47 | useHistoryApi: true,
48 | swipeTopToClose: false,
49 | swipeBottomToClose: true,
50 | swipeOffset: 100,
51 | headerHeight: 60,
52 | footerHeight: 60,
53 | forceInterval: 10,
54 | registance: 0.5,
55 | loadOffset: 2,
56 | resizeStyle: 'fit',
57 | lazyAttribute: 'data-src'
58 | };
59 |
60 | export default class SmartPhoto extends ATemplate {
61 | constructor(selector, settings) {
62 | super();
63 | this.data = util.extend({}, defaults, settings);
64 | this.data.currentIndex = 0;
65 | this.data.oldIndex = 0;
66 | this.data.hide = true;
67 | this.data.group = {};
68 | this.data.scaleSize = 1;
69 | this.data.scale = false;
70 | this.pos = { x: 0, y: 0 };
71 | this.data.photoPosX = 0;
72 | this.data.photoPosY = 0;
73 | this.handlers = [];
74 | this.convert = {
75 | increment: this.increment,
76 | virtualPos: this.virtualPos,
77 | round: this.round
78 | };
79 | this.data.groupItems = this.groupItems;
80 | this.elements = typeof selector === 'string' ? document.querySelectorAll(selector) : selector;
81 | const date = new Date();
82 | this.tapSecond = date.getTime();
83 | this.onListMove = false;
84 | this.clicked = false;
85 | this.id = this._getUniqId();
86 | this.vx = 0;
87 | this.vy = 0;
88 | this.data.appearEffect = null;
89 | this.addTemplate(this.id, template);
90 | this.data.isSmartPhone = this._isSmartPhone();
91 | const body = document.querySelector('body');
92 | util.append(body, ``);
93 | [].forEach.call(this.elements, (element) => {
94 | this.addNewItem(element);
95 | });
96 |
97 | this.update();
98 | const currentItem = this._getCurrentItemByHash();
99 | if (currentItem) {
100 | util.triggerEvent(currentItem.element, 'click');
101 | }
102 |
103 | this.interval = setInterval(() => {
104 | this._doAnim();
105 | }, this.data.forceInterval);
106 |
107 | if (!this.data.isSmartPhone) {
108 | const resizeHandler = () => {
109 | if (!this.groupItems()) {
110 | return;
111 | }
112 | this._resetTranslate();
113 | this._setPosByCurrentIndex();
114 | this._setSizeByScreen();
115 | this.update();
116 | };
117 | const keydownHandler = (e) => {
118 | const code = e.keyCode || e.which;
119 | if (this.data.hide === true) {
120 | return;
121 | }
122 | if (code === 37) {
123 | this.gotoSlide(this.data.prev);
124 | } else if (code === 39) {
125 | this.gotoSlide(this.data.next);
126 | } else if (code === 27) {
127 | this.hidePhoto();
128 | }
129 | };
130 | window.addEventListener('resize', resizeHandler);
131 | window.addEventListener('keydown', keydownHandler);
132 | this._registerRemoveEvent(window, 'resize', resizeHandler);
133 | this._registerRemoveEvent(window, 'keydown', keydownHandler);
134 | return;
135 | }
136 |
137 | const orientationChangeHandler = () => {
138 | if (!this.groupItems()) {
139 | return;
140 | }
141 |
142 | // 画像の配置をリセット
143 | this._resetTranslate();
144 | this._setPosByCurrentIndex();
145 | this._setHashByCurrentIndex();
146 | this._setSizeByScreen();
147 | this.update();
148 |
149 | // orientationchangeが発火するタイミングとwindowのサイズが変化するタイミングが違うデバイスが存在する
150 | // その対策として、一定時間待機し、windowのサイズが変化しないかどうか確かめる
151 | // 変化した場合、もう一度画像の配置をリセットする
152 | const prevWidth = this._getWindowWidth(); // 現在の画面サイズ
153 | const timeout = 500; // 最大待機時間
154 | const photoResizeAfterWindowSizeChange = (time) => {
155 | new Promise((resolve) => {
156 | // 5ms秒待機
157 | setTimeout(() => {
158 | resolve();
159 | }, 25);
160 | }).then(() => {
161 | if (prevWidth !== this._getWindowWidth()) {
162 | // windowのサイズが変化したら、画像の配置をリセット
163 | this._resetTranslate();
164 | this._setPosByCurrentIndex();
165 | this._setHashByCurrentIndex();
166 | this._setSizeByScreen();
167 | this.update();
168 | } else if (time <= timeout) {
169 | // 待機時間内であれば再待機
170 | photoResizeAfterWindowSizeChange(time + 25);
171 | }
172 | });
173 | };
174 | photoResizeAfterWindowSizeChange(0); // 待機開始
175 | };
176 |
177 | window.addEventListener('orientationchange', orientationChangeHandler);
178 | this._registerRemoveEvent(window, 'orientationchange', orientationChangeHandler);
179 |
180 | if (!this.data.useOrientationApi) {
181 | return;
182 | }
183 |
184 | const deviceorientationHandler = (e) => {
185 | const { orientation } = window;
186 | if (!e || !e.gamma || this.data.appearEffect) {
187 | return;
188 | }
189 | if (!this.isBeingZoomed && !this.photoSwipable && !this.data.elastic && this.data.scale) {
190 | if (orientation === 0) {
191 | this._calcGravity(e.gamma, e.beta);
192 | } else if (orientation === 90) {
193 | this._calcGravity(e.beta, e.gamma);
194 | } else if (orientation === -90) {
195 | this._calcGravity(-e.beta, -e.gamma);
196 | } else if (orientation === 180) {
197 | this._calcGravity(-e.gamma, -e.beta);
198 | }
199 | }
200 | };
201 |
202 | window.addEventListener('deviceorientation', deviceorientationHandler);
203 | this._registerRemoveEvent(window, 'deviceorientation', deviceorientationHandler);
204 | }
205 |
206 | on(event, fn) {
207 | const photo = this._getElementByClass(this.data.classNames.smartPhoto);
208 | const handler = (e) => {
209 | fn.call(photo, e);
210 | };
211 | photo.addEventListener(event, handler);
212 | this._registerRemoveEvent(photo, event, handler);
213 | }
214 |
215 | _registerRemoveEvent(target, event, handler) {
216 | this.handlers.push({
217 | target,
218 | event,
219 | handler
220 | });
221 | }
222 |
223 | destroy() {
224 | this.handlers.forEach((handler) => {
225 | handler.target.removeEventListener(handler.event, handler.handler);
226 | });
227 | const wrapper = document.querySelector(`[data-id="${this.id}"]`);
228 | util.removeElement(wrapper);
229 | clearInterval(this.interval);
230 | this.removeTemplateEvents();
231 | }
232 |
233 | increment(item) {
234 | return item + 1;
235 | }
236 |
237 | round(number) {
238 | return Math.round(number);
239 | }
240 |
241 | virtualPos(pos) {
242 | pos = parseInt(pos, 10);
243 | const item = this._getSelectedItem();
244 | return pos / item.scale / this.data.scaleSize;
245 | }
246 |
247 | groupItems() {
248 | return this.data.group[this.data.currentGroup];
249 | }
250 |
251 | _resetTranslate() {
252 | const items = this.groupItems();
253 | items.forEach((item, index) => {
254 | item.translateX = this._getWindowWidth() * index;
255 | });
256 | }
257 |
258 | addNewItem(element) {
259 | const groupId = element.getAttribute('data-group') || 'nogroup';
260 | const { group } = this.data;
261 | if (groupId === 'nogroup') {
262 | element.setAttribute('data-group', 'nogroup');
263 | }
264 | if (!group[groupId]) {
265 | group[groupId] = [];
266 | }
267 | const index = group[groupId].length;
268 | const body = document.querySelector('body');
269 | const src = element.getAttribute('href');
270 | const img = element.querySelector('img');
271 | let thumb = src;
272 | if (img) {
273 | if (img.getAttribute(this.data.lazyAttribute)) {
274 | thumb = img.getAttribute(this.data.lazyAttribute);
275 | } else if (img.currentSrc) {
276 | thumb = img.currentSrc;
277 | } else {
278 | thumb = img.src;
279 | }
280 | }
281 | const item = {
282 | src,
283 | thumb,
284 | caption: element.getAttribute('data-caption'),
285 | groupId,
286 | translateX: this._getWindowWidth() * index,
287 | index,
288 | translateY: 0,
289 | width: 50,
290 | height: 50,
291 | id: element.getAttribute('data-id') || index,
292 | loaded: false,
293 | processed: false,
294 | element
295 | };
296 | group[groupId].push(item);
297 | this.data.currentGroup = groupId;
298 | const id = element.getAttribute('data-id');
299 | if (!id) {
300 | element.setAttribute('data-id', index);
301 | }
302 | element.setAttribute('data-index', index);
303 | const clickHandler = (event) => {
304 | event.preventDefault();
305 | this.data.currentGroup = element.getAttribute('data-group');
306 | this.data.currentIndex = parseInt(element.getAttribute('data-index'), 10);
307 | this._setHashByCurrentIndex();
308 | const currentItem = this._getSelectedItem();
309 | if (currentItem.loaded) {
310 | this._initPhoto();
311 | this.addAppearEffect(element, currentItem);
312 | this.clicked = true;
313 | this.update();
314 | body.style.overflow = 'hidden';
315 | this._fireEvent('open');
316 | } else {
317 | this._loadItem(currentItem).then(() => {
318 | this._initPhoto();
319 | this.addAppearEffect(element, currentItem);
320 | this.clicked = true;
321 | this.update();
322 | body.style.overflow = 'hidden';
323 | this._fireEvent('open');
324 | });
325 | }
326 | };
327 | element.addEventListener('click', clickHandler);
328 | this._registerRemoveEvent(element, 'click', clickHandler);
329 | }
330 |
331 | _initPhoto() {
332 | this.data.total = this.groupItems().length;
333 | this.data.hide = false;
334 | this.data.photoPosX = 0;
335 | this.data.photoPosY = 0;
336 | this._setPosByCurrentIndex();
337 | this._setSizeByScreen();
338 | this.setArrow();
339 | if (this.data.resizeStyle === 'fill' && this.data.isSmartPhone) {
340 | this.data.scale = true;
341 | this.data.hideUi = true;
342 | this.data.scaleSize = this._getScaleBoarder();
343 | }
344 | }
345 |
346 | onUpdated() {
347 | if (this.data.appearEffect && this.data.appearEffect.once) {
348 | this.data.appearEffect.once = false;
349 | this.execEffect().then(() => {
350 | this.data.appearEffect = null;
351 | this.data.appear = true;
352 | this.update();
353 | });
354 | }
355 | if (this.clicked) {
356 | this.clicked = false;
357 | const { classNames } = this.data;
358 | const caption = this._getElementByClass(classNames.smartPhotoCaption);
359 | caption.focus();
360 | }
361 | }
362 |
363 | execEffect() {
364 | return new Promise((resolve) => {
365 | if (util.isOldIE()) {
366 | resolve();
367 | }
368 | const { appearEffect, classNames } = this.data;
369 | const effect = this._getElementByClass(classNames.smartPhotoImgClone);
370 | const handler = () => {
371 | effect.removeEventListener('transitionend', handler, true);
372 | resolve();
373 | };
374 | effect.addEventListener('transitionend', handler, true);
375 | setTimeout(() => {
376 | effect.style.transform = `translate(${appearEffect.afterX}px, ${appearEffect.afterY}px) scale(${appearEffect.scale})`;
377 | }, 10);
378 | });
379 | }
380 |
381 | addAppearEffect(element, item) {
382 | if (this.data.showAnimation === false) {
383 | this.data.appear = true;
384 | return;
385 | }
386 | const img = element.querySelector('img');
387 | const pos = util.getViewPos(img);
388 | const appear = {};
389 | let scale = 1;
390 | appear.width = img.offsetWidth;
391 | appear.height = img.offsetHeight;
392 | appear.top = pos.top;
393 | appear.left = pos.left;
394 | appear.once = true;
395 | if (img.getAttribute(this.data.lazyAttribute)) {
396 | appear.img = img.getAttribute(this.data.lazyAttribute);
397 | } else {
398 | appear.img = item.src;
399 | }
400 | const toX = this._getWindowWidth();
401 | const toY = this._getWindowHeight();
402 | const screenY = toY - this.data.headerHeight - this.data.footerHeight;
403 |
404 | if (this.data.resizeStyle === 'fill' && this.data.isSmartPhone) {
405 | if (img.offsetWidth > img.offsetHeight) {
406 | scale = toY / img.offsetHeight;
407 | } else {
408 | scale = toX / img.offsetWidth;
409 | }
410 | } else {
411 | if (appear.width >= appear.height) {
412 | if (item.height < screenY) {
413 | scale = item.width / appear.width;
414 | } else {
415 | scale = screenY / appear.height;
416 | }
417 | } else if (appear.height > appear.width) {
418 | if (item.height < screenY) {
419 | scale = item.height / appear.height;
420 | } else {
421 | scale = screenY / appear.height;
422 | }
423 | }
424 | if (appear.width * scale > toX) {
425 | scale = toX / appear.width;
426 | }
427 | }
428 |
429 | const x = (scale - 1) / 2 * img.offsetWidth + (toX - (img.offsetWidth * scale)) / 2;
430 | const y = (scale - 1) / 2 * img.offsetHeight + (toY - (img.offsetHeight * scale)) / 2;
431 | appear.afterX = x;
432 | appear.afterY = y;
433 | appear.scale = scale;
434 | this.data.appearEffect = appear;
435 | }
436 |
437 | hidePhoto(dir = 'bottom') {
438 | this.data.hide = true;
439 | this.data.appear = false;
440 | this.data.appearEffect = null;
441 | this.data.hideUi = false;
442 | this.data.scale = false;
443 | this.data.scaleSize = 1;
444 | const scrollX = (window.pageXOffset !== undefined) ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft;
445 | const scrollY = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
446 | const body = document.querySelector('body');
447 | if (window.location.hash) {
448 | this._setHash('');
449 | }
450 | window.scroll(scrollX, scrollY);
451 | this._doHideEffect(dir).then(() => {
452 | this.update();
453 | body.style.overflow = '';
454 | this._fireEvent('close');
455 | });
456 | }
457 |
458 | _doHideEffect(dir) {
459 | return new Promise((resolve) => {
460 | if (util.isOldIE()) {
461 | resolve();
462 | }
463 | const { classNames } = this.data;
464 | const photo = this._getElementByClass(classNames.smartPhoto);
465 | const img = this._getElementByQuery(`.current .${classNames.smartPhotoImg}`);
466 | const height = this._getWindowHeight();
467 | const handler = () => {
468 | photo.removeEventListener('transitionend', handler, true);
469 | resolve();
470 | };
471 | photo.style.opacity = 0;
472 | if (dir === 'bottom') {
473 | img.style.transform = `translateY(${height}px)`;
474 | } else if (dir === 'top') {
475 | img.style.transform = `translateY(-${height}px)`;
476 | }
477 | photo.addEventListener('transitionend', handler, true);
478 | });
479 | }
480 |
481 | _getElementByClass(className) {
482 | return document.querySelector(`[data-id="${this.id}"] .${className}`);
483 | }
484 |
485 | _getElementByQuery(query) {
486 | return document.querySelector(`[data-id="${this.id}"] ${query}`);
487 | }
488 |
489 | _getTouchPos() {
490 | let x = 0;
491 | let y = 0;
492 | const e = typeof event === 'undefined' ? this.e : event;
493 | if (this._isTouched(e)) {
494 | x = e.touches[0].pageX;
495 | y = e.touches[0].pageY;
496 | } else if (e.pageX) {
497 | x = e.pageX;
498 | y = e.pageY;
499 | }
500 | return { x, y };
501 | }
502 |
503 | _getGesturePos(e) {
504 | const touches = e.touches;
505 | return [
506 | { x: touches[0].pageX, y: touches[0].pageY },
507 | { x: touches[1].pageX, y: touches[1].pageY }
508 | ];
509 | }
510 |
511 | _setPosByCurrentIndex() {
512 | const items = this.groupItems();
513 | const moveX = -1 * items[this.data.currentIndex].translateX;
514 | this.pos.x = moveX;
515 | setTimeout(() => {
516 | this.data.translateX = moveX;
517 | this.data.translateY = 0;
518 | this._listUpdate();
519 | }, 1);
520 | }
521 |
522 | _setHashByCurrentIndex() {
523 | const scrollX = (window.pageXOffset !== undefined) ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft;
524 | const scrollY = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
525 | const items = this.groupItems();
526 | const id = items[this.data.currentIndex].id;
527 | const group = this.data.currentGroup;
528 | const hash = `group=${group}&photo=${id}`;
529 | this._setHash(hash);
530 | window.scroll(scrollX, scrollY);
531 | }
532 |
533 | _setHash(hash) {
534 | if (!(window.history && window.history.pushState) || !this.data.useHistoryApi) {
535 | return;
536 | }
537 | if (hash) {
538 | window.history.replaceState(null, null, `${location.pathname}${location.search}#${hash}`);
539 | } else {
540 | window.history.replaceState(null, null, `${location.pathname}${location.search}`);
541 | }
542 | }
543 |
544 | _getCurrentItemByHash() {
545 | const group = this.data.group;
546 | const hash = location.hash.substr(1);
547 | const hashObj = util.parseQuery(hash);
548 | let currentItem = null;
549 | const getCurrentItem = (item) => {
550 | if (hashObj.group === item.groupId && hashObj.photo === item.id) {
551 | currentItem = item;
552 | }
553 | };
554 | Object.keys(group).forEach((key) => {
555 | group[key].forEach(getCurrentItem);
556 | });
557 | return currentItem;
558 | }
559 |
560 | _loadItem(item) {
561 | return new Promise((resolve) => {
562 | const img = new Image();
563 | img.onload = () => {
564 | item.width = img.width;
565 | item.height = img.height;
566 | item.loaded = true;
567 | resolve();
568 | };
569 | img.onerror = () => {
570 | resolve();
571 | };
572 | img.src = item.src;
573 | });
574 | }
575 |
576 | _getItemByIndex(index) {
577 | const { data } = this;
578 | if (data.group[data.currentGroup][index]) {
579 | return data.group[data.currentGroup][index];
580 | }
581 | return null;
582 | }
583 |
584 | _loadNeighborItems() {
585 | const index = this.data.currentIndex;
586 | const { loadOffset } = this.data;
587 | const from = index - loadOffset;
588 | const to = index + loadOffset;
589 | const promises = [];
590 | for (let i = from; i < to; i++) {
591 | const item = this._getItemByIndex(i);
592 | if (item && !item.loaded) {
593 | promises.push(this._loadItem(item));
594 | }
595 | }
596 | if (promises.length) {
597 | Promise.all(promises).then(() => {
598 | this._initPhoto();
599 | this.update();
600 | });
601 | }
602 | }
603 |
604 | _setSizeByScreen() {
605 | const windowX = this._getWindowWidth();
606 | const windowY = this._getWindowHeight();
607 | const headerHeight = this.data.headerHeight;
608 | const footerHeight = this.data.footerHeight;
609 | const screenY = windowY - (headerHeight + footerHeight);
610 | const items = this.groupItems();
611 | items.forEach((item) => {
612 | if (!item.loaded) {
613 | return;
614 | }
615 | item.processed = true;
616 | item.scale = screenY / item.height;
617 | if (item.height < screenY) {
618 | item.scale = 1;
619 | }
620 | item.x = (item.scale - 1) / 2 * item.width + (windowX - (item.width * item.scale)) / 2;
621 | item.y = (item.scale - 1) / 2 * item.height + (windowY - (item.height * item.scale)) / 2;
622 | if (item.width * item.scale > windowX) {
623 | item.scale = windowX / item.width;
624 | item.x = (item.scale - 1) / 2 * item.width;
625 | }
626 | });
627 | }
628 |
629 | _slideList() {
630 | this.data.scaleSize = 1;
631 | this.isBeingZoomed = false;
632 | this.data.hideUi = false;
633 | this.data.scale = false;
634 | this.data.photoPosX = 0;
635 | this.data.photoPosY = 0;
636 | this.data.onMoveClass = true;
637 | this._setPosByCurrentIndex();
638 | this._setHashByCurrentIndex();
639 | this._setSizeByScreen();
640 | setTimeout(() => {
641 | const item = this._getSelectedItem();
642 | this.data.onMoveClass = false;
643 | this.setArrow();
644 | this.update();
645 | if (this.data.oldIndex !== this.data.currentIndex) {
646 | this._fireEvent('change');
647 | }
648 | this.data.oldIndex = this.data.currentIndex;
649 | this._loadNeighborItems();
650 | if (!item.loaded) {
651 | this._loadItem(item).then(() => {
652 | this._initPhoto();
653 | this.update();
654 | });
655 | }
656 | }, 200);
657 | }
658 |
659 | gotoSlide(index) {
660 | if (this.e && this.e.preventDefault) {
661 | this.e.preventDefault();
662 | }
663 | this.data.currentIndex = parseInt(index, 10);
664 | if (!this.data.currentIndex) {
665 | this.data.currentIndex = 0;
666 | }
667 | this._slideList();
668 | }
669 |
670 | setArrow() {
671 | const items = this.groupItems();
672 | const length = items.length;
673 | const next = this.data.currentIndex + 1;
674 | const prev = this.data.currentIndex - 1;
675 | this.data.showNextArrow = false;
676 | this.data.showPrevArrow = false;
677 | if (next !== length) {
678 | this.data.next = next;
679 | this.data.showNextArrow = true;
680 | }
681 | if (prev !== -1) {
682 | this.data.prev = prev;
683 | this.data.showPrevArrow = true;
684 | }
685 | }
686 |
687 | beforeDrag() {
688 | if (this._isGestured(this.e)) {
689 | this.beforeGesture();
690 | return;
691 | }
692 | this.isBeingZoomed = false;
693 | if (this.data.scale) {
694 | this.beforePhotoDrag();
695 | return;
696 | }
697 | const pos = this._getTouchPos();
698 | this.isSwipable = true;
699 | this.dragStart = true;
700 | this.firstPos = pos;
701 | this.oldPos = pos;
702 | }
703 |
704 | afterDrag() {
705 | const items = this.groupItems();
706 | const date = new Date();
707 | const tapSecond = date.getTime();
708 | const offset = this.tapSecond - tapSecond;
709 | let swipeWidth = 0;
710 | let swipeHeight = 0;
711 | this.isSwipable = false;
712 | this.onListMove = false;
713 |
714 | if (this.oldPos) {
715 | swipeWidth = this.oldPos.x - this.firstPos.x;
716 | swipeHeight = this.oldPos.y - this.firstPos.y;
717 | }
718 | if (this.isBeingZoomed) {
719 | this.afterGesture();
720 | return;
721 | }
722 | if (this.data.scale) {
723 | this.afterPhotoDrag();
724 | return;
725 | } else if (!util.isSmartPhone() && swipeWidth === 0 && swipeHeight === 0) {
726 | this.zoomPhoto();
727 | return;
728 | }
729 | if (Math.abs(offset) <= 500 && swipeWidth === 0 && swipeHeight === 0) {
730 | this.e.preventDefault();
731 | this.zoomPhoto();
732 | return;
733 | }
734 | this.tapSecond = tapSecond;
735 | this._fireEvent('swipeend');
736 | if (this.moveDir === 'horizontal') {
737 | if (swipeWidth >= this.data.swipeOffset && this.data.currentIndex !== 0) {
738 | this.data.currentIndex -= 1;
739 | } else if (swipeWidth <= -this.data.swipeOffset && this.data.currentIndex !== items.length - 1) {
740 | this.data.currentIndex += 1;
741 | }
742 | this._slideList();
743 | }
744 | if (this.moveDir === 'vertical') {
745 | if (this.data.swipeBottomToClose && swipeHeight >= this.data.swipeOffset) {
746 | this.hidePhoto('bottom');
747 | } else if (this.data.swipeTopToClose && swipeHeight <= -this.data.swipeOffset) {
748 | this.hidePhoto('top');
749 | } else {
750 | this.data.translateY = 0;
751 | this._slideList();
752 | }
753 | }
754 | }
755 |
756 | onDrag() {
757 | this.e.preventDefault();
758 | if (this._isGestured(this.e) && this.onListMove === false) {
759 | this.onGesture();
760 | return;
761 | }
762 | if (this.isBeingZoomed) {
763 | return;
764 | }
765 | if (this.data.scale) {
766 | this.onPhotoDrag();
767 | return;
768 | }
769 | if (!this.isSwipable) {
770 | return;
771 | }
772 |
773 | const pos = this._getTouchPos();
774 | const x = pos.x - this.oldPos.x;
775 | const y = pos.y - this.firstPos.y;
776 |
777 | if (this.dragStart) {
778 | this._fireEvent('swipestart');
779 | this.dragStart = false;
780 | if (Math.abs(x) > Math.abs(y)) {
781 | this.moveDir = 'horizontal';
782 | } else {
783 | this.moveDir = 'vertical';
784 | }
785 | }
786 |
787 | if (this.moveDir === 'horizontal') {
788 | this.pos.x += x;
789 | this.data.translateX = this.pos.x;
790 | } else {
791 | this.data.translateY = y;
792 | }
793 | this.onListMove = true;
794 | this.oldPos = pos;
795 | this._listUpdate();
796 | }
797 |
798 | zoomPhoto() {
799 | this.data.hideUi = true;
800 | this.data.scaleSize = this._getScaleBoarder();
801 | if (this.data.scaleSize <= 1) {
802 | return;
803 | }
804 | this.data.photoPosX = 0;
805 | this.data.photoPosY = 0;
806 | this._photoUpdate();
807 | setTimeout(() => {
808 | this.data.scale = true;
809 | this._photoUpdate();
810 | this._fireEvent('zoomin');
811 | }, 300);
812 | }
813 |
814 | zoomOutPhoto() {
815 | this.data.scaleSize = 1;
816 | this.isBeingZoomed = false;
817 | this.data.hideUi = false;
818 | this.data.scale = false;
819 | this.data.photoPosX = 0;
820 | this.data.photoPosY = 0;
821 | this._photoUpdate();
822 | this._fireEvent('zoomout');
823 | }
824 |
825 | beforePhotoDrag() {
826 | const pos = this._getTouchPos();
827 | this.photoSwipable = true;
828 | if (!this.data.photoPosX) {
829 | this.data.photoPosX = 0;
830 | }
831 | if (!this.data.photoPosY) {
832 | this.data.photoPosY = 0;
833 | }
834 | this.oldPhotoPos = pos;
835 | this.firstPhotoPos = pos;
836 | }
837 |
838 | onPhotoDrag() {
839 | if (!this.photoSwipable) {
840 | return;
841 | }
842 | this.e.preventDefault();
843 | const pos = this._getTouchPos();
844 | const x = pos.x - this.oldPhotoPos.x;
845 | const y = pos.y - this.oldPhotoPos.y;
846 | const moveX = this._round(this.data.scaleSize * x, 6);
847 | const moveY = this._round(this.data.scaleSize * y, 6);
848 | if (typeof moveX === 'number') {
849 | this.data.photoPosX += moveX;
850 | this.photoVX = moveX;
851 | }
852 | if (typeof moveY === 'number') {
853 | this.data.photoPosY += moveY;
854 | this.photoVY = moveY;
855 | }
856 | this.oldPhotoPos = pos;
857 | this._photoUpdate();
858 | }
859 |
860 | afterPhotoDrag() {
861 | if (this.oldPhotoPos.x === this.firstPhotoPos.x && this.photoSwipable) {
862 | this.photoSwipable = false;
863 | this.zoomOutPhoto();
864 | } else {
865 | this.photoSwipable = false;
866 | const item = this._getSelectedItem();
867 | const bound = this._makeBound(item);
868 | const offset = this.data.swipeOffset * this.data.scaleSize;
869 | let flagX = 0;
870 | let flagY = 0;
871 | if (this.data.photoPosX > bound.maxX) {
872 | flagX = -1;
873 | } else if (this.data.photoPosX < bound.minX) {
874 | flagX = 1;
875 | }
876 | if (this.data.photoPosY > bound.maxY) {
877 | flagY = -1;
878 | } else if (this.data.photoPosY < bound.minY) {
879 | flagY = 1;
880 | }
881 |
882 | if (this.data.photoPosX - bound.maxX > offset && this.data.currentIndex !== 0) {
883 | this.gotoSlide(this.data.prev);
884 | return;
885 | }
886 |
887 | if (bound.minX - this.data.photoPosX > offset && this.data.currentIndex + 1 !== this.data.total) {
888 | this.gotoSlide(this.data.next);
889 | return;
890 | }
891 |
892 | // todo
893 | // if(this.data.photoPosY - bound.maxY > offset) {
894 | // this.hidePhoto();
895 | // return;
896 | // }
897 |
898 | if (flagX === 0 && flagY === 0) {
899 | this.vx = this.photoVX / 5;
900 | this.vy = this.photoVY / 5;
901 | } else {
902 | this._registerElasticForce(flagX, flagY);
903 | }
904 | }
905 | }
906 |
907 | beforeGesture() {
908 | this._fireEvent('gesturestart');
909 | const pos = this._getGesturePos(this.e);
910 | const distance = this._getDistance(pos[0], pos[1]);
911 | this.isBeingZoomed = true;
912 | this.oldDistance = distance;
913 | this.data.scale = true;
914 | this.e.preventDefault();
915 | }
916 |
917 | onGesture() {
918 | const pos = this._getGesturePos(this.e);
919 | const distance = this._getDistance(pos[0], pos[1]);
920 | const size = (distance - this.oldDistance) / 100;
921 | const oldScaleSize = this.data.scaleSize;
922 | const posX = this.data.photoPosX;
923 | const posY = this.data.photoPosY;
924 | this.isBeingZoomed = true;
925 | this.data.scaleSize += this._round(size, 6);
926 | if (this.data.scaleSize < 0.2) {
927 | this.data.scaleSize = 0.2;
928 | }
929 | // todo
930 | if (this.data.scaleSize < oldScaleSize) {
931 | this.data.photoPosX = (1 + this.data.scaleSize - oldScaleSize) * posX;
932 | this.data.photoPosY = (1 + this.data.scaleSize - oldScaleSize) * posY;
933 | }
934 |
935 | if (this.data.scaleSize < 1 || this.data.scaleSize > this._getScaleBoarder()) {
936 | this.data.hideUi = true;
937 | } else {
938 | this.data.hideUi = false;
939 | }
940 | this.oldDistance = distance;
941 | this.e.preventDefault();
942 | this._photoUpdate();
943 | }
944 |
945 | afterGesture() {
946 | if (this.data.scaleSize > this._getScaleBoarder()) {
947 | return;
948 | }
949 | this.data.photoPosX = 0;
950 | this.data.photoPosY = 0;
951 | this.data.scale = false;
952 | this.data.scaleSize = 1;
953 | this.data.hideUi = false;
954 | this._fireEvent('gestureend');
955 | this._photoUpdate();
956 | }
957 |
958 | _getForceAndTheta(vx, vy) {
959 | return {
960 | force: Math.sqrt((vx * vx) + (vy * vy)),
961 | theta: Math.atan2(vy, vx)
962 | };
963 | }
964 |
965 | _getScaleBoarder() {
966 | const item = this._getSelectedItem();
967 | const windowWidth = this._getWindowWidth();
968 | const windowHeight = this._getWindowHeight();
969 | if (!util.isSmartPhone()) {
970 | return 1 / item.scale;
971 | }
972 | if (item.width > item.height) {
973 | return windowHeight / (item.height * item.scale);
974 | }
975 | return windowWidth / (item.width * item.scale);
976 | }
977 |
978 | _makeBound(item) {
979 | const width = item.width * item.scale * this.data.scaleSize;
980 | const height = item.height * item.scale * this.data.scaleSize;
981 | let minX;
982 | let minY;
983 | let maxX;
984 | let maxY;
985 | const windowWidth = this._getWindowWidth();
986 | const windowHeight = this._getWindowHeight();
987 | if (windowWidth > width) {
988 | maxX = (windowWidth - width) / 2;
989 | minX = -1 * maxX;
990 | } else {
991 | maxX = (width - windowWidth) / 2;
992 | minX = -1 * maxX;
993 | }
994 | if (windowHeight > height) {
995 | maxY = (windowHeight - height) / 2;
996 | minY = -1 * maxY;
997 | } else {
998 | maxY = (height - windowHeight) / 2;
999 | minY = -1 * maxY;
1000 | }
1001 | return {
1002 | minX: this._round(minX, 6) * this.data.scaleSize,
1003 | minY: this._round(minY, 6) * this.data.scaleSize,
1004 | maxX: this._round(maxX, 6) * this.data.scaleSize,
1005 | maxY: this._round(maxY, 6) * this.data.scaleSize
1006 | };
1007 | }
1008 |
1009 | _registerElasticForce(x, y) {
1010 | const item = this._getSelectedItem();
1011 | const bound = this._makeBound(item);
1012 | this.data.elastic = true;
1013 | if (x === 1) {
1014 | this.data.photoPosX = bound.minX;
1015 | } else if (x === -1) {
1016 | this.data.photoPosX = bound.maxX;
1017 | }
1018 | if (y === 1) {
1019 | this.data.photoPosY = bound.minY;
1020 | } else if (y === -1) {
1021 | this.data.photoPosY = bound.maxY;
1022 | }
1023 | this._photoUpdate();
1024 | setTimeout(() => {
1025 | this.data.elastic = false;
1026 | this._photoUpdate();
1027 | }, 300);
1028 | }
1029 |
1030 | _getSelectedItem() {
1031 | const data = this.data;
1032 | const index = data.currentIndex;
1033 | return data.group[data.currentGroup][index];
1034 | }
1035 |
1036 | _getUniqId() {
1037 | return (Date.now().toString(36) + Math.random().toString(36).substr(2, 5)).toUpperCase();
1038 | }
1039 |
1040 | _getDistance(point1, point2) {
1041 | const x = point1.x - point2.x;
1042 | const y = point1.y - point2.y;
1043 | return Math.sqrt((x * x) + (y * y));
1044 | }
1045 |
1046 | _round(val, precision) {
1047 | const digit = Math.pow(10, precision);
1048 | val *= digit;
1049 | val = Math.round(val);
1050 | val /= digit;
1051 | return val;
1052 | }
1053 |
1054 | _isTouched(e) {
1055 | if (e && e.touches) {
1056 | return true;
1057 | }
1058 | return false;
1059 | }
1060 |
1061 | _isGestured(e) {
1062 | if (e && e.touches && e.touches.length > 1) {
1063 | return true;
1064 | }
1065 | return false;
1066 | }
1067 |
1068 | _isSmartPhone() {
1069 | const agent = navigator.userAgent;
1070 | if (agent.indexOf('iPhone') > 0 || agent.indexOf('iPad') > 0
1071 | || agent.indexOf('ipod') > 0 || agent.indexOf('Android') > 0) {
1072 | return true;
1073 | }
1074 | return false;
1075 | }
1076 |
1077 | _calcGravity(gamma, beta) {
1078 | if (gamma > 5 || gamma < -5) {
1079 | this.vx += gamma * 0.05;
1080 | }
1081 | if (this.data.verticalGravity === false) {
1082 | return;
1083 | }
1084 | if (beta > 5 || beta < -5) {
1085 | this.vy += beta * 0.05;
1086 | }
1087 | }
1088 |
1089 | _photoUpdate() {
1090 | const classNames = this.data.classNames;
1091 | const current = this._getElementByQuery('.current');
1092 | const img = current.querySelector(`.${classNames.smartPhotoImg}`);
1093 | const nav = this._getElementByQuery(`.${classNames.smartPhotoNav}`);
1094 | const arrows = this._getElementByQuery(`.${classNames.smartPhotoArrows}`);
1095 | const photoPosX = this.virtualPos(this.data.photoPosX);
1096 | const photoPosY = this.virtualPos(this.data.photoPosY);
1097 | const scaleSize = this.data.scaleSize;
1098 | const transform = `translate(${photoPosX}px,${photoPosY}px) scale(${scaleSize})`;
1099 |
1100 | img.style.transform = transform;
1101 | if (this.data.scale) {
1102 | util.addClass(img, classNames.smartPhotoImgOnMove);
1103 | } else {
1104 | util.removeClass(img, classNames.smartPhotoImgOnMove);
1105 | }
1106 | if (this.data.elastic) {
1107 | util.addClass(img, classNames.smartPhotoImgElasticMove);
1108 | } else {
1109 | util.removeClass(img, classNames.smartPhotoImgElasticMove);
1110 | }
1111 | if (this.data.hideUi) {
1112 | if (nav) {
1113 | nav.setAttribute('aria-hidden', 'true');
1114 | }
1115 | if (arrows) {
1116 | arrows.setAttribute('aria-hidden', 'true');
1117 | }
1118 | } else {
1119 | if (nav) {
1120 | nav.setAttribute('aria-hidden', 'false');
1121 | }
1122 | if (arrows) {
1123 | arrows.setAttribute('aria-hidden', 'false');
1124 | }
1125 | }
1126 | }
1127 |
1128 | _getWindowWidth() {
1129 | if (document && document.documentElement) {
1130 | return document.documentElement.clientWidth;
1131 | } else if (window && window.innerWidth) {
1132 | return window.innerWidth;
1133 | }
1134 | return 0;
1135 | }
1136 |
1137 | _getWindowHeight() {
1138 | if (document && document.documentElement) {
1139 | return document.documentElement.clientHeight;
1140 | } else if (window && window.innerHeight) {
1141 | return window.innerHeight;
1142 | }
1143 | return 0;
1144 | }
1145 |
1146 | _listUpdate() {
1147 | const classNames = this.data.classNames;
1148 | const list = this._getElementByQuery(`.${classNames.smartPhotoList}`);
1149 | const transform = `translate(${this.data.translateX}px,${this.data.translateY}px)`;
1150 | list.style.transform = transform;
1151 | // $list
1152 | if (this.data.onMoveClass) {
1153 | util.addClass(list, classNames.smartPhotoListOnMove);
1154 | } else {
1155 | util.removeClass(list, classNames.smartPhotoListOnMove);
1156 | }
1157 | }
1158 |
1159 | _fireEvent(eventName) {
1160 | const photo = this._getElementByClass(this.data.classNames.smartPhoto);
1161 | util.triggerEvent(photo, eventName);
1162 | }
1163 |
1164 | _doAnim() {
1165 | if (this.isBeingZoomed ||
1166 | this.isSwipable ||
1167 | this.photoSwipable ||
1168 | this.data.elastic ||
1169 | !this.data.scale
1170 | ) {
1171 | return;
1172 | }
1173 | this.data.photoPosX += this.vx;
1174 | this.data.photoPosY += this.vy;
1175 | const item = this._getSelectedItem();
1176 | const bound = this._makeBound(item);
1177 | if (this.data.photoPosX < bound.minX) {
1178 | this.data.photoPosX = bound.minX;
1179 | this.vx *= -0.2;
1180 | } else if (this.data.photoPosX > bound.maxX) {
1181 | this.data.photoPosX = bound.maxX;
1182 | this.vx *= -0.2;
1183 | }
1184 | if (this.data.photoPosY < bound.minY) {
1185 | this.data.photoPosY = bound.minY;
1186 | this.vy *= -0.2;
1187 | } else if (this.data.photoPosY > bound.maxY) {
1188 | this.data.photoPosY = bound.maxY;
1189 | this.vy *= -0.2;
1190 | }
1191 | const power = this._getForceAndTheta(this.vx, this.vy);
1192 | let force = power.force;
1193 | const theta = power.theta;
1194 | force -= this.data.registance;
1195 | if (Math.abs(force) < 0.5) {
1196 | return;
1197 | }
1198 | this.vx = Math.cos(theta) * force;
1199 | this.vy = Math.sin(theta) * force;
1200 | this._photoUpdate();
1201 | }
1202 | }
1203 |
--------------------------------------------------------------------------------
/src/core/viwer.html:
--------------------------------------------------------------------------------
1 | aria-hidden="true" aria-hidden="false" role="dialog">
2 |
3 |
4 |
9 |
data-action-touchstart="beforeDrag" data-action-touchmove="onDrag" data-action-touchend="afterDrag(false)" data-action-click="hidePhoto()">
10 |
11 |
12 |
13 | -
14 |
15 |
data-action-mousemove="onDrag" data-action-mousedown="beforeDrag" data-action-mouseup="afterDrag" data-action-touchstart="beforeDrag" data-action-touchmove="onDrag" data-action-touchend="afterDrag">
16 |

17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
32 |
33 |
34 |
41 |
42 |
43 |
44 |

47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = require('./core/');
4 |
--------------------------------------------------------------------------------
/src/lib/util.js:
--------------------------------------------------------------------------------
1 | export const isSmartPhone = () => {
2 | const agent = navigator.userAgent
3 | if (agent.indexOf('iPhone') > 0 || agent.indexOf('iPad') > 0
4 | || agent.indexOf('ipod') > 0 || agent.indexOf('Android') > 0) {
5 | return true
6 | } else {
7 | return false
8 | }
9 | }
10 |
11 | function deepExtend(out){
12 | out = out || {};
13 |
14 | for (var i = 1; i < arguments.length; i++) {
15 | var obj = arguments[i];
16 | if (!obj) {
17 | continue;
18 | }
19 |
20 | for (var key in obj) {
21 | if (obj.hasOwnProperty(key)) {
22 | if (typeof obj[key] === 'object')
23 | out[key] = deepExtend(out[key], obj[key]);
24 | else
25 | out[key] = obj[key];
26 | }
27 | }
28 | }
29 |
30 | return out;
31 | };
32 |
33 | export const extend = deepExtend;
34 |
35 | export const triggerEvent = (el, eventName, options) => {
36 | let event;
37 | if (window.CustomEvent) {
38 | event = new CustomEvent(eventName, {cancelable:true});
39 | } else {
40 | event = document.createEvent('CustomEvent');
41 | event.initCustomEvent(eventName, false, false, options);
42 | }
43 | el.dispatchEvent(event);
44 | }
45 |
46 | export const parseQuery = (query) => {
47 | var s = query.split('&'),
48 | data = {},
49 | i = 0,
50 | iz = s.length,
51 | param, key, value;
52 | for (; i < iz; i++) {
53 | param = s[i].split('=');
54 | if (param[0] !== void 0) {
55 | key = param[0];
56 | value = (param[1] !== void 0) ? param.slice(1).join('=') : key;
57 | data[key] = decodeURIComponent(value);
58 | }
59 | }
60 | return data;
61 | }
62 |
63 | export const getViewPos = (element) => {
64 | return {
65 | left: element.getBoundingClientRect().left,
66 | top: element.getBoundingClientRect().top,
67 | }
68 | }
69 |
70 | export const removeElement = (element) => {
71 | if(element && element.parentNode) {
72 | element.parentNode.removeChild(element);
73 | }
74 | }
75 |
76 | export const append = (element, string) => {
77 | const div = document.createElement('div');
78 | div.innerHTML = string;
79 | while (div.children.length > 0) {
80 | element.appendChild(div.children[0]);
81 | }
82 | }
83 |
84 | export const addClass = (element,className) => {
85 | if (element.classList) {
86 | element.classList.add(className);
87 | } else {
88 | element.className += ` ${className}`;
89 | }
90 | }
91 |
92 | export const removeClass = (element,className) => {
93 | if (element.classList) {
94 | element.classList.remove(className);
95 | } else {
96 | element.className = element.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
97 | }
98 | }
99 |
100 | export const getBrowser = () => {
101 | const ua = window.navigator.userAgent.toLowerCase();
102 | const ver = window.navigator.appVersion.toLowerCase();
103 | let name = 'unknown';
104 |
105 | if (ua.indexOf('msie') != -1) {
106 | if (ver.indexOf('msie 6.') != -1) {
107 | name = 'ie6';
108 | } else if (ver.indexOf('msie 7.') != -1) {
109 | name = 'ie7';
110 | } else if (ver.indexOf('msie 8.') != -1) {
111 | name = 'ie8';
112 | } else if (ver.indexOf('msie 9.') != -1) {
113 | name = 'ie9';
114 | } else if (ver.indexOf('msie 10.') != -1) {
115 | name = 'ie10';
116 | } else {
117 | name = 'ie';
118 | }
119 | } else if (ua.indexOf('trident/7') != -1) {
120 | name = 'ie11';
121 | } else if (ua.indexOf('chrome') != -1) {
122 | name = 'chrome';
123 | } else if (ua.indexOf('safari') != -1) {
124 | name = 'safari';
125 | } else if (ua.indexOf('opera') != -1) {
126 | name = 'opera';
127 | } else if (ua.indexOf('firefox') != -1) {
128 | name = 'firefox';
129 | }
130 | return name;
131 | }
132 |
133 | export const isOldIE = () => {
134 | const browser = getBrowser();
135 | if (browser.indexOf('ie') !== -1) {
136 | if (parseInt(browser.replace(/[^0-9]/g, '')) <= 10 ) {
137 | return true;
138 | }
139 | }
140 | return false;
141 | }
--------------------------------------------------------------------------------
/test/preload.js:
--------------------------------------------------------------------------------
1 | window.__nightmare = {};
2 | __nightmare.ipc = require('electron').ipcRenderer;
3 | __nightmare.sliced = require('sliced');
4 |
5 | // Listen for error events
6 | window.addEventListener('error', function(e) {
7 | __nightmare.ipc.send('page', 'error', e.message, e.error.stack);
8 | });
9 |
10 | (function(){
11 | // listen for console.log
12 | var defaultLog = console.log;
13 | console.log = function() {
14 | __nightmare.ipc.send('console', 'log', __nightmare.sliced(arguments));
15 | return defaultLog.apply(this, arguments);
16 | };
17 |
18 | // listen for console.warn
19 | var defaultWarn = console.warn;
20 | console.warn = function() {
21 | __nightmare.ipc.send('console', 'warn', __nightmare.sliced(arguments));
22 | return defaultWarn.apply(this, arguments);
23 | };
24 |
25 | // listen for console.error
26 | var defaultError = console.error;
27 | console.error = function() {
28 | __nightmare.ipc.send('console', 'error', __nightmare.sliced(arguments));
29 | return defaultError.apply(this, arguments);
30 | };
31 |
32 | // overwrite the default alert
33 | window.alert = function(message){
34 | __nightmare.ipc.send('page', 'alert', message);
35 | };
36 |
37 | // overwrite the default prompt
38 | window.prompt = function(message, defaultResponse){
39 | __nightmare.ipc.send('page', 'prompt', message, defaultResponse);
40 | }
41 |
42 | // overwrite the default confirm
43 | window.confirm = function(message, defaultResponse){
44 | __nightmare.ipc.send('page', 'confirm', message, defaultResponse);
45 | return true;
46 | }
47 | })()
--------------------------------------------------------------------------------
/test/test.js:
--------------------------------------------------------------------------------
1 | const Nightmare = require('nightmare');
2 | const assert = require('assert');
3 | const fs = require('fs');
4 | const path = require('path');
5 | const test_url = "file:///"+path.resolve(__dirname,"../examples/vanilla.html");
6 | const hash_url = test_url + "#group=nogroup&photo=rhino";
7 |
8 | const nightmare = Nightmare({
9 | webPreferences : {
10 | partition : 'nopersist',
11 | preload: path.resolve(__dirname,'./preload.js')
12 | },
13 | show: true
14 | });
15 |
16 | describe('test',() => {
17 | it('caption', (done) => {
18 | nightmare.goto(test_url)
19 | .click('[data-caption="Lion"]')
20 | .wait(1000)
21 | .click('.smartphoto-arrow-right a')
22 | .wait(1000)
23 | .evaluate(() => {
24 | return document.querySelector('.smartphoto-caption').innerText;
25 | })
26 | .then((result) => {
27 | assert.equal(result,'Camel');
28 | done();
29 | })
30 | .catch((error) => {
31 | done(error);
32 | });
33 | });
34 |
35 | it('hash', (done) => {
36 | nightmare.goto(hash_url)
37 | .wait(1000)
38 | .evaluate(() => {
39 | return document.querySelector('.smartphoto-caption').innerText;
40 | })
41 | .then(result => {
42 | assert.equal(result,'Rhino');
43 | done();
44 | })
45 | .catch(error => {
46 | done(error);
47 | });
48 | });
49 | });
50 |
--------------------------------------------------------------------------------
/tools/index.js:
--------------------------------------------------------------------------------
1 | "use strict"
2 | const cmd = require('node-cmd');
3 | const co = require('co');
4 | const fs = require('fs-extra');
5 | const pkg = require('../package.json');
6 |
7 | const SystemPromise = (cmd_string) => {
8 | return new Promise((resolve, reject) => {
9 | cmd.get(
10 | cmd_string,
11 | (data, err, stderr) => {
12 | if ( err ) {
13 | console.log(err)
14 | }
15 | if ( stderr ) {
16 | console.log(stderr)
17 | }
18 | resolve(data)
19 | }
20 | )
21 | })
22 | }
23 |
24 | co(function *() {
25 | try {
26 | yield SystemPromise(`git add -A`);
27 | yield SystemPromise(`git commit -m "v${pkg.version}"`);
28 | yield SystemPromise(`git push origin v${pkg.version}`);
29 | yield SystemPromise(`git push origin master`);
30 | yield SystemPromise(`npm publish`);
31 | } catch ( err ) {
32 | console.log(err)
33 | }
34 | });
--------------------------------------------------------------------------------