├── .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 | [![Donate via PayPal](https://img.shields.io/badge/paypal-donate-009cde.svg)](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 | - [Node​List​.prototype​.for​Each](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 |
80 | 81 | 82 | 83 | 84 |
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 | } --------------------------------------------------------------------------------