├── .DS_Store ├── favicon.ico ├── index.js ├── package.json ├── LICENSE ├── README.md ├── tutorial.md ├── style.css ├── .gitignore ├── index.html └── images ├── background.svg ├── transformed.svg ├── mystique.svg └── foreground.svg /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abnersn/x-men-svg-filter-animation/HEAD/.DS_Store -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abnersn/x-men-svg-filter-animation/HEAD/favicon.ico -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import gsap from "gsap"; 2 | import { throttle } from "lodash"; 3 | 4 | const tl = gsap.timeline({ 5 | paused: true, 6 | defaults: { 7 | ease: 'none' 8 | } 9 | }) 10 | 11 | tl 12 | .to('.mask', { 13 | translateY: 296, 14 | duration: 3, 15 | }) 16 | .to('#bg-color', { 17 | attr: { 18 | fill: '#ffd11b' 19 | }, 20 | duration: 2 21 | }, '<+=1') 22 | 23 | 24 | const $picture = document.querySelector('.picture') 25 | 26 | function handleMoveEvent(ev) { 27 | const rect = $picture.getBoundingClientRect(); 28 | 29 | const relPos = (ev.clientY - rect.top) / (rect.bottom - rect.top) 30 | 31 | tl.progress(relPos) 32 | } 33 | 34 | $picture.addEventListener('mousemove', throttle(handleMoveEvent, 60)) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "x-men-svg-filter-animation", 3 | "version": "1.0.0", 4 | "description": "Superhero-inspired SVG animation effect with filters", 5 | "main": "dist/index.js", 6 | "scripts": { 7 | "start": "parcel index.html", 8 | "build": "parcel build --no-minify --no-source-maps index.html --public-url ./" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/abnersn/x-men-svg-filter-animation.git" 13 | }, 14 | "keywords": [ 15 | "svg", 16 | "filter", 17 | "animation", 18 | "gsap" 19 | ], 20 | "author": "Abner Nascimento", 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/abnersn/x-men-svg-filter-animation/issues" 24 | }, 25 | "homepage": "https://github.com/abnersn/x-men-svg-filter-animation#readme", 26 | "dependencies": { 27 | "gsap": "^3.7.1", 28 | "lodash": "^4.17.21" 29 | }, 30 | "devDependencies": { 31 | "parcel-bundler": "^1.12.5" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2009 - 2021 [Codrops](https://tympanus.net/codrops) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Superhero SVG Filter Animation 2 | 3 | An interactive superhero-like illustration effect for the web using SVG filters and masks. 4 | 5 | ![Image Title](https://tympanus.net/codrops/wp-content/uploads/2021/08/mystique.jpg) 6 | 7 | [Article on Codrops](https://tympanus.net/codrops/?p=55944) 8 | 9 | [Demo](http://tympanus.net/Tutorials/Mystique/) 10 | 11 | 12 | ## Installation 13 | 14 | Install dependencies: 15 | 16 | ``` 17 | npm install 18 | ``` 19 | 20 | Compile the code for development and start a local server: 21 | 22 | ``` 23 | npm start 24 | ``` 25 | 26 | Create the build: 27 | 28 | ``` 29 | npm run build 30 | ``` 31 | 32 | ## Credits 33 | 34 | - https://inkscape.org/release/inkscape-1.1/ 35 | - https://jakearchibald.github.io/svgomg/ 36 | - https://yoksel.github.io/svg-filters/ 37 | - https://greensock.com/docs/ 38 | 39 | ## Misc 40 | 41 | Follow Abner: [GitHub](https://github.com/abnersn) 42 | 43 | Follow Codrops: [Twitter](http://www.twitter.com/codrops), [Facebook](http://www.facebook.com/codrops), [GitHub](https://github.com/codrops), [Instagram](https://www.instagram.com/codropsss/) 44 | 45 | ## License 46 | [MIT](LICENSE) 47 | 48 | Made with :blue_heart: by [Codrops](http://www.codrops.com) 49 | -------------------------------------------------------------------------------- /tutorial.md: -------------------------------------------------------------------------------- 1 | # Title (to be defined) 2 | 3 | Brief intro commenting about super hero movies and mystique. 4 | 5 | ## Creating an SVG file from a illustration 6 | 7 | Comment about illustrating with procreate, or the user's favorite illustration 8 | software. 9 | 10 | // Pic of the 2 versions I exported from procreate. 11 | 12 | Mention the importance of setting the page's dimensions correctly in inkscape. 13 | 14 | // Pic of the page definitions menu. 15 | 16 | Rasterize bitmap on inkscape. 17 | 18 | // Mention of the bitmap raster options 19 | 20 | Organize each element of the illustration into layers then exporting each 21 | layer as its own image. Export optimized svg. 22 | 23 | // Mention of svg export params 24 | 25 | Using svgo to clean up the files. 26 | 27 | // Code with the options 28 | 29 | ## Preparing the markup 30 | 31 | Very basic svg setting viewBox size to the size that was specified before. 32 | 33 | // Code 34 | 35 | Adding image links to the exported files. 36 | 37 | // Code 38 | 39 | ## CSS 40 | 41 | Briefly explain the stylesheet, it's very simple anyways. 42 | 43 | ## Adding masks 44 | 45 | Explain how masks work very quickly. 46 | 47 | // Code 48 | 49 | // Pic of where masks are positioned 50 | 51 | ## Adding SVG filters 52 | 53 | Brief comments about each filter. 54 | 55 | // Code 56 | 57 | ## Animation with GSAP 58 | 59 | Comment about GSAP 60 | 61 | // Basic looping animation code 62 | 63 | Comment about mouse events and removing the loop. 64 | 65 | // Code 66 | 67 | ## Making it interactive 68 | 69 | ## Extra 70 | 71 | Wandavision-style photo transition. 72 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | *, 2 | *::after, 3 | *::before { 4 | box-sizing: border-box; 5 | } 6 | 7 | :root { 8 | font-size: 16px; 9 | } 10 | 11 | body #cdawrap { 12 | --cda-bottom: 2rem; 13 | --cda-left: 2rem; 14 | --cda-footer-fontsize: 11px; 15 | } 16 | 17 | html, body { 18 | height: 100%; 19 | } 20 | 21 | body { 22 | margin: 0; 23 | --color-text: #fef5e7; 24 | --color-link: #f2a37c; 25 | --color-link-hover: #fef5e7; 26 | color: var(--color-text); 27 | background: radial-gradient(at top, #5e4082, #3a124d); 28 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif; 29 | -webkit-font-smoothing: antialiased; 30 | -moz-osx-font-smoothing: grayscale; 31 | } 32 | 33 | a { 34 | text-decoration: none; 35 | color: var(--color-link); 36 | outline: none; 37 | } 38 | 39 | a:hover { 40 | color: var(--color-link-hover); 41 | outline: none; 42 | } 43 | 44 | /* Better focus styles from https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible */ 45 | a:focus { 46 | /* Provide a fallback style for browsers 47 | that don't support :focus-visible */ 48 | outline: none; 49 | background: lightgrey; 50 | } 51 | 52 | a:focus:not(:focus-visible) { 53 | /* Remove the focus indicator on mouse-focus for browsers 54 | that do support :focus-visible */ 55 | background: transparent; 56 | } 57 | 58 | a:focus-visible { 59 | /* Draw a very noticeable focus style for 60 | keyboard-focus on browsers that do support 61 | :focus-visible */ 62 | outline: 2px solid red; 63 | background: transparent; 64 | } 65 | 66 | main { 67 | display: grid; 68 | height: 100%; 69 | } 70 | 71 | .frame { 72 | padding: 2rem; 73 | width: 100%; 74 | display: flex; 75 | justify-content: space-between; 76 | } 77 | 78 | .frame__title { 79 | margin: 0; 80 | font-size: 1.5rem; 81 | font-family: might-makes-right-bb, sans-serif; 82 | font-weight: 400; 83 | line-height: 1; 84 | } 85 | 86 | .frame__links a:not(:last-child) { 87 | margin-right: 1rem; 88 | } 89 | 90 | .picture { 91 | place-self: center; 92 | max-width: 100%; 93 | height: 80vh; 94 | filter: drop-shadow(2px 4px 6px rgba(0, 0, 0, 0.5)); 95 | } 96 | 97 | @media screen and (min-width: 53em) { 98 | .frame { 99 | position: absolute; 100 | } 101 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/node 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=node 4 | 5 | ### Node ### 6 | # Logs 7 | logs 8 | *.log 9 | npm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | lerna-debug.log* 13 | .pnpm-debug.log* 14 | 15 | # Diagnostic reports (https://nodejs.org/api/report.html) 16 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 17 | 18 | # Runtime data 19 | pids 20 | *.pid 21 | *.seed 22 | *.pid.lock 23 | 24 | # Directory for instrumented libs generated by jscoverage/JSCover 25 | lib-cov 26 | 27 | # Coverage directory used by tools like istanbul 28 | coverage 29 | *.lcov 30 | 31 | # nyc test coverage 32 | .nyc_output 33 | 34 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 35 | .grunt 36 | 37 | # Bower dependency directory (https://bower.io/) 38 | bower_components 39 | 40 | # node-waf configuration 41 | .lock-wscript 42 | 43 | # Compiled binary addons (https://nodejs.org/api/addons.html) 44 | build/Release 45 | 46 | # Dependency directories 47 | node_modules/ 48 | jspm_packages/ 49 | 50 | # Snowpack dependency directory (https://snowpack.dev/) 51 | web_modules/ 52 | 53 | # TypeScript cache 54 | *.tsbuildinfo 55 | 56 | # Optional npm cache directory 57 | .npm 58 | 59 | # Optional eslint cache 60 | .eslintcache 61 | 62 | # Microbundle cache 63 | .rpt2_cache/ 64 | .rts2_cache_cjs/ 65 | .rts2_cache_es/ 66 | .rts2_cache_umd/ 67 | 68 | # Optional REPL history 69 | .node_repl_history 70 | 71 | # Output of 'npm pack' 72 | *.tgz 73 | 74 | # Yarn Integrity file 75 | .yarn-integrity 76 | 77 | # dotenv environment variables file 78 | .env 79 | .env.test 80 | .env.production 81 | 82 | # parcel-bundler cache (https://parceljs.org/) 83 | .cache 84 | .parcel-cache 85 | 86 | # Next.js build output 87 | .next 88 | out 89 | 90 | # Nuxt.js build / generate output 91 | .nuxt 92 | dist 93 | 94 | # Gatsby files 95 | .cache/ 96 | # Comment in the public line in if your project uses Gatsby and not Next.js 97 | # https://nextjs.org/blog/next-9-1#public-directory-support 98 | # public 99 | 100 | # vuepress build output 101 | .vuepress/dist 102 | 103 | # Serverless directories 104 | .serverless/ 105 | 106 | # FuseBox cache 107 | .fusebox/ 108 | 109 | # DynamoDB Local files 110 | .dynamodb/ 111 | 112 | # TernJS port file 113 | .tern-port 114 | 115 | # Stores VSCode versions used for testing VSCode extensions 116 | .vscode-test 117 | 118 | # yarn v2 119 | .yarn/cache 120 | .yarn/unplugged 121 | .yarn/build-state.yml 122 | .yarn/install-state.gz 123 | .pnp.* 124 | 125 | # End of https://www.toptal.com/developers/gitignore/api/node 126 | n -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Mystique | Codrops 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 |

Superhero Animation
with SVG Filters and Masks

19 | 24 |
25 | 26 | 27 | 28 | 34 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
60 | 61 | 62 | -------------------------------------------------------------------------------- /images/background.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /images/transformed.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /images/mystique.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /images/foreground.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | --------------------------------------------------------------------------------