├── .gitignore ├── README.md ├── css ├── demo.css ├── demo1.css ├── demo2.css ├── demo3.css ├── demo4.css ├── demo5.css └── normalize.css ├── favicon.ico ├── index.html ├── index2.html ├── index3.html ├── index4.html ├── index5.html ├── js ├── anime.min.js ├── demo.js ├── demo1.js ├── demo2.js ├── demo3.js ├── demo4.js └── demo5.js └── pater ├── jetpack.png ├── jetpack_man.png └── pater.css /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Organic Shape Morph Ideas 2 | 3 | A small set of ideas for organic shape effects. The demos show some ways to use animated SVG morphs interactively on a website, including a menu hover and a content reveal effect. 4 | 5 | ![Organic Shape Morph Ideas](https://tympanus.net/codrops/wp-content/uploads/2017/09/OrganicShapeMorphIdeas.jpg) 6 | 7 | [Article on Codrops](https://tympanus.net/codrops/?p=32314) 8 | 9 | [Demo](http://tympanus.net/Development/ShapeMorphIdeas/) 10 | 11 | This demo is kindly sponsored by: [Jetpack Professional](http://go.hackingui.com/JetpackCodrops19092017), the only WordPress plugin you really need. 12 | 13 | ## Credits 14 | 15 | - [anime.js](http://anime-js.com/) by Julian Garnier 16 | - [Keyboard icon](https://thenounproject.com/term/keyboard/783/) by Paul te Kortschot from the Noun Project 17 | - Patterns from [Hero Patterns](http://www.heropatterns.com/) 18 | 19 | ## License 20 | This resource can be used freely if integrated or build upon in personal or commercial projects such as websites, web apps and web templates intended for sale. It is not allowed to take the resource "as-is" and sell it, redistribute, re-publish it, or sell "pluginized" versions of it. Free plugins built using this resource should have a visible mention and link to the original work. Always consider the licenses of all included libraries, scripts and images used. 21 | 22 | ## Misc 23 | 24 | Follow Codrops: [Twitter](http://www.twitter.com/codrops), [Facebook](http://www.facebook.com/codrops), [Google+](https://plus.google.com/101095823814290637419), [GitHub](https://github.com/codrops), [Pinterest](http://www.pinterest.com/codrops/), [Instagram](https://www.instagram.com/codropsss/) 25 | 26 | 27 | [© Codrops 2017](http://www.codrops.com) 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /css/demo.css: -------------------------------------------------------------------------------- 1 | *, 2 | *::after, 3 | *::before { 4 | box-sizing: border-box; 5 | } 6 | 7 | html { 8 | background: #fff; 9 | } 10 | 11 | body { 12 | font-family: 'Roboto', sans-serif; 13 | min-height: 100vh; 14 | color: #57585c; 15 | color: var(--color-text); 16 | background-color: #fff; 17 | background-color: var(--color-background); 18 | -webkit-font-smoothing: antialiased; 19 | -moz-osx-font-smoothing: grayscale; 20 | } 21 | 22 | /* Color schemes */ 23 | .demo-1 { 24 | --color-text: #d8d1d1; 25 | --color-background: #fff; 26 | --color-link: #72af3a; 27 | --color-link-hover: #d8d1d1; 28 | --color-info: #72af3a; 29 | } 30 | 31 | .demo-2 { 32 | --color-text: #333; 33 | --color-background: #bee897; 34 | --color-link: #72af3a; 35 | --color-link-hover: #485a36; 36 | --color-info: #fff; 37 | } 38 | 39 | .demo-3 { 40 | --color-text: #fff; 41 | --color-background: #193ccf; 42 | --color-link: #fff; 43 | --color-link-hover: #000; 44 | --color-info: #fff473; 45 | } 46 | 47 | .demo-4 { 48 | --color-text: #81838c; 49 | --color-background: #272927; 50 | --color-link: #96e23e; 51 | --color-link-hover: #fff; 52 | --color-info: #ea7836; 53 | } 54 | 55 | .demo-5 { 56 | --color-text: #fff; 57 | --color-background: #2b54ee; 58 | --color-link: #fff; 59 | --color-link-hover: #f7fb40; 60 | --color-info: #f7fb40; 61 | } 62 | 63 | /* Fade effect */ 64 | .js body { 65 | opacity: 0; 66 | transition: opacity 0.3s; 67 | 68 | } 69 | 70 | .js body.render { 71 | opacity: 1; 72 | } 73 | 74 | a { 75 | text-decoration: none; 76 | color: #5d93d8; 77 | color: var(--color-link); 78 | outline: none; 79 | } 80 | 81 | a:hover, 82 | a:focus { 83 | color: #423c2b; 84 | color: var(--color-link-hover); 85 | outline: none; 86 | } 87 | 88 | .hidden { 89 | position: absolute; 90 | overflow: hidden; 91 | width: 0; 92 | height: 0; 93 | pointer-events: none; 94 | } 95 | 96 | .message { 97 | background: var(--color-text); 98 | color: var(--color-background); 99 | text-align: center; 100 | padding: 1em; 101 | display: none; 102 | position: relative; 103 | z-index: 100; 104 | } 105 | 106 | /* Icons */ 107 | .icon { 108 | display: block; 109 | width: 1.5em; 110 | height: 1.5em; 111 | margin: 0 auto; 112 | fill: currentColor; 113 | } 114 | 115 | .icon--keyboard { 116 | display: none; 117 | } 118 | 119 | main { 120 | position: relative; 121 | width: 100%; 122 | } 123 | 124 | .content { 125 | position: relative; 126 | display: flex; 127 | justify-content: center; 128 | align-items: center; 129 | min-height: 100vh; 130 | margin: 0 auto; 131 | } 132 | 133 | .content--fixed { 134 | position: fixed; 135 | z-index: 10000; 136 | top: 0; 137 | left: 0; 138 | display: grid; 139 | align-content: space-between; 140 | width: 100%; 141 | max-width: none; 142 | height: 100vh; 143 | padding: 1.5em; 144 | pointer-events: none; 145 | grid-template-columns: 50% 50%; 146 | grid-template-rows: auto auto 4em; 147 | grid-template-areas: 'header ...' 148 | '... ...' 149 | 'github demos'; 150 | } 151 | 152 | .content--fixed a { 153 | pointer-events: auto; 154 | } 155 | 156 | /* Header */ 157 | .codrops-header { 158 | position: relative; 159 | z-index: 100; 160 | display: flex; 161 | flex-direction: row; 162 | align-items: flex-start; 163 | align-items: center; 164 | align-self: start; 165 | grid-area: header; 166 | justify-self: start; 167 | } 168 | 169 | .codrops-header__title { 170 | font-size: 1em; 171 | font-weight: bold; 172 | margin: 0; 173 | padding: 0.75em 0; 174 | } 175 | 176 | .info { 177 | margin: 0 0 0 1.25em; 178 | font-style: italic; 179 | color: var(--color-info); 180 | font-weight: bold; 181 | } 182 | 183 | .github { 184 | display: block; 185 | align-self: end; 186 | grid-area: github; 187 | justify-self: start; 188 | } 189 | 190 | .demos { 191 | position: relative; 192 | display: block; 193 | align-self: end; 194 | text-align: center; 195 | grid-area: demos; 196 | } 197 | 198 | .demo { 199 | margin: 0 0.15em; 200 | } 201 | 202 | .demo:hover, 203 | .demo:focus { 204 | opacity: 0.5; 205 | } 206 | 207 | .demo span { 208 | white-space: nowrap; 209 | text-transform: lowercase; 210 | pointer-events: none; 211 | } 212 | 213 | .demo span::before { 214 | content: '#'; 215 | } 216 | 217 | a.demo--current { 218 | pointer-events: none; 219 | } 220 | 221 | /* Top Navigation Style */ 222 | .codrops-links { 223 | position: relative; 224 | display: flex; 225 | justify-content: center; 226 | margin: 0 1em 0 0; 227 | text-align: center; 228 | white-space: nowrap; 229 | } 230 | 231 | .codrops-icon { 232 | display: inline-block; 233 | margin: 0.15em; 234 | padding: 0.25em; 235 | } 236 | 237 | .scene { 238 | position: fixed; 239 | top: 0; 240 | left: 0; 241 | width: 100%; 242 | height: 100vh; 243 | pointer-events: none; 244 | z-index: 1; 245 | } 246 | 247 | @media screen and (min-width: 55em) { 248 | .icon--keyboard { 249 | position: absolute; 250 | right: 0.55em; 251 | bottom: -30%; 252 | display: block; 253 | width: 54px; 254 | height: 46px; 255 | fill: var(--color-link); 256 | } 257 | .demos { 258 | display: flex; 259 | padding-right: 80px; 260 | justify-self: end; 261 | } 262 | .demo { 263 | display: block; 264 | width: 17px; 265 | height: 17px; 266 | margin: 0 4px; 267 | border-radius: 50%; 268 | background: var(--color-link); 269 | } 270 | a.demo--current { 271 | background: var(--color-link-hover); 272 | } 273 | .demo span { 274 | position: absolute; 275 | line-height: 1; 276 | right: 100%; 277 | display: none; 278 | margin: 0 1em 0 0; 279 | } 280 | .demo--current span { 281 | display: block; 282 | } 283 | } 284 | 285 | @media screen and (max-width: 55em) { 286 | html, 287 | body { 288 | overflow-x: hidden; 289 | width: 100vw; 290 | height: 100%; 291 | } 292 | .message { 293 | display: block; 294 | } 295 | .content { 296 | height: auto; 297 | min-height: 0; 298 | padding-bottom: 10em; 299 | flex-direction: column; 300 | } 301 | .content--fixed { 302 | position: relative; 303 | z-index: 1000; 304 | display: block; 305 | padding: 0.85em; 306 | } 307 | .codrops-header { 308 | flex-direction: column; 309 | align-items: center; 310 | } 311 | .codrops-header__title { 312 | font-weight: bold; 313 | padding-bottom: 0.25em; 314 | text-align: center; 315 | } 316 | .github { 317 | display: block; 318 | margin: 1em auto; 319 | } 320 | .codrops-links { 321 | margin: 0; 322 | } 323 | } 324 | -------------------------------------------------------------------------------- /css/demo1.css: -------------------------------------------------------------------------------- 1 | body.scene-hover { 2 | background-color: #000; 3 | } 4 | 5 | .scene { 6 | display: block; 7 | width: 50vh; 8 | height: 50vh; 9 | position: relative; 10 | pointer-events: auto; 11 | transition: transform 0.3s; 12 | } 13 | 14 | .scene-hover .scene { 15 | transform: scale3d(1.1,1.1,1); 16 | } 17 | 18 | .scene__bg { 19 | fill: #e7d2cd; 20 | } 21 | 22 | .scene__bgdots { 23 | fill: #c9bfbd; 24 | stroke: #8b8682; 25 | stroke-width: 1px; 26 | } 27 | 28 | .scene__overlay { 29 | fill: var(--color-link); 30 | } 31 | 32 | .scene-hover .scene__overlay { 33 | opacity: 0; 34 | } 35 | 36 | .scene__bacteria:first-of-type, 37 | .scene__bacteria:nth-of-type(2), 38 | .scene__bacteria:nth-of-type(3) { 39 | fill: #ac9893; 40 | } 41 | 42 | .scene__bacteria:nth-of-type(4), 43 | .scene__bacteria:nth-of-type(5) { 44 | fill: #625857; 45 | } 46 | 47 | .scene__bacteria:nth-of-type(6), 48 | .scene__bacteria:nth-of-type(7), 49 | .scene__bacteria:nth-of-type(8) { 50 | fill: #fff; 51 | stroke: #616161; 52 | } 53 | 54 | .scene__microscope { 55 | fill: #fff; 56 | pointer-events: none; 57 | } 58 | 59 | .scene-hover .scene__microscope { 60 | opacity: 0; 61 | } 62 | 63 | .intro { 64 | margin: 0 0 0 3em; 65 | } 66 | 67 | .intro__title { 68 | margin: 0; 69 | color: #181616; 70 | font-size: 1.85em; 71 | } 72 | 73 | .scene-hover .intro__title { 74 | color: #fff; 75 | } 76 | 77 | .intro__title-sub { 78 | display: block; 79 | font-weight: 400; 80 | font-size: 0.75em; 81 | } 82 | 83 | .intro__nav { 84 | margin: 1em 0 0 0; 85 | } 86 | 87 | .intro__nav-item:not(:last-child) { 88 | margin: 0 0.5em 0 0; 89 | } 90 | 91 | .intro__nav-item:not(:last-child)::after { 92 | content: '\25CF'; 93 | margin: 0 0 0 0.5em; 94 | } 95 | 96 | .intro__nav-item:not(:last-child):hover::after { 97 | color: var(--color-link); 98 | } 99 | 100 | @media screen and (max-width: 50em) { 101 | body { 102 | background-color: #000; 103 | } 104 | .scene { 105 | width: 200px; 106 | height: 200px; 107 | margin: 2em 0 0; 108 | } 109 | .scene__overlay, 110 | .scene__microscope { 111 | opacity: 0; 112 | } 113 | .intro { 114 | text-align: center; 115 | margin: 1em 0 0; 116 | } 117 | .intro__title { 118 | color: #fff; 119 | font-size: 1.25em; 120 | } 121 | .info { 122 | display: none; 123 | } 124 | .intro__nav-item { 125 | display: block; 126 | margin: 0.5em 0 0 !important; 127 | } 128 | .intro__nav-item:not(:last-child)::after { 129 | display: none; 130 | } 131 | } -------------------------------------------------------------------------------- /css/demo2.css: -------------------------------------------------------------------------------- 1 | .scene path { 2 | fill: #b9e194; 3 | } 4 | 5 | .menu { 6 | width: 100%; 7 | height: 100vh; 8 | display: flex; 9 | flex-direction: column; 10 | align-items: center; 11 | justify-content: center; 12 | position: relative; 13 | z-index: 900; 14 | padding-bottom: 10vh; 15 | color: #72ae3a; 16 | } 17 | 18 | .menu__title { 19 | font-weight: normal; 20 | text-transform: uppercase; 21 | letter-spacing: 0.325em; 22 | font-size: 1em; 23 | margin: 0 0 0.35em; 24 | padding: 0 0.25em 0.25em; 25 | border-bottom: 1px solid; 26 | } 27 | 28 | .menu__subtitle { 29 | text-transform: uppercase; 30 | font-size: 0.75em; 31 | letter-spacing: 0.225em; 32 | margin: 0 0 10vh; 33 | font-weight: normal; 34 | } 35 | 36 | .menu__item { 37 | font-family: 'Arapey', serif; 38 | color: #333; 39 | font-size: 2.5em; 40 | padding: 0.25em 0; 41 | } 42 | 43 | .menu__item:hover, 44 | .menu__item:focus { 45 | color: var(--color-link); 46 | } -------------------------------------------------------------------------------- /css/demo3.css: -------------------------------------------------------------------------------- 1 | .scene { 2 | background: #282886; 3 | } 4 | 5 | .scene path:first-child { 6 | fill: #4f4fea; 7 | } 8 | 9 | .scene path:nth-child(2) { 10 | fill: #0c27cf; 11 | } 12 | 13 | .scene path:nth-child(3) { 14 | fill: #13269c; 15 | } 16 | 17 | .scene path:nth-child(4) { 18 | fill: #242468; 19 | } 20 | 21 | .scene path:nth-child(5) { 22 | fill: #2648e6; 23 | } 24 | 25 | .scene path:nth-child(6) { 26 | fill: #2c31b0; 27 | } 28 | 29 | .scene path:nth-child(7) { 30 | fill: #262689; 31 | } 32 | 33 | .title { 34 | color: #fff; 35 | font-size: 6vw; 36 | font-weight: 400; 37 | z-index: 1000; 38 | font-family: "Arapey", serif; 39 | pointer-events: none; 40 | } -------------------------------------------------------------------------------- /css/demo4.css: -------------------------------------------------------------------------------- 1 | .title { 2 | color: #fff; 3 | font-size: 6vw; 4 | font-weight: 400; 5 | z-index: 1000; 6 | font-family: "Arapey", serif; 7 | pointer-events: none; 8 | } 9 | 10 | .scene path { 11 | fill: #171817; 12 | } -------------------------------------------------------------------------------- /css/demo5.css: -------------------------------------------------------------------------------- 1 | .scene { 2 | display: block; 3 | pointer-events: auto; 4 | } 5 | 6 | .scene a { 7 | cursor: pointer; 8 | } 9 | 10 | .content--reveal { 11 | position: absolute; 12 | z-index: 1001; 13 | top: 0; 14 | left: 0; 15 | width: 100%; 16 | height: 100vh; 17 | pointer-events: none; 18 | } 19 | 20 | .content__close { 21 | position: absolute; 22 | top: 0; 23 | right: 0; 24 | border: 0; 25 | padding: 0; 26 | margin: 2em; 27 | background: none; 28 | color: var(--color-link); 29 | opacity: 0; 30 | transition: opacity 0.3s; 31 | } 32 | 33 | .content__close:hover, 34 | .content__close:focus { 35 | outline: none; 36 | color: var(--color-link-hover); 37 | } 38 | 39 | .content__inner { 40 | position: absolute; 41 | left: 0; 42 | top: 0; 43 | width: 100%; 44 | height: 100%; 45 | display: grid; 46 | grid-template-columns: 15% 15% 15% 15%; 47 | grid-template-rows: 25% 25%; 48 | justify-content: center; 49 | align-items: center; 50 | align-content: center; 51 | justify-items: center; 52 | -webkit-touch-callout: none; 53 | -webkit-user-select: none; 54 | -khtml-user-select: none; 55 | -moz-user-select: none; 56 | -ms-user-select: none; 57 | user-select: none; 58 | } 59 | 60 | .js .content__inner { 61 | opacity: 0; 62 | transition: opacity 0.3s; 63 | } 64 | 65 | .js .content__inner--visible { 66 | opacity: 1; 67 | pointer-events: auto; 68 | } 69 | 70 | .content__inner--visible ~ .content__close { 71 | opacity: 1; 72 | pointer-events: auto; 73 | } 74 | 75 | .content__title { 76 | font-size: 12vw; 77 | margin: 0; 78 | position: relative; 79 | z-index: 10; 80 | grid-area: 1 / 1 / 2 / 5; 81 | opacity: 0; 82 | transform: translate3d(-30px,0,0); 83 | transition: transform 1s, opacity 0.6s; 84 | transition-timing-function: cubic-bezier(0.2,1,0.3,1); 85 | } 86 | 87 | .content__inner--visible .content__title { 88 | opacity: 1; 89 | transform: translate3d(0,0,0); 90 | } 91 | 92 | .content__img--1 { 93 | grid-area: 1 / 3 / 2 / 5; 94 | opacity: 0; 95 | transform: translate3d(30px,-30px,0); 96 | transition: transform 1.5s, opacity 0.6s; 97 | transition-timing-function: cubic-bezier(0.2,1,0.3,1); 98 | } 99 | 100 | .content__img--2 { 101 | grid-area: 2 / 1 / 3 / 3; 102 | opacity: 0; 103 | transform: translate3d(-30px,30px,0); 104 | transition: transform 1.5s, opacity 0.6s; 105 | transition-timing-function: cubic-bezier(0.2,1,0.3,1); 106 | } 107 | 108 | .content__inner--visible .content__img--1, 109 | .content__inner--visible .content__img--2 { 110 | opacity: 1; 111 | transform: translate3d(0,0,0); 112 | } 113 | 114 | .content__subtitle { 115 | grid-area: 2 / 2 / 3 / 4; 116 | font-size: 2em; 117 | transform: translate3d(10px,0,0); 118 | transition: transform 0.6s, opacity 0.6s; 119 | } 120 | 121 | .content__inner--visible .content__subtitle { 122 | opacity: 1; 123 | transform: translate3d(0,0,0); 124 | } 125 | 126 | .pattern-color-1 { 127 | fill: #191139; 128 | } 129 | 130 | .pattern-color-2 { 131 | fill: #212499; 132 | } 133 | 134 | .pattern-color-3 { 135 | fill: #6056f2; 136 | } 137 | 138 | .pattern-color-4 { 139 | fill: #90a1f4; 140 | } 141 | 142 | .pattern-color-5 { 143 | fill: #39486c; 144 | } 145 | 146 | .pattern-color-6 { 147 | fill: #4b3b86; 148 | } 149 | 150 | .rect-color-hero { 151 | fill: #33256d; 152 | } 153 | 154 | .rect-color-2 { 155 | fill: #3f43d9; 156 | } 157 | 158 | .rect-color-3 { 159 | fill: #8178ff; 160 | } 161 | 162 | .rect-color-4 { 163 | fill: #adbcf4; 164 | } 165 | 166 | .rect-color-5 { 167 | fill: #191e2d; 168 | } 169 | 170 | .rect-color-6 { 171 | fill: #7461c7; 172 | } 173 | 174 | .content__img--1 rect { 175 | fill: #6554b3; 176 | } 177 | 178 | .content__img--1 circle { 179 | fill: none; 180 | stroke: #1c133f; 181 | } 182 | 183 | .content__img--2 rect { 184 | fill: #6554b3; 185 | } 186 | 187 | .content__img--2 polygon { 188 | fill: none; 189 | stroke: #1c133f; 190 | } 191 | 192 | .label { 193 | font-size: 3em; 194 | fill: #f7fb40; 195 | font-weight: 700; 196 | transition: fill 0.2s; 197 | } 198 | 199 | .label:hover { 200 | fill: #fff; 201 | } 202 | 203 | .label tspan:first-child { 204 | font-size: 0.75em; 205 | border-bottom: 2px solid #ddd; 206 | } 207 | 208 | @media screen and (max-width: 55em) { 209 | main { 210 | height: 100vh; 211 | } 212 | .scene, .content__inner, .content--reveal { 213 | height: calc(100vw * 0.55); 214 | top: auto; 215 | bottom: 0; 216 | } 217 | .content__inner { 218 | grid-template-columns: 25% 25% 25% 25%; 219 | } 220 | .content__title { 221 | font-size: 2em; 222 | } 223 | .content__subtitle { 224 | font-size: 1em; 225 | } 226 | .content__img { 227 | width: 100px; 228 | height: 100px; 229 | } 230 | } -------------------------------------------------------------------------------- /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/ShapeMorphIdeas/eeb7a4f4d7cf580bf8f0b8fb921f1af10f5ffce7/favicon.ico -------------------------------------------------------------------------------- /index2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Organic Shape Morph Ideas | Demo 2 | Codrops 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 41 |
42 |
Please view this demo on a desktop.
43 |
44 |
45 | 49 |

Organic Shape Morph Ideas

50 | Hover the menu items 51 |
52 | 53 | 61 | 62 | 63 |
64 |

Jetpack Professional - the only WordPress plugin you really need

65 |

Includes premium themes, business class security, and priority, expert support.

66 |
67 |
68 |
69 | 70 | 71 | 72 | 81 |
82 |
83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /index3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Organic Shape Morph Ideas | Demo 3 | Codrops 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 41 |
42 |
Please view this demo on a desktop.
43 |
44 |
45 | 49 |

Organic Shape Morph Ideas

50 | Recreated from Kévin Lagier's design 51 |
52 | 53 | 61 | 62 | 63 |
64 |

Jetpack Professional - the only WordPress plugin you really need

65 |

Includes premium themes, business class security, and priority, expert support

66 |
67 |
68 |
69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 |

Fluid Life

79 |
80 |
81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /index4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Organic Shape Morph Ideas | Demo 4 | Codrops 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 41 |
42 |
Please view this demo on a desktop.
43 |
44 |
45 | 49 |

Organic Shape Morph Ideas

50 | Move your mouse around 51 |
52 | 53 | 61 | 62 | 63 |
64 |

Jetpack Professional - the only WordPress plugin you really need

65 |

Includes premium themes, business class security, and priority, expert support

66 |
67 |
68 |
69 | 70 | 71 | 72 |

Botanic Wisdom

73 |
74 |
75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /index5.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Organic Shape Morph Ideas | Demo 5 | Codrops 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 44 |
45 |
Please view this demo on a desktop.
46 |
47 |
48 | 52 |

Organic Shape Morph Ideas

53 | Click the shape titles 54 |
55 | 56 | 64 |
65 |
66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 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 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | #1 Hero 133 | 134 | 135 | #2 Qualm 136 | 137 | 138 | #3 Waxy 139 | 140 | 141 | #4 Love 142 | 143 | 144 | #5 Woods 145 | 146 | 147 | #6 Beach 148 | 149 | 150 |
151 |
152 |
153 |

Hero.

154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 |

An unkissed loaf's hydrogen comes with it.

163 |
164 |
165 |

Qualm.

166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 |

The pinks could be said to resemble freeborn squirrels.

175 |
176 |
177 |

Waxy.

178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 |

A surgeon is the glue of a purchase.

187 |
188 |
189 |

Love.

190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 |

Authors often misinterpret the korean as a heavies gemini.

199 |
200 |
201 |

Woods.

202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 |

Some servo tips are thought of simply as russias.

211 |
212 |
213 |

Beach.

214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 |

To be more specific, the angora is a quilt.

223 |
224 | 225 |
226 |
227 | 228 | 229 | 230 | 231 | 232 | -------------------------------------------------------------------------------- /js/anime.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | 2017 Julian Garnier 3 | Released under the MIT license 4 | */ 5 | var $jscomp$this=this; 6 | (function(u,r){"function"===typeof define&&define.amd?define([],r):"object"===typeof module&&module.exports?module.exports=r():u.anime=r()})(this,function(){function u(a){if(!g.col(a))try{return document.querySelectorAll(a)}catch(b){}}function r(a){return a.reduce(function(a,c){return a.concat(g.arr(c)?r(c):c)},[])}function v(a){if(g.arr(a))return a;g.str(a)&&(a=u(a)||a);return a instanceof NodeList||a instanceof HTMLCollection?[].slice.call(a):[a]}function E(a,b){return a.some(function(a){return a===b})} 7 | function z(a){var b={},c;for(c in a)b[c]=a[c];return b}function F(a,b){var c=z(a),d;for(d in a)c[d]=b.hasOwnProperty(d)?b[d]:a[d];return c}function A(a,b){var c=z(a),d;for(d in b)c[d]=g.und(a[d])?b[d]:a[d];return c}function R(a){a=a.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,function(a,b,c,h){return b+b+c+c+h+h});var b=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(a);a=parseInt(b[1],16);var c=parseInt(b[2],16),b=parseInt(b[3],16);return"rgb("+a+","+c+","+b+")"}function S(a){function b(a,b,c){0> 8 | c&&(c+=1);1c?b:c<2/3?a+(b-a)*(2/3-c)*6:a}var c=/hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/g.exec(a);a=parseInt(c[1])/360;var d=parseInt(c[2])/100,c=parseInt(c[3])/100;if(0==d)d=c=a=c;else{var e=.5>c?c*(1+d):c+d-c*d,k=2*c-e,d=b(k,e,a+1/3),c=b(k,e,a);a=b(k,e,a-1/3)}return"rgb("+255*d+","+255*c+","+255*a+")"}function w(a){if(a=/([\+\-]?[0-9#\.]+)(%|px|pt|em|rem|in|cm|mm|ex|pc|vw|vh|deg|rad|turn)?/.exec(a))return a[2]}function T(a){if(-1k&&q=m&&(f.began=!0,e("begin")),e("run")):(q<=k&&0!==O&&(d(0),p&&g()),q>=h&&O!==h&&(d(h),p||g()));a>=h&&(f.remaining?(t=n,"alternate"===f.direction&&(f.reversed=!f.reversed)):(f.pause(),P(),Q=b(),f.completed||(f.completed=!0,e("complete"))),l=0);if(f.children)for(a=f.children,h=0;h=b&& 22 | 0<=d&&1>=d){var g=new Float32Array(11);if(b!==c||d!==e)for(var h=0;11>h;++h)g[h]=a(.1*h,b,d);return function(h){if(b===c&&d===e)return h;if(0===h)return 0;if(1===h)return 1;for(var k=0,l=1;10!==l&&g[l]<=h;++l)k+=.1;--l;var l=k+(h-g[l])/(g[l+1]-g[l])*.1,n=3*(1-3*d+3*b)*l*l+2*(3*d-6*b)*l+3*b;if(.001<=n){for(k=0;4>k;++k){n=3*(1-3*d+3*b)*l*l+2*(3*d-6*b)*l+3*b;if(0===n)break;var m=a(l,b,d)-h,l=l-m/n}h=l}else if(0===n)h=l;else{var l=k,k=k+.1,f=0;do m=l+(k-l)/2,n=a(m,b,d)-h,0++f);h=m}return a(h,c,e)}}}}(),M=function(){function a(a,b){return 0===a||1===a?a:-Math.pow(2,10*(a-1))*Math.sin(2*(a-1-b/(2*Math.PI)*Math.asin(1))*Math.PI/b)}var b="Quad Cubic Quart Quint Sine Expo Circ Back Elastic".split(" "),c={In:[[.55,.085,.68,.53],[.55,.055,.675,.19],[.895,.03,.685,.22],[.755,.05,.855,.06],[.47,0,.745,.715],[.95,.05,.795,.035],[.6,.04,.98,.335],[.6,-.28,.735,.045],a],Out:[[.25,.46,.45,.94],[.215,.61,.355,1],[.165,.84,.44,1],[.23,1,.32,1],[.39,.575,.565,1],[.19,1,.22,1], 24 | [.075,.82,.165,1],[.175,.885,.32,1.275],function(b,c){return 1-a(1-b,c)}],InOut:[[.455,.03,.515,.955],[.645,.045,.355,1],[.77,0,.175,1],[.86,0,.07,1],[.445,.05,.55,.95],[1,0,0,1],[.785,.135,.15,.86],[.68,-.55,.265,1.55],function(b,c){return.5>b?a(2*b,c)/2:1-a(-2*b+2,c)/2}]},d={linear:x(.25,.25,.75,.75)},e={},k;for(k in c)e.type=k,c[e.type].forEach(function(a){return function(c,e){d["ease"+a.type+b[e]]=g.fnc(c)?c:x.apply($jscomp$this,c)}}(e)),e={type:e.type};return d}(),ha={css:function(a,b,c){return a.style[b]= 25 | c},attribute:function(a,b,c){return a.setAttribute(b,c)},object:function(a,b,c){return a[b]=c},transform:function(a,b,c,d,e){d[e]||(d[e]=[]);d[e].push(b+"("+c+")")}},p=[],y=0,ia=function(){function a(){y=requestAnimationFrame(b)}function b(b){var c=p.length;if(c){for(var e=0;ed&&(b.duration=a.duration);b.children.push(a)});return b};return b};m.random=function(a,b){return Math.floor(Math.random()*(b-a+1))+a};return m}); -------------------------------------------------------------------------------- /js/demo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * demo.js 3 | * http://www.codrops.com 4 | * 5 | * Licensed under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 8 | * Copyright 2017, Codrops 9 | * http://www.codrops.com 10 | */ 11 | { 12 | setTimeout(() => document.body.classList.add('render'), 60); 13 | const navdemos = Array.from(document.querySelectorAll('nav.demos > .demo')); 14 | const total = navdemos.length; 15 | const current = navdemos.findIndex(el => el.classList.contains('demo--current')); 16 | const navigate = (linkEl) => { 17 | document.body.classList.remove('render'); 18 | document.body.addEventListener('transitionend', () => window.location = linkEl.href); 19 | }; 20 | navdemos.forEach(link => link.addEventListener('click', (ev) => { 21 | ev.preventDefault(); 22 | navigate(ev.target); 23 | })); 24 | document.addEventListener('keydown', (ev) => { 25 | const keyCode = ev.keyCode || ev.which; 26 | let linkEl; 27 | if ( keyCode === 37 ) { 28 | linkEl = current > 0 ? navdemos[current-1] : navdemos[total-1]; 29 | } 30 | else if ( keyCode === 39 ) { 31 | linkEl = current < total-1 ? navdemos[current+1] : navdemos[0]; 32 | } 33 | else { 34 | return false; 35 | } 36 | navigate(linkEl); 37 | }); 38 | } 39 | -------------------------------------------------------------------------------- /js/demo1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * demo1.js 3 | * http://www.codrops.com 4 | * 5 | * Licensed under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 8 | * Copyright 2017, Codrops 9 | * http://www.codrops.com 10 | */ 11 | { 12 | const getRandomFloat = (min,max) => { 13 | return Math.random() * (max - min) + min; 14 | }; 15 | 16 | // From https://davidwalsh.name/javascript-debounce-function. 17 | const debounce = (func, wait, immediate) => { 18 | let timeout; 19 | return function() { 20 | let context = this; 21 | var args = arguments; 22 | let later = () => { 23 | timeout = null; 24 | if (!immediate) func.apply(context, args); 25 | }; 26 | let callNow = immediate && !timeout; 27 | clearTimeout(timeout); 28 | timeout = setTimeout(later, wait); 29 | if (callNow) func.apply(context, args); 30 | }; 31 | }; 32 | 33 | const DOM = {}; 34 | DOM.scene = document.querySelector('svg.scene'); 35 | DOM.gElems = Array.from(DOM.scene.querySelectorAll('g > g')); 36 | 37 | class Bacteria { 38 | constructor(el) { 39 | this.DOM = {}; 40 | this.DOM.el = el; 41 | this.DOM.path = this.DOM.el.querySelector('path'); 42 | this.CONFIG = { 43 | // Random value from 5 to 30px. 44 | motionIncrement: [5,20] 45 | }; 46 | this.init(); 47 | this.initEvents(); 48 | } 49 | init() { 50 | // Measures. 51 | this.getSizes(); 52 | 53 | // Different shape/paths. 54 | this.paths = this.DOM.path.getAttribute('pathdata:id').split(';'); 55 | 56 | // Current values for the transform. 57 | this.transform = {tx: 0, ty: 0, rz: 0, sx:0, sy:0}; 58 | // Current step. 59 | this.step = 0; 60 | 61 | // The element will alternate its shape (initial path plus all the other ones defined in pathdata:id). 62 | this.paths.splice(this.paths.length, 0, this.DOM.path.getAttribute('d')); 63 | // The total number of possible shapes/paths. 64 | this.totalPaths = this.paths.length; 65 | 66 | // Set Origin. 67 | this.DOM.el.style.transformOrigin = '50% 50%'; 68 | 69 | // Start the shape animatation (path morphing). 70 | this.changeShape(); 71 | // Start the transforms animation. 72 | this.move(); 73 | } 74 | initEvents() { 75 | window.addEventListener('resize', debounce(() => this.getSizes(), 10)); 76 | } 77 | getSizes() { 78 | this.domrect = { 79 | scene: DOM.scene.getBoundingClientRect(), 80 | el: this.DOM.el.getBoundingClientRect() 81 | }; 82 | } 83 | changeShape() { 84 | anime.remove(this.DOM.path); 85 | anime({ 86 | targets: this.DOM.path, 87 | duration: anime.random(2000,8000), 88 | easing: 'linear', 89 | d: this.paths, 90 | loop: true 91 | }); 92 | } 93 | getTransform(prop) { 94 | let val; 95 | if ( prop === 'rz' ) { 96 | val = anime.random(-30,30); 97 | } 98 | else if (prop === 'sx' || prop === 'sy') { 99 | val = getRandomFloat(0.8,1.2); 100 | } 101 | else { 102 | const inc = anime.random(this.CONFIG.motionIncrement[0],this.CONFIG.motionIncrement[1]) * (anime.random(0,1) ? -1 : 1); 103 | 104 | const vSize = prop === 'tx' ? 'width' : 'height'; 105 | const position = prop === 'tx' ? 'left' : 'top'; 106 | 107 | val = this.transform[prop] + inc; 108 | // Out of viewport. 109 | if ( val > 0 && val > this.domrect.scene[vSize] - this.domrect.el[position] || val < 0 && Math.abs(val) > this.domrect.el[position] + this.domrect.el[vSize] ) { 110 | val -= 2*inc; 111 | } 112 | } 113 | 114 | return val; 115 | } 116 | move() { 117 | this.step++; 118 | this.transform.tx = this.getTransform('tx'); 119 | this.transform.ty = this.getTransform('ty'); 120 | this.transform.rz = this.getTransform('rz'); 121 | this.transform.sx = this.getTransform('sx'); 122 | this.transform.sy = this.getTransform('sy'); 123 | 124 | let pos; 125 | if ( this.step % this.totalPaths === 0 ) { 126 | this.step = pos = 0; 127 | } 128 | else { 129 | pos = this.totalPaths - (this.totalPaths - this.step); 130 | } 131 | 132 | const delay = anime.random(0,1) ? 0 : anime.random(0, 1000); 133 | const duration = anime.random(4000,8000); 134 | const easing = 'easeInOutQuad'; 135 | anime.remove(this.DOM.el); 136 | anime({ 137 | targets: this.DOM.el, 138 | duration: duration, 139 | easing: easing, 140 | delay: delay, 141 | translateX: this.transform.tx, 142 | translateY: this.transform.ty, 143 | scaleX: this.transform.sx, 144 | scaleY: this.transform.sy, 145 | rotate: this.transform.rz, 146 | complete: () => this.move() 147 | }); 148 | } 149 | }; 150 | 151 | DOM.gElems.forEach(gElem => new Bacteria(gElem)); 152 | 153 | DOM.scene.querySelector('g').addEventListener('mouseenter', () => document.body.classList.add('scene-hover')); 154 | DOM.scene.querySelector('g').addEventListener('mouseleave', () => document.body.classList.remove('scene-hover')); 155 | }; -------------------------------------------------------------------------------- /js/demo2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * demo2.js 3 | * http://www.codrops.com 4 | * 5 | * Licensed under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 8 | * Copyright 2017, Codrops 9 | * http://www.codrops.com 10 | */ 11 | { 12 | class Menu { 13 | constructor(el) { 14 | this.DOM = {}; 15 | this.DOM.el = el; 16 | this.DOM.items = Array.from(this.DOM.el.querySelectorAll('.menu__item')); 17 | this.DOM.bgshape = document.querySelector('svg.scene > path'); 18 | this.initialShape = this.DOM.bgshape.getAttribute('d'); 19 | this.initEvents(); 20 | } 21 | changeShape(el) { 22 | anime.remove(this.DOM.bgshape); 23 | anime({ 24 | targets: this.DOM.bgshape, 25 | duration: 3000, 26 | easing: 'easeOutQuad', 27 | d: el.dataset.shape 28 | }); 29 | } 30 | resetShape() { 31 | anime.remove(this.DOM.bgshape); 32 | anime({ 33 | targets: this.DOM.bgshape, 34 | duration: 4000, 35 | easing: 'easeOutQuint', 36 | d: this.initialShape 37 | }); 38 | } 39 | initEvents() { 40 | this.mouseenterFn = (ev) => this.mouseTimeout = setTimeout(() => { 41 | this.isActive = true; 42 | this.changeShape(ev.target); 43 | clearTimeout(this.resetTimeout); 44 | }, 50); 45 | 46 | this.mouseleaveFn = () => { 47 | clearTimeout(this.mouseTimeout); 48 | if( !this.isActive ) return; 49 | this.isActive = false; 50 | 51 | this.resetTimeout = setTimeout(() => { 52 | this.resetShape(); 53 | }, 300); 54 | }; 55 | 56 | this.DOM.items.forEach((item) => { 57 | item.addEventListener('mouseenter', this.mouseenterFn); 58 | item.addEventListener('mouseleave', this.mouseleaveFn); 59 | item.addEventListener('touchstart', this.mouseenterFn); 60 | item.addEventListener('touchend', this.mouseleaveFn); 61 | }); 62 | } 63 | }; 64 | 65 | new Menu(document.querySelector('nav.menu')); 66 | }; -------------------------------------------------------------------------------- /js/demo3.js: -------------------------------------------------------------------------------- 1 | /** 2 | * demo3.js 3 | * http://www.codrops.com 4 | * 5 | * Licensed under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 8 | * Copyright 2017, Codrops 9 | * http://www.codrops.com 10 | */ 11 | { 12 | class MorphingBG { 13 | constructor(el) { 14 | this.DOM = {}; 15 | this.DOM.el = el; 16 | this.DOM.paths = Array.from(this.DOM.el.querySelectorAll('path')); 17 | this.animate(); 18 | } 19 | animate() { 20 | this.DOM.paths.forEach((path) => { 21 | setTimeout(() => { 22 | anime({ 23 | targets: path, 24 | duration: anime.random(3000,5000), 25 | easing: [0.5,0,0.5,1], 26 | d: path.getAttribute('pathdata:id'), 27 | loop: true, 28 | direction: 'alternate' 29 | }); 30 | }, anime.random(0,1000)); 31 | }); 32 | } 33 | }; 34 | 35 | new MorphingBG(document.querySelector('svg.scene')); 36 | }; -------------------------------------------------------------------------------- /js/demo4.js: -------------------------------------------------------------------------------- 1 | /** 2 | * demo4.js 3 | * http://www.codrops.com 4 | * 5 | * Licensed under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 8 | * Copyright 2017, Codrops 9 | * http://www.codrops.com 10 | */ 11 | { 12 | // equation of a line 13 | const lineEq = (y2, y1, x2, x1, currentVal) => { 14 | // y = mx + b 15 | const m = (y2 - y1) / (x2 - x1); 16 | const b = y1 - m * x1; 17 | 18 | return m * currentVal + b; 19 | } 20 | 21 | // from http://www.quirksmode.org/js/events_properties.html#position 22 | const getMousePos = (e) => { 23 | let posx = 0; 24 | let posy = 0; 25 | if (!e) {let e = window.event}; 26 | if (e.pageX || e.pageY) { 27 | posx = e.pageX; 28 | posy = e.pageY; 29 | } 30 | else if (e.clientX || e.clientY) { 31 | posx = e.clientX + document.body.scrollLeft 32 | + document.documentElement.scrollLeft; 33 | posy = e.clientY + document.body.scrollTop 34 | + document.documentElement.scrollTop; 35 | } 36 | return { 37 | x : posx, 38 | y : posy 39 | }; 40 | }; 41 | 42 | // From https://davidwalsh.name/javascript-debounce-function. 43 | function debounce(func, wait, immediate) { 44 | var timeout; 45 | return function() { 46 | var context = this, args = arguments; 47 | var later = function() { 48 | timeout = null; 49 | if (!immediate) func.apply(context, args); 50 | }; 51 | var callNow = immediate && !timeout; 52 | clearTimeout(timeout); 53 | timeout = setTimeout(later, wait); 54 | if (callNow) func.apply(context, args); 55 | }; 56 | }; 57 | 58 | class MorphingBG { 59 | constructor(el) { 60 | this.DOM = {}; 61 | this.DOM.el = el; 62 | this.DOM.el.style.opacity = 0; 63 | this.DOM.el.style.transition = 'transform 2s ease-out'; 64 | this.DOM.pathEl = this.DOM.el.querySelector('path'); 65 | this.paths = this.DOM.pathEl.getAttribute('pathdata:id').split(';') 66 | this.paths.splice(this.paths.length, 0, this.DOM.pathEl.getAttribute('d')); 67 | this.win = {width: window.innerWidth, height: window.innerHeight}; 68 | this.animate(); 69 | this.initEvents(); 70 | } 71 | animate() { 72 | anime.remove(this.DOM.pathEl); 73 | anime({ 74 | targets: this.DOM.pathEl, 75 | duration: 10000, 76 | easing: [0.5,0,0.5,1], 77 | d: this.paths, 78 | loop: true 79 | }); 80 | } 81 | initEvents() { 82 | // Mousemove event / Tilt functionality. 83 | const tilt = { 84 | tx: this.win.width/8, 85 | ty: this.win.height/4, 86 | rz: 45, 87 | sx: [0.8,2], 88 | sy: [0.8,2] 89 | } 90 | const onMouseMoveFn = (ev) => { 91 | requestAnimationFrame(() => { 92 | if ( !this.started ) { 93 | this.started = true; 94 | anime({ 95 | targets: this.DOM.el, 96 | duration: 300, 97 | easing: 'linear', 98 | opacity: [0,1] 99 | }); 100 | } 101 | else { 102 | const mousepos = getMousePos(ev); 103 | const rotZ = 2*tilt.rz/this.win.height*mousepos.y - tilt.rz; 104 | const scaleX = mousepos.x < this.win.width/2 ? lineEq(tilt.sx[0],tilt.sx[1],this.win.width/2,0,mousepos.x) : lineEq(tilt.sx[1],tilt.sx[0],this.win.width,this.win.width/2,mousepos.x); 105 | const scaleY = mousepos.y < this.win.height/2 ? lineEq(tilt.sy[0],tilt.sy[1],this.win.height/2,0,mousepos.y) : lineEq(tilt.sy[1],tilt.sy[0],this.win.height,this.win.height/2,mousepos.y); 106 | const transX = 2*tilt.tx/this.win.width*mousepos.x - tilt.tx; 107 | const transY = 2*tilt.ty/this.win.height*mousepos.y - tilt.ty; 108 | 109 | this.DOM.el.style.transform = `translate3d(${transX}px, ${transY}px,0) rotate3d(0,0,1,${rotZ}deg) scale3d(${scaleX},${scaleY},1)`; 110 | } 111 | }); 112 | }; 113 | 114 | // Window resize. 115 | const onResizeFn = debounce(() => this.win = {width: window.innerWidth, height: window.innerHeight}, 20); 116 | 117 | document.addEventListener('mousemove', onMouseMoveFn); 118 | document.addEventListener('touchstart', onMouseMoveFn); 119 | window.addEventListener('resize', ev => onResizeFn()); 120 | } 121 | }; 122 | 123 | new MorphingBG(document.querySelector('svg.scene')); 124 | }; -------------------------------------------------------------------------------- /js/demo5.js: -------------------------------------------------------------------------------- 1 | /** 2 | * demo5.js 3 | * http://www.codrops.com 4 | * 5 | * Licensed under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 8 | * Copyright 2017, Codrops 9 | * http://www.codrops.com 10 | */ 11 | { 12 | // equation of a line 13 | const lineEq = (y2, y1, x2, x1, currentVal) => { 14 | // y = mx + b 15 | const m = (y2 - y1) / (x2 - x1); 16 | const b = y1 - m * x1; 17 | 18 | return m * currentVal + b; 19 | } 20 | 21 | // from http://www.quirksmode.org/js/events_properties.html#position 22 | const getMousePos = (e) => { 23 | let posx = 0; 24 | let posy = 0; 25 | if (!e) {let e = window.event}; 26 | if (e.pageX || e.pageY) { 27 | posx = e.pageX; 28 | posy = e.pageY; 29 | } 30 | else if (e.clientX || e.clientY) { 31 | posx = e.clientX + document.body.scrollLeft 32 | + document.documentElement.scrollLeft; 33 | posy = e.clientY + document.body.scrollTop 34 | + document.documentElement.scrollTop; 35 | } 36 | return { 37 | x : posx, 38 | y : posy 39 | }; 40 | }; 41 | 42 | // From https://davidwalsh.name/javascript-debounce-function. 43 | function debounce(func, wait, immediate) { 44 | var timeout; 45 | return function() { 46 | var context = this, args = arguments; 47 | var later = function() { 48 | timeout = null; 49 | if (!immediate) func.apply(context, args); 50 | }; 51 | var callNow = immediate && !timeout; 52 | clearTimeout(timeout); 53 | timeout = setTimeout(later, wait); 54 | if (callNow) func.apply(context, args); 55 | }; 56 | }; 57 | 58 | const ua = navigator.userAgent.toLowerCase(); 59 | const isSafari = ua.indexOf('safari') != -1 && ua.indexOf('chrome') <= -1; 60 | 61 | let win = {width: window.innerWidth, height: window.innerHeight}; 62 | 63 | class Blob { 64 | constructor(path, link, shape, content) { 65 | this.DOM = {}; 66 | this.DOM.path = path; 67 | this.DOM.link = link; 68 | this.DOM.shape = shape; 69 | this.DOM.content = content; 70 | this.DOM.path.style.transformOrigin = this.DOM.link.style.transformOrigin = '50% 50%'; 71 | this.DOM.path.style.transition = isSafari ? 'none' : 'transform 0.2s ease-out'; 72 | this.transform = {tx: 0, ty: 0, rz: 0}; 73 | this.paths = { 74 | reveal: this.DOM.path.getAttribute('pathdata:id'), 75 | unreveal: this.DOM.path.getAttribute('d') 76 | }; 77 | this.tilt = true; 78 | this.initEvents(); 79 | } 80 | initEvents() { 81 | // Mousemove event / Tilt functionality. 82 | const tilt = { 83 | tx: anime.random(5,40), 84 | ty: anime.random(20,60), 85 | rz: anime.random(-10,10) 86 | } 87 | const onMouseMoveFn = (ev) => { 88 | requestAnimationFrame(() => { 89 | if ( !this.tilt ) return false; 90 | const mousepos = getMousePos(ev); 91 | 92 | const rotZ = 2*tilt.rz/win.width*mousepos.x - tilt.rz; 93 | const transX = 2*tilt.tx/win.width*mousepos.x - tilt.tx; 94 | const transY = 2*tilt.ty/win.height*mousepos.y - tilt.ty; 95 | 96 | this.DOM.path.style.transform = `translateX(${transX}px) translateY(${transY}px) rotate(${rotZ}deg)`; 97 | 98 | this.transform = {tx: transX, ty: transY, rz: rotZ}; 99 | }); 100 | }; 101 | document.addEventListener('mousemove', onMouseMoveFn); 102 | } 103 | reveal() { 104 | this.tilt = false; 105 | if ( this.isRevealed || this.isAnimating ) return false; 106 | this.toggleLink(); 107 | this.isRevealed = true; 108 | anime.remove(this.DOM.path); 109 | anime({ 110 | targets: this.DOM.path, 111 | duration: 1000, 112 | easing: 'easeInOutQuint', 113 | d: this.paths.reveal, 114 | translateX: 0, 115 | translateY: 0, 116 | rotate: 0, 117 | begin: () => this.isAnimating = true, 118 | complete: () => { 119 | this.isAnimating = false; 120 | } 121 | }); 122 | setTimeout(() => this.DOM.content.classList.add('content__inner--visible'), 600); 123 | this.transform = {tx: 0, ty: 0, rz: 0}; 124 | } 125 | unreveal() { 126 | setTimeout(() => this.DOM.content.classList.remove('content__inner--visible'), 200); 127 | anime.remove(this.DOM.path); 128 | anime({ 129 | targets: this.DOM.path, 130 | duration: 1000, 131 | easing: 'easeInOutQuint', 132 | d: this.paths.unreveal, 133 | begin: () => this.isAnimating = true, 134 | complete: () => { 135 | this.tilt = true; 136 | this.isRevealed = false; 137 | this.isAnimating = false; 138 | } 139 | }); 140 | this.toggleLink(true, 550); 141 | } 142 | hide() { 143 | const duration = anime.random(300,600); 144 | const easing = 'easeInOutSine'; 145 | 146 | anime.remove(this.DOM.path); 147 | anime({ 148 | targets: this.DOM.path, 149 | duration: duration, 150 | easing: easing, 151 | translateX: this.transform.tx, 152 | translateY: this.transform.ty, 153 | scale: [1,0], 154 | rotate: this.transform.rz 155 | }); 156 | 157 | anime.remove(this.DOM.shape); 158 | anime({ 159 | targets: this.DOM.shape, 160 | duration: duration, 161 | easing: easing, 162 | opacity: [1,0] 163 | }); 164 | 165 | this.toggleLink(); 166 | } 167 | show() { 168 | this.tilt = false; 169 | const duration = anime.random(300,600); 170 | const easing = 'easeOutQuint'; 171 | const delay = 500; 172 | 173 | anime.remove(this.DOM.shape); 174 | anime({ 175 | targets: this.DOM.path, 176 | duration: duration, 177 | delay: delay, 178 | easing: easing, 179 | translateX: this.transform.tx, 180 | translateY: this.transform.ty, 181 | scale: [0,1], 182 | rotate: this.transform.rz, 183 | complete: () => { 184 | this.tilt = true; 185 | } 186 | }); 187 | 188 | anime.remove(this.DOM.shape); 189 | anime({ 190 | targets: this.DOM.shape, 191 | duration: duration, 192 | delay: delay, 193 | easing: easing, 194 | opacity: 1 195 | }); 196 | 197 | this.toggleLink(true, 550); 198 | } 199 | toggleLink(isVisible = false, delay = 0) { 200 | setTimeout(() => { 201 | anime.remove(this.DOM.link); 202 | anime({ 203 | targets: this.DOM.link, 204 | duration: isVisible ? 700 : 1200, 205 | easing: 'easeOutQuint', 206 | opacity: isVisible ? [0,1] : [1,0], 207 | translateX: isVisible ? (t,i) => { 208 | return [anime.random(-50,50),0]; 209 | } : (t,i) => { 210 | return [0,anime.random(-20,20)]; 211 | } 212 | }); 213 | }, delay); 214 | } 215 | }; 216 | 217 | class MorphingBG { 218 | constructor() { 219 | this.DOM = {}; 220 | this.DOM.scene = document.querySelector('svg.scene'); 221 | this.DOM.links = Array.from(this.DOM.scene.querySelectorAll('a.label')); 222 | this.DOM.shapes = Array.from(this.DOM.scene.querySelectorAll('g.shape')); 223 | this.DOM.contents = Array.from(document.querySelectorAll('.content > .content__inner')); 224 | this.DOM.closeCtrl = document.querySelector('.content__close'); 225 | 226 | this.blobs = []; 227 | Array.from(this.DOM.scene.querySelectorAll('clipPath > path')).forEach((path, pos) => this.blobs.push(new Blob(path, this.DOM.links[pos], this.DOM.shapes[pos], this.DOM.contents[pos]))); 228 | 229 | this.initEvents(); 230 | } 231 | initEvents() { 232 | const onResizeFn = debounce(() => win = {width: window.innerWidth, height: window.innerHeight}, 20); 233 | window.addEventListener('resize', ev => onResizeFn()); 234 | 235 | const onRevealFn = (ev, pos) => { 236 | ev.preventDefault(); 237 | 238 | this.current = pos; 239 | const currentBlob = this.blobs[this.current]; 240 | if ( currentBlob.isAnimating ) return; 241 | currentBlob.reveal(); 242 | 243 | this.blobs.filter(el => el != currentBlob).forEach(blob => blob.hide()); 244 | }; 245 | this.DOM.links.forEach((link,pos) => { 246 | link.addEventListener('click', (ev) => onRevealFn(ev,pos)); 247 | link.addEventListener('touchstart', (ev) => onRevealFn(ev,pos)); 248 | }); 249 | 250 | const onUnrevealFn = (ev) => { 251 | ev.preventDefault(); 252 | 253 | const currentBlob = this.blobs[this.current]; 254 | if ( currentBlob.isAnimating ) return; 255 | currentBlob.unreveal(); 256 | 257 | this.blobs.filter(el => el != currentBlob).forEach(blob => blob.show()); 258 | }; 259 | this.DOM.closeCtrl.addEventListener('click', onUnrevealFn); 260 | this.DOM.closeCtrl.addEventListener('touchstart', onUnrevealFn); 261 | } 262 | }; 263 | 264 | new MorphingBG(); 265 | }; -------------------------------------------------------------------------------- /pater/jetpack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/ShapeMorphIdeas/eeb7a4f4d7cf580bf8f0b8fb921f1af10f5ffce7/pater/jetpack.png -------------------------------------------------------------------------------- /pater/jetpack_man.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/ShapeMorphIdeas/eeb7a4f4d7cf580bf8f0b8fb921f1af10f5ffce7/pater/jetpack_man.png -------------------------------------------------------------------------------- /pater/pater.css: -------------------------------------------------------------------------------- 1 | .pater { 2 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif !important; 3 | position: fixed; 4 | z-index: 1000; 5 | right: 0; 6 | bottom: 0; 7 | display: grid; 8 | width: 100%; 9 | padding: 1em 0; 10 | text-align: left; 11 | color: #333; 12 | background: #ddd; 13 | grid-template-columns: auto; 14 | grid-template-rows: auto auto auto; 15 | } 16 | 17 | .pater:hover, 18 | .pater:focus { 19 | color: #000; 20 | } 21 | 22 | .pater--theme-alt { 23 | background: #333333; 24 | color: #e2e2e2; 25 | } 26 | 27 | .pater--theme-alt:hover, 28 | .pater--theme-alt:focus { 29 | color: #fff; 30 | } 31 | 32 | .pater::before { 33 | content: 'Our Sponsor'; 34 | font-size: 0.75em; 35 | display: inline-block; 36 | padding: 0 0 5px 10px; 37 | vertical-align: middle; 38 | grid-area: 1 / 1 / 2 / 2; 39 | } 40 | 41 | .pater__img { 42 | display: none; 43 | overflow: hidden; 44 | background-image: url(jetpack.png); 45 | background-size: cover; 46 | grid-area: 2 / 1 / 3 / 2; 47 | } 48 | 49 | .pater__img-inner { 50 | background: url(jetpack_man.png) no-repeat 0 100% ; 51 | background-size: 150px; 52 | width: 100%; 53 | height: 100%; 54 | } 55 | 56 | .pater:hover .pater__img-inner { 57 | animation: animMan 0.4s cubic-bezier(0.1,1,0.3,1) forwards; 58 | } 59 | 60 | @keyframes animMan { 61 | 25% { 62 | opacity: 0; 63 | transform: translate3d(0,0,0); 64 | } 65 | 26% { 66 | opacity: 0; 67 | transform: translate3d(-100%,100%,0) scale3d(0.1,0.1,1); 68 | } 69 | 100% { 70 | opacity: 1; 71 | transform: translate3d(0,0,0); 72 | } 73 | } 74 | 75 | .pater__title { 76 | font-size: 0.85em; 77 | font-weight: normal; 78 | font-weight: bold; 79 | align-self: end; 80 | margin: 0; 81 | } 82 | 83 | .pater__title, 84 | .pater__description { 85 | align-self: start; 86 | padding: 10px 0 0 10px; 87 | grid-area: 2 / 1 / 3 / 3; 88 | } 89 | 90 | .pater__description { 91 | font-size: 0.85em; 92 | display: none; 93 | margin: 0; 94 | opacity: 0; 95 | } 96 | 97 | .pater__description strong { 98 | display: block; 99 | padding-top: 5px; 100 | color: #ee4e97; 101 | } 102 | 103 | @media screen and (min-width: 60em) { 104 | .pater { 105 | top: 0; 106 | right: 0; 107 | bottom: auto; 108 | width: calc(180px + 2em); 109 | margin: 0 1.5em 0 0; 110 | padding: 0; 111 | padding: 1em; 112 | text-align: right; 113 | border-radius: 0 0 5px 5px; 114 | background: #f9f9f9; 115 | } 116 | .pater--theme-alt { 117 | background: #333333; 118 | } 119 | .pater__img { 120 | display: flex; 121 | width: 100%; 122 | height: 180px; 123 | } 124 | .pater::before { 125 | display: block; 126 | padding: 0 0 10px 0; 127 | } 128 | .pater:hover .pater__title { 129 | opacity: 0; 130 | } 131 | .pater:hover .pater__description { 132 | opacity: 1; 133 | } 134 | .pater__description { 135 | display: block; 136 | } 137 | .pater__title { 138 | padding: 10px; 139 | } 140 | .pater__title, 141 | .pater__description { 142 | padding-left: 0; 143 | transition: opacity 0.5s; 144 | grid-area: 3 / 1 / 4 / 2; 145 | } 146 | } 147 | --------------------------------------------------------------------------------