├── demo ├── .gitignore ├── img │ ├── h1_small.jpg │ ├── h2_small.jpg │ ├── v1_small.jpg │ ├── close_cursor.png │ └── plus_cursor.png ├── css │ └── styles.css ├── scss │ └── styles.scss └── index.html ├── .gitignore ├── .github └── FUNDING.yml ├── package.json ├── readme.md ├── intense.min.js └── intense.js /demo/.gitignore: -------------------------------------------------------------------------------- 1 | .sass-cache/* 2 | .DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [tholman] 2 | custom: ['https://www.buymeacoffee.com/tholman'] 3 | -------------------------------------------------------------------------------- /demo/img/h1_small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tholman/intense-images/HEAD/demo/img/h1_small.jpg -------------------------------------------------------------------------------- /demo/img/h2_small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tholman/intense-images/HEAD/demo/img/h2_small.jpg -------------------------------------------------------------------------------- /demo/img/v1_small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tholman/intense-images/HEAD/demo/img/v1_small.jpg -------------------------------------------------------------------------------- /demo/img/close_cursor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tholman/intense-images/HEAD/demo/img/close_cursor.png -------------------------------------------------------------------------------- /demo/img/plus_cursor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tholman/intense-images/HEAD/demo/img/plus_cursor.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tholman/intense-images", 3 | "version": "1.0.7", 4 | "description": 5 | "A simple library to view large images up close using simple mouse interaction, and the full screen.", 6 | "main": "intense.js", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/tholman/intense-images.git" 10 | }, 11 | "keywords": ["web", "front-end", "image viewer", "photography"], 12 | "author": "Tim Holman ", 13 | "license": "MIT", 14 | "bugs": { 15 | "url": "https://github.com/tholman/intense-images/issues" 16 | }, 17 | "homepage": "https://github.com/tholman/intense-images#readme" 18 | } 19 | -------------------------------------------------------------------------------- /demo/css/styles.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * intense-image-viewer 3 | * 4 | * MIT licensed 5 | * Copyright (C) 2013 Tim Holman, http://tholman.com 6 | */ 7 | /********************************************* 8 | * 9 | *********************************************/ 10 | * { 11 | -webkit-font-smoothing: antialiased; 12 | -moz-box-sizing: border-box; 13 | box-sizing: border-box; } 14 | 15 | html, 16 | body { 17 | font-family: "Ubuntu Mono", monospace; 18 | margin: 0px; 19 | height: 100%; 20 | width: 100%; } 21 | 22 | body { 23 | padding: 20px; 24 | text-align: center; 25 | min-width: 700px; } 26 | 27 | .logo { 28 | width: 55px; 29 | height: 55px; 30 | background: #222; 31 | color: #fff; 32 | text-align: center; 33 | line-height: 56px; 34 | border-radius: 100%; 35 | font-size: 27px; 36 | letter-spacing: -7px; 37 | text-indent: -6px; 38 | margin: auto; 39 | margin-bottom: 20px; 40 | margin-top: 20px; } 41 | 42 | header h1, 43 | footer h1 { 44 | font-weight: normal; 45 | width: 604px; 46 | background: #222; 47 | color: #fff; 48 | font-size: 18px; 49 | height: 55px; 50 | line-height: 55px; 51 | margin: auto; 52 | margin-top: 0px; 53 | margin-bottom: 20px; } 54 | 55 | .demos { 56 | text-align: center; 57 | margin-top: 20px; } 58 | 59 | .demo-image { 60 | cursor: url("../img/plus_cursor.png") 25 25, pointer; 61 | display: inline-block; 62 | width: 290px; 63 | height: 290px; 64 | background-size: cover; 65 | background-position: 50% 50%; 66 | margin-left: 8px; 67 | margin-right: 8px; 68 | margin-bottom: 16px; } 69 | .demo-image.first { 70 | background-image: url("../img/h1_small.jpg"); } 71 | .demo-image.second { 72 | background-position: 50% 10%; 73 | background-image: url("../img/v1_small.jpg"); } 74 | .demo-image.third { 75 | background-image: url("../img/h2_small.jpg"); } 76 | 77 | footer h1 { 78 | padding-left: 20px; 79 | background: #e9e9e9; 80 | color: #222; 81 | font-size: 16px; } 82 | footer h1 a { 83 | color: #222; } 84 | 85 | iframe { 86 | margin-bottom: -5px; 87 | margin-left: 2px; } 88 | 89 | .github-link { 90 | position: fixed; 91 | z-index: 2; 92 | top: 0; 93 | right: 0; 94 | border: 0; } 95 | 96 | .github-corner:hover .octo-arm { 97 | animation: octocat-wave 560ms ease-in-out; } 98 | 99 | @keyframes octocat-wave { 100 | 0%, 101 | 100% { 102 | transform: rotate(0); } 103 | 20%, 104 | 60% { 105 | transform: rotate(-25deg); } 106 | 40%, 107 | 80% { 108 | transform: rotate(10deg); } } 109 | @media (max-width: 500px) { 110 | .github-corner:hover .octo-arm { 111 | animation: none; } 112 | 113 | .github-corner .octo-arm { 114 | animation: octocat-wave 560ms ease-in-out; } } 115 | 116 | /*# sourceMappingURL=styles.css.map */ 117 | -------------------------------------------------------------------------------- /demo/scss/styles.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * intense-image-viewer 3 | * 4 | * MIT licensed 5 | * Copyright (C) 2013 Tim Holman, http://tholman.com 6 | */ 7 | 8 | /********************************************* 9 | * 10 | *********************************************/ 11 | 12 | $black: #222; 13 | 14 | * { 15 | -webkit-font-smoothing: antialiased; 16 | -moz-box-sizing: border-box; 17 | box-sizing: border-box; 18 | } 19 | 20 | html, 21 | body { 22 | font-family: "Ubuntu Mono", monospace; 23 | margin: 0px; 24 | height: 100%; 25 | width: 100%; 26 | } 27 | 28 | body { 29 | padding: 20px; 30 | text-align: center; 31 | min-width: 700px; 32 | } 33 | 34 | .logo { 35 | width: 55px; 36 | height: 55px; 37 | background: $black; 38 | color: #fff; 39 | text-align: center; 40 | line-height: 56px; 41 | border-radius: 100%; 42 | font-size: 27px; 43 | letter-spacing: -7px; 44 | text-indent: -6px; 45 | margin: auto; 46 | margin-bottom: 20px; 47 | margin-top: 20px; 48 | } 49 | 50 | header, 51 | footer { 52 | h1 { 53 | font-weight: normal; 54 | width: 604px; 55 | background: $black; 56 | color: #fff; 57 | font-size: 18px; 58 | height: 55px; 59 | line-height: 55px; 60 | margin: auto; 61 | margin-top: 0px; 62 | margin-bottom: 20px; 63 | } 64 | } 65 | 66 | .demos { 67 | text-align: center; 68 | margin-top: 20px; 69 | } 70 | 71 | .demo-image { 72 | cursor: url("../img/plus_cursor.png") 25 25, pointer; 73 | display: inline-block; 74 | width: 290px; 75 | height: 290px; 76 | background-size: cover; 77 | background-position: 50% 50%; 78 | margin-left: 8px; 79 | margin-right: 8px; 80 | margin-bottom: 16px; 81 | 82 | &.first { 83 | background-image: url("../img/h1_small.jpg"); 84 | } 85 | 86 | &.second { 87 | background-position: 50% 10%; 88 | background-image: url("../img/v1_small.jpg"); 89 | } 90 | 91 | &.third { 92 | background-image: url("../img/h2_small.jpg"); 93 | } 94 | } 95 | 96 | footer { 97 | h1 { 98 | padding-left: 20px; 99 | background: #e9e9e9; 100 | color: $black; 101 | font-size: 16px; 102 | 103 | a { 104 | color: $black; 105 | } 106 | } 107 | } 108 | 109 | iframe { 110 | margin-bottom: -5px; 111 | margin-left: 2px; 112 | } 113 | 114 | .github-link { 115 | position: fixed; 116 | z-index: 2; 117 | top: 0; 118 | right: 0; 119 | border: 0; 120 | } 121 | 122 | .github-corner:hover .octo-arm { 123 | animation: octocat-wave 560ms ease-in-out; 124 | } 125 | 126 | @keyframes octocat-wave { 127 | 0%, 128 | 100% { 129 | transform: rotate(0); 130 | } 131 | 20%, 132 | 60% { 133 | transform: rotate(-25deg); 134 | } 135 | 40%, 136 | 80% { 137 | transform: rotate(10deg); 138 | } 139 | } 140 | 141 | @media (max-width: 500px) { 142 | .github-corner:hover .octo-arm { 143 | animation: none; 144 | } 145 | .github-corner .octo-arm { 146 | animation: octocat-wave 560ms ease-in-out; 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Intense Images 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |
21 |

Intense Image Viewer

22 |

A javascript library for viewing images in a fully full screen.

23 |

Click the images to see it in action!

24 |
25 |
26 |
27 | 28 |
29 |
30 |
31 |
32 | 33 | 40 | 41 | 42 | 47 | 48 | 49 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Intense Images 2 | 3 | A stand alone javascript library for viewing images on the full, full screen. Using the touch/mouse position for panning. [Here's a demo](http://tholman.com/intense-images)! You can also play with the code [live on CodePen](http://codepen.io/tholman/pen/mlDiK). 4 | 5 | ### Instructions 6 | 7 | Intense images is a stand alone library (no jquery, or the likes) so usage is pretty straight forward. All styling of image elements is up to the user, ```Intense.js``` only handles the creation, styling and management of the image viewer and captions. 8 | 9 | #### HTML 10 | 11 | There aren't many restrictions for the `html` elements you want to use to activate the Intense image viewer, the one mandatory attribute is either a `src`, `data-image` or a `href`, which needs to point to an image file. You can use `data-image` if you want to load in a different version of the image to the original source (higher resolution, for example). 12 | 13 | ```html 14 | 15 | 16 | 17 | 18 |
19 | ``` 20 | 21 | You can also pass through titles, and subcaptions, which will appear at the bottom right of the viewer. To do this, you use the `data-title` and `data-caption` attributes. 22 | 23 | ```html 24 | 25 | ``` 26 | 27 | #### JS 28 | 29 | Intense.js is fairly robust when it comes to assigning elements to be used, its as simple as passing them to the ```Intense``` function, once they have been rendered. You can do this with `document.querySelector` finding your elements however you like. 30 | 31 | ```html 32 | 33 | 34 | 41 | ``` 42 | 43 | Or doing multiple at once, with a classname. 44 | 45 | ```html 46 | 47 | 48 | 49 | 56 | ``` 57 | 58 | If you want, you can invert the direction of the interactions 59 | 60 | ```html 61 | 62 | 63 | 64 | 71 | ``` 72 | 73 | #### CSS 74 | There aren't any css restrictions. Although you'll want to avoid tainting the js files css with anything else (editing the base h1 tag, for instance), unless of course, thats what you want to customize. 75 | 76 | If you wish to use the `+` cursor, you can find the image in the demo folder, here's the css snippet. 77 | 78 | ```css 79 | .your-image-class { 80 | cursor: url('./you-image-directory/plus_cursor.png') 25 25, auto; 81 | } 82 | ``` 83 | 84 | #### Image/Example 85 | 86 | Here's a quick screenshot of Intense.js in action. You should really look at the [demo](http://tholman.com/intense-images) though, to get a full feel for the interactions. 87 | 88 | ![Intense.js in action](http://i.imgur.com/C98D6tw.png "Image Viewer") 89 | 90 | ### Browser support 91 | 92 | Intense has been tested in the latest stable builds of Safari, Chrome and Firefox. It "should work" in Internet Explorer 9 and up as well. 93 | 94 | ### Other frameworks 95 | 96 | If you're using React, check out [react-intense](https://github.com/brycedorn/react-intense)! 97 | 98 | ### License 99 | 100 | The MIT License (MIT) 101 | 102 | Copyright (C) 2016 ~ [Tim Holman](http://tholman.com) ~ timothy.w.holman@gmail.com 103 | -------------------------------------------------------------------------------- /intense.min.js: -------------------------------------------------------------------------------- 1 | window.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(e){window.setTimeout(e,1e3/60)}}(),window.cancelRequestAnimFrame=function(){return window.cancelAnimationFrame||window.webkitCancelRequestAnimationFrame||window.mozCancelRequestAnimationFrame||window.oCancelRequestAnimationFrame||window.msCancelRequestAnimationFrame||clearTimeout}();var Intense=function(){"use strict";function e(e,n){for(var t in n)t in e||(e[t]=n[t]);return e}function n(e,n){for(var t in n)e.style[t]=n[t]}function t(e){var n=window.innerHeight/e.h;if(e.w*n>window.innerWidth)return{w:e.w*n,h:e.h*n,fit:!0};var t=window.innerWidth/e.w;return{w:e.w*t,h:e.h*t,fit:!1}}function i(e){var n;if(e.length)for(n=0;n window.innerWidth) { 81 | return { 82 | w: source.w * heightRatio, 83 | h: source.h * heightRatio, 84 | fit: true 85 | }; 86 | } else { 87 | var widthRatio = window.innerWidth / source.w; 88 | return { w: source.w * widthRatio, h: source.h * widthRatio, fit: false }; 89 | } 90 | } 91 | 92 | /* ------------------------- 93 | /* APP 94 | /* -------------------------*/ 95 | 96 | function startTracking(passedElements) { 97 | var i; 98 | 99 | // If passed an array of elements, assign tracking to all. 100 | if (passedElements.length) { 101 | // Loop and assign 102 | for (i = 0; i < passedElements.length; i++) { 103 | track(passedElements[i]); 104 | } 105 | } else { 106 | track(passedElements); 107 | } 108 | } 109 | 110 | function track(element) { 111 | // Element needs a src at minumun. 112 | if (element.getAttribute("data-image") || element.src || element.href) { 113 | element.addEventListener( 114 | "click", 115 | function(e) { 116 | if (element.tagName === "A") { 117 | e.preventDefault(); 118 | } 119 | if (!active) { 120 | init(this); 121 | } 122 | }, 123 | false 124 | ); 125 | } 126 | } 127 | 128 | function start() { 129 | loop(); 130 | } 131 | 132 | function stop() { 133 | cancelRequestAnimFrame(looper); 134 | } 135 | 136 | function loop() { 137 | looper = requestAnimFrame(loop); 138 | positionTarget(); 139 | } 140 | 141 | // Lock scroll on the document body. 142 | function lockBody() { 143 | overflowValue = document.body.style.overflow; 144 | document.body.style.overflow = "hidden"; 145 | } 146 | 147 | // Unlock scroll on the document body. 148 | function unlockBody() { 149 | document.body.style.overflow = overflowValue; 150 | } 151 | 152 | function setState(element, newClassName) { 153 | if (element) { 154 | element.className = element.className.replace("intense--loading", ""); 155 | element.className = element.className.replace("intense--viewing", ""); 156 | element.className += " " + newClassName; 157 | } else { 158 | // Remove element with class .view 159 | var elems = document.querySelectorAll(".intense--viewing"); 160 | [].forEach.call(elems, function(el) { 161 | el.className = el.className.replace("intense--viewing", "").trim(); 162 | }); 163 | } 164 | } 165 | 166 | function createViewer(title, caption) { 167 | /* 168 | * Container 169 | */ 170 | var containerProperties = { 171 | backgroundColor: "rgba(0,0,0,0.8)", 172 | width: "100%", 173 | height: "100%", 174 | position: "fixed", 175 | top: "0px", 176 | left: "0px", 177 | overflow: "hidden", 178 | zIndex: "999999", 179 | margin: "0px", 180 | webkitTransition: "opacity 150ms cubic-bezier( 0, 0, .26, 1 )", 181 | MozTransition: "opacity 150ms cubic-bezier( 0, 0, .26, 1 )", 182 | transition: "opacity 150ms cubic-bezier( 0, 0, .26, 1 )", 183 | webkitBackfaceVisibility: "hidden", 184 | opacity: "0" 185 | }; 186 | container = document.createElement("figure"); 187 | container.appendChild(target); 188 | applyProperties(container, containerProperties); 189 | 190 | var imageProperties = { 191 | cursor: 192 | 'url( "data:image/png;base64,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" ) 25 25, no-drop' 193 | }; 194 | applyProperties(target, imageProperties); 195 | 196 | /* 197 | * Caption Container 198 | */ 199 | var captionContainerProperties = { 200 | fontFamily: 'Georgia, Times, "Times New Roman", serif', 201 | position: "fixed", 202 | bottom: "0px", 203 | left: "0px", 204 | padding: "20px", 205 | color: "#fff", 206 | wordSpacing: "0.2px", 207 | webkitFontSmoothing: "antialiased", 208 | textShadow: "-1px 0px 1px rgba(0,0,0,0.4)" 209 | }; 210 | var captionContainer = document.createElement("figcaption"); 211 | applyProperties(captionContainer, captionContainerProperties); 212 | 213 | /* 214 | * Caption Title 215 | */ 216 | if (title) { 217 | var captionTitleProperties = { 218 | margin: "0px", 219 | padding: "0px", 220 | fontWeight: "normal", 221 | fontSize: "40px", 222 | letterSpacing: "0.5px", 223 | lineHeight: "35px", 224 | textAlign: "left" 225 | }; 226 | var captionTitle = document.createElement("h1"); 227 | applyProperties(captionTitle, captionTitleProperties); 228 | captionTitle.innerHTML = title; 229 | captionContainer.appendChild(captionTitle); 230 | } 231 | 232 | if (caption) { 233 | var captionTextProperties = { 234 | margin: "0px", 235 | padding: "0px", 236 | fontWeight: "normal", 237 | fontSize: "20px", 238 | letterSpacing: "0.1px", 239 | maxWidth: "500px", 240 | textAlign: "left", 241 | background: "none", 242 | marginTop: "5px" 243 | }; 244 | var captionText = document.createElement("h2"); 245 | applyProperties(captionText, captionTextProperties); 246 | captionText.innerHTML = caption; 247 | captionContainer.appendChild(captionText); 248 | } 249 | 250 | container.appendChild(captionContainer); 251 | 252 | setDimensions(); 253 | 254 | mouse.xCurr = mouse.xDest = window.innerWidth / 2; 255 | mouse.yCurr = mouse.yDest = window.innerHeight / 2; 256 | 257 | document.body.appendChild(container); 258 | setTimeout(function() { 259 | container.style["opacity"] = "1"; 260 | }, 10); 261 | } 262 | 263 | function removeViewer() { 264 | unlockBody(); 265 | unbindEvents(); 266 | stop(); 267 | document.body.removeChild(container); 268 | active = false; 269 | setState(false); 270 | } 271 | 272 | function setDimensions() { 273 | // Manually set height to stop bug where 274 | var imageDimensions = getFit(sourceDimensions); 275 | target.width = imageDimensions.w; 276 | target.height = imageDimensions.h; 277 | horizontalOrientation = imageDimensions.fit; 278 | 279 | targetDimensions = { w: target.width, h: target.height }; 280 | containerDimensions = { w: window.innerWidth, h: window.innerHeight }; 281 | overflowArea = { 282 | x: containerDimensions.w - targetDimensions.w, 283 | y: containerDimensions.h - targetDimensions.h 284 | }; 285 | } 286 | 287 | function init(element) { 288 | setState(element, "intense--loading"); 289 | var imageSource = 290 | element.getAttribute("data-image") || element.src || element.href; 291 | var title = element.getAttribute("data-title") || element.title; 292 | var caption = element.getAttribute("data-caption"); 293 | 294 | // Clear old onload message 295 | if (image) { 296 | image.onload = null; 297 | } 298 | 299 | image = new Image(); 300 | image.onload = function() { 301 | sourceDimensions = { w: image.width, h: image.height }; // Save original dimensions for later. 302 | target = this; 303 | createViewer(title, caption); 304 | lockBody(); 305 | bindEvents(); 306 | loop(); 307 | 308 | setState(element, "intense--viewing"); 309 | }; 310 | 311 | image.src = imageSource; 312 | } 313 | 314 | function bindEvents() { 315 | container.addEventListener("mousemove", onMouseMove, false); 316 | container.addEventListener("touchmove", onTouchMove, false); 317 | window.addEventListener("resize", setDimensions, false); 318 | window.addEventListener("keyup", onKeyUp, false); 319 | target.addEventListener("click", removeViewer, false); 320 | } 321 | 322 | function unbindEvents() { 323 | container.removeEventListener("mousemove", onMouseMove, false); 324 | container.removeEventListener("touchmove", onTouchMove, false); 325 | window.removeEventListener("resize", setDimensions, false); 326 | window.removeEventListener("keyup", onKeyUp, false); 327 | target.removeEventListener("click", removeViewer, false); 328 | } 329 | 330 | function onMouseMove(event) { 331 | mouse.xDest = event.clientX; 332 | mouse.yDest = event.clientY; 333 | } 334 | 335 | function onTouchMove(event) { 336 | event.preventDefault(); // Needed to keep this event firing. 337 | mouse.xDest = window.innerWidth - event.touches[0].clientX; 338 | mouse.yDest = window.innerHeight - event.touches[0].clientY; 339 | } 340 | 341 | // Exit on excape key pressed; 342 | function onKeyUp(event) { 343 | event.preventDefault(); 344 | if (event.keyCode === KEYCODE_ESC) { 345 | removeViewer(); 346 | } 347 | } 348 | 349 | function positionTarget() { 350 | mouse.xCurr += (mouse.xDest - mouse.xCurr) * 0.05; 351 | mouse.yCurr += (mouse.yDest - mouse.yCurr) * 0.05; 352 | 353 | if (horizontalOrientation === true) { 354 | // HORIZONTAL SCANNING 355 | currentPosition += mouse.xCurr - currentPosition; 356 | if (mouse.xCurr !== lastPosition) { 357 | var position = parseFloat( 358 | calcPosition(currentPosition, containerDimensions.w) 359 | ); 360 | position = overflowArea.x * position; 361 | target.style["webkitTransform"] = "translate(" + position + "px, 0px)"; 362 | target.style["MozTransform"] = "translate(" + position + "px, 0px)"; 363 | target.style["msTransform"] = "translate(" + position + "px, 0px)"; 364 | lastPosition = mouse.xCurr; 365 | } 366 | } else if (horizontalOrientation === false) { 367 | // VERTICAL SCANNING 368 | currentPosition += mouse.yCurr - currentPosition; 369 | if (mouse.yCurr !== lastPosition) { 370 | var position = parseFloat( 371 | calcPosition(currentPosition, containerDimensions.h) 372 | ); 373 | position = overflowArea.y * position; 374 | target.style["webkitTransform"] = "translate( 0px, " + position + "px)"; 375 | target.style["MozTransform"] = "translate( 0px, " + position + "px)"; 376 | target.style["msTransform"] = "translate( 0px, " + position + "px)"; 377 | lastPosition = mouse.yCurr; 378 | } 379 | } 380 | 381 | function calcPosition(current, total) { 382 | return invertInteractionDirection 383 | ? (total - current) / total 384 | : current / total; 385 | } 386 | } 387 | 388 | function config(options) { 389 | if ("invertInteractionDirection" in options) 390 | invertInteractionDirection = options.invertInteractionDirection; 391 | } 392 | 393 | function main(element, configOptions) { 394 | // Parse arguments 395 | if (!element) { 396 | throw "You need to pass an element!"; 397 | } 398 | 399 | // If they have a config, use it! 400 | if (configOptions) { 401 | config(configOptions); 402 | } 403 | 404 | startTracking(element); 405 | } 406 | 407 | return extend(main, { 408 | resize: setDimensions, 409 | start: start, 410 | stop: stop, 411 | config: config 412 | }); 413 | })(); 414 | 415 | if (typeof module !== "undefined" && module.exports) { 416 | module.exports = Intense; 417 | } 418 | --------------------------------------------------------------------------------