├── .gitattributes
├── .github
└── FUNDING.yml
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── build.js
├── demos
├── default.html
└── images
│ ├── 1.jpg
│ ├── 10.jpg
│ ├── 11.jpg
│ ├── 12.jpg
│ ├── 13.jpg
│ ├── 14.jpg
│ ├── 15.jpg
│ ├── 16.jpg
│ ├── 17.jpg
│ ├── 18.jpg
│ ├── 19.jpg
│ ├── 2.jpg
│ ├── 20.jpg
│ ├── 21.jpg
│ ├── 22.jpg
│ ├── 23.jpg
│ ├── 24.jpg
│ ├── 25.jpg
│ ├── 26.jpg
│ ├── 27.jpg
│ ├── 28.jpg
│ ├── 29.jpg
│ ├── 3.jpg
│ ├── 30.jpg
│ ├── 31.jpg
│ ├── 32.jpg
│ ├── 33.jpg
│ ├── 34.jpg
│ ├── 35.jpg
│ ├── 36.jpg
│ ├── 4.jpg
│ ├── 5.jpg
│ ├── 6.jpg
│ ├── 7.jpg
│ ├── 8.jpg
│ └── 9.jpg
├── dist
├── basicRotate.min.css
└── basicRotate.min.js
├── package.json
└── src
├── scripts
└── main.js
└── styles
└── main.scss
/.gitattributes:
--------------------------------------------------------------------------------
1 | dist/**/* binary
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: electerious
2 | custom: ['https://paypal.me/electerious', 'https://www.buymeacoffee.com/electerious']
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | yarn.lock
3 | package-lock.json
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6 |
7 | ## [1.1.2] - 2021-01-17
8 |
9 | ### Changed
10 |
11 | - Updated dependencies
12 |
13 | ## [1.1.1] - 2020-03-20
14 |
15 | ### Changed
16 |
17 | - Updated dependencies
18 |
19 | ## [1.1.0] - 2019-08-10
20 |
21 | ### Added
22 |
23 | - Touch support
24 |
25 | ## [1.0.0] - 2019-08-10
26 |
27 | ### Added
28 |
29 | - Everything
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) Tobias Reich
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
13 | all 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
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # basicRotate
2 |
3 | [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CYKBESW577YWE)
4 |
5 | Rotate throw a set of 360 degree images using your mouse or finger.
6 |
7 | ## Contents
8 |
9 | - [Demos](#demos)
10 | - [Features](#features)
11 | - [Requirements](#requirements)
12 | - [Setup](#setup)
13 | - [Usage](#usage)
14 | - [API](#api)
15 | - [Instance API](#instance-api)
16 | - [Options](#options)
17 |
18 | ## Demos
19 |
20 | | Name | Description | Link |
21 | |:-----------|:------------|:------------|
22 | | Default | Includes most features. | [Try it on CodePen](https://codepen.io/electerious/pen/wVYoYK) |
23 |
24 | ## Features
25 |
26 | - Works in all modern browsers and IE11 ([with polyfills](#requirements))
27 | - Supports any kind of images
28 | - Zero dependencies
29 | - CommonJS and AMD support
30 | - Simple JS API
31 |
32 | ## Requirements
33 |
34 | basicRotate depends on the following browser APIs:
35 |
36 | - [NodeList.prototype.forEach](https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach)
37 | - [Number.isFinite](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite)
38 | - [Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
39 |
40 | Some of these APIs are capable of being polyfilled in older browsers. Check the linked resources above to determine if you must polyfill to achieve your desired level of browser support.
41 |
42 | ## Setup
43 |
44 | We recommend installing basicRotate using [npm](https://npmjs.com) or [yarn](https://yarnpkg.com).
45 |
46 | ```sh
47 | npm install basicrotate
48 | ```
49 |
50 | ```sh
51 | yarn add basicrotate
52 | ```
53 |
54 | Include the CSS file in the `head` tag and the JS file at the end of your `body` tag…
55 |
56 | ```html
57 |
58 | ```
59 |
60 | ```html
61 |
62 | ```
63 |
64 | …or skip the JS file and use basicRotate as a module:
65 |
66 | ```js
67 | const basicRotate = require('basicrotate')
68 | ```
69 |
70 | ```js
71 | import * as basicRotate from 'basicrotate'
72 | ```
73 |
74 | ## Usage
75 |
76 | Create an element filled with equal-sized images. Add the `basicRotate` class and initialize basicRotate using the `basicRotate.create` function. That's it!
77 |
78 | ```html
79 |
85 | ```
86 |
87 | ```js
88 | basicRotate.create(document.querySelector('.basicRotate'))
89 | ```
90 |
91 | ## API
92 |
93 | ### .create(elem, opts)
94 |
95 | Creates a new basicRotate instance.
96 |
97 | Be sure to assign your instance to a variable. Using your instance, you can…
98 |
99 | * …get the current image index.
100 | * …jump back and forward.
101 | * …goto a specific image.
102 |
103 | Examples:
104 |
105 | ```js
106 | const instance = basicRotate.create(document.querySelector('#rotate'))
107 | ```
108 |
109 | ```js
110 | const instance = basicRotate.create(document.querySelector('#rotate'), {
111 | index: 1,
112 | tolerance: 5
113 | })
114 | ```
115 |
116 | ```js
117 | const instance = basicRotate.create(document.querySelector('#rotate'), {
118 | beforeChange: (instance, newIndex, oldIndex) => console.log('beforeChange', instance, newIndex, oldIndex),
119 | afterChange: (instance, newIndex, oldIndex) => console.log('afterChange', instance, newIndex, oldIndex)
120 | })
121 | ```
122 |
123 | Parameters:
124 |
125 | - `elem` `{Node}` The DOM element/node which contains all images.
126 | - `opts` `{?Object}` An object of [options](#options).
127 |
128 | Returns:
129 |
130 | - `{Object}` The created instance.
131 |
132 | ## Instance API
133 |
134 | Each basicRotate instance has a handful of handy functions. Below are all of them along with a short description.
135 |
136 | ### .current()
137 |
138 | Returns the current image index.
139 |
140 | Example:
141 |
142 | ```js
143 | const current = instance.current()
144 | ```
145 |
146 | Returns:
147 |
148 | - `{Number}` Current image index.
149 |
150 | ### .goto(newIndex)
151 |
152 | Navigates to an image by index and executes the beforeChange and afterChange callback functions.
153 |
154 | Example:
155 |
156 | ```js
157 | instance.goto(0)
158 | ```
159 |
160 | Parameters:
161 |
162 | - `newIndex` `{Number}` Index of the image to be displayed.
163 |
164 | ### .prev()
165 |
166 | Navigates to the previous image and executes the beforeChange and afterChange callback functions.
167 |
168 | Example:
169 |
170 | ```js
171 | instance.prev()
172 | ```
173 |
174 | ### .next()
175 |
176 | Navigates to the next image and executes the beforeChange and afterChange callback functions.
177 |
178 | Example:
179 |
180 | ```js
181 | instance.next()
182 | ```
183 |
184 | ## Options
185 |
186 | The option object can include the following properties:
187 |
188 | ```js
189 | {
190 | /*
191 | * Initial image.
192 | */
193 | index: 0,
194 | /*
195 | * Rotate image by dragging.
196 | */
197 | draggable: true,
198 | /*
199 | * Dragging tolerance.
200 | * Small number (1) = Very sensitive = Fast.
201 | * Large number (∞) = Very insensitive = Slow.
202 | */
203 | tolerance: 10,
204 | /*
205 | * Dragging direction.
206 | * x (or basicRotate.DIRECTION_X) = Detect movements on the x-axis.
207 | * y (or basicRotate.DIRECTION_Y) = Detect movements on the y-axis.
208 | */
209 | index: 'x',
210 | /*
211 | * Callback functions.
212 | * Returning false will stop the caller function and prevent the image from changing.
213 | */
214 | beforeChange: (instance, newIndex, oldIndex) => {},
215 | afterChange: (instance, newIndex, oldIndex) => {}
216 | }
217 | ```
--------------------------------------------------------------------------------
/build.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const { writeFile } = require('fs').promises
4 | const js = require('rosid-handler-js')
5 | const sass = require('rosid-handler-sass')
6 |
7 | sass('src/styles/main.scss', {
8 |
9 | optimize: true
10 |
11 | }).then((data) => {
12 |
13 | return writeFile('dist/basicRotate.min.css', data)
14 |
15 | })
16 |
17 | js('src/scripts/main.js', {
18 |
19 | optimize: true,
20 | babel: {
21 | presets: [ '@babel/preset-env' ],
22 | babelrc: false,
23 | global: true
24 | },
25 | browserify: {
26 | standalone: 'basicRotate'
27 | }
28 |
29 | }).then((data) => {
30 |
31 | return writeFile('dist/basicRotate.min.js', data)
32 |
33 | })
--------------------------------------------------------------------------------
/demos/default.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | basicRotate Demo
6 |
7 |
8 |
9 |
10 |
11 |
34 |
35 |
36 |
37 |
Default
38 |
39 |
40 |

41 |

42 |

43 |

44 |

45 |

46 |

47 |

48 |

49 |

50 |

51 |

52 |

53 |

54 |

55 |

56 |

57 |

58 |

59 |

60 |

61 |

62 |

63 |

64 |

65 |

66 |

67 |

68 |

69 |

70 |

71 |

72 |

73 |

74 |

75 |

76 |
77 |
78 |
Custom start index
79 |
80 |
81 |

82 |

83 |

84 |

85 |

86 |

87 |

88 |

89 |

90 |

91 |

92 |

93 |

94 |

95 |

96 |

97 |

98 |

99 |

100 |

101 |

102 |

103 |

104 |

105 |

106 |

107 |

108 |

109 |

110 |

111 |

112 |

113 |

114 |

115 |

116 |

117 |
118 |
119 |
Custom tolerance (fast)
120 |
121 |
122 |

123 |

124 |

125 |

126 |

127 |

128 |

129 |

130 |

131 |

132 |

133 |

134 |

135 |

136 |

137 |

138 |

139 |

140 |

141 |

142 |

143 |

144 |

145 |

146 |

147 |

148 |

149 |

150 |

151 |

152 |

153 |

154 |

155 |

156 |

157 |

158 |
159 |
160 |
Custom tolerance (slow)
161 |
162 |
163 |

164 |

165 |

166 |

167 |

168 |

169 |

170 |

171 |

172 |

173 |

174 |

175 |

176 |

177 |

178 |

179 |

180 |

181 |

182 |

183 |

184 |

185 |

186 |

187 |

188 |

189 |

190 |

191 |

192 |

193 |

194 |

195 |

196 |

197 |

198 |

199 |
200 |
201 |
With Callbacks
202 |
203 |
204 |

205 |

206 |

207 |

208 |

209 |

210 |

211 |

212 |

213 |

214 |

215 |

216 |

217 |

218 |

219 |

220 |

221 |

222 |

223 |

224 |

225 |

226 |

227 |

228 |

229 |

230 |

231 |

232 |

233 |

234 |

235 |

236 |

237 |

238 |

239 |

240 |
241 |
242 |
With blocking callback
243 |
244 |
245 |

246 |

247 |

248 |

249 |

250 |

251 |

252 |

253 |

254 |

255 |

256 |

257 |

258 |

259 |

260 |

261 |

262 |

263 |

264 |

265 |

266 |

267 |

268 |

269 |

270 |

271 |

272 |

273 |

274 |

275 |

276 |

277 |

278 |

279 |

280 |

281 |
282 |
283 |
Y direction
284 |
285 |
286 |

287 |

288 |

289 |

290 |

291 |

292 |

293 |

294 |

295 |

296 |

297 |

298 |

299 |

300 |

301 |

302 |

303 |

304 |

305 |

306 |

307 |

308 |

309 |

310 |

311 |

312 |

313 |

314 |

315 |

316 |

317 |

318 |

319 |

320 |

321 |

322 |
323 |
324 |
With custom buttons and draggable disabled
325 |
326 |
327 |

328 |

329 |

330 |

331 |

332 |

333 |

334 |

335 |

336 |

337 |

338 |

339 |

340 |

341 |

342 |

343 |

344 |

345 |

346 |

347 |

348 |

349 |

350 |

351 |

352 |

353 |

354 |

355 |

356 |

357 |

358 |

359 |

360 |

361 |

362 |

363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
430 |
431 |
--------------------------------------------------------------------------------
/demos/images/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/1.jpg
--------------------------------------------------------------------------------
/demos/images/10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/10.jpg
--------------------------------------------------------------------------------
/demos/images/11.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/11.jpg
--------------------------------------------------------------------------------
/demos/images/12.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/12.jpg
--------------------------------------------------------------------------------
/demos/images/13.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/13.jpg
--------------------------------------------------------------------------------
/demos/images/14.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/14.jpg
--------------------------------------------------------------------------------
/demos/images/15.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/15.jpg
--------------------------------------------------------------------------------
/demos/images/16.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/16.jpg
--------------------------------------------------------------------------------
/demos/images/17.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/17.jpg
--------------------------------------------------------------------------------
/demos/images/18.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/18.jpg
--------------------------------------------------------------------------------
/demos/images/19.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/19.jpg
--------------------------------------------------------------------------------
/demos/images/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/2.jpg
--------------------------------------------------------------------------------
/demos/images/20.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/20.jpg
--------------------------------------------------------------------------------
/demos/images/21.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/21.jpg
--------------------------------------------------------------------------------
/demos/images/22.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/22.jpg
--------------------------------------------------------------------------------
/demos/images/23.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/23.jpg
--------------------------------------------------------------------------------
/demos/images/24.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/24.jpg
--------------------------------------------------------------------------------
/demos/images/25.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/25.jpg
--------------------------------------------------------------------------------
/demos/images/26.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/26.jpg
--------------------------------------------------------------------------------
/demos/images/27.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/27.jpg
--------------------------------------------------------------------------------
/demos/images/28.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/28.jpg
--------------------------------------------------------------------------------
/demos/images/29.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/29.jpg
--------------------------------------------------------------------------------
/demos/images/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/3.jpg
--------------------------------------------------------------------------------
/demos/images/30.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/30.jpg
--------------------------------------------------------------------------------
/demos/images/31.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/31.jpg
--------------------------------------------------------------------------------
/demos/images/32.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/32.jpg
--------------------------------------------------------------------------------
/demos/images/33.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/33.jpg
--------------------------------------------------------------------------------
/demos/images/34.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/34.jpg
--------------------------------------------------------------------------------
/demos/images/35.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/35.jpg
--------------------------------------------------------------------------------
/demos/images/36.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/36.jpg
--------------------------------------------------------------------------------
/demos/images/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/4.jpg
--------------------------------------------------------------------------------
/demos/images/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/5.jpg
--------------------------------------------------------------------------------
/demos/images/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/6.jpg
--------------------------------------------------------------------------------
/demos/images/7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/7.jpg
--------------------------------------------------------------------------------
/demos/images/8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/8.jpg
--------------------------------------------------------------------------------
/demos/images/9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/electerious/basicRotate/991e5b90653c8b826648ca21623b49228f035db7/demos/images/9.jpg
--------------------------------------------------------------------------------
/dist/basicRotate.min.css:
--------------------------------------------------------------------------------
1 | .basicRotate{position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:-webkit-grab;cursor:grab}.basicRotate:active{cursor:-webkit-grabbing;cursor:grabbing}.basicRotate img{position:absolute;top:0;left:0;width:100%;opacity:0;pointer-events:none}.basicRotate img:first-child{position:relative}.basicRotate img.active{opacity:1}
--------------------------------------------------------------------------------
/dist/basicRotate.min.js:
--------------------------------------------------------------------------------
1 | !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).basicRotate=e()}}((function(){return function e(n,t,o){function r(u,f){if(!t[u]){if(!n[u]){var c="function"==typeof require&&require;if(!f&&c)return c(u,!0);if(i)return i(u,!0);var a=new Error("Cannot find module '"+u+"'");throw a.code="MODULE_NOT_FOUND",a}var d=t[u]={exports:{}};n[u][0].call(d.exports,(function(e){return r(n[u][1][e]||e)}),d,d.exports,e,n,t,o)}return t[u].exports}for(var i="function"==typeof require&&require,u=0;u=0&&(r=0+r),r<0&&(r=o+r),e+r}}},{}],2:[function(e,n,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.create=t.DIRECTION_Y=t.DIRECTION_X=void 0;var o,r=(o=e("count-between"))&&o.__esModule?o:{default:o};t.DIRECTION_X="x";t.DIRECTION_Y="y";var i=function(e){return{x:e.pageX||e.touches[0].pageX,y:e.pageY||e.touches[0].pageY}},u=function(e,n){e.forEach((function(e){return e.classList.remove("active")})),e[n].classList.add("active")},f=function(e,n,t,o){if(u(n,t.current()),!1!==o.draggable){var r,f,c=function(e){r=t.current(),f=i(e)},a=function(e){if(!1!=(null!=r&&null!=f)){var n,u,c,a=i(e),d=(n=f,u=a,c=o.direction,n[c]-u[c]),l=Math.round(d/o.tolerance);t.goto(r+l)}},d=function(){r=void 0,f=void 0};e.ontouchstart=c,e.onmousedown=c,document.addEventListener("touchmove",a),document.addEventListener("mousemove",a),document.addEventListener("touchend",d),document.addEventListener("mouseup",d)}};t.create=function(e,n){n=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return e=Object.assign({},e),!1===Number.isFinite(e.index)&&(e.index=0),!1===Number.isFinite(e.tolerance)&&(e.tolerance=10),!1!==e.draggable&&(e.draggable=!0),"y"!==e.direction&&(e.direction="x"),"function"!=typeof e.beforeChange&&(e.beforeChange=function(){}),"function"!=typeof e.afterChange&&(e.afterChange=function(){}),e}(n);var t=e.querySelectorAll("img"),o=(0,r.default)(0,t.length-1,n.index),i=function(e){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:o();if(!1===n.beforeChange(c,e,i))return!1;o=(0,r.default)(0,t.length-1,e),u(t,o()),n.afterChange(c,e,i)},c={current:function(){return o()},goto:i,prev:function(){var e=o(),n=o(-1);i(n,e)},next:function(){var e=o(),n=o(1);i(n,e)}};return f(e,t,c,n),c}},{"count-between":1}]},{},[2])(2)}));
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "basicrotate",
3 | "version": "1.1.2",
4 | "authors": [
5 | "Tobias Reich "
6 | ],
7 | "description": "Rotate throw a set of 360 degree images using your mouse or finger",
8 | "main": "dist/basicRotate.min.js",
9 | "keywords": [
10 | "slider",
11 | "slides",
12 | "carousel",
13 | "rotate",
14 | "rotation",
15 | "360",
16 | "surround",
17 | "reel"
18 | ],
19 | "scripts": {
20 | "build": "node build.js"
21 | },
22 | "license": "MIT",
23 | "homepage": "https://github.com/electerious/basicRotate",
24 | "repository": {
25 | "type": "git",
26 | "url": "https://github.com/electerious/basicRotate.git"
27 | },
28 | "files": [
29 | "dist",
30 | "src"
31 | ],
32 | "dependencies": {
33 | "count-between": "^3.0.0"
34 | },
35 | "devDependencies": {
36 | "rosid-handler-js": "^13.0.0",
37 | "rosid-handler-sass": "^8.0.0"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/scripts/main.js:
--------------------------------------------------------------------------------
1 | import counter from 'count-between'
2 |
3 | export const DIRECTION_X = 'x'
4 | export const DIRECTION_Y = 'y'
5 |
6 | const validate = function(opts = {}) {
7 |
8 | opts = Object.assign({}, opts)
9 |
10 | if (Number.isFinite(opts.index) === false) opts.index = 0
11 | if (Number.isFinite(opts.tolerance) === false) opts.tolerance = 10
12 |
13 | if (opts.draggable !== false) opts.draggable = true
14 | if (opts.direction !== DIRECTION_Y) opts.direction = DIRECTION_X
15 |
16 | if (typeof opts.beforeChange !== 'function') opts.beforeChange = () => {}
17 | if (typeof opts.afterChange !== 'function') opts.afterChange = () => {}
18 |
19 | return opts
20 |
21 | }
22 |
23 | const getMousePosition = function(e) {
24 |
25 | return {
26 | x: e.pageX || e.touches[0].pageX,
27 | y: e.pageY || e.touches[0].pageY
28 | }
29 |
30 | }
31 |
32 | const getDistance = function(a, b, direction) {
33 |
34 | return a[direction] - b[direction]
35 |
36 | }
37 |
38 | const setImage = function(images, index) {
39 |
40 | images.forEach((image) => image.classList.remove('active'))
41 | images[index].classList.add('active')
42 |
43 | }
44 |
45 | const init = function(elem, images, instance, opts) {
46 |
47 | // Set initial image using the setImage function
48 | // to avoid that a callback blocks the initial call.
49 | setImage(images, instance.current())
50 |
51 | // Stop here when the user disabled draggable
52 | if (opts.draggable === false) return
53 |
54 | let startIndex
55 | let startPosition
56 |
57 | const isDragging = () => (
58 | startIndex != null &&
59 | startPosition != null
60 | )
61 |
62 | const start = (e) => {
63 |
64 | startIndex = instance.current()
65 | startPosition = getMousePosition(e)
66 |
67 | }
68 |
69 | const move = (e) => {
70 |
71 | if (isDragging() === false) return
72 |
73 | const currentPosition = getMousePosition(e)
74 | const distance = getDistance(startPosition, currentPosition, opts.direction)
75 | const offset = Math.round(distance / opts.tolerance)
76 |
77 | instance.goto(startIndex + offset)
78 |
79 | }
80 |
81 | const end = () => {
82 |
83 | startIndex = undefined
84 | startPosition = undefined
85 |
86 | }
87 |
88 | elem.ontouchstart = start
89 | elem.onmousedown = start
90 |
91 | document.addEventListener('touchmove', move)
92 | document.addEventListener('mousemove', move)
93 |
94 | document.addEventListener('touchend', end)
95 | document.addEventListener('mouseup', end)
96 |
97 | }
98 |
99 | export const create = function(elem, opts) {
100 |
101 | opts = validate(opts)
102 |
103 | // All images inside the element
104 | const images = elem.querySelectorAll('img')
105 |
106 | // Image index counter
107 | let c = counter(0, images.length - 1, opts.index)
108 |
109 | // Returns the current image index
110 | const _current = () => c()
111 |
112 | // Navigate to a given image
113 | // Use c() as the default oldIndex as the counter hasn't been recreated yet,
114 | // when called through the API. Internal functions can set a custom oldIndex.
115 | const _goto = (newIndex, oldIndex = c()) => {
116 |
117 | // Run beforePrev event
118 | // Stop execution when function returns false
119 | if (opts.beforeChange(instance, newIndex, oldIndex) === false) return false
120 |
121 | // Recreate counter with new initial value
122 | c = counter(0, images.length - 1, newIndex)
123 |
124 | setImage(images, c())
125 |
126 | // Run afterShow event
127 | opts.afterChange(instance, newIndex, oldIndex)
128 |
129 | }
130 |
131 | // Navigate to the previous image
132 | const _prev = () => {
133 |
134 | // Store old index before modifying the counter
135 | const oldIndex = c()
136 | const newIndex = c(-1)
137 |
138 | _goto(newIndex, oldIndex)
139 |
140 | }
141 |
142 | // Navigate to the next image
143 | const _next = () => {
144 |
145 | // Store old index before modifying the counter
146 | const oldIndex = c()
147 | const newIndex = c(1)
148 |
149 | _goto(newIndex, oldIndex)
150 |
151 | }
152 |
153 | // Assign instance to a variable so the instance can be used
154 | // elsewhere in the current function.
155 | const instance = {
156 | current: _current,
157 | goto: _goto,
158 | prev: _prev,
159 | next: _next
160 | }
161 |
162 | // Initialize the element
163 | init(elem, images, instance, opts)
164 |
165 | return instance
166 |
167 | }
--------------------------------------------------------------------------------
/src/styles/main.scss:
--------------------------------------------------------------------------------
1 | .basicRotate {
2 |
3 | position: relative;
4 | user-select: none;
5 | cursor: grab;
6 |
7 | &:active {
8 | cursor: grabbing;
9 | }
10 |
11 | img {
12 | position: absolute;
13 | top: 0;
14 | left: 0;
15 | width: 100%;
16 | opacity: 0;
17 | pointer-events: none;
18 |
19 | &:first-child {
20 | // The first element defines the size
21 | position: relative;
22 | }
23 |
24 | &.active {
25 | opacity: 1;
26 | }
27 | }
28 |
29 | }
--------------------------------------------------------------------------------