├── .gitignore ├── README.md ├── css ├── component.css ├── demo.css └── normalize.css ├── favicon.ico ├── img ├── 1.jpg ├── 2.jpg ├── 3.jpg ├── 4.jpg ├── 5.jpg ├── 6.jpg ├── close.cur ├── close.png ├── map.png ├── pins.svg ├── related │ ├── ImageTiltEffect.jpg │ └── TooltipStylesInspiration.png └── sponsor │ └── AcuityScheduling_logo.svg ├── index.html └── js ├── imagesloaded.pkgd.min.js ├── lunar.js └── main.js /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Simple Interactive Points Effect 2 | 3 | An interactive transparency background effect that makes images visible when specific points are hovered, showing some content once clicked. 4 | 5 | [Article on Codrops](http://tympanus.net/codrops/?p=27459) 6 | 7 | [Demo](http://tympanus.net/Development/InteractivePoints/) 8 | 9 | ![Featured Image Interactive Points](http://tympanus.net/codrops/wp-content/uploads/2016/07/InteractivePoints_800x600.jpg) 10 | 11 | ## Sponsor 12 | 13 | This demo is sponsored by [Acuity Scheduling](https://goo.gl/VqOfus). 14 | 15 | ## License 16 | 17 | Integrate or build upon it for free in your personal or commercial projects. Don't republish, redistribute or sell "as-is". 18 | 19 | Read more here: [License](http://tympanus.net/codrops/licensing/) 20 | 21 | ## Credits 22 | 23 | - [Lunar.js](https://github.com/toddmotto/lunar) by Todd Motto: SVG class module for has/add/remove/toggleClass 24 | 25 | - [Map](https://www.openstreetmap.org/way/4358417#map=18/51.50980/-0.13000) by OpenStreetMap®. OpenStreetMap® is open data, licensed under the [Open Data Commons Open Database License (ODbL)](http://opendatacommons.org/licenses/odbl/) by the [OpenStreetMap Foundation (OSMF)](OpenStreetMap Foundation). Read more here: [https://www.openstreetmap.org/copyright](https://www.openstreetmap.org/copyright) 26 | 27 | - Location pin icon made by [Madebyoliver](http://www.flaticon.com/authors/madebyoliver "Madebyoliver") from [www.flaticon.com](http://www.flaticon.com "Flaticon") is licensed by [CC 3.0 BY](http://creativecommons.org/licenses/by/3.0/ "Creative Commons BY 3.0") 28 | 29 | - Vintage London images by [Stockholm Transport Museum](https://www.flickr.com/photos/stockholmtransportmuseum_commons/), [London, England album](https://www.flickr.com/photos/stockholmtransportmuseum_commons/albums/72157627860632062). 30 | 31 | ## Misc 32 | 33 | Follow Codrops: [Twitter](http://www.twitter.com/codrops), [Facebook](http://www.facebook.com/pages/Codrops/159107397912), [Google+](https://plus.google.com/101095823814290637419), [GitHub](https://github.com/codrops), [Pinterest](http://www.pinterest.com/codrops/) 34 | 35 | [© Codrops 2016](http://www.codrops.com) 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /css/component.css: -------------------------------------------------------------------------------- 1 | .interactive-points { 2 | position: relative; 3 | display: inline-block; 4 | overflow: hidden; 5 | width: 100%; 6 | margin-bottom: -0.4em; 7 | background: #cfced7; 8 | } 9 | 10 | .interactive-points:focus { 11 | outline: none; 12 | } 13 | 14 | .backgrounds, 15 | .background__element { 16 | position: relative; 17 | width: 100%; 18 | } 19 | 20 | .background__element { 21 | height: 50vh; 22 | background-repeat: no-repeat; 23 | background-position: 50% 50%; 24 | background-size: cover; 25 | } 26 | 27 | .static { 28 | position: relative; 29 | display: block; 30 | margin: 0 auto; 31 | opacity: 0.5; 32 | } 33 | 34 | .points { 35 | position: absolute; 36 | top: 0; 37 | left: 0; 38 | display: none; 39 | } 40 | 41 | .static, 42 | .points { 43 | width: 100%; 44 | height: auto; 45 | } 46 | 47 | @media screen and (min-aspect-ratio: 1885/1000) { 48 | .static, 49 | .points { 50 | width: auto; 51 | height: calc(100vh - 6em); 52 | min-height: 500px; 53 | } 54 | } 55 | 56 | .points { 57 | left: 50%; 58 | -webkit-transform: translate3d(-50%,0,0); 59 | transform: translate3d(-50%,0,0); 60 | } 61 | 62 | .point { 63 | cursor: pointer; 64 | fill: #28282f; 65 | -webkit-transition: opacity 0.3s, -webkit-transform 0.3s, fill 0.3s; 66 | transition: opacity 0.3s, transform 0.3s, fill 0.3s; 67 | -webkit-transition-timing-function: cubic-bezier(0.2,1,0.3,1); 68 | transition-timing-function: cubic-bezier(0.2,1,0.3,1); 69 | } 70 | 71 | .point--active { 72 | fill: #408283; 73 | -webkit-transform: scale3d(1.3,1.3,1); 74 | transform: scale3d(1.3,1.3,1); 75 | } 76 | 77 | .point--hide { 78 | opacity: 0; 79 | pointer-events: none; 80 | -webkit-transform: translate3d(0,10px,0); 81 | transform: translate3d(0,10px,0); 82 | } 83 | 84 | .points-tooltips, 85 | .points-content { 86 | position: absolute; 87 | bottom: 0; 88 | left: 0; 89 | width: 100%; 90 | height: 100%; 91 | pointer-events: none; 92 | } 93 | 94 | .points-tooltips { 95 | display: -webkit-box; 96 | display: -ms-flexbox; 97 | display: flex; 98 | -webkit-box-orient: vertical; 99 | -webkit-box-direction: normal; 100 | -ms-flex-direction: column; 101 | flex-direction: column; 102 | -webkit-box-pack: end; 103 | -ms-flex-pack: end; 104 | justify-content: flex-end; 105 | } 106 | 107 | .point-tooltip { 108 | height: 50vh; 109 | } 110 | 111 | .point-tooltip__title { 112 | font-family: 'Source Serif Pro', serif; 113 | font-size: 1.5em; 114 | line-height: 1; 115 | margin: 0 0 0.15em; 116 | display: inline-block; 117 | background: #28282f; 118 | padding: 5px; 119 | } 120 | 121 | .point-tooltip__description { 122 | font-size: 0.85em; 123 | font-weight: 500; 124 | margin: 0; 125 | line-height: 1; 126 | display: inline-block; 127 | background: #28282f; 128 | padding: 5px; 129 | } 130 | 131 | .points-content { 132 | -webkit-transition: background 0.1s; 133 | transition: background 0.1s; 134 | } 135 | 136 | .points-content--open { 137 | cursor: url(img/close.cur), pointer; 138 | pointer-events: auto; 139 | background: rgba(50,49,59,0.6); 140 | } 141 | 142 | @supports (cursor: zoom-in) { 143 | .points-content--open { 144 | cursor: url(../img/close.png) 12 6, pointer; 145 | } 146 | } 147 | 148 | .point-content { 149 | font-size: 1.25em; 150 | position: absolute; 151 | bottom: 0; 152 | left: 0; 153 | width: 100%; 154 | min-width: 300px; 155 | padding: 0 0 3em 3em; 156 | opacity: 0; 157 | } 158 | 159 | .point-content--current { 160 | pointer-events: auto; 161 | opacity: 1; 162 | } 163 | 164 | .point-content__title { 165 | font-family: 'Source Serif Pro', serif; 166 | font-size: 2.25em; 167 | margin: 0; 168 | text-shadow: 0 1px 5px rgba(0,0,0,0.2); 169 | } 170 | 171 | .point-content__subtitle { 172 | font-family: 'Source Serif Pro', serif; 173 | font-weight: bold; 174 | margin: 0.25em 0 0; 175 | display: inline-block; 176 | background: #408283; 177 | color: #28282f; 178 | padding: 0 10px; 179 | line-height: 1.5; 180 | } 181 | 182 | .point-content__text { 183 | font-weight: 500; 184 | margin: 1em 0 0 0; 185 | } 186 | 187 | .point-content > * { 188 | opacity: 0; 189 | -webkit-transform: translate3d(0,-40px,0); 190 | transform: translate3d(0,-40px,0); 191 | -webkit-transition: opacity 0.3s, -webkit-transform 0.3s; 192 | transition: opacity 0.3s, transform 0.3s; 193 | } 194 | 195 | .point-content--current > * { 196 | opacity: 1; 197 | -webkit-transform: translate3d(0,0,0); 198 | transform: translate3d(0,0,0); 199 | } 200 | 201 | .point-content--current > *:first-child { 202 | -webkit-transition-delay: 0.1s; 203 | transition-delay: 0.1s; 204 | } 205 | 206 | .point-content--current > *:nth-child(2) { 207 | -webkit-transition-delay: 0.05s; 208 | transition-delay: 0.05s; 209 | } 210 | 211 | /* Second example */ 212 | .interactive-points--alter .point-content { 213 | text-align: right; 214 | left: auto; 215 | right: 0; 216 | padding: 0 3em 3em; 217 | } 218 | 219 | @media screen and (min-width: 52.375em) { 220 | .point-content { 221 | width: 50%; 222 | } 223 | .js .points { 224 | display: block; 225 | } 226 | .js .backgrounds, 227 | .js .background__element { 228 | position: absolute; 229 | top: 0; 230 | left: 0; 231 | width: 100%; 232 | height: 100%; 233 | } 234 | .js .background__element { 235 | opacity: 0; 236 | -webkit-transition: opacity 0.1s; 237 | transition: opacity 0.1s; 238 | } 239 | .js .points-tooltip { 240 | display: block; 241 | } 242 | .js .point-tooltip { 243 | position: absolute; 244 | margin: 0.75em 0 0 0.25em; 245 | opacity: 0; 246 | -webkit-transform: translate3d(0,10px,0); 247 | transform: translate3d(0,10px,0); 248 | -webkit-transition: opacity 0.3s, -webkit-transform 0.3s; 249 | transition: opacity 0.3s, transform 0.3s; 250 | } 251 | .js .point-tooltip--current { 252 | opacity: 1; 253 | -webkit-transform: translate3d(0,0,0); 254 | transform: translate3d(0,0,0); 255 | } 256 | } 257 | 258 | 259 | 260 | -------------------------------------------------------------------------------- /css/demo.css: -------------------------------------------------------------------------------- 1 | *, *::after, *::before { -webkit-box-sizing: border-box; box-sizing: border-box; } 2 | 3 | body { 4 | font-family: 'Avenir Next', Avenir, 'Helvetica Neue', Helvetica, Arial, sans-serif; 5 | color: #fff; 6 | background: #34343d; 7 | -webkit-font-smoothing: antialiased; 8 | -moz-osx-font-smoothing: grayscale; 9 | text-align: center; 10 | } 11 | 12 | a { 13 | outline: none; 14 | color: #60B8B9; 15 | text-decoration: none; 16 | } 17 | 18 | a:hover, a:focus { 19 | color: #fff; 20 | } 21 | 22 | .hidden { 23 | position: absolute; 24 | overflow: hidden; 25 | width: 0; 26 | height: 0; 27 | pointer-events: none; 28 | } 29 | 30 | .message { 31 | font-weight: bold; 32 | color: #914a58; 33 | background: #f0d4d8; 34 | font-size: 0.85em; 35 | margin: 0; 36 | padding: 1em; 37 | display: none; 38 | } 39 | 40 | /* Icons */ 41 | .icon-link { 42 | padding: 0 0.5em; 43 | margin: 0 0 0 auto; 44 | font-size: 0.85em; 45 | white-space: nowrap; 46 | } 47 | 48 | .icon { 49 | display: inline-block; 50 | vertical-align: middle; 51 | width: 1.5em; 52 | height: 1.5em; 53 | margin: 0 auto; 54 | fill: currentColor; 55 | } 56 | 57 | .icon-text { 58 | line-height: 1; 59 | vertical-align: middle; 60 | padding: 0.35em; 61 | font-weight: bold; 62 | display: inline-block; 63 | } 64 | 65 | main { 66 | max-width: 1885px; 67 | display: inline-block; 68 | margin: 0 auto; 69 | position: relative; 70 | text-align: left; 71 | } 72 | 73 | /* Header */ 74 | .codrops-header { 75 | position: relative; 76 | padding: 1em; 77 | width: 100%; 78 | display: -webkit-box; 79 | display: -ms-flexbox; 80 | display: -webkit-flex; 81 | display: flex; 82 | -webkit-box-orient: horizontal; 83 | -webkit-box-direction: normal; 84 | -ms-flex-direction: row; 85 | -webkit-flex-direction: row; 86 | flex-direction: row; 87 | -webkit-align-items: center; 88 | align-items: center; 89 | z-index: 10; 90 | background: #28282f; 91 | } 92 | 93 | .codrops-header__title { 94 | margin: 0; 95 | letter-spacing: -1px; 96 | font-size: 1.65em; 97 | white-space: nowrap; 98 | line-height: 1; 99 | font-family: 'Source Serif Pro', serif; 100 | } 101 | 102 | .codrops-header__tagline { 103 | margin: 0 0 0 1.5em; 104 | color: #495050; 105 | font-weight: bold; 106 | } 107 | 108 | /* Top Navigation Style */ 109 | .codrops-links { 110 | position: relative; 111 | display: inline-block; 112 | text-align: center; 113 | white-space: nowrap; 114 | font-size: 0.8em; 115 | margin: 0 1em 0 0; 116 | } 117 | 118 | .codrops-links::after { 119 | position: absolute; 120 | top: 15%; 121 | left: 50%; 122 | width: 1px; 123 | height: 70%; 124 | background: currentColor; 125 | opacity: 0.2; 126 | content: ''; 127 | -webkit-transform: rotate3d(0,0,1,22.5deg); 128 | transform: rotate3d(0,0,1,22.5deg); 129 | } 130 | 131 | .codrops-icon { 132 | display: inline-block; 133 | margin: 0.5em; 134 | padding: 0.5em; 135 | } 136 | 137 | /* Demo links */ 138 | .codrops-demos { 139 | margin: 0 0 0 auto; 140 | text-align: right; 141 | } 142 | 143 | .codrops-demos a { 144 | display: inline-block; 145 | margin: 0 0.5em; 146 | font-weight: bold; 147 | } 148 | 149 | .codrops-demos a.current-demo { 150 | color: #28282f; 151 | } 152 | 153 | /* Content */ 154 | .content { 155 | background: #28282f; 156 | } 157 | 158 | .content__inner { 159 | max-width: 1000px; 160 | margin: 0 auto; 161 | padding: 8em 10% 4em; 162 | } 163 | 164 | .content__title, 165 | .content__subtitle { 166 | font-family: 'Source Serif Pro', serif; 167 | } 168 | 169 | .content__title { 170 | font-size: 3em; 171 | margin: 0; 172 | } 173 | 174 | .content__subtitle { 175 | font-size: 2em; 176 | font-weight: normal; 177 | margin: 0.25em 0 0; 178 | color: #9f9da7; 179 | } 180 | 181 | .content p { 182 | font-size: 1.175em; 183 | line-height: 1.6; 184 | margin: 1.5em 0; 185 | } 186 | 187 | p.margin-paragraph { 188 | margin: 8em 0 1.5em; 189 | } 190 | 191 | /* Related demos */ 192 | .content--related { 193 | padding: 4em 1em; 194 | text-align: center; 195 | font-weight: bold; 196 | background: #1c1c21; 197 | color: #495050; 198 | } 199 | 200 | .content--related a:hover, 201 | .content--related a:focus { 202 | color: #fff; 203 | } 204 | 205 | .media-item { 206 | display: inline-block; 207 | padding: 1em; 208 | vertical-align: top; 209 | -webkit-transition: color 0.3s; 210 | transition: color 0.3s; 211 | } 212 | 213 | .media-item__img { 214 | max-width: 100%; 215 | opacity: 0.3; 216 | -webkit-transition: opacity 0.3s; 217 | transition: opacity 0.3s; 218 | } 219 | 220 | .media-item:hover .media-item__img, 221 | .media-item:focus .media-item__img { 222 | opacity: 1; 223 | } 224 | 225 | .media-item__title { 226 | margin: 0; 227 | padding: 0.5em; 228 | font-size: 1em; 229 | } 230 | 231 | /* Sponsor */ 232 | .pater { 233 | display: none; 234 | position: relative; 235 | background: rgba(96,184,185,0.6); 236 | padding: 2.5em 1em 2.5em; 237 | width: 100%; 238 | pointer-events: auto; 239 | } 240 | 241 | .pater:focus { 242 | outline: none; 243 | } 244 | 245 | .pater::after { 246 | content: 'Sponsored by'; 247 | position: absolute; 248 | top: 20px; 249 | left: 20px; 250 | color: #408283; 251 | font-size: 0.65em; 252 | font-weight: bold; 253 | } 254 | 255 | .pater__img { 256 | max-width: 100%; 257 | } 258 | 259 | .pater__title { 260 | font-size: 1em; 261 | color: #fff; 262 | margin: 0 0 0.25em 10px; 263 | } 264 | 265 | .pater__description { 266 | color: #1a2638; 267 | font-size: 0.85em; 268 | font-weight: 600; 269 | margin: 0 0 0 10px; 270 | } 271 | 272 | .pater__description strong { 273 | color: #ffe38e; 274 | } 275 | 276 | .pater--responsive { 277 | display: block; 278 | } 279 | 280 | @media screen and (min-width: 52.375em) { 281 | .pater { 282 | display: block; 283 | position: absolute; 284 | bottom: 0; 285 | right: 0; 286 | width: 400px; 287 | padding: 2.5em 1em 1em; 288 | -webkit-transform: translate3d(0,3.5em,0); 289 | transform: translate3d(0,3.5em,0); 290 | -webkit-transition: background 0.3s, -webkit-transform 0.3s; 291 | transition: background 0.3s, transform 0.3s; 292 | } 293 | .points-content--open ~ .pater { 294 | pointer-events: none; 295 | -webkit-transform: translate3d(0,100%,0); 296 | transform: translate3d(0,100%,0); 297 | } 298 | .pater:focus, 299 | .pater:hover { 300 | background: rgba(96,184,185,1); 301 | -webkit-transform: translate3d(0,0,0); 302 | transform: translate3d(0,0,0); 303 | } 304 | .pater__img { 305 | -webkit-transform-origin: 0% 50%; 306 | transform-origin: 0% 50%; 307 | -webkit-transform: scale(1.5); 308 | transform: scale(1.5); 309 | -webkit-transition: -webkit-transform 0.3s; 310 | transition: transform 0.3s; 311 | } 312 | .pater:focus .pater__img, 313 | .pater:hover .pater__img { 314 | -webkit-transform: scale(1); 315 | transform: scale(1); 316 | } 317 | .pater__description { 318 | opacity: 0; 319 | -webkit-transform: translate3d(0,1em,0); 320 | transform: translate3d(0,1em,0); 321 | -webkit-transition: opacity 0.3s, -webkit-transform 0.3s; 322 | transition: opacity 0.3s, transform 0.3s; 323 | } 324 | 325 | .pater:focus .pater__description, 326 | .pater:hover .pater__description { 327 | -webkit-transform: translate3d(0,0,0); 328 | transform: translate3d(0,0,0); 329 | opacity: 1; 330 | } 331 | .pater--responsive { 332 | display: none; 333 | } 334 | } 335 | 336 | @media screen and (max-width: 52.375em) { 337 | .codrops-header { 338 | padding: 0.25em; 339 | font-size: 0.65em; 340 | } 341 | .codrops-header__tagline { 342 | display: none; 343 | } 344 | .content { 345 | font-size: 0.75em; 346 | } 347 | .message { 348 | display: block; 349 | } 350 | } 351 | -------------------------------------------------------------------------------- /css/normalize.css: -------------------------------------------------------------------------------- 1 | article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block;}audio,canvas,video{display:inline-block;}audio:not([controls]){display:none;height:0;}[hidden]{display:none;}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;}body{margin:0;}a:focus{outline:thin dotted;}a:active,a:hover{outline:0;}h1{font-size:2em;margin:0.67em 0;}abbr[title]{border-bottom:1px dotted;}b,strong{font-weight:bold;}dfn{font-style:italic;}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0;}mark{background:#ff0;color:#000;}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em;}pre{white-space:pre-wrap;}q{quotes:"\201C" "\201D" "\2018" "\2019";}small{font-size:80%;}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sup{top:-0.5em;}sub{bottom:-0.25em;}img{border:0;}svg:not(:root){overflow:hidden;}figure{margin:0;}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em;}legend{border:0;padding:0;}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0;}button,input{line-height:normal;}button,select{text-transform:none;}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;}button[disabled],html input[disabled]{cursor:default;}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none;}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}textarea{overflow:auto;vertical-align:top;}table{border-collapse:collapse;border-spacing:0;} -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/InteractivePoints/8419b6377dba812c39c7610688e2b0017a1e4676/favicon.ico -------------------------------------------------------------------------------- /img/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/InteractivePoints/8419b6377dba812c39c7610688e2b0017a1e4676/img/1.jpg -------------------------------------------------------------------------------- /img/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/InteractivePoints/8419b6377dba812c39c7610688e2b0017a1e4676/img/2.jpg -------------------------------------------------------------------------------- /img/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/InteractivePoints/8419b6377dba812c39c7610688e2b0017a1e4676/img/3.jpg -------------------------------------------------------------------------------- /img/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/InteractivePoints/8419b6377dba812c39c7610688e2b0017a1e4676/img/4.jpg -------------------------------------------------------------------------------- /img/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/InteractivePoints/8419b6377dba812c39c7610688e2b0017a1e4676/img/5.jpg -------------------------------------------------------------------------------- /img/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/InteractivePoints/8419b6377dba812c39c7610688e2b0017a1e4676/img/6.jpg -------------------------------------------------------------------------------- /img/close.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/InteractivePoints/8419b6377dba812c39c7610688e2b0017a1e4676/img/close.cur -------------------------------------------------------------------------------- /img/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/InteractivePoints/8419b6377dba812c39c7610688e2b0017a1e4676/img/close.png -------------------------------------------------------------------------------- /img/map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/InteractivePoints/8419b6377dba812c39c7610688e2b0017a1e4676/img/map.png -------------------------------------------------------------------------------- /img/pins.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | 10 | 11 | 13 | 15 | 17 | 19 | 21 | 23 | 24 | -------------------------------------------------------------------------------- /img/related/ImageTiltEffect.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/InteractivePoints/8419b6377dba812c39c7610688e2b0017a1e4676/img/related/ImageTiltEffect.jpg -------------------------------------------------------------------------------- /img/related/TooltipStylesInspiration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/InteractivePoints/8419b6377dba812c39c7610688e2b0017a1e4676/img/related/TooltipStylesInspiration.png -------------------------------------------------------------------------------- /img/sponsor/AcuityScheduling_logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 22 | Asset 1 23 | 24 | 25 | 26 | 29 | 32 | 34 | 37 | 41 | 43 | 44 | 46 | 48 | 52 | 53 | 56 | 58 | 60 | 62 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 73 | 74 | 76 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Interactive Points | Codrops 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 37 |
38 |
39 | 43 |

Interactive Points

44 |

Hover/click opaqueness background effect

45 | View on GitHub 46 |
47 |

Please view this demo on a larger screen.

48 |
49 | Map of London 50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 |
67 |

Rupert Street


The connection to London Bridge that no one knew about

68 |

Swiss Court


The crazy story of a rebel

69 |

Bear Street


Hidden gems and stories

70 |

Leicester Square


A never ending love story

71 |

Oxendon Street


No need to panik, rescue is close

72 |

Haymarket


Adventures to be discovered

73 |
74 |
75 |
76 |

The Rupert Connection

77 |

24th of February, 1927

78 |

Descended from astronomers encyclopaedia galactica from which we spring worldlets intelligent beings gathered by gravity billions.

79 |
80 |
81 |

Swiss Court, Miss

82 |

3rd of March, 1928

83 |

Hydrogen atoms circumnavigated Cambrian explosion, a mote of dust suspended in a sunbeam Hypatia.

84 |
85 |
86 |

Hiding in Bear Street

87 |

19th of July, 1927

88 |

From which we spring the ash of stellar alchemy from which we spring emerged into consciousness, great turbulent clouds rich in heavy atoms.

89 |
90 |
91 |

Leicester Square Love

92 |

12th of August, 1930

93 |

A mote of dust suspended in a sunbeam are creatures of the cosmos decipherment, Orion's sword corpus callosum galaxies shores of the cosmic ocean.

94 |
95 |
96 |

Oxendon of Oxes

97 |

26th of March, 1927

98 |

Extraplanetary concept of the number one vanquish the impossible culture trillion the sky calls to us.

99 |
100 |
101 |

Haymarket Forever

102 |

14th of January, 1927

103 |

Birth, are creatures of the cosmos Cambrian explosion colonies great turbulent clouds cosmos are creatures of the cosmos! Great turbulent clouds.

104 |
105 |
106 | 107 | Acuity Scheduling Logo 108 |

Developer Friendly Appointment Scheduling

109 |

Get your clients off their phones with online appointment scheduling from Acuity Scheduling and just 2 lines of code. Get started for free!

110 |
111 |
112 | 113 | Acuity Scheduling Logo 114 |

Developer Friendly Appointment Scheduling

115 |

Get your clients off their phones with online appointment scheduling from Acuity Scheduling and just 2 lines of code. Get started for free!

116 |
117 |
118 |
119 |

Seeing the Past in a New Light

120 |

Life can only be understood backwards;
but it must be lived forwards.

121 |

Extraordinary claims require extraordinary evidence billions upon billions, great turbulent clouds preserve and cherish that pale blue dot not a sunrise but a galaxyrise! The only home we've ever known as a patch of light. Courage of our questions ship of the imagination the only home we've ever known take root and flourish, billions upon billions, cosmos. Not a sunrise but a galaxyrise ship of the imagination birth vastness is bearable only through love at the edge of forever, not a sunrise but a galaxyrise, from which we spring! Not a sunrise but a galaxyrise Euclid with pretty stories for which there's little good evidence, the only home we've ever known a very small stage in a vast cosmic arena birth, the ash of stellar alchemy.

122 |

The following example shows some different configuration options:

123 |
124 |
125 |
126 | Map of London 127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 |
144 |

Rupert Street


The connection to London Bridge that no one knew about

145 |

Swiss Court


The crazy story of a rebel

146 |

Bear Street


Hidden gems and stories

147 |

Leicester Square


A never ending love story

148 |

Oxendon Street


No need to panik, rescue is close

149 |

Haymarket


Adventures to be discovered

150 |
151 |
152 |
153 |

The Rupert Connection

154 |

24th of February, 1927

155 |

Descended from astronomers encyclopaedia galactica from which we spring worldlets intelligent beings gathered by gravity billions.

156 |
157 |
158 |

Swiss Court, Miss

159 |

3rd of March, 1928

160 |

Hydrogen atoms circumnavigated Cambrian explosion, a mote of dust suspended in a sunbeam Hypatia.

161 |
162 |
163 |

Hiding in Bear Street

164 |

19th of July, 1927

165 |

From which we spring the ash of stellar alchemy from which we spring emerged into consciousness, great turbulent clouds rich in heavy atoms.

166 |
167 |
168 |

Leicester Square Love

169 |

12th of August, 1930

170 |

A mote of dust suspended in a sunbeam are creatures of the cosmos decipherment, Orion's sword corpus callosum galaxies shores of the cosmic ocean.

171 |
172 |
173 |

Oxendon of Oxes

174 |

26th of March, 1927

175 |

Extraplanetary concept of the number one vanquish the impossible culture trillion the sky calls to us.

176 |
177 |
178 |

Haymarket Forever

179 |

14th of January, 1927

180 |

Birth, are creatures of the cosmos Cambrian explosion colonies great turbulent clouds cosmos are creatures of the cosmos! Great turbulent clouds.

181 |
182 |
183 |
184 | 185 | 198 |
199 | 200 | 201 | 202 | 213 | 214 | 215 | -------------------------------------------------------------------------------- /js/imagesloaded.pkgd.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * imagesLoaded PACKAGED v4.1.0 3 | * JavaScript is all like "You images are done yet or what?" 4 | * MIT License 5 | */ 6 | 7 | !function(t,e){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",e):"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}(this,function(){function t(){}var e=t.prototype;return e.on=function(t,e){if(t&&e){var i=this._events=this._events||{},n=i[t]=i[t]||[];return-1==n.indexOf(e)&&n.push(e),this}},e.once=function(t,e){if(t&&e){this.on(t,e);var i=this._onceEvents=this._onceEvents||{},n=i[t]=i[t]||[];return n[e]=!0,this}},e.off=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=i.indexOf(e);return-1!=n&&i.splice(n,1),this}},e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=0,o=i[n];e=e||[];for(var r=this._onceEvents&&this._onceEvents[t];o;){var s=r&&r[o];s&&(this.off(t,o),delete r[o]),o.apply(this,e),n+=s?0:1,o=i[n]}return this}},t}),function(t,e){"use strict";"function"==typeof define&&define.amd?define(["ev-emitter/ev-emitter"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter")):t.imagesLoaded=e(t,t.EvEmitter)}(window,function(t,e){function i(t,e){for(var i in e)t[i]=e[i];return t}function n(t){var e=[];if(Array.isArray(t))e=t;else if("number"==typeof t.length)for(var i=0;i 0 ? this.wrapper.offsetWidth/this.options.viewportFactor : this.options.maxDistance; 88 | if( this.dmax < this.options.activeOn ) { 89 | this.options.activeOn = this.dmax-5; // todo 90 | } 91 | // Init/Bind events. 92 | this._initEvents(); 93 | } 94 | 95 | /** 96 | * Point options/settings. 97 | */ 98 | Point.prototype.options = { 99 | // Maximum opacity that the bgEl can have. 100 | maxOpacity : 1, 101 | // When the mouse is [activeOn]px away from the point, its image gets opacity = this.options.maxOpacity. 102 | activeOn : 20, 103 | // The distance from the mouse pointer to a Point where the opacity of the background element is 0. 104 | maxDistance : 100, 105 | // If viewportFactor is different than -1, then the maxDistance will be overwritten by [window´s width / viewportFactor] 106 | viewportFactor : -1, 107 | onActive : function() { return false; }, 108 | onInactive : function() { return false; }, 109 | onClick : function() { return false; } 110 | }; 111 | 112 | /** 113 | * Initialize/Bind events. 114 | */ 115 | Point.prototype._initEvents = function() { 116 | var self = this; 117 | 118 | // Mousemove event. 119 | this._throttleMousemove = throttle(function(ev) { 120 | requestAnimationFrame(function() { 121 | // Mouse position relative to the mapEl. 122 | var mousepos = getMousePos(ev); 123 | // Calculate the opacity value. 124 | if( self.bgEl ) { 125 | // Distance from the position of the point to the mouse position. 126 | var distance = distancePoints(mousepos.x - docScrolls.left, mousepos.y - docScrolls.top, self.position.x - docScrolls.left, self.position.y - docScrolls.top), 127 | // Convert this distance to a opacity value. (distance = 0 -> opacity = 1). 128 | opacity = self._distanceToOpacity(distance); 129 | 130 | self.bgEl.style.opacity = opacity; 131 | 132 | // Callback 133 | if( !self.isActive && opacity === self.options.maxOpacity ) { 134 | self.options.onActive(); 135 | self.isActive = true; 136 | } 137 | 138 | if( opacity !== self.options.maxOpacity && self.isActive ) { 139 | self.options.onInactive(); 140 | self.isActive = false; 141 | } 142 | } 143 | }); 144 | }, 20); 145 | this.wrapper.addEventListener('mousemove', this._throttleMousemove); 146 | 147 | // Clicking a point. 148 | this._click = function(ev) { 149 | // Callback. 150 | self.options.onClick(); 151 | }; 152 | this.el.addEventListener('click', this._click); 153 | 154 | // Window resize. 155 | this._throttleResize = throttle(function() { 156 | // Update Point´s position. 157 | self.position = self._updatePosition(); 158 | // Update dmax 159 | if( self.options.viewportFactor != -1 && self.options.viewportFactor > 0 ) { 160 | self.dmax = self.wrapper.offsetWidth/self.options.viewportFactor; 161 | } 162 | }, 100); 163 | window.addEventListener('resize', this._throttleResize); 164 | 165 | // Set the opacity of the bgEl to 0 when leaving the wrapper area.. 166 | this.wrapper.addEventListener('mouseleave', function() { 167 | if( !self.isActive ) { 168 | self.bgEl.style.opacity = 0; 169 | } 170 | }); 171 | }; 172 | 173 | /** 174 | * Update Point´s position. 175 | */ 176 | Point.prototype._updatePosition = function() { 177 | var rect = this.el.getBoundingClientRect(), bbox = this.el.getBBox(); 178 | // Also update origins.. 179 | this.el.style.transformOrigin = this.el.style.WebkitTransformOrigin = (bbox.x + rect.width/2) + 'px ' + (bbox.y + rect.height) + 'px'; 180 | return {x : rect.left + rect.width/2 + docScrolls.left, y : rect.top + rect.height/2 + docScrolls.top}; 181 | }; 182 | 183 | /** 184 | * Maps the distance to opacity. 185 | */ 186 | Point.prototype._distanceToOpacity = function(d) { 187 | return Math.min(Math.max(lineEq(this.options.maxOpacity, 0, this.options.activeOn, this.dmax, d), 0), this.options.maxOpacity); 188 | }; 189 | 190 | /** 191 | * Hides the Point. 192 | */ 193 | Point.prototype.hide = function() { 194 | lunar.addClass(this.el, 'point--hide'); 195 | }; 196 | 197 | /** 198 | * 199 | */ 200 | Point.prototype.show = function() { 201 | lunar.removeClass(this.el, 'point--hide') 202 | }; 203 | 204 | /** 205 | * 206 | */ 207 | Point.prototype.pause = function() { 208 | this.wrapper.removeEventListener('mousemove', this._throttleMousemove); 209 | }; 210 | 211 | /** 212 | * 213 | */ 214 | Point.prototype.resume = function() { 215 | this.wrapper.addEventListener('mousemove', this._throttleMousemove); 216 | }; 217 | 218 | /** 219 | * PointsMap obj. 220 | */ 221 | function PointsMap(el, options) { 222 | this.el = el; 223 | // Options/Settings. 224 | this.options = extend( {}, this.options ); 225 | extend( this.options, options ); 226 | 227 | // Backgrounds container. 228 | this.bgsWrapper = this.el.querySelector('.backgrounds'); 229 | if( !this.bgsWrapper ) { return; } 230 | 231 | // Background elements. 232 | this.bgElems = [].slice.call(this.bgsWrapper.querySelectorAll('.background__element')); 233 | // Total background elements. 234 | this.bgElemsTotal = this.bgElems.length; 235 | if( this.bgElemsTotal <= 1 ) { return; } 236 | 237 | // Points container. 238 | this.pointsWrapper = this.el.querySelector('.points'); 239 | if( !this.pointsWrapper || getComputedStyle(this.pointsWrapper, null).display === 'none' ) { return; } 240 | 241 | // Points tooltips 242 | this.tooltips = [].slice.call(this.el.querySelector('.points-tooltips').children); 243 | 244 | // Points´s content 245 | this.pointsContentWrapper = this.el.querySelector('.points-content'); 246 | this.contents = [].slice.call(this.pointsContentWrapper.children); 247 | 248 | // Init.. 249 | this._init(); 250 | } 251 | 252 | /** 253 | * PointsMap options/settings. 254 | */ 255 | PointsMap.prototype.options = { 256 | // Maximum opacity that the background element of a Point can have when the point is active (mouse gets closer to it). 257 | maxOpacityOnActive : 0.3, 258 | // The distance from the mouse pointer to a Point where the opacity of the background element is 0. 259 | maxDistance : 100, 260 | // If viewportFactor is different than -1, then the maxDistance will be overwritten by [point´s parent width / viewportFactor] 261 | viewportFactor : 9, 262 | // When the mouse is [activeOn]px away from one point, its image gets opacity = point.options.maxOpacity. 263 | activeOn : 30 264 | }; 265 | 266 | /** 267 | * Init. 268 | */ 269 | PointsMap.prototype._init = function() { 270 | var self = this, 271 | onLoaded = function() { 272 | // Create the Points. 273 | self._createPoints(); 274 | }; 275 | 276 | // Preload all images. 277 | imagesLoaded(this.bgsWrapper, { background: true }, onLoaded); 278 | 279 | // Init/Bind events. 280 | this._initEvents(); 281 | }; 282 | 283 | /** 284 | * Init/Bind events. 285 | */ 286 | PointsMap.prototype._initEvents = function() { 287 | var self = this; 288 | 289 | // Window resize. 290 | this._throttleResize = throttle(function() { 291 | // Update Document scroll values. 292 | docScrolls = {left : document.body.scrollLeft + document.documentElement.scrollLeft, top : document.body.scrollTop + document.documentElement.scrollTop}; 293 | }, 100); 294 | window.addEventListener('resize', this._throttleResize); 295 | 296 | // Close content. 297 | this._closeContent = function() { 298 | var currentPoint = self.points[self.currentPoint]; 299 | currentPoint.isActive = false; 300 | // Hide Point´s bgEl. 301 | currentPoint.bgEl.style.opacity = 0; 302 | // Hide content. 303 | self.pointsContentWrapper.classList.remove('points-content--open'); 304 | self.contents[self.currentPoint].classList.remove('point-content--current'); 305 | // Start mousemove event on Points. 306 | self._pointsAction('resume'); 307 | // Show all points. 308 | self._pointsAction('show'); 309 | }; 310 | this.pointsContentWrapper.addEventListener('click', this._closeContent); 311 | 312 | // Keyboard navigation events. 313 | this.el.addEventListener('keydown', function(ev) { 314 | var keyCode = ev.keyCode || ev.which; 315 | if( keyCode === 27 ) { 316 | self._closeContent(); 317 | } 318 | }); 319 | }; 320 | 321 | /** 322 | * Create the Points. 323 | */ 324 | PointsMap.prototype._createPoints = function() { 325 | this.points = []; 326 | 327 | var self = this; 328 | [].slice.call(this.pointsWrapper.querySelectorAll('.point')).forEach(function(point, pos) { 329 | var p = new Point(point, self.bgElems[pos], self.el, { 330 | maxOpacity : self.options.maxOpacityOnActive, 331 | activeOn : self.options.activeOn, 332 | maxDistance : self.options.maxDistance, 333 | viewportFactor : self.options.viewportFactor, 334 | onActive : function() { 335 | // Add class active (scales up the pin and changes the fill color). 336 | lunar.addClass(self.points[pos].el, 'point--active'); 337 | // Hide all other points. 338 | self._pointsAction('hide', pos); 339 | // Show tooltip. 340 | var tooltip = self.tooltips[pos]; 341 | tooltip.classList.add('point-tooltip--current'); 342 | // Position tooltip. 343 | var rect = self.points[pos].el.getBoundingClientRect(), 344 | bounds = self.el.getBoundingClientRect(); 345 | 346 | tooltip.style.left = rect.left - bounds.left + rect.width/2 + 'px'; 347 | tooltip.style.top = rect.top - bounds.top + rect.height + 'px'; 348 | }, 349 | onInactive : function() { 350 | lunar.removeClass(self.points[pos].el, 'point--active'); 351 | // Show all points. 352 | self._pointsAction('show', pos); 353 | // Hide tooltip. 354 | self.tooltips[pos].classList.remove('point-tooltip--current'); 355 | }, 356 | onClick : function() { 357 | self.currentPoint = pos; 358 | lunar.removeClass(self.points[pos].el, 'point--active'); 359 | // Hide the current point (and all other points). 360 | self._pointsAction('hide'); 361 | // Hide tooltip. 362 | self.tooltips[pos].classList.remove('point-tooltip--current'); 363 | // Stop mousemove event on Points. 364 | self._pointsAction('pause'); 365 | // Show Point´s bgEl. 366 | self.points[pos].bgEl.style.opacity = 1; 367 | // Show content. 368 | self.pointsContentWrapper.classList.add('points-content--open'); 369 | self.contents[pos].classList.add('point-content--current'); 370 | } 371 | }); 372 | self.points.push(p); 373 | }); 374 | }; 375 | 376 | /** 377 | * Calls a Point´s fn. Excludes the point with index = excludedPoint. 378 | */ 379 | PointsMap.prototype._pointsAction = function(action, excludedPoint) { 380 | for(var i = 0, len = this.points.length; i < len; ++i) { 381 | if( i !== excludedPoint ) { 382 | this.points[i][action](); 383 | } 384 | } 385 | }; 386 | 387 | window.PointsMap = PointsMap; 388 | document.documentElement.className = 'js'; 389 | 390 | })(window); --------------------------------------------------------------------------------