├── .gitignore ├── bundler └── webpack.config.js ├── contribution.md ├── dist ├── Shery.css ├── Shery.js └── Shery.js.LICENSE.txt ├── examples ├── Image Effects │ ├── Dynamic3DWaveEffect.html │ ├── Dynamic3DWindEffect.html │ ├── DynamicCyberSquaresEffect.html │ ├── DynamicDistortionEffect.html │ ├── DynamicPerlinEffect.html │ ├── InfinityGooeyEffect.html │ ├── LiquidDistortionEffect.html │ ├── media │ │ └── boy.webp │ └── style.css └── nodeExample │ ├── package-lock.json │ ├── package.json │ ├── readme.md │ ├── src │ ├── index.html │ ├── index.js │ └── styles.css │ └── webpack.config.js ├── licence.md ├── media ├── banner.png ├── debug.png ├── effect1.gif ├── effect2.gif ├── effect3.gif ├── effect4.gif ├── effect6.gif ├── effect7.gif ├── gooey.gif ├── logo.png ├── multi.gif ├── shape-controls.gif └── zoomer.gif ├── package-lock.json ├── package.json ├── presets └── wigglewobble.json ├── readme.md └── src ├── Effects.js ├── Shery.css ├── Shery.js ├── Utils.js └── shaders ├── effect1 ├── fragment.glsl └── vertex.glsl ├── effect2 ├── fragment.glsl └── vertex.glsl ├── effect3 ├── fragment.glsl └── vertex.glsl ├── effect4 ├── fragment.glsl └── vertex.glsl ├── effect5 ├── fragment.glsl └── vertex.glsl ├── effect6 ├── fragment.glsl └── vertex.glsl └── effect7 ├── fragment.glsl └── vertex.glsl /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | node_modules 3 | testing -------------------------------------------------------------------------------- /bundler/webpack.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | const path = require('path'); 3 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 4 | const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); 5 | const TerserPlugin = require('terser-webpack-plugin'); 6 | 7 | module.exports = { 8 | entry: './src/Shery.js', 9 | output: { 10 | path: path.resolve(__dirname, '../dist'), 11 | filename: 'Shery.js', 12 | library: 'Shery', 13 | libraryTarget: 'umd', 14 | umdNamedDefine: true, 15 | }, 16 | mode: 'production', 17 | module: { 18 | rules: [ 19 | { 20 | test: /\.css$/, 21 | use: [MiniCssExtractPlugin.loader, 'css-loader'], 22 | }, 23 | { 24 | test: /\.glsl$/, 25 | use: 'glsl-shader-loader', 26 | }, 27 | ], 28 | }, 29 | externals: { 30 | gsap: 'gsap', 31 | three: 'THREE', 32 | controlkit: 'ControlKit', 33 | }, 34 | plugins: [ 35 | new webpack.BannerPlugin({ 36 | banner: `@license\nCopyright 2023-${new Date().getFullYear()} Three.js Aayush Chouhan, Harsh Vandana Sharma\nLicense: MIT`, 37 | }), 38 | new MiniCssExtractPlugin({ 39 | filename: 'Shery.css', 40 | }), 41 | ], 42 | optimization: { 43 | minimize: true, 44 | minimizer: [ 45 | new CssMinimizerPlugin(), 46 | new TerserPlugin(), 47 | ], 48 | }, 49 | }; 50 | -------------------------------------------------------------------------------- /contribution.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines for Shery.js 2 | 3 | Welcome to the Shery.js open-source project! We're excited that you're interested in contributing. These guidelines are designed to help you understand how to contribute to the project effectively and maintain a collaborative and friendly environment. 4 | 5 | ## Table of Contents 6 | 7 | 1. [Getting Started](#getting-started) 8 | - [Code of Conduct](#code-of-conduct) 9 | - [Communication Channels](#communication-channels) 10 | - [Forking the Repository](#forking-the-repository) 11 | - [Setting Up the Development Environment](#setting-up-the-development-environment) 12 | 13 | 2. [Making Contributions](#making-contributions) 14 | - [Creating Issues](#creating-issues) 15 | - [Working on Issues or Features](#working-on-issues-or-features) 16 | - [Coding Guidelines](#coding-guidelines) 17 | - [Testing](#testing) 18 | - [Documentation](#documentation) 19 | 20 | 3. [Submitting Pull Requests](#submitting-pull-requests) 21 | - [Pull Request Process](#pull-request-process) 22 | - [Code Review](#code-review) 23 | 24 | 4. [Community and Collaboration](#community-and-collaboration) 25 | - [Acknowledgments](#acknowledgments) 26 | - [License](#license) 27 | 28 | ## Getting Started 29 | 30 | ### Code of Conduct 31 | 32 | Before you start contributing, please read and adhere to our [Code of Conduct](CODE_OF_CONDUCT.md). We aim to maintain a welcoming and inclusive environment for everyone. 33 | 34 | ### Communication Channels 35 | 36 | For discussions, questions, and collaboration, join our [communication channel](link_to_channel) (e.g., Slack, Discord, Gitter). 37 | 38 | ### Forking the Repository 39 | 40 | Fork the repository to your GitHub account. This will create a copy of the project in your account that you can freely experiment with. 41 | 42 | ### Setting Up the Development Environment 43 | 44 | 1. Clone your forked repository to your local machine. 45 | 2. Navigate to the repository's directory. 46 | 3. Run `npm install` to install the project dependencies. 47 | 4. You might need to set up any environment variables required for the project. 48 | 5. Start the development server with `npm start` or your preferred method. 49 | 50 | ## Making Contributions 51 | 52 | ### Creating Issues 53 | 54 | If you find a bug, have a feature request, or want to suggest an improvement, open an issue in the [issue tracker](link_to_issue_tracker). Make sure to provide sufficient details to reproduce the issue or understand the proposed feature. 55 | 56 | ### Working on Issues or Features 57 | 58 | 1. Assign yourself to an open issue you'd like to work on. 59 | 2. Create a new branch for your work based on the latest `main` branch. 60 | 3. Implement your changes, following the coding guidelines. 61 | 4. Write tests for the new code or modifications. 62 | 5. Update the documentation if necessary. 63 | 64 | ### Coding Guidelines 65 | 66 | - Follow [JavaScript style guide](link_to_style_guide) for code formatting. 67 | - Write clear and meaningful commit messages. 68 | - Keep your code modular and well-documented. 69 | 70 | ### Testing 71 | 72 | - Write unit tests and integration tests for your code. 73 | - Run the existing tests using `npm test` to ensure you didn't break anything. 74 | 75 | ### Documentation 76 | 77 | - Document any new features or changes you've made. 78 | - Ensure that your documentation is clear and easy to understand. 79 | 80 | ## Submitting Pull Requests 81 | 82 | ### Pull Request Process 83 | 84 | 1. Create a pull request from your branch to the original repository's `main` branch. 85 | 2. Include a descriptive title and detailed description of the changes. 86 | 3. Reference any related issues in your pull request description. 87 | 88 | ### Code Review 89 | 90 | - Expect feedback and be ready to make changes if necessary. 91 | - Maintain a constructive and respectful attitude during code review. 92 | 93 | ## Community and Collaboration 94 | 95 | ### Acknowledgments 96 | 97 | We appreciate all contributions to the project. Contributors will be acknowledged in the project's README or a dedicated contributors list. 98 | 99 | ### License 100 | 101 | By contributing, you agree that your contributions will be licensed under the [project's license](LICENSE.md). 102 | 103 | Thank you for your interest and contributions to Shery.js! Your efforts help make this project better for everyone. 104 | -------------------------------------------------------------------------------- /dist/Shery.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * @license 3 | * Copyright 2023-2023 Three.js Aayush Chouhan, Harsh Vandana Sharma 4 | * License: MIT 5 | */:root{--mousefollowercolor:#000}body{background-color:#fff}.mousefollower{background-color:var(--mousefollowercolor);border-radius:50%;height:15px;left:-10%;mix-blend-mode:exclusion;pointer-events:none;position:fixed;top:-10%;transform:translate(-50%,-50%);width:15px;z-index:99999}#behindmouse{background-color:#fff}.mask{display:inline-block;overflow:hidden;position:relative}.circle{align-items:center;background-color:#000000e8;border-radius:50%;box-sizing:content-box;color:#fff;display:flex;font-family:inherit;font-size:10px;justify-content:center;left:-10%;padding:10px;pointer-events:none;position:absolute;text-align:center;top:-10%;transform:translate(-50%,-50%);z-index:9999}.parent,.sheryelem span{display:inline-block}#controlKit .panel .group-list .group .sub-group-list .sub-group ul li,#controlKit .panel .scrollBar{background-color:#181c20!important;background-image:none!important}#controlKit .panel .head,#controlKit .panel .panel-head-inactive,#controlKit .picker,#controlKit .picker .head{background-color:#292d39!important}#controlKit .panel .button,#controlKit .picker .button{background-color:#383c4a;background-image:none!important;border-radius:7px!important;box-shadow:none!important;color:#8c92a4;font-size:.9em!important;font-weight:800!important;text-shadow:none!important}#controlKit .picker canvas{position:relative}#controlKit .panel .button:hover{background-color:#007bff!important;color:#fff!important}#controlKit .panel .button:active{background-color:#292d39!important;color:#fff!important}#controlKit .panel .group-list .group .sub-group-list .sub-group .head .wrap .label,#controlKit .panel .group-list .group .sub-group-list .sub-group .head-inactive .wrap .label,#controlKit .panel .head .label,#controlKit .picker .head .label{color:#8c92a4!important;font-size:.8em!important;font-weight:800!important;text-shadow:none!important}#controlKit .panel .scrollBar .track .thumb{background-color:#383c4a!important;box-shadow:none!important}#controlKit .panel .group-list .group .sub-group-list .sub-group .head-inactive,#controlKit .panel .select,#controlKit .panel .select-active{background:#292d39!important;border-radius:7px!important;box-shadow:none!important;color:#8c92a4!important;text-align:center!important;text-shadow:none!important}#controlKit .options,#controlKit .options ul,#controlKit .options ul li,#controlKit .panel{background-color:#fff;border-radius:7px!important;color:#000;text-align:center!important;text-shadow:none!important}ul.sub-group-list{margin-top:5px!important}#controlKit .options ul .li-selected,#controlKit .options ul li:hover,#controlKit .panel .slider-handle{background:#007bff!important}#controlKit .panel .group-list .group .sub-group-list .sub-group .wrap .label{width:auto!important}#controlKit{position:fixed!important;z-index:1000000000000000000}#controlKit .panel .menu input[type=button],#controlKit .panel .menu input[type=button]:hover,#controlKit .panel .menu-active input[type=button],#controlKit .picker .menu input[type=button]{background-color:#00000000;box-shadow:none!important}.hovercircle{display:inline-block;position:relative;z-index:5}.hovercircle:hover{color:#000;transition:all 1s cubic-bezier(.19,1,.22,1)}.movercirc{border-radius:50%;height:0;left:0;max-height:250px;max-width:250px;mix-blend-mode:exclusion;opacity:0;overflow:hidden;pointer-events:none;position:fixed;top:0;width:0;z-index:15}.movercirc img{height:100%;left:50%;object-fit:cover;position:absolute;top:50%;transform:translate(-50%,-50%);width:100%}.movercirc.blend{filter:invert(1);mix-blend-mode:exclusion}.just-a-white-blend-screen{background:#fff}.movercirc video{left:50%;position:absolute;top:50%;transform:translate(-50%,-50%) scale(1.3)}._canvas_container{height:100vh;left:0;pointer-events:none;position:fixed;top:0;width:100vw;z-index:-9996999} -------------------------------------------------------------------------------- /dist/Shery.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /*! 2 | * @license 3 | * Copyright 2023-2023 Three.js Aayush Chouhan, Harsh Vandana Sharma 4 | * License: MIT 5 | */ 6 | 7 | /*! 8 | * GSAP 3.12.2 9 | * https://greensock.com 10 | * 11 | * @license Copyright 2008-2023, GreenSock. All rights reserved. 12 | * Subject to the terms at https://greensock.com/standard-license or for 13 | * Club GreenSock members, the agreement issued with that membership. 14 | * @author: Jack Doyle, jack@greensock.com 15 | */ 16 | 17 | //!SECTION 18 | 19 | //!STUB 20 | -------------------------------------------------------------------------------- /examples/Image Effects/Dynamic3DWaveEffect.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | 14 | 46 |
47 |
48 |
49 |
50 |

Learn from the coolest
coding platform
in
India.

51 |
52 | Top notch projects 53 |
54 |
55 | Support via mentors 56 |
57 | Explore our courses 58 |
59 |
60 | 61 |
62 | 66 |
67 |
68 |
69 | 70 |
71 | 72 |
73 |
74 |
75 |
76 | 77 |
78 | 79 | 80 | 81 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /examples/Image Effects/Dynamic3DWindEffect.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | 14 | 46 |
47 |
48 |
49 |
50 |

Learn from the coolest
coding platform
in
India.

51 |
52 | Top notch projects 53 |
54 |
55 | Support via mentors 56 |
57 | Explore our courses 58 |
59 |
60 | 61 |
62 | 66 |
67 |
68 |
69 | 70 |
71 | 72 |
73 |
74 |
75 |
76 | 77 |
78 | 79 | 80 | 81 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /examples/Image Effects/DynamicCyberSquaresEffect.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | 14 | 46 |
47 |
48 |
49 |
50 |

Learn from the coolest
coding platform
in
India.

51 |
52 | Top notch projects 53 |
54 |
55 | Support via mentors 56 |
57 | Explore our courses 58 |
59 |
60 | 61 |
62 | 66 |
67 |
68 |
69 | 70 |
71 | 72 |
73 |
74 |
75 |
76 | 77 |
78 | 79 | 80 | 81 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /examples/Image Effects/DynamicDistortionEffect.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | 14 | 46 |
47 |
48 |
49 |
50 |

Learn from the coolest
coding platform
in
India.

51 |
52 | Top notch projects 53 |
54 |
55 | Support via mentors 56 |
57 | Explore our courses 58 |
59 |
60 | 61 |
62 | 66 |
67 |
68 |
69 |
70 | 71 |
72 |
73 |
74 |
75 | 76 |
77 | 78 | 79 | 80 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /examples/Image Effects/DynamicPerlinEffect.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | 14 | 46 |
47 |
48 |
49 |
50 |

Learn from the coolest
coding platform
in
India.

51 |
52 | Top notch projects 53 |
54 |
55 | Support via mentors 56 |
57 | Explore our courses 58 |
59 |
60 | 61 |
62 | 66 |
67 |
68 |
69 | 70 |
71 | 72 |
73 |
74 |
75 |
76 | 77 |
78 | 79 | 80 | 81 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /examples/Image Effects/InfinityGooeyEffect.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Infinite gooey 8 | 9 | 21 | 22 | 23 | 24 |
25 | 26 | 27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /examples/Image Effects/LiquidDistortionEffect.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | 14 | 46 |
47 |
48 |
49 |
50 |

Learn from the coolest
coding platform
in
India.

51 |
52 | Top notch projects 53 |
54 |
55 | Support via mentors 56 |
57 | Explore our courses 58 |
59 |
60 | 61 |
62 | 66 |
67 |
68 |
69 | 70 |
71 | 72 |
73 |
74 |
75 |
76 | 77 |
78 | 79 | 80 | 81 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /examples/Image Effects/media/boy.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithUsman0/sheryjs/8db24d6c479f771a57870f75c1b68149e850832a/examples/Image Effects/media/boy.webp -------------------------------------------------------------------------------- /examples/Image Effects/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | overflow-x: hidden; 6 | font-family: "Gilroy"; 7 | text-rendering: geometricPrecision; 8 | font-synthesis: weight; 9 | overflow: hidden; 10 | } 11 | 12 | html, 13 | body { 14 | width: 100%; 15 | height: 100%; 16 | } 17 | 18 | body { 19 | /* background-color: red; */ 20 | padding-bottom: 0vh; 21 | } 22 | 23 | #nav-main { 24 | position: fixed !important; 25 | z-index: 100; 26 | padding: 0 0.5vw; 27 | transition: all cubic-bezier(0.19, 1, 0.22, 1) 0.5s; 28 | z-index: 99999; 29 | width: 100vw; 30 | margin-bottom: 0vh; 31 | background-color: transparent; 32 | height: 7vh; 33 | display: flex; 34 | justify-content: space-between; 35 | } 36 | 37 | #left-main-nav { 38 | width: 25vw; 39 | height: 100%; 40 | display: flex; 41 | justify-content: flex-start; 42 | padding: 0vw; 43 | padding-left: 3vw; 44 | align-items: center; 45 | overflow: hidden; 46 | } 47 | 48 | #left-main-nav img { 49 | z-index: 90; 50 | height: 2.3vw; 51 | } 52 | 53 | #nav-main-line { 54 | z-index: 90; 55 | width: 2px; 56 | margin: 0 1vw; 57 | height: 40%; 58 | background-color: rgb(157, 157, 157); 59 | } 60 | 61 | #left-main-nav a { 62 | font-size: 1.1vw; 63 | transition: all cubic-bezier(0.19, 1, 0.22, 1) 1s; 64 | } 65 | 66 | #nav-main a { 67 | text-decoration: none; 68 | z-index: 90; 69 | color: #222222; 70 | } 71 | 72 | #left-main-nav a h4, 73 | #right-main-nav a h4 { 74 | font-weight: 600; 75 | } 76 | 77 | #right-main-nav { 78 | transition: all cubic-bezier(0.19, 1, 0.22, 1) 1s; 79 | width: 55vw; 80 | height: 100%; 81 | display: flex; 82 | align-items: center; 83 | padding: 0 1.2vw; 84 | justify-content: space-between !important; 85 | margin-right: 1vw; 86 | } 87 | 88 | #right-main-nav a { 89 | margin-right: 0vw !important; 90 | font-size: 1.1vw; 91 | } 92 | 93 | img { 94 | overflow-clip-margin: content-box; 95 | overflow: clip; 96 | } 97 | 98 | 99 | #page-1 { 100 | width: 100vw; 101 | display: flex; 102 | } 103 | 104 | #page-1-left { 105 | display: flex; 106 | align-items: center; 107 | justify-content: center; 108 | height: 100vh; 109 | width: 50vw; 110 | } 111 | 112 | #page-1-main { 113 | font-size: 1.7vw; 114 | font-weight: 900; 115 | } 116 | 117 | #page-1-main h1 { 118 | 119 | padding-bottom: 2vh; 120 | font-family: "Gilroy"; 121 | font-weight: 600; 122 | font-size: 4vw; 123 | 124 | 125 | } 126 | 127 | #page-1-main h1 span { 128 | font-family: "Gilroy"; 129 | 130 | color: #289e8a; 131 | } 132 | 133 | #page-1-main h6 { 134 | align-items: center; 135 | display: flex; 136 | font-family: "Gilroy"; 137 | font-weight: 600; 138 | margin-top: 20px; 139 | } 140 | 141 | #page-1-main h6 i { 142 | margin-right: 1vw; 143 | background-color: #289e8a; 144 | color: #fff; 145 | height: 27px; 146 | font-size: 15px; 147 | width: 27px; 148 | border-radius: 50%; 149 | display: flex; 150 | align-items: center; 151 | justify-content: center; 152 | } 153 | 154 | #page-1-right { 155 | display: flex; 156 | align-items: center; 157 | justify-content: center; 158 | object-fit: cover; 159 | height: 100vh; 160 | width: 50vw; 161 | background-size: cover; 162 | background-position: center; 163 | } 164 | 165 | 166 | #cta { 167 | display: inline-block; 168 | text-decoration: none; 169 | padding: 1.5vw 2vw; 170 | font-size: 1vw; 171 | margin-top: 3vw; 172 | font-weight: 500; 173 | color: #fff; 174 | border-radius: 5px; 175 | background-color: #289e8a; 176 | } 177 | 178 | #cta:hover { 179 | background-color: #196659; 180 | } 181 | 182 | #form button:hover { 183 | background-color: #A5DDD4; 184 | color: black 185 | } 186 | 187 | 188 | #page1-down { 189 | margin-top: 5vh; 190 | width: 35vw; 191 | padding: 2px; 192 | display: flex; 193 | align-items: center; 194 | } 195 | 196 | #page1-down #left { 197 | display: flex; 198 | align-items: center; 199 | justify-content: center; 200 | width: 40px; 201 | height: 40px; 202 | border-radius: 50%; 203 | background-color: #A5DDD4; 204 | } 205 | 206 | #page1-down #left img { 207 | width: 50%; 208 | } 209 | 210 | #page1-down #right { 211 | height: 100%; 212 | width: 85%; 213 | font-size: 0.9vw; 214 | padding: 10px; 215 | font-family: "Gilroy"; 216 | font-weight: 600; 217 | } 218 | 219 | #chat-button { 220 | position: absolute; 221 | bottom: 50px; 222 | width: 50px; 223 | font-size: 25px; 224 | color: white; 225 | display: flex; 226 | justify-content: center; 227 | align-items: center; 228 | height: 50px; 229 | border-radius: 50%; 230 | right: 50px; 231 | transition: 0.3s; 232 | z-index: 999999; 233 | background-color: rgb(65, 150, 225); 234 | } -------------------------------------------------------------------------------- /examples/nodeExample/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nodeExample", 3 | "version": "1.0.0", 4 | "description": "A Webpack App", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --open --mode development", 8 | "build": "webpack --mode production" 9 | }, 10 | "devDependencies": { 11 | "@babel/core": "^7.22.11", 12 | "@babel/preset-env": "^7.22.10", 13 | "babel-loader": "^9.1.3", 14 | "css-loader": "^6.8.1", 15 | "glslify-loader": "^2.0.0", 16 | "html-loader": "^4.2.0", 17 | "html-webpack-plugin": "^5.5.3", 18 | "mini-css-extract-plugin": "^2.7.6", 19 | "raw-loader": "^4.0.2", 20 | "terser-webpack-plugin": "^5.3.9", 21 | "webpack": "^5.88.2", 22 | "webpack-cli": "^4.10.0", 23 | "webpack-dev-server": "^4.15.1" 24 | }, 25 | "dependencies": { 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/nodeExample/readme.md: -------------------------------------------------------------------------------- 1 | # Using Sheryjs Library with Node Project 2 | 3 | This README provides a step-by-step guide on how to integrate and use the `sheryjs` library in a webpack project. `sheryjs` is a library that provides various effects for enhancing user interfaces. 4 | 5 | ## Prerequisites 6 | 7 | Before you begin, ensure that you have the following prerequisites installed: 8 | 9 | 1. Node.js and npm (Node Package Manager) 10 | 2. Basic understanding of node 11 | 12 | ## Step 1: Create a Webpack Project 13 | 14 | 1. Install the `generate-webpack` library globally using the following command: 15 | 16 | ```bash 17 | npm install -g generate-webpack 18 | ``` 19 | 20 | 2. Generate a new webpack project using `generate-webpack`: 21 | 22 | ```bash 23 | generate-webpack ProjectName 24 | ``` 25 | 26 | 3. Open the generated project in your preferred integrated development environment (IDE). We recommend using Visual Studio Code (VSCode). 27 | 28 | ## Step 2: Install and Use sheryjs 29 | 30 | 1. In the terminal, navigate to the root of your generated project. 31 | 2. Install the `sheryjs` library using npm: 32 | 33 | ```bash 34 | npm install sheryjs 35 | ``` 36 | 37 | 3. In the `src` folder (located in the root of your project), open the `index.js` file. 38 | 4. Import the `sheryjs` library at the top of the `index.js` file: 39 | 40 | ```javascript 41 | import Shery from 'sheryjs'; 42 | ``` 43 | 44 | 5. You can now utilize the effects provided by `sheryjs` in your project. For example: 45 | 46 | ```javascript 47 | // Example usage of sheryjs effect 48 | Shery.mouseFollower(); 49 | ``` 50 | 51 | ## Step 3: Build and Run 52 | 53 | 1. After importing and using `sheryjs` in your project, you can build your webpack project using the following command: 54 | 55 | ```bash 56 | npm run build 57 | ``` 58 | 59 | 2. Open the generated `dist` folder and locate the `index.html` file. 60 | 3. Open the `index.html` file in a web browser to see the effects applied by the `sheryjs` library. 61 | 62 | ## Conclusion 63 | 64 | Congratulations! You have successfully integrated and used the `sheryjs` library in a webpack project. You can explore and utilize various effects provided by the library to enhance the user experience of your web application. 65 | 66 | For more information and documentation about the available effects and customization options, please refer to the official documentation of the `sheryjs` library. 67 | 68 | **Note:** This README provides a basic example of using the `sheryjs` library in a webpack project. Depending on your project's complexity and requirements, you may need to adjust the configurations and usage accordingly. 69 | -------------------------------------------------------------------------------- /examples/nodeExample/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 |
12 | 14 | 16 | 18 |
19 |

Tiny world, big dreams

20 | 21 | 22 | -------------------------------------------------------------------------------- /examples/nodeExample/src/index.js: -------------------------------------------------------------------------------- 1 | import './styles.css' 2 | import Shery from '../.././../src/Shery' 3 | import * as THREE from "three" 4 | import gsap from 'gsap' 5 | 6 | Shery.imageEffect('.img', { 7 | style: 2, 8 | debug: true, 9 | config: { "resolutionXY": { "value": 100 }, "distortion": { "value": true }, "mode": { "value": -3 }, "mousemove": { "value": 0 }, "modeA": { "value": 1 }, "modeN": { "value": 0 }, "speed": { "value": 0.77, "range": [-500, 500], "rangep": [-10, 10] }, "frequency": { "value": 50, "range": [-800, 800], "rangep": [-50, 50] }, "angle": { "value": 1.13, "range": [0, 3.141592653589793] }, "waveFactor": { "value": 1.4, "range": [-3, 3] }, "color": { "value": 10212607 }, "pixelStrength": { "value": -3.85, "range": [-20, 100], "rangep": [-20, 20] }, "quality": { "value": 10, "range": [0, 10] }, "contrast": { "value": 1, "range": [-25, 25] }, "brightness": { "value": 1, "range": [-1, 25] }, "colorExposer": { "value": 0.19, "range": [-5, 5] }, "strength": { "value": 0.13, "range": [-40, 40], "rangep": [-5, 5] }, "exposer": { "value": 8, "range": [-100, 100] }, "zindex": { "value": -9996999, "range": [-9999999, 9999999] }, "aspect": { "value": 1.847763391800257 }, "ignoreShapeAspect": { "value": true }, "shapePosition": { "value": { "x": 0, "y": -0.30 } }, "shapeScale": { "value": { "x": 0.49, "y": 0.95 } }, "shapeEdgeSoftness": { "value": 0.5, "range": [0, 0.5], "_gsap": { "id": 2 } }, "shapeRadius": { "value": 2, "range": [0, 2], "_gsap": { "id": 1 } }, "currentScroll": { "value": 0 }, "scrollLerp": { "value": 0.07 }, "gooey": { "value": true }, "infiniteGooey": { "value": true }, "growSize": { "value": 1, "range": [1, 15] }, "durationOut": { "value": 2.46, "range": [0.1, 5] }, "durationIn": { "value": 1.5, "range": [0.1, 5] }, "displaceAmount": { "value": 0.5 }, "masker": { "value": false }, "maskVal": { "value": 1, "range": [1, 5] }, "scrollType": { "value": 0 }, "geoVertex": { "range": [1, 64], "value": 1 }, "noEffectGooey": { "value": false }, "onMouse": { "value": 0 }, "noise_speed": { "value": 1.3, "range": [0, 10] }, "metaball": { "value": 0.14, "range": [0, 2], "_gsap": { "id": 3 } }, "discard_threshold": { "value": 0.54, "range": [0, 1] }, "antialias_threshold": { "value": 0.06, "range": [0, 0.1] }, "noise_height": { "value": 0.5, "range": [0, 2] }, "noise_scale": { "value": 6.11, "range": [0, 100] } }, 10 | gooey: true, 11 | setUniforms: (uniforms) => { 12 | gsap.to(uniforms.shapeRadius, { "value": 0.2, duration: 2 }) 13 | gsap.to(document.querySelector('h1'), { "opacity": 1, duration: 2, delay: 1 }) 14 | gsap.to(uniforms.shapeEdgeSoftness, { "value": 0, duration: 2 }) 15 | setTimeout(() => { 16 | Shery.textAnimate("h1", { 17 | style: 2, 18 | multiplier: 0.1, 19 | }) 20 | }, 1000) 21 | } 22 | }) 23 | Shery.makeMagnet("h1", { 24 | ease: "cubic-bezier(0.23, 1, 0.320, 1)", 25 | duration: 1, 26 | }) 27 | -------------------------------------------------------------------------------- /examples/nodeExample/src/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | height: 100vh; 5 | display: flex; 6 | align-items: center; 7 | justify-content: center; 8 | background-color: black !important; 9 | overflow: hidden; 10 | } 11 | 12 | .img { 13 | width: 90vw; 14 | height:90vh; 15 | overflow: hidden; 16 | } 17 | 18 | h1 { 19 | position: absolute; 20 | width: 100%; 21 | text-align: center; 22 | font-size: 8vw; 23 | color: white; 24 | opacity: 0; 25 | text-shadow: 0 0 3px #3bc60c40, 0 0 5px rgba(0, 0, 0, 0.296); 26 | } -------------------------------------------------------------------------------- /examples/nodeExample/webpack.config.js: -------------------------------------------------------------------------------- 1 | 2 | const path = require('path'); 3 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 4 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 5 | const TerserPlugin = require('terser-webpack-plugin'); 6 | 7 | module.exports = { 8 | entry: './src/index.js', 9 | output: { 10 | path: path.resolve(__dirname, 'dist'), 11 | filename: 'bundle.js', 12 | publicPath: '/', 13 | }, 14 | optimization: { 15 | minimize: true, 16 | minimizer: [new TerserPlugin()], 17 | }, 18 | module: { 19 | rules: [ 20 | { 21 | test: /.(html)$/, 22 | use: ['html-loader'], 23 | }, 24 | { 25 | test: /.js$/, 26 | exclude: /node_modules/, 27 | use: ['babel-loader'], 28 | }, 29 | { 30 | test: /.css$/, 31 | use: [MiniCssExtractPlugin.loader, 'css-loader'], 32 | }, 33 | { 34 | test: /.(jpg|png|gif|svg)$/, 35 | type: 'asset/resource', 36 | generator: { 37 | filename: 'assets/images/[hash][ext]', 38 | }, 39 | }, 40 | { 41 | test: /.(glsl|frag|vert)$/, 42 | use: ['raw-loader', 'glslify-loader'], 43 | }, 44 | ], 45 | }, 46 | plugins: [ 47 | new HtmlWebpackPlugin({ 48 | template: './src/index.html', 49 | }), 50 | new MiniCssExtractPlugin({ 51 | filename: 'styles.css', 52 | }), 53 | ], 54 | devServer: { 55 | static: path.resolve(__dirname, 'dist'), 56 | port: 4000, 57 | }, 58 | }; -------------------------------------------------------------------------------- /licence.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright 2023 [Harsh Vandana Sharma](https://github.com/asynchronousJavascriptor) and [Aayush Chouhan](https://github.com/aayushchouhan24) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /media/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithUsman0/sheryjs/8db24d6c479f771a57870f75c1b68149e850832a/media/banner.png -------------------------------------------------------------------------------- /media/debug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithUsman0/sheryjs/8db24d6c479f771a57870f75c1b68149e850832a/media/debug.png -------------------------------------------------------------------------------- /media/effect1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithUsman0/sheryjs/8db24d6c479f771a57870f75c1b68149e850832a/media/effect1.gif -------------------------------------------------------------------------------- /media/effect2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithUsman0/sheryjs/8db24d6c479f771a57870f75c1b68149e850832a/media/effect2.gif -------------------------------------------------------------------------------- /media/effect3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithUsman0/sheryjs/8db24d6c479f771a57870f75c1b68149e850832a/media/effect3.gif -------------------------------------------------------------------------------- /media/effect4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithUsman0/sheryjs/8db24d6c479f771a57870f75c1b68149e850832a/media/effect4.gif -------------------------------------------------------------------------------- /media/effect6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithUsman0/sheryjs/8db24d6c479f771a57870f75c1b68149e850832a/media/effect6.gif -------------------------------------------------------------------------------- /media/effect7.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithUsman0/sheryjs/8db24d6c479f771a57870f75c1b68149e850832a/media/effect7.gif -------------------------------------------------------------------------------- /media/gooey.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithUsman0/sheryjs/8db24d6c479f771a57870f75c1b68149e850832a/media/gooey.gif -------------------------------------------------------------------------------- /media/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithUsman0/sheryjs/8db24d6c479f771a57870f75c1b68149e850832a/media/logo.png -------------------------------------------------------------------------------- /media/multi.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithUsman0/sheryjs/8db24d6c479f771a57870f75c1b68149e850832a/media/multi.gif -------------------------------------------------------------------------------- /media/shape-controls.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithUsman0/sheryjs/8db24d6c479f771a57870f75c1b68149e850832a/media/shape-controls.gif -------------------------------------------------------------------------------- /media/zoomer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithUsman0/sheryjs/8db24d6c479f771a57870f75c1b68149e850832a/media/zoomer.gif -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sheryjs", 3 | "version": "1.0.0-beta.0.1.7", 4 | "description": "Shery.js: JavaScript library for captivating web effects and 3D features.", 5 | "main": "src/Shery.js", 6 | "directories": { 7 | "example": "examples" 8 | }, 9 | "scripts": { 10 | "build": "webpack --config bundler/webpack.config.js" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "https://bit.ly/sheryjs" 15 | }, 16 | "keywords": [ 17 | "javascript", 18 | "library", 19 | "web-development", 20 | "3D-features", 21 | "three.js" 22 | ], 23 | "author": "@aayushchouhan24, @asynchronousJavascriptor", 24 | "license": "MIT", 25 | "bugs": { 26 | "url": "https://bit.ly/sheryjs-issues" 27 | }, 28 | "homepage": "https://bit.ly/sheryjs-homepage", 29 | "dependencies": { 30 | "controlkit": "^0.1.9", 31 | "gsap": "^3.12.2", 32 | "three": "^0.155.0" 33 | }, 34 | "files": [ 35 | "dist", 36 | "src" 37 | ], 38 | "style": "src/Shery.css", 39 | "devDependencies": { 40 | "css-loader": "^6.8.1", 41 | "css-minimizer-webpack-plugin": "^5.0.1", 42 | "glsl-shader-loader": "^0.1.6", 43 | "mini-css-extract-plugin": "^2.7.6", 44 | "terser-webpack-plugin": "^5.3.9", 45 | "webpack": "^5.88.2", 46 | "webpack-cli": "^5.1.4", 47 | "webpack-dev-server": "^4.15.1" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /presets/wigglewobble.json: -------------------------------------------------------------------------------- 1 | { 2 | "distortion": { "value": true }, 3 | "mode": { "value": -10 }, 4 | "mousemove": { "value": 3 }, 5 | "modeA": { "value": 1 }, 6 | "modeN": { "value": 3 }, 7 | "speed": { "value": 10, "range": [-500, 500], "rangep": [-10, 10] }, 8 | "frequency": { "value": 26.92, "range": [-800, 800], "rangep": [-50, 50] }, 9 | "angle": { "value": 0, "range": [0, 3.141592653589793] }, 10 | "waveFactor": { "value": -1.19, "range": [-3, 3] }, 11 | "color": { "value": 5548287 }, 12 | "pixelStrength": { "value": 100, "range": [-20, 100], "rangep": [-20, 20] }, 13 | "quality": { "value": 10, "range": [0, 10] }, 14 | "contrast": { "value": 1, "range": [-25, 25] }, 15 | "brightness": { "value": 1, "range": [-1, 25] }, 16 | "colorExposer": { "value": -0.58, "range": [-5, 5] }, 17 | "strength": { "value": 0.19, "range": [-40, 40], "rangep": [-5, 5] }, 18 | "exposer": { "value": -57.69, "range": [-100, 100] }, 19 | "onMouse": { "value": 0 } 20 | } 21 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Shery.js - Add Life to Your Web Experience 2 | 3 | ![Shery.js Logo](https://cdn.jsdelivr.net/gh/aayushchouhan24/sheryjs@main/media/banner.png) 4 | 5 | Shery.js is a fantastic JavaScript library designed to make your web projects pop with eye-catching effects and mesmerizing 3D features. Whether you're a developer looking to jazz up your website or a designer wanting to add that extra flair, Shery.js has got you covered. This GitHub readme will walk you through the key aspects of using Shery.js in your web development journey. 6 | 7 | ## Table of Contents 8 | 9 | 1. [Introduction](#introduction) 10 | 2. [Installation](#installation) 11 | 3. [Getting Started](#getting-started) 12 | - Required Libraries 13 | 4. [Cool Effects](#cool-effects) 14 | - Mouse Follower 15 | - Image Masker / Mask Zoomer 16 | - Make Magnet 17 | - Text Animate 18 | - Hover With Media Circle 19 | 5. [3D Image Effects](#3d-image-effects) 20 | - Simple Liquid Distortion Effect 21 | - Dynamic Distortion Effect 22 | - Dynamic 3D Wave/Wobble Effect 23 | - Dynamic 3D Wind Effect 24 | - Dynamic Perlin Noise Effect 25 | - Dynamin Cyber Squares Effect 26 | 6. [Dynamic Gooey Effect](#dynamic-gooey-effect) 27 | 7. [Dynamic Zoom Effect](#dynamic-zoom-effect) 28 | 8. [Shape Controls](#shape-controls) 29 | 9. [Multiple Image (Scroll Effect)](#multiple-image-scroll-effect) 30 | - Custom Scroll Trigger Callback 31 | 10. [Debug Usage](#debug-usage) 32 | - Preset Usage 33 | 11. [Callback Usage](#callback-usage) 34 | 12. [Examples](#examples) 35 | 13. [Contributing](#contributing) 36 | 14. [License](#license) 37 | 38 | ## Introduction 39 | 40 | Shery.js is designed to make it easy for developers to incorporate cool visual effects into their web applications without the need for complex and time-consuming coding. The library leverages the power of Three.js to create stunning 3D effects and animations, and also provides simpler 2D effects for added versatility. 41 | 42 | ## Installation 43 | 44 | To use Shery.js in your project, you can include it in your HTML file via a CDN or import it in js by using node. 45 | 46 | When using node or browserify install 47 | 48 | ```bash 49 | npm install sheryjs 50 | ``` 51 | 52 | and require 53 | 54 | ```javascript 55 | import Shery from "sheryjs"; 56 | ``` 57 | 58 | To understand clearly see this [Example](/examples/nodeExample/). 59 | 60 | Alternatively use the standalone version found in ./dist locally 61 | 62 | ```html 63 | 64 | ``` 65 | 66 | ```html 67 | 68 | ``` 69 | 70 | or use CDN version any one **only** `CSS`. 71 | 72 | ```html 73 | 74 | ``` 75 | 76 | OR 77 | 78 | ```html 79 | 80 | ``` 81 | 82 | --- 83 | 84 | Use **only** one `JAVASCRIP CDN` 85 | 86 | ```html 87 | 88 | ``` 89 | 90 | OR 91 | 92 | ```html 93 | 94 | ``` 95 | 96 | ## Getting Started 97 | 98 | Once you have included Shery.js in your project, you can start using its effects and Three.js functionalities. The library provides a straightforward API to make implementation easier. 99 | 100 | ```javascript 101 | // Example code to initialize Shery.js and use a cool effect. 102 | 103 | import Shery from "sheryjs"; /*Don't use if using CDN*/ 104 | 105 | Shery.mouseFollower(); 106 | ``` 107 | 108 | ### Required Libraries 109 | 110 | To successfully run with CDN, you'll need some libraries. 111 | 112 | ```html 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | ``` 125 | 126 | ## Cool Effects 127 | 128 | These are effects are implemented with the help of Gsap and Css to offer a unique experience with single function. 129 | 130 | ### Mouse Follower 131 | 132 | The feature creates smooth mouse follower, creating an engaging user experience. 133 | 134 | ```javascript 135 | Shery.mouseFollower({ 136 | //Parameters are optional. 137 | skew: true, 138 | ease: "cubic-bezier(0.23, 1, 0.320, 1)", 139 | duration: 1, 140 | }); 141 | ``` 142 | 143 | ### Mask Zoomer 144 | 145 | The mask zoomer effect enables zooming into an image on mouse hover with a smooth mask transition, directing the user's focus to the targeted content. 146 | 147 | ```javascript 148 | Shery.imageMasker(".mask-target" /* Element to target.*/, { 149 | //Parameters are optional. 150 | mouseFollower: true, 151 | text: "Shery", 152 | ease: "cubic-bezier(0.23, 1, 0.320, 1)", 153 | duration: 1, 154 | }); 155 | ``` 156 | 157 | ### Make Magnet 158 | 159 | The magnet mouse attractor effect draws elements towards the cursor, as if they are magnetically attracted, offering a unique and interactive experience. 160 | 161 | ```javascript 162 | Shery.makeMagnet(".magnet-target" /* Element to target.*/, { 163 | //Parameters are optional. 164 | ease: "cubic-bezier(0.23, 1, 0.320, 1)", 165 | duration: 1, 166 | }); 167 | ``` 168 | 169 | ### Text Animate 170 | 171 | The text animate effect animates text with cool animation , with many preset animation, offering a unique experience. 172 | 173 | ```javascript 174 | Shery.textAnimate(".text-target" /* Element to target.*/, { 175 | //Parameters are optional. 176 | style: 1, 177 | y: 10, 178 | delay: 0.1, 179 | duration: 2, 180 | ease: "cubic-bezier(0.23, 1, 0.320, 1)", 181 | multiplier: 0.1, 182 | }); 183 | ``` 184 | 185 | ### Hover With Media Circle 186 | 187 | The hover with media circle effect creates a circular media element (image or video) which follows the cursor's movement when hovering over specified elements with blending effect. This effect provides an engaging way to showcase media content associated with the hovered elements. 188 | 189 | ```javascript 190 | Shery.hoverWithMediaCircle(".hover-target" /* Element to target.*/, { 191 | images: ["image1.jpg", "image2.jpg", "image3.jpg"] /*OR*/, 192 | //videos: ["video1.mp4", "video2.mp4"], 193 | }); 194 | ``` 195 | 196 | ## 3D Image Effects 197 | 198 | These are effects are implemented with the help of Three.js to offer a unique experience with single function. 199 | 200 | ```html 201 | //Must provide a class to image. 202 | ``` 203 | 204 | ```javascript 205 | Shery.imageEffect(".img", { 206 | style: 2, //Select Style 207 | debug: true, // Debug Panel 208 | config: { 209 | /* Config made from debug panel */ 210 | }, 211 | preset: "./presets/wigglewobble.json", 212 | }); 213 | ``` 214 | 215 | ### Simple Liquid Distortion Effect 216 | 217 | ![Simple Liquid Distortion Effect](./media/effect1.gif) 218 | 219 | The simple liquid distortion effect applies a mesmerizing distortion effect to image, giving the illusion of a liquid-like behavior. 220 | 221 | ```javascript 222 | Shery.imageEffect(".img", { 223 | style: 1 /*OR 5 for different variant */, 224 | debug: true, 225 | }); 226 | ``` 227 | 228 | ### Dynamic Distortion Effect 229 | 230 | ![Dynamic Distortion Effect](./media/effect2.gif) 231 | 232 | The dynamic distortion effect creates a more advanced and reactive distortion animation, providing an engaging visual experience with a debug panel. 233 | 234 | ```javascript 235 | Shery.imageEffect(".img", { 236 | style: 2, 237 | debug: true, 238 | }); 239 | ``` 240 | 241 | ### Dynamic 3D Wave/Wobble Effect 242 | 243 | ![Dynamic 3D Wave/Wobble Effect](./media/effect3.gif) 244 | 245 | Bring your web application to life with the dynamic 3D wave/wobble effect, making elements appear to ripple like waves or wobble like gelatin. 246 | 247 | ```javascript 248 | Shery.imageEffect(".img", { 249 | style: 3, 250 | debug: true, 251 | }); 252 | ``` 253 | 254 | ### Dynamic 3D Wind Effect 255 | 256 | ![Dynamic 3D Wind Effect](./media/effect4.gif) 257 | 258 | The dynamic 3D wind effect adds a subtle and natural swaying motion to elements, simulating the movement caused by wind. 259 | 260 | ```javascript 261 | Shery.imageEffect(".img", { 262 | style: 4, 263 | debug: true, 264 | }); 265 | ``` 266 | 267 | ### Dynamic Perlin Noise Effect 268 | 269 | ![Dynamic Perlin Noise Effect](./media/effect6.gif) 270 | 271 | The dynamic perlin noise effect adds a perlin noise to your image, can be used to create many type of noise related effects. 272 | 273 | ```javascript 274 | Shery.imageEffect(".img", { 275 | style: 6, 276 | debug: true, 277 | }); 278 | ``` 279 | 280 | ### Dynamic Cyber Squares Effect 281 | 282 | ![Dynamic Cyber Squares Effect](./media/effect7.gif) 283 | 284 | The dynamic cyber square effect adds a Cyber retro square patterns to your image, can be used to create many type of different square partern effects. 285 | 286 | ```javascript 287 | Shery.imageEffect(".img", { 288 | style: 6, 289 | debug: true, 290 | }); 291 | ``` 292 | 293 | ## Multiple Image Scroll Effect 294 | 295 | ![Multi](https://cdn.jsdelivr.net/gh/aayushchouhan24/sheryjs@main/media/multi.gif) 296 | 297 | All 3D effects in this library supports multi image with wave scroll effect which increases the productivity and usability of effect, offering a unique and interactive experience. 298 | 299 | To use this you just need to give a div with images you want. 300 | 301 | ```html 302 |
303 | 304 | 305 | 306 |
307 | ``` 308 | 309 | ```javascript 310 | Shery.imageEffect(".images", { 311 | style: 3, 312 | /*optional parameters 313 | these parameter dose not applies to custom scroll trigger callback */ 314 | scrollSnapping: true, 315 | scrollSpeed: 6, 316 | touchSpeed: 6, 317 | damping: 7, 318 | }); 319 | ``` 320 | 321 | ### Custom Scroll Trigger Callback 322 | 323 | To implement the GSAP ScrollTrigger or any other scroll library, as well as vanilla JavaScript and to achieve them full potential of Multiple Image Scroll Effect, you can define your custom scroll behavior using the callback parameter `slideStyle` within the **Multiple Image Scroll Effect**. 324 | 325 | To define your specific scroll behavior, utilize the `slideStyle` callback in the following manner: `slideStyle: (setScroll) => {}`. This empowers you to establish your own scrolling conditions using the `setScroll()` function within the callback. To successfully implement this approach, adhere to the following steps: 326 | 327 | 1. Enable the `slideStyle` option for your chosen visual style effect. 328 | 2. Invoke the callback, passing in the `setScroll` parameter. 329 | 3. Within the callback function, you can dynamically update the scroll position, ranging from 0 to the position of the last image. 330 | 4. Employ a scroll event listener within this context to keep track of changes in the scrolling behavior. You can select any suitable method, such as GSAP or other libraries. 331 | 5. Inside the event listener, utilize the `setScroll` function and provide the parameter `window.scrollY / innerHeight` to obtain the current scroll position relative to the window height. You can customize this calculation as needed, possibly integrating the progress from GSAP or similar methods. 332 | 6. By following these steps, you will successfully implement your own personalized scroll-triggering mechanism. 333 | 334 | ```html 335 | 336 | 337 |
338 | 339 | 340 | 341 |
342 | ``` 343 | 344 | ```javascript 345 | Shery.imageEffect(".images", { 346 | style: 5, 347 | slideStyle: (setScroll) => { 348 | window.addEventListener("scroll", () => { 349 | setScroll(window.scrollY / innerHeight); //Updating the scroll 350 | }); 351 | }, 352 | }); 353 | ``` 354 | 355 | By adhering to these instructions, you can create and control your unique scroll-triggered effects in the **Multiple Image Scroll Effect** using the specified callback mechanism. 356 | 357 | ## Dynamic Gooey Effect 358 | 359 | ![Gooey](https://cdn.jsdelivr.net/gh/aayushchouhan24/sheryjs@main/media/gooey.gif) 360 | 361 | This is very dynamic gooey effect can be applied to any of the above effect with a single param `gooey:true` and can be tweaked in debug mode. 362 | 363 | ```html 364 |
365 | 366 | 367 |
368 | ``` 369 | 370 | ```javascript 371 | Shery.imageEffect(".images", { 372 | style: 6, 373 | debug: true, 374 | gooey: true, 375 | }); 376 | ``` 377 | 378 | ## Dynamic Zoom Effect 379 | 380 | ![Zoomer](https://cdn.jsdelivr.net/gh/aayushchouhan24/sheryjs@main/media/zoomer.gif) 381 | 382 | This is very dynamic zoom effect can be applied to any of the above effect with a single tick in debug panel `image zoomer` and can be tweaked in debug mode. 383 | 384 | ```javascript 385 | Shery.imageEffect(".image", { 386 | style: 6, 387 | debug: true, 388 | }); 389 | ``` 390 | 391 | ## Shape Controls 392 | 393 | ![Shape Control](https://cdn.jsdelivr.net/gh/aayushchouhan24/sheryjs@main/media/shape-controls.gif) 394 | 395 | This feature empowers users with precise control over the shape of the desired effect, allowing for the seamless customization of elements such as round corners and smooth corners. Additionally, users can employ basic clipping functionalities to finely define the shape, ensuring a tailored and polished appearance. These versatile controls provide a nuanced and intuitive means of shaping the visual impact, offering a range of options for users to craft designs with precision and finesse. 396 | 397 | To use this feature just enable debug panel and you can find `Shape Control`. 398 | 399 | ```javascript 400 | Shery.imageEffect(".image", { 401 | style: 6, 402 | debug: true, 403 | }); 404 | ``` 405 | 406 | ## Debug Usage 407 | 408 | ![Debug](https://cdn.jsdelivr.net/gh/aayushchouhan24/sheryjs@main/media/debug.png) 409 | 410 | To customize any of the 3d effects provided by Shery.js, simply enable debug mode with parameter `{debug:true}` for effects which supports it. 411 | 412 | To save/use the tweak from your debug you need to click on `SAVE TO CLIPBOARD` and the paste that config in config parameter. 413 | 414 | ```html 415 | 416 | ``` 417 | 418 | ```javascript 419 | Shery.imageEffect(".img", { 420 | style: 3, 421 | debug: true, 422 | config: { 423 | uFrequencyX: { value: 100, range: [0, 100] }, 424 | uFrequencyY: { value: 44.86, range: [0, 100] }, 425 | uFrequencyZ: { value: 100, range: [0, 100] }, 426 | uTime: { value: 37.14299999999965 }, 427 | }, 428 | }); 429 | ``` 430 | 431 | ### Preset Usage 432 | 433 | Create your own preset or use someone elses with the help of preset option `{preset:'./presets/wigglewobble.json'}` you can create your own preset with the help of debug panel like :- 434 | 435 | 1. Enable [debug panel](#debug-usage) for your chosen style effect. 436 | 2. Do your customization's in debug panel. 437 | 3. Now click on **SAVE TO CLIPBOARD** button in debug panel. 438 | 4. Now create an new **_.json_** file. 439 | 5. Paste the copied config there. 440 | 6. And you created a new preset you can use it later or share it and help community. 441 | 442 | ```javascript 443 | Shery.imageEffect("img", { 444 | style: 2, 445 | preset: "./presets/wigglewobble.json", 446 | }); 447 | ``` 448 | 449 | ### Callback Usage 450 | 451 | Create your own animation or condition for change values of `uniforms`, `meshes`, `camera`, `etc` where uniform are variable which you change from debug panel you can use this by option `setUniforms: (uniforms) => {}` you can console log the uniforms to get list of uniforms and for other attributes you can use option `setAttribute: (attributes) => {}` the variable attributes is an object which contains :- 452 | 453 | ```json 454 | { 455 | // Geometry of effect 456 | geometry, 457 | 458 | // 3js Scene 459 | scene, 460 | 461 | // 3js Camera 462 | camera, 463 | 464 | // WebGL Renderer 465 | renderer, 466 | 467 | // Array of uniforms of all elements of given class 468 | uniforms: [], 469 | 470 | // Array of meshes of all elements of given class 471 | meshes: [] 472 | } 473 | ``` 474 | 475 | ```javascript 476 | Shery.imageEffect('img', { 477 | style: 2, 478 | setUniforms: (uniforms) => { 479 | uniforms.maskVal.value = 3 // Syntax -> uniforms.uniform_name.value = your 480 | } 481 | }) 482 | ``` 483 | 484 | ```javascript 485 | Shery.imageEffect('img', { 486 | style: 2, 487 | setAttribute: (attributes) => { 488 | uniforms[0].maskVal.value = 3 489 | } 490 | }) 491 | ``` 492 | 493 | ## Examples 494 | 495 | For detailed usage examples and demos of each effect, check out the [examples](/examples/) directory in the Shery.js repository. 496 | 497 | ## Meet the Visionaries Behind Shery.js 🌟 498 | 499 | In the heart of the dynamic world of web development, the creators of Shery.js are making waves with their unique visions and unwavering determination. 500 | 501 | ### 🚀 Harsh Vandana Sharma - [@asynchronousJavascriptor](https://github.com/asynchronousJavascriptor) 502 | 503 | ![Harsh Sharma](https://media.licdn.com/dms/image/C4E03AQFS_A05xqS99w/profile-displayphoto-shrink_800_800/0/1627712637084?e=1698278400&v=beta&t=I0GoS7x-ZeImxYIOlNQHnnDVO9pmrOxJyVysA4z6QgE) 504 | 505 | A Tech Enthusiast and full-time learner, Harsh Sharma is not just a developer but a trailblazer with a mission. Hailing from the city of Bhopal, he's the visionary behind the awe-inspiring startup, **Sheryians Coding School**. With Sheryians, Harsh is defying conventions and making the impossible possible. He's on a quest to empower non-graduates to achieve their dreams by helping them secure tech jobs in the most remarkable way. 506 | 507 | Connect with him: [Harsh's Linkedin Profile](https://www.linkedin.com/in/harsh-sharma-924629147/) 508 | Step into his world: [Harsh's GitHub Profile](https://github.com/asynchronousJavascriptor) 509 | 510 | ### 🎮 Aayush Chouhan - [@aayushchouhan24](https://github.com/aayushchouhan24) 511 | 512 | ![Aayush Chouhan](https://media.licdn.com/dms/image/D4D03AQErH7fb8TgbXg/profile-displayphoto-shrink_800_800/0/1692557398040?e=1698278400&v=beta&t=hsQCaNR7LeeHRywyrpDfs1HsUj0XLHF8l1pWXDmFD5g) 513 | 514 | A lover of technology, computers, and the thrill of gaming, Aayush Chouhan is a true explorer in the realm of cyberspace. From his early days in game penetration testing to becoming a multifaceted developer, Aayush has always been drawn to the frontier of innovation. Starting with his foray into freelancing, he's honed his skills in programming languages and ventured into the intricate worlds of Web and Android development. His journey took an exciting turn as he embraced Three.js, diving into the captivating world of 3D graphics. 515 | 516 | Connect with him: [Aayush's Linkedin Profile](https://www.linkedin.com/in/aayushchouhan24/) 517 | Dive into his journey: [Aayush's GitHub Profile](https://github.com/aayushchouhan24) 518 | 519 | ## Contributing 520 | 521 | We welcome contributions from the community to enhance and expand [Shery.js](https://github.com/your-repo-link). If you encounter bugs, have feature suggestions, or want to contribute code, please check out our [contribution guidelines](contribution.md) for more information. 522 | 523 | ## License 524 | 525 | Shery.js is released under the [MIT License](license.md). Feel free to use it in both personal and commercial projects. 526 | -------------------------------------------------------------------------------- /src/Effects.js: -------------------------------------------------------------------------------- 1 | import gsap from "gsap" 2 | import * as THREE from "three" 3 | import vertex_1 from './shaders/effect1/vertex.glsl' 4 | import fragment_1 from './shaders/effect1/fragment.glsl' 5 | import vertex_2 from './shaders/effect2/vertex.glsl' 6 | import fragment_2 from './shaders/effect2/fragment.glsl' 7 | import vertex_3 from './shaders/effect3/vertex.glsl' 8 | import fragment_3 from './shaders/effect3/fragment.glsl' 9 | import vertex_4 from './shaders/effect4/vertex.glsl' 10 | import fragment_4 from './shaders/effect4/fragment.glsl' 11 | import vertex_5 from './shaders/effect5/vertex.glsl' 12 | import fragment_5 from './shaders/effect5/fragment.glsl' 13 | import vertex_6 from './shaders/effect6/vertex.glsl' 14 | import fragment_6 from './shaders/effect6/fragment.glsl' 15 | import vertex_7 from './shaders/effect7/vertex.glsl' 16 | import fragment_7 from './shaders/effect7/fragment.glsl' 17 | 18 | import { 19 | init, 20 | fix, 21 | lerp, 22 | redraw, 23 | } from "./Utils" 24 | import { Circ, Expo, Power1 } from "gsap/all" 25 | import { Power2 } from "gsap/all" 26 | 27 | // SECTION - Mouse Follower 28 | var globalMouseFollower = null 29 | var picchemousefollower = null 30 | 31 | export function mouseFollower(opts = {}) { 32 | globalMouseFollower = document.createElement("div") 33 | picchemousefollower = document.createElement("div") 34 | globalMouseFollower.classList.add("mousefollower") 35 | picchemousefollower.classList.add("mousefollower") 36 | picchemousefollower.id = "behindmouse" 37 | var posx = 0 38 | var diff = 0 39 | addEventListener("mousemove", function (dets) { 40 | if (opts.skew) { 41 | diff = gsap.utils.clamp(15, 35, dets.clientX - posx) 42 | posx = dets.clientX 43 | gsap.to(".mousefollower", { 44 | width: diff + "px", 45 | ease: opts.ease || Expo.easeOut, 46 | duration: opts.duration || 1, 47 | }) 48 | } 49 | // difference nikaalo 50 | gsap.to(".mousefollower", { 51 | top: dets.clientY, 52 | left: dets.clientX, 53 | duration: opts.duration || 1, 54 | ease: opts.ease || Expo.easeOut, 55 | }) 56 | }) 57 | 58 | addEventListener("mouseenter", function () { 59 | gsap.to(".mousefollower", { 60 | opacity: 1, 61 | }) 62 | }) 63 | addEventListener("mouseleave", function () { 64 | gsap.to(".mousefollower", { 65 | opacity: 0, 66 | duration: opts.duration || 1, 67 | ease: opts.ease || Expo.easeOut, 68 | }) 69 | }) 70 | document.body.appendChild(picchemousefollower) 71 | document.body.appendChild(globalMouseFollower) 72 | } //!SECTION 73 | 74 | // SECTION - Image Masker 75 | export function imageMasker(element = "img", opts = {}) { 76 | document.querySelectorAll(element).forEach(function (elem) { 77 | var parent = elem.parentNode 78 | var mask = document.createElement("div") 79 | 80 | if (opts.mouseFollower) { 81 | var circle = document.createElement("div") 82 | 83 | circle.style.width = 84 | gsap.utils.clamp(50, 70, elem.getBoundingClientRect().width * 0.3) + 85 | "px" 86 | circle.style.height = 87 | gsap.utils.clamp(50, 70, elem.getBoundingClientRect().width * 0.3) + 88 | "px" 89 | 90 | circle.textContent = opts.text || "View More" 91 | 92 | circle.classList.add("circle") 93 | 94 | mask.addEventListener("mousemove", function (dets) { 95 | mask.appendChild(circle) 96 | gsap.to(circle, { 97 | top: dets.clientY - mask.getBoundingClientRect().y, 98 | left: dets.clientX - mask.getBoundingClientRect().x, 99 | ease: Expo.easeOut, 100 | duration: 2, 101 | }) 102 | }) 103 | 104 | mask.addEventListener("mouseleave", function () { 105 | gsap.to(circle, { 106 | opacity: 0, 107 | ease: Expo.easeOut, 108 | duration: 0.8, 109 | }) 110 | }) 111 | 112 | 113 | } 114 | mask.classList.add("mask") 115 | parent.replaceChild(mask, elem) 116 | 117 | mask.appendChild(elem) 118 | mask.addEventListener("mouseenter", function () { 119 | gsap.to(globalMouseFollower, { 120 | opacity: 0, 121 | ease: gsap.EasePower1, 122 | }) 123 | gsap.to(picchemousefollower, { 124 | opacity: 0, 125 | ease: gsap.EasePower1, 126 | }) 127 | gsap.to(circle, { 128 | opacity: 1, 129 | ease: Expo.easeOut, 130 | duration: 0.8, 131 | }) 132 | }) 133 | 134 | mask.addEventListener("mousemove", function (dets) { 135 | gsap.to(elem, { 136 | scale: opts.scale || elem.getBoundingClientRect().width < 450 ? 1.05 : 1.025, 137 | ease: opts.ease || Expo.easeOut, 138 | duration: opts.duration || 0.7, 139 | }) 140 | }) 141 | 142 | mask.addEventListener("mouseleave", function () { 143 | gsap.to(globalMouseFollower, { 144 | opacity: 1, 145 | ease: Power1, 146 | }) 147 | gsap.to(picchemousefollower, { 148 | opacity: 1, 149 | ease: Power1, 150 | }) 151 | gsap.to(this.childNodes[0], { 152 | scale: 1, 153 | ease: opts.ease || Expo.easeOut, 154 | duration: opts.duration || 1, 155 | }) 156 | }) 157 | }) 158 | } //!SECTION 159 | 160 | // SECTION - Make Magnet 161 | export function makeMagnet(element, opts = {}) { 162 | document.querySelectorAll(element).forEach(function (elem) { 163 | elem.addEventListener("mousemove", function (dets) { 164 | var bcr = elem.getBoundingClientRect() 165 | var zeroonex = gsap.utils.mapRange( 166 | 0, 167 | bcr.width, 168 | 0, 169 | 1, 170 | dets.clientX - bcr.left 171 | ) 172 | var zerooney = gsap.utils.mapRange( 173 | 0, 174 | bcr.height, 175 | 0, 176 | 1, 177 | dets.clientY - bcr.top 178 | ) 179 | 180 | gsap.to(".mousefollower", { 181 | scale: 4, 182 | ease: Power2, 183 | duration: 0.5, 184 | }) 185 | 186 | gsap.to(elem, { 187 | x: lerp(-20, 20, zeroonex), 188 | y: lerp(-20, 20, zerooney), 189 | duration: opts.duration || 1, 190 | ease: opts.ease || Expo.easeOut, 191 | }) 192 | }) 193 | elem.addEventListener("mouseleave", function (dets) { 194 | gsap.to(".mousefollower", { 195 | scale: 1, 196 | ease: Power2, 197 | duration: 0.5, 198 | }) 199 | gsap.to(elem, { 200 | x: 0, 201 | y: 0, 202 | duration: opts.duration || 1, 203 | ease: opts.ease || Expo.easeOut, 204 | }) 205 | }) 206 | }) 207 | } //!SECTION 208 | 209 | // SECTION - Text Animate 210 | export function textAnimate(element, opts = {}) { 211 | var alltexts = document.querySelectorAll(element) 212 | alltexts.forEach(function (elem) { 213 | elem.textContent = elem.textContent.trim().replaceAll(' ', ' ') 214 | elem.classList.add("sheryelem") 215 | var clutter = "" 216 | elem.textContent.split("").forEach(function (char) { 217 | clutter += `${char}` 218 | }) 219 | elem.innerHTML = clutter 220 | }) 221 | switch (opts.style || 1) { 222 | case 1: 223 | alltexts.forEach(function (elem) { 224 | gsap.from(elem.childNodes, { 225 | scrollTrigger: { 226 | trigger: elem, 227 | start: "top 80%", 228 | }, 229 | y: opts.y || 10, 230 | stagger: opts.delay || 0.1, 231 | opacity: 0, 232 | duration: opts.duration || 2, 233 | ease: opts.ease || Expo.easeOut, 234 | }) 235 | }) 236 | break 237 | case 2: 238 | alltexts.forEach(function (elem, i) { 239 | var len = elem.childNodes.length - 1 240 | for (var i = 0; i < elem.childNodes.length / 2; i++) { 241 | elem.childNodes[i].dataset.delay = i 242 | } 243 | for ( 244 | var i = Math.floor(elem.childNodes.length / 2); 245 | i < elem.childNodes.length; 246 | i++ 247 | ) { 248 | elem.childNodes[i].dataset.delay = len - i 249 | } 250 | elem.childNodes.forEach(function (al) { 251 | gsap.from(al, { 252 | y: 20, 253 | delay: al.dataset.delay * (opts.multiplier || 0.1), 254 | opacity: 0, 255 | ease: opts.ease || Expo.easeOut, 256 | }) 257 | }) 258 | }) 259 | break 260 | default: 261 | console.warn( 262 | "SheryJS : no such style available for text, mentioned in textanimate()" 263 | ) 264 | } 265 | } //!SECTION 266 | 267 | // SECTION - Hover With Media 268 | export function hoverWithMediaCircle(element, opts) { 269 | function calculateMedia(indexofelem) { 270 | var lengthofres = opts.images ? opts.images.length : opts.videos.length 271 | return indexofelem % lengthofres 272 | } 273 | 274 | var parent = document.body 275 | var parentDiv = document.createElement("div") 276 | parentDiv.classList.add("just-a-white-blend-screen") 277 | parentDiv.classList.add("movercirc") 278 | 279 | var circle = document.createElement("div") 280 | 281 | // 282 | var media = null 283 | document.body.click() 284 | if (opts.images) { 285 | var img = document.createElement("img") 286 | media = img 287 | } else if (opts.videos) { 288 | var vid = document.createElement("video") 289 | vid.preload = true 290 | vid.autoplay = true 291 | vid.muted = true 292 | media = vid 293 | } 294 | 295 | circle.appendChild(media) 296 | parent.appendChild(parentDiv) 297 | parent.appendChild(circle) 298 | 299 | circle.classList.add("movercirc") 300 | 301 | document.querySelectorAll(element).forEach(function (elem, index) { 302 | var prevx = 0 303 | var prevy = 0 304 | 305 | elem.classList.add("hovercircle") 306 | elem.addEventListener("mouseenter", function (dets) { 307 | media.setAttribute( 308 | "src", 309 | opts.images 310 | ? opts.images[calculateMedia(index)] 311 | : opts.videos[calculateMedia(index)] 312 | ) 313 | }) 314 | 315 | var timer 316 | elem.addEventListener("mousemove", function (dets) { 317 | var trans = gsap.utils.pipe( 318 | gsap.utils.clamp(-1, 1), 319 | gsap.utils.mapRange(-1, 1, 0.8, 1.2) 320 | ) 321 | var diffx = trans(dets.clientX - prevx) 322 | var diffy = trans(dets.clientY - prevy) 323 | prevx = dets.clientX 324 | prevy = dets.clientY 325 | 326 | clearTimeout(timer) 327 | timer = setTimeout(function () { 328 | gsap.to(".movercirc", { 329 | transform: `translate(-50%,-50%)`, 330 | }) 331 | }, 500) 332 | 333 | gsap.to(".movercirc", { 334 | left: dets.clientX, 335 | top: dets.clientY, 336 | width: "20vw", 337 | height: "20vw", 338 | transform: `translate(-50%,-50%) scale(${(diffx, diffy)})`, 339 | ease: Circ, 340 | duration: 0.4, 341 | opacity: 1, 342 | }) 343 | circle.classList.add("blend") 344 | }) 345 | 346 | elem.addEventListener("mouseleave", function (dets) { 347 | gsap.to(".movercirc", { 348 | width: "0", 349 | height: "0", 350 | ease: Power2, 351 | duration: 0.4, 352 | opacity: 0, 353 | }) 354 | circle.classList.remove("blend") 355 | }) 356 | }) 357 | } //!SECTION 358 | 359 | // SECTION - Image Effects 360 | 361 | var scene, camera, renderer, container = null 362 | 363 | export function imageEffect(element = "img", opts = {}) { 364 | let width = innerWidth 365 | let height = innerHeight 366 | const geometry = new THREE.PlaneGeometry(1, 1, 1, 1) 367 | 368 | if (scene == null) { 369 | scene = new THREE.Scene() 370 | camera = new THREE.PerspectiveCamera(70, width / height, .01, 1000) 371 | camera.fov = 2 * Math.atan(height / 2 / 10) * (180 / Math.PI) 372 | camera.position.set(0, 0, 10) 373 | 374 | renderer = new THREE.WebGLRenderer({ 375 | antialias: true, 376 | alpha: true, 377 | }) 378 | renderer.setSize(width, height) 379 | renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)) 380 | 381 | container = document.createElement("div") 382 | container.classList.add("_canvas_container") 383 | container.appendChild(renderer.domElement) 384 | document.body.appendChild(container) 385 | } 386 | 387 | const attributes = { 388 | geometry, 389 | scene, 390 | camera, 391 | renderer, 392 | uniforms: [], 393 | meshes: [] 394 | } 395 | 396 | document.querySelectorAll(element).forEach(function (elem) { 397 | elem.style.opacity = "0" 398 | switch (opts.style || 1) { 399 | // STUB - Simple Liquid Distortion Effect 400 | case 1: { 401 | var { debugObj, panel, uniforms, animate } = init( 402 | elem, 403 | vertex_1, 404 | fragment_1, { 405 | a: { value: 2, range: [0, 30] }, 406 | b: { value: 0.7, range: [-1, 1] }, 407 | }, 408 | { 409 | camera, 410 | attributes, 411 | renderer, 412 | width, 413 | height, 414 | scene, 415 | geometry, 416 | effect: 1, 417 | opts, 418 | offset: -0.04, 419 | } 420 | ) 421 | 422 | if (panel) { 423 | panel 424 | .addSelect(debugObj, "onMouse", { 425 | target: "Active", 426 | label: "Effect Mode", 427 | onChange: (x) => (uniforms.onMouse.value = x), 428 | }) 429 | .addSlider(uniforms.a, "value", "range", { 430 | label: "Speed", 431 | step: 0.001, 432 | }) 433 | .addSlider(uniforms.b, "value", "range", { 434 | label: "Wobbliness", 435 | step: 0.001, 436 | }) 437 | fix() 438 | } 439 | animate() 440 | } 441 | break //!STUB 442 | 443 | // STUB - Dynamic Distortion Effect 444 | case 2: { 445 | var { debugObj, controlKit, panel, uniforms, animate } = init( 446 | elem, 447 | vertex_2, 448 | fragment_2, 449 | { 450 | resolutionXY: { value: 100 }, 451 | distortion: { value: true }, 452 | mode: { value: -3 }, 453 | mousemove: { value: 0 }, 454 | modeA: { value: 1 }, 455 | modeN: { value: 0 }, 456 | speed: { value: 1, range: [-500, 500], rangep: [-10, 10] }, 457 | frequency: { value: 50, range: [-800, 800], rangep: [-50, 50] }, 458 | angle: { value: 0.5, range: [0, Math.PI] }, 459 | waveFactor: { value: 1.4, range: [-3, 3] }, 460 | color: { value: new THREE.Color(0.33, 0.66, 1) }, 461 | pixelStrength: { value: 3, range: [-20, 100], rangep: [-20, 20] }, 462 | quality: { value: 5, range: [0, 10] }, 463 | contrast: { value: 1, range: [-25, 25] }, 464 | brightness: { value: 1, range: [-1, 25] }, 465 | colorExposer: { value: 0.182, range: [-5, 5] }, 466 | strength: { value: 0.2, range: [-40, 40], rangep: [-5, 5] }, 467 | exposer: { value: 8, range: [-100, 100] }, 468 | }, 469 | { 470 | camera, 471 | attributes, 472 | renderer, 473 | width, 474 | height, 475 | scene, 476 | geometry, 477 | effect: 2, 478 | opts, 479 | } 480 | ) 481 | if (panel) { 482 | panel 483 | .addCheckbox(uniforms.distortion, "value", { 484 | label: "Distortion Effect", 485 | }) 486 | .addSelect(debugObj, "onMouse", { 487 | target: "Active", 488 | label: "Effect Mode", 489 | onChange: (x) => (uniforms.onMouse.value = x), 490 | }) 491 | .addSelect(debugObj, "Mode", { 492 | target: "Mode Active", 493 | label: "Blend/Overlay Mode", 494 | onChange: (x) => (uniforms.mode.value = x - 10), 495 | }) 496 | .addSelect(debugObj, "Mouse", { 497 | target: "Mouse Active", 498 | label: "Mousemove Effect", 499 | onChange: (x) => (uniforms.mousemove.value = x), 500 | }) 501 | .addSelect(debugObj, "Trigo", { 502 | target: "Trig A", 503 | label: "Effect StyleA", 504 | onChange: (x) => (uniforms.modeA.value = x), 505 | }) 506 | .addSelect(debugObj, "Trigo", { 507 | target: "Trig N", 508 | label: "Effect StyleN", 509 | onChange: (x) => (uniforms.modeN.value = x), 510 | }) 511 | .addColor(debugObj, "Color", { 512 | colorMode: "hex", 513 | onChange: (x) => uniforms.color.value.set(x), 514 | }) 515 | controlKit 516 | .addPanel({ 517 | enable: false, 518 | label: "Controls Panel", 519 | width: 350, 520 | fixed: false, 521 | position: [20, opts.debug ? 90 : 50], 522 | }) 523 | .addSlider(debugObj.speed, "normal", "range", { 524 | label: "Speed", 525 | step: 0.00001, 526 | onChange: () => (uniforms.speed.value = debugObj.speed.normal), 527 | }) 528 | .addSlider(debugObj.speed, "precise", "rangep", { 529 | label: "Speed Precise", 530 | step: 0.00001, 531 | onChange: () => (uniforms.speed.value = debugObj.speed.precise), 532 | }) 533 | .addSlider(debugObj.frequency, "normal", "range", { 534 | label: "Frequency", 535 | step: 0.00001, 536 | onChange: () => 537 | (uniforms.frequency.value = debugObj.frequency.normal), 538 | }) 539 | .addSlider(debugObj.frequency, "precise", "rangep", { 540 | label: "Frequency Precise", 541 | step: 0.00001, 542 | onChange: () => 543 | (uniforms.frequency.value = debugObj.frequency.precise), 544 | }) 545 | .addSlider(debugObj.Resolution_XY, "value", "range", { 546 | label: "Resolution", 547 | step: 0.00001, 548 | onChange: () => { 549 | uniforms.resolutionXY.value = debugObj.Resolution_XY.value 550 | } 551 | }) 552 | .addSlider(debugObj.Resolution_XY, "precise", "rangep", { 553 | label: "Resolution Precise", 554 | step: 0.00001, 555 | onChange: () => { 556 | uniforms.resolutionXY.value = debugObj.Resolution_XY.precise 557 | } 558 | }) 559 | .addSlider(uniforms.angle, "value", "range", { 560 | label: "Angle", 561 | step: 0.00001, 562 | }) 563 | .addSlider(uniforms.waveFactor, "value", "range", { 564 | label: "Wave Factor", 565 | step: 0.00001, 566 | }) 567 | .addSlider(debugObj.pixelStrength, "normal", "range", { 568 | label: "Pixel Strength", 569 | step: 0.00001, 570 | onChange: () => 571 | (uniforms.pixelStrength.value = 572 | debugObj.pixelStrength.normal), 573 | }) 574 | .addSlider(debugObj.pixelStrength, "precise", "rangep", { 575 | label: "Precise Pixel", 576 | step: 0.00001, 577 | onChange: () => 578 | (uniforms.pixelStrength.value = 579 | debugObj.pixelStrength.normal), 580 | }) 581 | .addSlider(uniforms.quality, "value", "range", { 582 | label: "Quality", 583 | step: 0.00001, 584 | }) 585 | .addSlider(uniforms.contrast, "value", "range", { 586 | label: "Contrast", 587 | step: 0.00001, 588 | }) 589 | .addSlider(uniforms.brightness, "value", "range", { 590 | label: "Brightness", 591 | step: 0.00001, 592 | }) 593 | .addSlider(uniforms.colorExposer, "value", "range", { 594 | label: "Color Exposer", 595 | step: 0.00001, 596 | }) 597 | .addSlider(debugObj.strength, "normal", "range", { 598 | label: "Strength", 599 | step: 0.00001, 600 | onChange: (x) => 601 | (uniforms.strength.value = debugObj.strength.normal), 602 | }) 603 | .addSlider(debugObj.strength, "precise", "rangep", { 604 | label: "Strength Precise", 605 | step: 0.00001, 606 | onChange: (x) => 607 | (uniforms.strength.value = debugObj.strength.precise), 608 | }) 609 | .addSlider(uniforms.exposer, "value", "range", { 610 | label: "Exposer", 611 | step: 0.00001, 612 | }) 613 | fix() 614 | } 615 | animate() 616 | } 617 | break //!STUB 618 | 619 | // STUB - Dynamic 3d Wave/Wobble Effect 620 | case 3: { 621 | var { debugObj, panel, elemMesh, uniforms, animate } = init( 622 | elem, 623 | vertex_3, 624 | fragment_3, 625 | { 626 | uFrequencyX: { value: 12, range: [0, 100] }, 627 | uFrequencyY: { value: 12, range: [0, 100] }, 628 | uFrequencyZ: { value: 10, range: [0, 100] }, 629 | geoVertex: { value: 32, range: [1, 64] } 630 | }, 631 | { 632 | camera, 633 | attributes, 634 | renderer, 635 | width, 636 | height, 637 | scene, 638 | geometry, 639 | effect: 3, 640 | opts, 641 | fov: 1.0375, 642 | size: 0.01744, 643 | offset: -0.04, 644 | } 645 | ) 646 | if (panel) { 647 | panel 648 | .addSelect(debugObj, "onMouse", { 649 | target: "Active", 650 | label: "Effect Mode", 651 | onChange: (x) => (uniforms.onMouse.value = x), 652 | }) 653 | .addSlider(uniforms.geoVertex, "value", "range", { 654 | label: "VertexCount", 655 | step: 1, 656 | onChange: () => { 657 | redraw(elemMesh, uniforms.geoVertex.value) 658 | }, 659 | }) 660 | .addSlider(uniforms.uFrequencyX, "value", "range", { 661 | label: "FrequencyX", 662 | step: 0.01, 663 | }) 664 | .addSlider(uniforms.uFrequencyY, "value", "range", { 665 | label: "FrequencyY", 666 | step: 0.01, 667 | }) 668 | .addSlider(uniforms.uFrequencyZ, "value", "range", { 669 | label: "FrequencyZ", 670 | step: 0.01, 671 | }) 672 | fix() 673 | } 674 | animate() 675 | } 676 | break //!STUB 677 | 678 | // STUB - Wind Distortion Effect 679 | case 4: { 680 | var { debugObj, panel, elemMesh, uniforms, animate } = init( 681 | elem, 682 | vertex_4, 683 | fragment_4, 684 | { 685 | uColor: { value: false }, 686 | uSpeed: { value: 0.6, range: [0.1, 1], rangep: [1, 10] }, 687 | uAmplitude: { value: 1.5, range: [0, 5] }, 688 | uFrequency: { value: 3.5, range: [0, 10] }, 689 | geoVertex: { value: 32, range: [1, 64] } 690 | }, 691 | { 692 | camera, 693 | attributes, 694 | renderer, 695 | width, 696 | height, 697 | scene, 698 | geometry, 699 | effect: 4, 700 | opts, 701 | offset: -0.04, 702 | } 703 | ) 704 | 705 | if (opts.config) 706 | Object.keys(opts.config).forEach( 707 | (key) => (uniforms[key].value = opts.config[key].value) 708 | ) 709 | if (panel) { 710 | panel 711 | .addCheckbox(uniforms.uColor, "value", { label: "Color Depth" }) 712 | .addSelect(debugObj, "onMouse", { 713 | target: "Active", 714 | label: "Effect Mode", 715 | onChange: (x) => (uniforms.onMouse.value = x), 716 | }) 717 | .addSlider(uniforms.geoVertex, "value", "range", { 718 | label: "VertexCount", 719 | step: 1, 720 | onChange: () => redraw(elemMesh, uniforms.geoVertex.value), 721 | }) 722 | .addSlider(debugObj, "s", "range", { 723 | label: "Speed", 724 | onChange: () => (uniforms.uSpeed.value = debugObj.s), 725 | step: 0.01, 726 | }) 727 | .addSlider(debugObj, "f", "rangep", { 728 | label: "FastForward", 729 | onChange: () => (uniforms.uSpeed.value = debugObj.f), 730 | step: 0.01, 731 | }) 732 | .addSlider(uniforms.uAmplitude, "value", "range", { 733 | label: "Amplitude", 734 | step: 0.01, 735 | }) 736 | .addSlider(uniforms.uFrequency, "value", "range", { 737 | label: "Frequency", 738 | step: 0.01, 739 | }) 740 | fix() 741 | } 742 | animate() 743 | } 744 | break //!STUB 745 | 746 | // STUB - MultiImage Effect 747 | case 5: { 748 | var { debugObj, panel, uniforms, animate } = init( 749 | elem, 750 | vertex_5, 751 | fragment_5, 752 | 753 | { 754 | a: { value: 2, range: [0, 30] }, 755 | b: { value: 1 / 1.333, range: [-1, 1] }, 756 | }, 757 | { 758 | camera, 759 | attributes, 760 | renderer, 761 | width, 762 | height, 763 | scene, 764 | geometry, 765 | effect: 5, 766 | opts, 767 | fov: 0.9, 768 | onDoc: true, 769 | offset: -0.04, 770 | } 771 | ) 772 | if (panel) { 773 | panel 774 | .addSelect(debugObj, "onMouse", { 775 | target: "Active", 776 | label: "Effect Mode", 777 | onChange: (x) => (uniforms.onMouse.value = x), 778 | }) 779 | .addSlider(uniforms.a, "value", "range", { 780 | label: "Speed", 781 | step: 0.001, 782 | }) 783 | .addSlider(uniforms.b, "value", "range", { 784 | label: "Wobbliness", 785 | step: 0.001, 786 | }) 787 | fix() 788 | } 789 | animate() 790 | } 791 | break //!STUB 792 | 793 | // STUB - Perlin Noise Effect 794 | case 6: { 795 | var { debugObj, panel, uniforms, animate } = init( 796 | elem, 797 | vertex_6, 798 | fragment_6, 799 | { 800 | "noiseDetail": { "value": 7.44, "range": [0, 100] }, 801 | "distortionAmount": { "value": 2.98, "range": [0, 10] }, 802 | "scale": { "value": 36.36, "range": [0, 100] }, 803 | "speed": { "value": 0.79, "range": [0, 1] } 804 | }, 805 | { 806 | camera, 807 | attributes, 808 | renderer, 809 | width, 810 | height, 811 | scene, 812 | geometry, 813 | effect: 6, 814 | opts, 815 | } 816 | ) 817 | 818 | if (panel) { 819 | panel 820 | .addSlider(uniforms.speed, "value", "range", { 821 | label: "speed", 822 | step: 0.001, 823 | }) 824 | .addSlider(uniforms.scale, "value", "range", { 825 | label: "scale", 826 | step: 0.001, 827 | }) 828 | .addSlider(uniforms.distortionAmount, "value", "range", { 829 | label: "Amount", 830 | step: 0.001, 831 | }) 832 | .addSlider(uniforms.noiseDetail, "value", "range", { 833 | label: "noiseDetail", 834 | step: 0.001, 835 | }) 836 | 837 | fix() 838 | } 839 | animate() 840 | } 841 | break //!STUB 842 | 843 | // STUB - Cyber Cube Effect 844 | case 7: { 845 | var { debugObj, panel, uniforms, animate } = init( 846 | elem, 847 | vertex_7, 848 | fragment_7, 849 | { 850 | invert: { value: false }, 851 | isTexture: { value: false }, 852 | autorotate: { value: true }, 853 | mouseMove: { value: true }, 854 | color: { value: new THREE.Color(0xffffff) }, 855 | mouseMoveEWX: { value: 0, range: [0, 1] }, 856 | mouseMoveEHY: { value: 0.07, range: [0, 1] }, 857 | smoothness: { value: 1.44, range: [0, 3] }, 858 | circular: { value: 0, range: [-.1, .1] }, 859 | styling: { value: .82, range: [-3, 3] }, 860 | clustering: { value: 5.0, range: [0, 5] }, 861 | gapping: { value: .63, range: [0, 1] }, 862 | rotation: { value: 60, range: [0, 90] }, 863 | density: { value: .07, range: [0, 1] }, 864 | scale: { value: 42, range: [0, 100] }, 865 | pattern: { value: 5.58, range: [0, 15] }, 866 | }, 867 | { 868 | camera, 869 | attributes, 870 | renderer, 871 | width, 872 | height, 873 | scene, 874 | geometry, 875 | effect: 7, 876 | opts, 877 | } 878 | ) 879 | 880 | if (panel) { 881 | panel 882 | .addCheckbox(uniforms.invert, "value", { 883 | label: "Invert", 884 | }) 885 | .addCheckbox(uniforms.autorotate, "value", { 886 | label: "Auto Rotate", 887 | }) 888 | .addCheckbox(uniforms.mouseMove, "value", { 889 | label: "Mouse Effect", 890 | }) 891 | .addSlider(uniforms.mouseMoveEWX, 'value', 'range', { 892 | label: 'EWX', 893 | step: 0.001, 894 | }) 895 | .addSlider(uniforms.mouseMoveEHY, 'value', 'range', { 896 | label: 'EHY', 897 | step: 0.001, 898 | }) 899 | .addSlider(uniforms.rotation, 'value', 'range', { 900 | label: 'Rotation', 901 | step: 0.001, 902 | }) 903 | .addSlider(uniforms.scale, 'value', 'range', { 904 | label: 'Scale', 905 | step: 0.001, 906 | }) 907 | .addSlider(uniforms.pattern, 'value', 'range', { 908 | label: 'Pattern', 909 | step: 0.001, 910 | }) 911 | .addSlider(uniforms.density, 'value', 'range', { 912 | label: 'Density', 913 | step: 0.001, 914 | }) 915 | .addSlider(uniforms.clustering, 'value', 'range', { 916 | label: 'Clustering', 917 | step: 0.001, 918 | }) 919 | .addSlider(uniforms.gapping, 'value', 'range', { 920 | label: 'Gapping', 921 | step: 0.001, 922 | }) 923 | .addSlider(uniforms.smoothness, 'value', 'range', { 924 | label: 'Smoothness', 925 | step: 0.001, 926 | }) 927 | .addSlider(uniforms.styling, 'value', 'range', { 928 | label: 'Styling', 929 | step: 0.001, 930 | }) 931 | .addSlider(uniforms.circular, 'value', 'range', { 932 | label: 'Ring Contrast', 933 | step: 0.001, 934 | }) 935 | .addColor(debugObj, "Color", { 936 | colorMode: "hex", 937 | onChange: (x) => uniforms.color.value.set(x), 938 | }) 939 | .addStringInput(debugObj, 'backgroundImage', { 940 | label: 'Effect Background Image Source', 941 | onChange: () => { 942 | if (debugObj.backgroundImage == '') { 943 | uniforms.isTexture.value = false 944 | } else { 945 | uniforms.isTexture.value = true 946 | } 947 | uniforms.uTexture.value[2] = new THREE.TextureLoader().load(debugObj.backgroundImage) 948 | } 949 | }) 950 | 951 | fix() 952 | } 953 | animate() 954 | } 955 | break //!STUB 956 | } 957 | }) 958 | 959 | if (opts.setAttribute && typeof opts.setAttribute === "function") 960 | opts.setAttribute(attributes) 961 | 962 | } //!SECTION 963 | 964 | export class ScrollPos { 965 | constructor() { 966 | this.acceleration = 0 967 | this.maxAcceleration = 5 968 | this.maxSpeed = 20 969 | this.velocity = 0 970 | this.dampen = 0.97 971 | this.speed = 8 972 | this.touchSpeed = 8 973 | this.scrollPos = 0 974 | this.velocityThreshold = 1 975 | this.snapToTarget = false 976 | this.mouseDown = false 977 | this.lastDelta = 0 978 | 979 | document.addEventListener("touchstart", e => e.preventDefault(), { passive: false }) 980 | 981 | window.addEventListener("touchend", () => this.lastDelta = 0) 982 | 983 | window.addEventListener("touchmove", e => { 984 | // e.preventDefault(); 985 | let delta = this.lastDelta - e.targetTouches[0].clientY 986 | this.accelerate(Math.sign(delta) * this.touchSpeed) 987 | this.lastDelta = e.targetTouches[0].clientY 988 | }) 989 | 990 | window.addEventListener("wheel", e => { 991 | this.accelerate(Math.sign(e.deltaY) * this.speed) 992 | }) 993 | 994 | 995 | window.addEventListener("mousemove", e => { 996 | if (this.mouseDown) { 997 | let delta = this.lastDelta - e.clientY 998 | this.accelerate(Math.sign(delta) * this.touchSpeed * 0.4) 999 | this.lastDelta = e.clientY 1000 | } 1001 | }) 1002 | 1003 | window.addEventListener("mouseup", () => { 1004 | this.lastDelta = 0 1005 | this.mouseDown = false 1006 | }) 1007 | 1008 | } 1009 | accelerate(amount) { 1010 | if (this.acceleration < this.maxAcceleration) { 1011 | this.acceleration += amount 1012 | } 1013 | } 1014 | update() { 1015 | this.velocity += this.acceleration 1016 | if (Math.abs(this.velocity) > this.velocityThreshold) { 1017 | this.velocity *= this.dampen 1018 | this.scrollPos += this.velocity 1019 | this.scrollPos = this.scrollPos >= 0 ? this.scrollPos : 0 // added by ankur 1020 | } else { 1021 | this.velocity = 0 1022 | } 1023 | if (Math.abs(this.velocity) > this.maxSpeed) { 1024 | this.velocity = Math.sign(this.velocity) * this.maxSpeed 1025 | } 1026 | this.acceleration = 0 1027 | } 1028 | snap(snapTarget, dampenThreshold = 100, velocityThresholdOffset = 1.5) { 1029 | if (Math.abs(snapTarget - this.scrollPos) < dampenThreshold) { 1030 | this.velocity *= this.dampen 1031 | } 1032 | if (Math.abs(this.velocity) < this.velocityThreshold + velocityThresholdOffset) { 1033 | this.scrollPos += (snapTarget - this.scrollPos) * 0.1 1034 | } 1035 | } 1036 | project(steps = 1) { 1037 | if (steps === 1) return this.scrollPos + this.velocity * this.dampen 1038 | var scrollPos = this.scrollPos 1039 | var velocity = this.velocity 1040 | 1041 | for (var i = 0; i < steps; i++) { 1042 | velocity *= this.dampen 1043 | scrollPos += velocity 1044 | } 1045 | return scrollPos 1046 | } 1047 | } -------------------------------------------------------------------------------- /src/Shery.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --mousefollowercolor: black; 3 | } 4 | body{ 5 | background-color: #fff; 6 | } 7 | .mousefollower { 8 | pointer-events: none; 9 | transform: translate(-50%, -50%); 10 | position: fixed; 11 | top: -10%; 12 | left: -10%; 13 | width: 15px; 14 | height: 15px; 15 | border-radius: 50%; 16 | z-index: 99999; 17 | mix-blend-mode: exclusion; 18 | background-color: var(--mousefollowercolor); 19 | } 20 | 21 | #behindmouse { 22 | background-color: white; 23 | } 24 | 25 | .mask { 26 | position: relative; 27 | display: inline-block; 28 | overflow: hidden; 29 | } 30 | 31 | .circle { 32 | text-align: center; 33 | pointer-events: none; 34 | box-sizing: content-box; 35 | padding: 10px; 36 | display: flex; 37 | align-items: center; 38 | justify-content: center; 39 | top: -10%; 40 | left: -10%; 41 | transform: translate(-50%, -50%); 42 | border-radius: 50%; 43 | position: absolute; 44 | z-index: 9999; 45 | background-color: #000000e8; 46 | color: #fff; 47 | font-family: inherit; 48 | font-size: 10px; 49 | } 50 | 51 | .sheryelem span { 52 | display: inline-block; 53 | } 54 | 55 | .parent { 56 | display: inline-block; 57 | } 58 | 59 | #controlKit .panel .group-list .group .sub-group-list .sub-group ul li, 60 | #controlKit .panel .scrollBar, 61 | #controlKit .panel { 62 | background-image: none !important; 63 | background-color: #181c20 !important; 64 | } 65 | #controlKit .panel .group-list .group .sub-group-list .sub-group:last-of-type{ 66 | border-bottom: 1px solid #222729 !important; 67 | } 68 | #controlKit .panel .group-list .group .sub-group-list .sub-group .head-inactive{ 69 | margin: 5px; 70 | } 71 | 72 | #controlKit .panel .head, 73 | #controlKit .panel .panel-head-inactive, 74 | #controlKit .picker .head, 75 | #controlKit .picker { 76 | background-color: #292d39 !important; 77 | } 78 | 79 | #controlKit .panel .button, 80 | #controlKit .picker .button { 81 | background-color: #383c4a ; 82 | background-image: none !important; 83 | box-shadow: none !important; 84 | border-radius: 7px !important; 85 | color: #8c92a4 ; 86 | font-size: .9em !important; 87 | text-shadow: none !important; 88 | font-weight: 800 !important; 89 | } 90 | 91 | #controlKit .picker canvas{ 92 | position: relative; 93 | } 94 | 95 | #controlKit .panel .button:hover{ 96 | background-color: #007bff !important; 97 | color: #fff !important; 98 | } 99 | #controlKit .panel .button:active{ 100 | background-color: #292d39 !important; 101 | color: #fff !important; 102 | } 103 | 104 | #controlKit .panel .head .label, 105 | #controlKit .picker .head .label,#controlKit .panel .group-list .group .sub-group-list .sub-group .head .wrap .label, #controlKit .panel .group-list .group .sub-group-list .sub-group .head-inactive .wrap .label { 106 | color: #8c92a4 !important; 107 | font-size: .8em !important; 108 | text-shadow: none !important; 109 | font-weight: 800 !important; 110 | 111 | } 112 | 113 | #controlKit .panel .scrollBar .track .thumb { 114 | background-color: #383c4a !important; 115 | box-shadow: none !important; 116 | } 117 | 118 | #controlKit .panel .select , #controlKit .panel .select-active ,#controlKit .panel .group-list .group .sub-group-list .sub-group .head-inactive{ 119 | border-radius: 7px !important; 120 | box-shadow: none !important; 121 | text-shadow: none !important; 122 | color: #8c92a4 !important; 123 | background: #292d39 !important; 124 | text-align: center !important; 125 | } 126 | 127 | 128 | #controlKit .panel, 129 | #controlKit .options ul, 130 | #controlKit .options ul li, 131 | #controlKit .options { 132 | border-radius: 7px !important; 133 | background-color: #fff; 134 | color: #000; 135 | text-shadow: none !important; 136 | text-align: center !important; 137 | 138 | } 139 | ul.sub-group-list{ 140 | margin-top: 5px !important; 141 | } 142 | #controlKit .options ul li:hover, 143 | #controlKit .options ul .li-selected, 144 | #controlKit .panel .slider-handle { 145 | background: #007bff !important; 146 | } 147 | 148 | #controlKit .panel .group-list .group .sub-group-list .sub-group .wrap .label { 149 | width: auto !important; 150 | } 151 | #controlKit{ 152 | z-index: 999999999999999999; 153 | position: fixed !important; 154 | } 155 | 156 | #controlKit .panel .menu input[type=button], 157 | #controlKit .panel .menu input[type=button]:hover, 158 | #controlKit .panel .menu-active input[type=button], 159 | #controlKit .picker .menu input[type=button] { 160 | box-shadow: none !important; 161 | background-color: #00000000; 162 | } 163 | 164 | .hovercircle{ 165 | position: relative; 166 | z-index: 5; 167 | display: inline-block; 168 | } 169 | 170 | .hovercircle:hover{ 171 | transition: all cubic-bezier(0.19, 1, 0.22, 1) 1s; 172 | color: #000; 173 | } 174 | 175 | .movercirc { 176 | mix-blend-mode: exclusion; 177 | pointer-events: none; 178 | position: fixed; 179 | z-index: 15; 180 | top: 0; 181 | left: 0; 182 | border-radius: 50%; 183 | width: 0; 184 | opacity: 0; 185 | overflow: hidden; 186 | height: 0; 187 | max-width: 250px; 188 | max-height: 250px; 189 | } 190 | 191 | .movercirc img{ 192 | width: 100%; 193 | height: 100%; 194 | object-fit: cover; 195 | position: absolute; 196 | top: 50%; 197 | left: 50%; 198 | transform: translate(-50%,-50%); 199 | } 200 | 201 | .movercirc.blend { 202 | mix-blend-mode: exclusion; 203 | filter: invert(1); 204 | } 205 | 206 | .just-a-white-blend-screen { 207 | background: #ffffff; 208 | /* z-index: -1; */ 209 | } 210 | 211 | .movercirc video{ 212 | position: absolute; 213 | top: 50%; 214 | left: 50%; 215 | transform: translate(-50%,-50%) scale(1.3); 216 | } 217 | 218 | ._canvas_container { 219 | pointer-events: none; 220 | width: 100vw; 221 | height: 100vh; 222 | position: fixed; 223 | z-index: -9996999; 224 | top: 0; 225 | left: 0; 226 | } -------------------------------------------------------------------------------- /src/Shery.js: -------------------------------------------------------------------------------- 1 | import './Shery.css' 2 | import * as Shery from './Effects' 3 | 4 | export * from './Effects' 5 | 6 | export default Shery -------------------------------------------------------------------------------- /src/Utils.js: -------------------------------------------------------------------------------- 1 | import * as THREE from "three" 2 | import ControlKit from "controlkit" 3 | import { ScrollPos } from "./Effects" 4 | import gsap from "gsap" 5 | import { Expo } from "gsap/all" 6 | 7 | export const lerp = (x, y, a) => x * (1 - a) + y * a 8 | 9 | export const clamp = (val, min = 1, max = 10) => 10 | Math.min(Math.max(val, min), max) 11 | 12 | export const fix = () => { 13 | const s = 14 | "#controlKit .panel .group-list .group .sub-group-list .sub-group .wrap .wrap" 15 | const c = "#controlKit .panel .button, #controlKit .picker .button" 16 | if (document.querySelector(s)) 17 | document.querySelectorAll(s).forEach((e, i) => (e.style.width = i != 3 ? "30%" : "50%")) 18 | if (document.querySelector(c)) { 19 | document.querySelector(c).parentElement.style.float = "none" 20 | document.querySelector(c).parentElement.style.width = "100% " 21 | } 22 | if (document.querySelector(s + ".color")) 23 | document.querySelector(s + ".color").parentElement.style.width = "60%" 24 | } 25 | 26 | export const redraw = (elemMesh, v) => { 27 | let newGeometry = new THREE.PlaneGeometry(elemMesh.geometry.parameters.width, elemMesh.geometry.parameters.height, v, v) 28 | elemMesh.geometry.dispose() 29 | elemMesh.geometry = newGeometry 30 | } 31 | 32 | function getTranslate3d(el) { 33 | var values = el.style.transform.split(/\w+\(|\);?/) 34 | if (!values[1] || !values[1].length) { 35 | return [] 36 | } 37 | values = values[1].split(/,\s?/g) 38 | 39 | return values.map(c => parseFloat(c.replace('px', ''))) 40 | } 41 | 42 | function stringify(obj) { 43 | let cache = [] 44 | let str = JSON.stringify(obj, function (key, value) { 45 | if (typeof value === "object" && value !== null) { 46 | if (cache.indexOf(value) !== -1) { 47 | return 48 | } 49 | cache.push(value) 50 | } 51 | return value 52 | }) 53 | cache = null 54 | return str 55 | } 56 | 57 | var isdebug = [] 58 | export const init = ( 59 | elem, 60 | vertex, 61 | fragment, 62 | uniforms, 63 | { 64 | attributes, 65 | camera, 66 | renderer, 67 | width, 68 | height, 69 | scene, 70 | geometry, 71 | opts, 72 | effect = 0, 73 | } = {} 74 | ) => { 75 | const o = "#controlKit .options" 76 | 77 | let elemWidth = elem.getBoundingClientRect().width 78 | let elemHeight = elem.getBoundingClientRect().height 79 | let elemLeft = elem.getBoundingClientRect().left 80 | 81 | const mouse = new THREE.Vector2() 82 | const mousem = new THREE.Vector2() 83 | 84 | const src = [elem.getAttribute("src") && elem.getAttribute("src")] 85 | let t = [elem.getAttribute("src") && new THREE.TextureLoader().load(src[0])] 86 | 87 | const sources = [] 88 | 89 | if (elem.getAttribute("src")) { 90 | if (elem.nodeName.toLowerCase() === "video") { 91 | const video = document.createElement('video') 92 | video.crossOrigin = 'anonymous' 93 | video.src = src[0] 94 | video.muted = true 95 | video.loop = true 96 | video.preload = true 97 | video.play() 98 | sources[0] = video 99 | } else { 100 | const img = new Image() 101 | img.crossOrigin = "anonymous" 102 | img.src = src[0] 103 | sources[0] = img 104 | } 105 | } 106 | const doAction = (lerp) => { 107 | if (uniforms.currentScroll.value >= 0) { 108 | uniforms.uScroll.value = THREE.MathUtils.lerp(uniforms.uScroll.value, uniforms.currentScroll.value, lerp) 109 | uniforms.uSection.value = Math.floor(uniforms.uScroll.value) 110 | var sec = uniforms.uSection.value 111 | if (t.length > sec) { 112 | if (t.length > sec + 1) 113 | uniforms.uTexture.value = [t[sec], t[sec + 1]] 114 | else uniforms.uTexture.value = [t[t.length - 1], t[t.length - 1]] 115 | } 116 | } 117 | } 118 | var mouseWheel = new ScrollPos() 119 | const staticScroll = () => { 120 | if (!(elem.nodeName.toLowerCase() === "img") && !opts.slideStyle) { 121 | mouseWheel.update() 122 | mouseWheel.dampen = 0.9 + clamp(opts.damping || 7, 0, 9) / 100 123 | mouseWheel.speed = Math.abs(opts.scrollSpeed || 6) 124 | mouseWheel.touchSpeed = Math.abs(opts.touchSpeed || 6) 125 | let scrollTarget = 126 | Math.floor((mouseWheel.scrollPos + elemHeight * 0.5) / elemHeight) * 127 | elemHeight 128 | if (opts.scrollSnapping) { 129 | mouseWheel.snap(scrollTarget) 130 | } 131 | let { scrollPos } = mouseWheel 132 | if (scrollPos < 0) { 133 | scrollPos = 0 134 | } 135 | if (scrollPos > 0 && scrollPos < elemHeight * (t.length - 1)) 136 | uniforms.currentScroll.value = scrollPos / elemHeight 137 | } 138 | } 139 | if (!(elem.nodeName.toLowerCase() === "img")) { 140 | fragment = fragment.replace( 141 | "!isMulti;", 142 | opts.gooey && !opts.slideStyle === true 143 | ? /*glsl*/` 144 | vec2 pos=vec2(vuv.x,vuv.y/aspect); 145 | vec2 mouse=vec2(mousei.x,(mousei.y)/aspect); 146 | vec2 interpole=mix(vec2(0),vec2(metaball,noise_height),uIntercept); 147 | float noise=(snoise(vec3(pos*noise_scale,time*noise_speed))+1.)/2.; 148 | float val=noise*interpole.y; 149 | float u=1.0-smoothstep(interpole.x,.0,distance(mouse,pos)); 150 | float mouseMetaball=clamp(1.-u,0.,1.); 151 | val+=mouseMetaball; 152 | float alpha=smoothstep(discard_threshold-antialias_threshold,discard_threshold,val); 153 | gl_FragColor=vec4(mix(gl_FragColor,texture2D(uTexture[1],uv2),alpha));` 154 | 155 | : `float c = (sin((uv.x*7.0*snoise(vec3(uv,1.0)))+(time))/15.0*snoise(vec3(uv,1.0)))+.01; 156 | float blend=uScroll-uSection;float blend2=1.-blend;vec4 imageA=texture2D(uTexture[0],vec2(uv.x,uv.y-(((texture2D(uTexture[0],uv).r*displaceAmount)*blend)*2.)))*blend2;vec4 imageB=texture2D(uTexture[1],vec2(uv.x,uv.y+(((texture2D(uTexture[1],uv).r*displaceAmount)*blend2)*2.)))*blend; 157 | gl_FragColor =scrollType == 0.0? mix(texture2D(uTexture[1], uv), texture2D(uTexture[0], uv), step((uScroll)-uSection, sin(c) + uv.y)):imageA.bbra*blend+imageA*blend2+imageB.bbra*blend2+imageB*blend;` 158 | ) 159 | for (let i = 0; i < elem.children.length; i++) { 160 | src[i] = elem.children[i].getAttribute("src") 161 | t[i] = new THREE.TextureLoader().load(src[i]) 162 | if (i > 0) { 163 | elem.children[i].style.display = "none" 164 | } 165 | if (elem.children[i].nodeName.toLowerCase() === "video") { 166 | const video = document.createElement('video') 167 | video.crossOrigin = 'anonymous' 168 | video.src = src[i] 169 | video.muted = true 170 | video.loop = true 171 | video.preload = true 172 | video.play() 173 | sources[i] = video 174 | } else { 175 | const img = new Image() 176 | img.crossOrigin = "anonymous" 177 | img.src = src[i] 178 | sources[i] = img 179 | } 180 | } 181 | } 182 | Object.assign(uniforms, { 183 | zindex: { value: -9996999, range: [-9999999, 9999999] }, 184 | aspect: { 185 | value: elemWidth / elemHeight, 186 | }, 187 | ignoreShapeAspect: { value: true }, 188 | shapePosition: { value: new THREE.Vector2(0.0, 0.0)}, 189 | shapeScale: { value: new THREE.Vector2(0.5, 0.5) }, 190 | shapeEdgeSoftness: { value: 0.0, range: [0, .5] }, 191 | shapeRadius: { value: 0.0, range: [0, 2] }, 192 | currentScroll: { value: 0 }, 193 | scrollLerp: { value: 0.07 }, 194 | gooey: { value: opts.gooey ? true : false }, 195 | infiniteGooey: { value: false }, 196 | growSize: { value: 4, range: [1, 15] }, 197 | durationOut: { value: 1, range: [.1, 5] }, 198 | durationIn: { value: 1.5, range: [.1, 5] }, 199 | time: { value: 0 }, 200 | displaceAmount: { value: 0.5 }, 201 | mousei: { value: new THREE.Vector2() }, 202 | mouse: { value: mouse }, 203 | masker: { value: false }, 204 | maskVal: { value: 1, range: [1, 5] }, 205 | scrollType: { value: 0 }, 206 | uIntercept: { value: 0 }, 207 | geoVertex: { 208 | range: [1, 64], 209 | value: uniforms.geoVertex ? uniforms.geoVertex.value : 1, 210 | }, 211 | noEffectGooey: { value: true }, 212 | onMouse: { value: 0 }, 213 | uSection: { value: 0 }, 214 | isMulti: { value: !(elem.nodeName.toLowerCase() === "img") }, 215 | uScroll: { value: 0 }, 216 | noise_speed: { value: 0.2, range: [0, 10] }, 217 | metaball: { value: .2, range: [0, 2] }, 218 | discard_threshold: { value: 0.5, range: [0, 1] }, 219 | antialias_threshold: { value: 0.002, range: [0, 0.1] }, 220 | noise_height: { value: 0.5, range: [0, 2] }, 221 | noise_scale: { value: 10, range: [0, 100] }, 222 | uTexture: { 223 | value: elem.nodeName.toLowerCase() === "img" ? t : [t[0], t[1]], 224 | }, 225 | }) 226 | 227 | 228 | 229 | const snoise = `vec3 mod289(vec3 x){return x-floor(x*(1./289.))*289.;}vec4 mod289(vec4 x){return x-floor(x*(1./289.))*289.;}vec4 permute(vec4 x){return mod289(((x*34.)+1.)*x);}vec4 taylorInvSqrt(vec4 r){return 1.79284291400159-.85373472095314*r;}float snoise(vec3 v){const vec2 C=vec2(1./6.,1./3.);const vec4 D=vec4(0.,.5,1.,2.);vec3 i=floor(v+dot(v,C.yyy));vec3 x0=v-i+dot(i,C.xxx);vec3 g=step(x0.yzx,x0.xyz);vec3 l=1.-g;vec3 i1=min(g.xyz,l.zxy);vec3 i2=max(g.xyz,l.zxy);vec3 x1=x0-i1+C.xxx;vec3 x2=x0-i2+C.yyy;vec3 x3=x0-D.yyy;i=mod289(i);vec4 p=permute(permute(permute(i.z+vec4(0.,i1.z,i2.z,1.))+i.y+vec4(0.,i1.y,i2.y,1.))+i.x+vec4(0.,i1.x,i2.x,1.));float n_=.142857142857;vec3 ns=n_*D.wyz-D.xzx;vec4 j=p-49.*floor(p*ns.z*ns.z);vec4 x_=floor(j*ns.z);vec4 y_=floor(j-7.*x_);vec4 x=x_*ns.x+ns.yyyy;vec4 y=y_*ns.x+ns.yyyy;vec4 h=1.-abs(x)-abs(y);vec4 b0=vec4(x.xy,y.xy);vec4 b1=vec4(x.zw,y.zw);vec4 s0=floor(b0)*2.+1.;vec4 s1=floor(b1)*2.+1.;vec4 sh=-step(h,vec4(0.));vec4 a0=b0.xzyw+s0.xzyw*sh.xxyy;vec4 a1=b1.xzyw+s1.xzyw*sh.zzww;vec3 p0=vec3(a0.xy,h.x);vec3 p1=vec3(a0.zw,h.y);vec3 p2=vec3(a1.xy,h.z);vec3 p3=vec3(a1.zw,h.w);vec4 norm=taylorInvSqrt(vec4(dot(p0,p0),dot(p1,p1),dot(p2,p2),dot(p3,p3)));p0*=norm.x;p1*=norm.y;p2*=norm.z;p3*=norm.w;vec4 m=max(.6-vec4(dot(x0,x0),dot(x1,x1),dot(x2,x2),dot(x3,x3)),0.);m=m*m;return 42.*dot(m*m,vec4(dot(p0,x0),dot(p1,x1),dot(p2,x2),dot(p3,x3)));}` 230 | const shapeModifier = /*glsl*/` 231 | uniform float shapeRadius,shapeEdgeSoftness; 232 | uniform vec2 shapePosition,shapeScale; 233 | uniform bool ignoreShapeAspect ; 234 | void roundedBoxSDF() { 235 | float asc=ignoreShapeAspect?aspect:1.0; 236 | float distance = length(max(abs((vec2(vuv.x,vuv.y/asc))-vec2(shapePosition.x,shapePosition.y/asc)*1.5-vec2(.5,.5/asc)) - vec2(shapeScale.x,shapeScale.y/asc) + shapeRadius, 0.0)) - shapeRadius; 237 | float smoothedAlpha = 1.0-smoothstep(0.0, shapeEdgeSoftness/10., distance); 238 | gl_FragColor = vec4(gl_FragColor.xyz, smoothedAlpha);} 239 | ` 240 | const material = new THREE.ShaderMaterial({ 241 | transparent: true, 242 | vertexShader: vertex.replace("#define SNOISEHOLDER", snoise), 243 | fragmentShader: fragment.replace("#define SNOISEHOLDER", snoise).replace("#define SHAPEMODIFIER", shapeModifier), 244 | uniforms, 245 | }) 246 | 247 | const elemMesh = new THREE.Mesh(geometry, material) 248 | elemMesh.scale.set(elemWidth, elemHeight) 249 | redraw(elemMesh, uniforms.geoVertex.value) 250 | elemMesh.visible = false 251 | scene.add(elemMesh) 252 | 253 | var debugObj = { 254 | backgroundImage: '', 255 | shapePosition: [0, 0], 256 | shapeScaleX: .5, 257 | shapeScaleY: .5, 258 | shapeScaleR: [0, 1], 259 | shapePositionX: .0, 260 | shapePositionY: .0, 261 | shapePositionR: [-2, 2], 262 | 263 | Mode: [ 264 | "Off", 265 | "Reflect/Glow", 266 | "Exclusion", 267 | "Difference", 268 | "Darken", 269 | "ColorBurn", 270 | "ColorDoge", 271 | "SoftLight", 272 | "Overlay", 273 | "Phoenix", 274 | "Add", 275 | "Multiply", 276 | "Screen", 277 | "Negative", 278 | "Divide", 279 | "Subtract", 280 | "Neon", 281 | "Natural", 282 | "Mod", 283 | "NeonNegative", 284 | "Dark", 285 | "Average", 286 | ], 287 | "Mode Active": "Soft Light", 288 | Trigo: ["Sin", "Cos", "Tan", "Atan"], 289 | "Trig A": "Cos", 290 | "Trig N": "Sin", 291 | Mouse: ["Off", "Mode 1", " Mode 2", " Mode 3"], 292 | onMouse: ["Always Active", "Active On Hover", "Deactivate On Hover"], 293 | Active: "Always Active", 294 | scrollType: ["Wave", "Morph"], 295 | scrollTypeIs: "Wave", 296 | "Mouse Active": "Off", 297 | Color: "#54A8FF", 298 | speed: { precise: 1, normal: 1, range: [-500, 500], rangep: [-10, 10] }, 299 | frequency: { 300 | precise: 1, 301 | normal: 50, 302 | range: [-800, 800], 303 | rangep: [-50, 50], 304 | }, 305 | Resolution_XY: { 306 | value: 1000, 307 | range: [0, 1000], 308 | precise: 1, 309 | rangep: [0, 100], 310 | }, 311 | pixelStrength: { 312 | precise: 1, 313 | normal: 3, 314 | range: [-20, 100], 315 | rangep: [-20, 20], 316 | }, 317 | strength: { precise: 1, normal: 0.2, range: [-40, 40], rangep: [-5, 5] }, 318 | s: 0.6, 319 | range: [0.1, 1], 320 | f: 0.6, 321 | rangep: [1, 10], 322 | } 323 | 324 | var controlKit = null 325 | var panel = null 326 | 327 | const config = (c) => { 328 | c = JSON.parse(JSON.stringify(c)) 329 | Object.assign(uniforms, c) 330 | if (c.color) c.color.value = new THREE.Color(c.color.value) 331 | Object.assign(uniforms, c) 332 | document.querySelector('._canvas_container').style.zIndex = uniforms.zindex.value 333 | } 334 | 335 | if (opts.preset) 336 | fetch(opts.preset) 337 | .then((response) => response.json()) 338 | .then((json) => config(json)) 339 | if (opts.config) config(opts.config) 340 | 341 | if ((opts.debug && !isdebug[effect]) || false) { 342 | isdebug[effect] = true 343 | controlKit = new ControlKit() 344 | 345 | if (opts.gooey === true) { 346 | controlKit 347 | .addPanel({ 348 | enable: false, 349 | label: "Gooey Panel", 350 | width: 300, 351 | fixed: false, 352 | position: [20, 50], 353 | }) 354 | .addSubGroup({ label: 'InfiniteGooey', enable: false }) 355 | .addCheckbox(uniforms.infiniteGooey, "value", { 356 | label: "Enable", 357 | }) 358 | .addSlider(uniforms.growSize, "value", "range", { 359 | label: "Grow Size", 360 | step: 0.001, 361 | }) 362 | .addSlider(uniforms.durationOut, "value", "range", { 363 | label: "Duration Out", 364 | step: 0.001, 365 | }) 366 | .addSlider(uniforms.durationIn, "value", "range", { 367 | label: "Duration In", 368 | step: 0.001, 369 | }) 370 | .addGroup() 371 | .addCheckbox(uniforms.noEffectGooey, "value", { 372 | label: "GooeyBakEffect", 373 | }) 374 | .addSlider(uniforms.noise_speed, "value", "range", { 375 | label: "Speed", 376 | step: 0.001, 377 | }) 378 | .addSlider(uniforms.metaball, "value", "range", { 379 | label: "GooeyBall", 380 | step: 0.001, 381 | }) 382 | .addSlider(uniforms.discard_threshold, "value", "range", { 383 | label: "Threshold", 384 | step: 0.001, 385 | }) 386 | .addSlider(uniforms.antialias_threshold, "value", "range", { 387 | label: "Antialias", 388 | step: 0.001, 389 | }) 390 | .addSlider(uniforms.noise_height, "value", "range", { 391 | label: "Height", 392 | step: 0.001, 393 | }) 394 | .addSlider(uniforms.noise_scale, "value", "range", { 395 | label: "Scale", 396 | step: 0.001, 397 | }) 398 | } 399 | 400 | panel = controlKit 401 | .addPanel({ 402 | enable: false, 403 | label: "Debug Panel", 404 | fixed: false, 405 | position: [20, 10], 406 | width: 300, 407 | }) 408 | .addButton("Save To Clipboard", () => { 409 | const { 410 | uScroll, 411 | isMulti, 412 | uSection, 413 | time, 414 | resolution, 415 | uTexture, 416 | mouse, 417 | mousem, 418 | mousei, 419 | uIntercept, 420 | ...rest 421 | } = uniforms 422 | navigator.clipboard.writeText(stringify(rest)).then( 423 | () => { 424 | document.querySelector('#controlKit .panel .button, #controlKit .picker .button').value = "Copied Successfully" 425 | document.querySelector('#controlKit .panel .button, #controlKit .picker .button').style.pointerEvents = "none" 426 | document.querySelector('body #controlKit .panel .button, #controlKit .picker .button').style.backgroundColor = "darkgreen" 427 | document.querySelector('body #controlKit .panel .button, #controlKit .picker .button').style.color = "white" 428 | setTimeout(() => { 429 | document.querySelector('#controlKit .panel .button, #controlKit .picker .button').value = "Save To Clipboard" 430 | document.querySelector('#controlKit .panel .button, #controlKit .picker .button').style.pointerEvents = "initial" 431 | document.querySelector('body #controlKit .panel .button, #controlKit .picker .button').style.backgroundColor = "#383c4a" 432 | document.querySelector('body #controlKit .panel .button, #controlKit .picker .button').style.color = "#8c92a4" 433 | }, 1500) 434 | }, 435 | () => { 436 | document.querySelector('#controlKit .panel .button, #controlKit .picker .button').value = "Failed To Copy" 437 | document.querySelector('#controlKit .panel .button, #controlKit .picker .button').style.pointerEvents = "none" 438 | document.querySelector('body #controlKit .panel .button, #controlKit .picker .button').style.backgroundColor = "red" 439 | document.querySelector('body #controlKit .panel .button, #controlKit .picker .button').style.color = "white" 440 | setTimeout(() => { 441 | document.querySelector('#controlKit .panel .button, #controlKit .picker .button').value = "Save To Clipboard" 442 | document.querySelector('#controlKit .panel .button, #controlKit .picker .button').style.pointerEvents = "initial" 443 | document.querySelector('body #controlKit .panel .button, #controlKit .picker .button').style.backgroundColor = "#383c4a" 444 | document.querySelector('body #controlKit .panel .button, #controlKit .picker .button').style.color = "#8c92a4" 445 | }, 1500) 446 | }, 447 | ) 448 | }) 449 | .addStringInput(uniforms.zindex, "value", { 450 | label: "Canvas Z-Index", 451 | step: 1, 452 | onChange: () => (document.querySelector('._canvas_container').style.zIndex = uniforms.zindex.value), 453 | }) 454 | .addSubGroup({ label: 'Shape Control', enable: false }) 455 | .addCheckbox(uniforms.ignoreShapeAspect,'value', { label: 'Ignore Shape Aspect' }) 456 | .addSlider(uniforms.shapeRadius, "value", "range", { 457 | label: "Radius", 458 | step: 0.001, 459 | }) 460 | .addSlider(uniforms.shapeEdgeSoftness, "value", "range", { 461 | label: "Edge Softness", 462 | step: 0.001, 463 | }) 464 | .addSlider(debugObj, "shapeScaleX", "shapeScaleR", { 465 | label: "Scale X", 466 | step: 0.001, 467 | onChange: () => uniforms.shapeScale.value.x = debugObj.shapeScaleX 468 | }) 469 | .addSlider(debugObj, "shapeScaleY", "shapeScaleR", { 470 | label: "Scale Y", 471 | step: 0.001, 472 | onChange: () => uniforms.shapeScale.value.y = debugObj.shapeScaleY 473 | }) 474 | .addSlider(debugObj, "shapePositionX", "shapePositionR", { 475 | label: "Position X", 476 | step: 0.001, 477 | onChange: () => uniforms.shapePosition.value.x = debugObj.shapePositionX 478 | }) 479 | .addSlider(debugObj, "shapePositionY", "shapePositionR", { 480 | label: "Position Y", 481 | step: 0.001, 482 | onChange: () => uniforms.shapePosition.value.y = debugObj.shapePositionY 483 | }) 484 | 485 | .addGroup() 486 | document.querySelector('body #controlKit .panel .button, #controlKit .picker .button').style.color = "#8c92a4" 487 | if (!(elem.nodeName.toLowerCase() === "img") && opts.gooey != true) 488 | panel.addSelect(debugObj, "scrollType", { 489 | target: "scrollTypeIs", 490 | label: "Scroll Type", 491 | onChange: (x) => (uniforms.scrollType.value = x), 492 | }) 493 | panel 494 | .addCheckbox(uniforms.masker, "value", { 495 | label: "Image Zoomer", 496 | }) 497 | .addSlider(uniforms.maskVal, "value", "range", { 498 | label: "Zoom level", 499 | step: 0.00001, 500 | }) 501 | } 502 | 503 | const raycaster = new THREE.Raycaster() 504 | let mouseCoords = new THREE.Vector2(0.5, 0.5) 505 | 506 | let isMouseOverElemMesh = false 507 | 508 | const mover = (event) => { 509 | raycaster.setFromCamera(new THREE.Vector2((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window.innerHeight) * 2 + 1), camera) 510 | 511 | const intersects = raycaster.intersectObject(elemMesh) 512 | 513 | if (intersects.length > 0) { 514 | mouseCoords = intersects[0].uv 515 | mouse.x = (intersects[0].uv.x) * 2 - 1 516 | mouse.y = -(intersects[0].uv.y) * 2 - 1 517 | 518 | if (!isMouseOverElemMesh) 519 | isMouseOverElemMesh = true 520 | } else if (isMouseOverElemMesh) { 521 | isMouseOverElemMesh = false 522 | } 523 | } 524 | 525 | let scrollPos = null 526 | document.addEventListener("mousemove", mover) 527 | document.addEventListener("wheel", mover) 528 | // document.addEventListener("wheel", (e) => { 529 | // console.log(scrollPos != scrollY, scrollY) 530 | // if (scrollPos != scrollY) { 531 | // if (e.deltaY > 0 || !scrollPos) { 532 | // scrollPos = scrollY 533 | // mouseCoords.y -= e.deltaY / window.innerHeight 534 | // } 535 | // } 536 | // }) 537 | let isGooeyLerping = false 538 | let currentGooey = 0 539 | 540 | function calculateGooey(i) { 541 | var l = src.length 542 | return i % l 543 | } 544 | 545 | if (opts.slideStyle && typeof opts.slideStyle === "function") 546 | opts.slideStyle((x) => uniforms.currentScroll.value = x, (y) => uniforms.scrollLerp.value = y) 547 | if (opts.setUniforms && typeof opts.setUniforms === "function") 548 | opts.setUniforms(uniforms) 549 | 550 | const originalGooey = uniforms.metaball.value 551 | elem.addEventListener('mousedown', (e) => { 552 | if ((e.button == 0) && !isGooeyLerping && uniforms.infiniteGooey.value && opts.gooey && !opts.slideStyle) { 553 | gsap.to(uniforms.metaball, { 554 | value: uniforms.growSize.value, 555 | duration: uniforms.durationOut.value, 556 | ease: Expo.easeInOut, 557 | onStart: () => { 558 | isGooeyLerping = true 559 | }, 560 | onComplete: () => { 561 | currentGooey++ 562 | uniforms.metaball.value = 0 563 | isGooeyLerping = false 564 | uniforms.uTexture.value = [t[calculateGooey(currentGooey)], t[calculateGooey(currentGooey + 1)]] 565 | gsap.to(uniforms.metaball, { 566 | value: originalGooey, 567 | ease: Expo.easeInOut, 568 | duration: uniforms.durationIn.value 569 | }) 570 | } 571 | }) 572 | } 573 | }) 574 | 575 | 576 | document.addEventListener("mousemove", (e) => { 577 | const centerX = window.innerWidth / 2 578 | const centerY = window.innerHeight / 2 579 | const mouseX = event.clientX 580 | const mouseY = event.clientY 581 | 582 | const deltaX = mouseX - centerX 583 | const deltaY = mouseY - centerY 584 | 585 | const normalizedX = deltaX / centerX 586 | const normalizedY = deltaY / centerY 587 | 588 | mousem.x = normalizedX / 300 589 | mousem.y = normalizedY / 300 590 | }) 591 | 592 | 593 | 594 | const fit = () => { 595 | width = innerWidth 596 | height = innerHeight 597 | 598 | renderer.setSize(width, height) 599 | renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)) 600 | 601 | camera.fov = 2 * Math.atan(height / 2 / 10) * (180 / Math.PI) 602 | 603 | camera.aspect = width / height 604 | camera.updateProjectionMatrix() 605 | 606 | elemLeft = elem.getBoundingClientRect().left 607 | elemWidth = elem.getBoundingClientRect().width 608 | elemHeight = elem.getBoundingClientRect().height 609 | 610 | elemMesh.scale.set( 611 | elem.getBoundingClientRect().width, 612 | elem.getBoundingClientRect().height 613 | ) 614 | 615 | const size = new THREE.Vector3() 616 | new THREE.Box3().setFromObject(elemMesh).getSize(size) 617 | createCroppedTexture(sources, size.x / size.y, t) 618 | .then((texture) => { 619 | texture.minFilter = THREE.LinearFilter 620 | texture.magFilter = THREE.LinearFilter 621 | elemMesh.material.uniforms.uTexture.value = texture 622 | t = texture 623 | elemMesh.visible = true 624 | }) 625 | .catch((error) => { 626 | console.error("Error loading image:", error) 627 | }) 628 | uniforms.aspect.value = elemWidth / elemHeight 629 | } 630 | let loaded = false 631 | function createCroppedTexture(sources, newAspect, oldTextures = []) { 632 | return Promise.all( 633 | sources.map((source, index) => { 634 | return new Promise((resolve, reject) => { 635 | if (source.nodeName.toLowerCase() === "video") { 636 | source.onloadedmetadata = () => { 637 | if (oldTextures[index]) { 638 | oldTextures[index].dispose() 639 | } 640 | var videoTexture = new THREE.VideoTexture(source) 641 | videoTexture.minFilter = THREE.LinearFilter 642 | videoTexture.magFilter = THREE.LinearFilter 643 | resolve(videoTexture) 644 | } 645 | } else { 646 | function load() { 647 | const imgWidth = source.width 648 | const imgHeight = source.height 649 | let newWidth, newHeight 650 | let xOffset = 0 651 | let yOffset = 0 652 | 653 | if (imgWidth / imgHeight > newAspect) { 654 | newWidth = imgHeight * newAspect 655 | newHeight = imgHeight 656 | xOffset = (imgWidth - newWidth) / 2 657 | } else { 658 | newWidth = imgWidth 659 | newHeight = imgWidth / newAspect 660 | yOffset = (imgHeight - newHeight) / 2 661 | } 662 | 663 | const canvas = document.createElement("canvas") 664 | canvas.width = newWidth 665 | canvas.height = newHeight 666 | const ctx = canvas.getContext("2d") 667 | ctx.drawImage( 668 | source, 669 | xOffset, 670 | yOffset, 671 | newWidth, 672 | newHeight, 673 | 0, 674 | 0, 675 | newWidth, 676 | newHeight 677 | ) 678 | 679 | if (oldTextures[index]) { 680 | oldTextures[index].dispose() 681 | } 682 | 683 | const newTexture = new THREE.Texture(canvas) 684 | newTexture.needsUpdate = true 685 | resolve(newTexture) 686 | } 687 | if (loaded) load() 688 | source.onload = () => { 689 | load() 690 | loaded = true 691 | } 692 | source.onerror = (error) => { 693 | reject(error) 694 | } 695 | } 696 | }) 697 | }) 698 | ) 699 | } 700 | 701 | fit() 702 | setTimeout(window.dispatchEvent(new Event("resize")), 0) 703 | addEventListener("resize", fit) 704 | 705 | 706 | const clock = new THREE.Clock() 707 | function animate() { 708 | elemMesh.position.y = -elem.getBoundingClientRect().top + height / 2 - elem.getBoundingClientRect().height / 2 709 | elemMesh.position.x = elem.getBoundingClientRect().left - width / 2 + elem.getBoundingClientRect().width / 2 710 | if (!opts.slideStyle) if (opts.gooey != true) staticScroll() 711 | 712 | if (document.querySelector(o)) 713 | if (parseInt(document.querySelector(o).style.top) < 0) 714 | document.querySelector(o).style.top = "0px" 715 | 716 | renderer.render(scene, camera) 717 | 718 | Object.assign(uniforms, { 719 | time: { value: clock.getElapsedTime() }, 720 | mouse: { value: mouse }, 721 | mousem: { value: mousem }, 722 | }) 723 | 724 | uniforms.mousei.value.x = THREE.MathUtils.lerp(uniforms.mousei.value.x, mouseCoords.x, .07) 725 | uniforms.mousei.value.y = THREE.MathUtils.lerp(uniforms.mousei.value.y, mouseCoords.y, .07) 726 | if (!opts.gooey || opts.slideStyle) 727 | doAction(uniforms.scrollLerp.value) 728 | 729 | 730 | if (!isGooeyLerping) 731 | uniforms.uIntercept.value = THREE.MathUtils.lerp( 732 | uniforms.uIntercept.value, 733 | isMouseOverElemMesh ? 1 : 0, 734 | 0.07 735 | ) 736 | 737 | elemLeft = elem.getBoundingClientRect().left 738 | elemWidth = elem.getBoundingClientRect().width 739 | elemHeight = elem.getBoundingClientRect().height 740 | 741 | 742 | elemMesh.scale.set( 743 | elem.getBoundingClientRect().width, 744 | elem.getBoundingClientRect().height 745 | ) 746 | 747 | elemMesh.material.uniforms.time.value = clock.getElapsedTime() 748 | if (getTranslate3d(elem)[2]) 749 | elemMesh.position.z = getTranslate3d(elem)[2] 750 | 751 | 752 | requestAnimationFrame(animate) 753 | } 754 | 755 | attributes.uniforms.push(uniforms) 756 | attributes.meshes.push(elemMesh) 757 | return { 758 | material, 759 | debugObj, 760 | controlKit, 761 | panel, 762 | animate, 763 | elemMesh, 764 | uniforms: elemMesh.material.uniforms, 765 | } 766 | } 767 | -------------------------------------------------------------------------------- /src/shaders/effect1/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D uTexture[16]; 2 | uniform float uIntercept,displaceAmount,scrollType,time,a,b,onMouse,uScroll,uSection; 3 | uniform bool isMulti,masker,noEffectGooey; 4 | uniform vec2 mousei; 5 | uniform float maskVal,aspect,noise_speed,metaball,discard_threshold,antialias_threshold,noise_height,noise_scale; 6 | 7 | varying vec2 vuv; 8 | #define SNOISEHOLDER 9 | #define SHAPEMODIFIER 10 | 11 | void main(){ 12 | vec2 uv=(vuv/1.1)+.05; 13 | uv=uv*2.-1.; 14 | uv=masker?mix(uv,uv/max(1.,maskVal),uIntercept):uv/max(1.,maskVal); 15 | uv=uv*.5+.5; 16 | vec3 v=vec3(vuv.x*1.+time*a/10.,vuv.y,time); 17 | vec2 surface=vec2(snoise(v)*.08,snoise(v)*.01); 18 | surface=onMouse==0.?surface:onMouse==1.?mix(vec2(0.),surface,uIntercept):mix(surface,vec2(0.),uIntercept); 19 | uv+=refract(vec2(.0,.0),surface,b); 20 | gl_FragColor=texture2D(uTexture[0],uv); 21 | vec2 uv2=noEffectGooey?vuv:uv; 22 | !isMulti; 23 | roundedBoxSDF(); 24 | } -------------------------------------------------------------------------------- /src/shaders/effect1/vertex.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vuv; 2 | void main(){ 3 | gl_Position=projectionMatrix*viewMatrix*modelMatrix*vec4(position,1.); 4 | vuv=uv; 5 | } -------------------------------------------------------------------------------- /src/shaders/effect2/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform vec2 mouse; 2 | uniform float resolutionXY,uIntercept,scrollType,displaceAmount,time,frequency,angle,speed,waveFactor,contrast,pixelStrength,quality,brightness,colorExposer,strength,exposer,uScroll,uSection; 3 | uniform int onMouse,mousemove,mode,modeA,modeN; 4 | uniform vec2 mousei; 5 | uniform float maskVal,aspect,noise_speed,metaball,discard_threshold,antialias_threshold,noise_height,noise_scale; 6 | uniform bool distortion,gooey,masker,noEffectGooey; 7 | uniform vec3 color; 8 | varying vec2 vuv; 9 | uniform sampler2D uTexture[16]; 10 | float mina(vec4 a){ 11 | return min(min(a.r,a.g),a.b); 12 | } 13 | float maxa(vec4 a){ 14 | return max(max(a.r,a.g),a.b); 15 | } 16 | vec4 minn(vec4 a,vec4 b){ 17 | return vec4(min(a.r,b.r),min(a.g,b.g),min(a.b,b.b),1.); 18 | } 19 | vec4 maxx(vec4 a,vec4 b){ 20 | return vec4(max(a.r,b.r),max(a.g,b.g),max(a.b,b.b),1.); 21 | } 22 | mat2 rotate2D(float r){ 23 | return mat2(cos(r),sin(r),-sin(r),cos(r)); 24 | } 25 | 26 | #define SNOISEHOLDER 27 | #define SHAPEMODIFIER 28 | vec4 img(vec2 uv,float c){ 29 | uv=uv*2.-1.; 30 | uv=masker?mix(uv,uv/max(1.,maskVal),uIntercept):uv/max(1.,maskVal); 31 | uv=uv*.5+.5; 32 | 33 | vec2 pos=vec2(vuv.x,vuv.y/aspect); 34 | vec2 mouse=vec2(mousei.x,(mousei.y)/aspect); 35 | vec2 interpole=mix(vec2(0),vec2(metaball,noise_height),uIntercept); 36 | float noise=(snoise(vec3(pos*noise_scale,time*noise_speed))+1.)/2.; 37 | float val=noise*interpole.y; 38 | float u=1.-smoothstep(interpole.x,.0,distance(mouse,pos)); 39 | float mouseMetaball=clamp(1.-u,0.,1.); 40 | val+=mouseMetaball; 41 | float alpha=smoothstep(discard_threshold-antialias_threshold,discard_threshold,val); 42 | 43 | float blend=uScroll-uSection; 44 | float blend2=1.-blend; 45 | vec4 imageA=texture2D(uTexture[0],vec2(uv.x,uv.y-(((texture2D(uTexture[0],uv).r*displaceAmount)*blend)*2.)))*blend2; 46 | vec4 imageB=texture2D(uTexture[1],vec2(uv.x,uv.y+(((texture2D(uTexture[1],uv).r*displaceAmount)*blend2)*2.)))*blend; 47 | 48 | vec2 uv2=noEffectGooey?vuv:uv; 49 | return gooey?vec4(mix(texture2D(uTexture[0],uv),texture2D(uTexture[1],uv2),alpha)):scrollType==0.?mix(texture2D(uTexture[1],uv),texture2D(uTexture[0],uv),step((uScroll)-uSection,c+uv.y)):imageA.bbra*blend+imageA*blend2+imageB.bbra*blend2+imageB*blend; 50 | } 51 | 52 | void main(){ 53 | vec2 resolution=vec2(resolutionXY*20.); 54 | float brightness=clamp(brightness,-1.,25.); 55 | float frequency=clamp(frequency,-999.,999.); 56 | float contrast=clamp(contrast,-50.,50.); 57 | float pixelStrength=clamp(pixelStrength,-20.,999.); 58 | float strength=clamp(strength,-100.,100.); 59 | float colorExposer=clamp(colorExposer,-5.,5.); 60 | 61 | vec2 uv=.5*(gl_FragCoord.xy-.5*resolution.xy)/resolution.y; 62 | uv=mousemove!=0?mix(uv,.5*(gl_FragCoord.xy-.5*resolution.xy)/resolution.y+mouse.xy/300.,uIntercept):uv; 63 | float c=(sin((uv.x*7.*snoise(vec3(uv,1.)))+(time))/15.*snoise(vec3(uv,1.)))+.01; 64 | vec3 col=vec3(0); 65 | vec2 n,q=vec2(0); 66 | vec2 p=(uv+brightness/10.); 67 | float d=dot(p,p); 68 | float a=-(contrast/100.); 69 | mat2 angle=rotate2D(angle); 70 | 71 | for(float i=1.;i<=10.;i++){ 72 | if(i>quality) 73 | break; 74 | p,n*=angle; 75 | if(mousemove==0) 76 | q=p*frequency+time*speed+sin(time)*.0018*i-pixelStrength*n; 77 | if(mousemove==1) 78 | q=p*frequency+time*speed+sin(time)*.0018*i+mouse-pixelStrength*n; 79 | if(mousemove==2) 80 | q=p*frequency+time*speed+sin(time)*.0018*i-pixelStrength+mouse*n; 81 | if(mousemove==3) 82 | q=p*frequency+time*speed+sin(time)*.0018*i+mouse-pixelStrength+mouse*n; 83 | if(modeA==0) 84 | a+=dot(sin(q)/frequency,vec2(strength)); 85 | else if(modeA==1) 86 | a+=dot(cos(q)/frequency,vec2(strength)); 87 | else if(modeA==2) 88 | a+=dot(tan(q)/frequency,vec2(strength)); 89 | else if(modeA==3) 90 | a+=dot(atan(q)/frequency,vec2(strength)); 91 | if(modeN==0) 92 | n-=sin(q); 93 | else if(modeN==1) 94 | n-=cos(q); 95 | else if(modeN==2) 96 | n-=tan(q); 97 | else if(modeN==3) 98 | n-=atan(q); 99 | n=mousemove!=0?mix(n+mouse,n,uIntercept):n; 100 | frequency*=waveFactor; 101 | } 102 | col=(color*4.5)*(a+colorExposer)+exposer*a+a+d; 103 | vec4 base=distortion?img((vuv+a+contrast/100.),c):img(vuv,c); 104 | base=onMouse==0?base:onMouse==1?mix(img(vuv,c),base,uIntercept):mix(base,img(vuv,c),uIntercept); 105 | vec4 blend=vec4(col,1.); 106 | vec4 final=mix(base,gl_FragColor,uIntercept); 107 | if(mode==-10) 108 | final=base; 109 | else if(mode==-1) 110 | final=minn(base,blend)-maxx(base,blend)+vec4(1.); 111 | else if(mode==-9) 112 | final=(maxa(blend)==1.)?blend:minn(base*base/(1.-blend),vec4(1.)); 113 | else if(mode==-8) 114 | final=base+blend-2.*base*blend; 115 | else if(mode==-7) 116 | final=abs(base-blend); 117 | else if(mode==-6) 118 | final=minn(base,blend); 119 | else if(mode==-5) 120 | final=(mina(blend)==0.)?blend:maxx((1.-((1.-base)/blend)),vec4(0.)); 121 | else if(mode==-4) 122 | final=maxa(base)==1.?blend:minn(base/(1.-blend),vec4(1.)); 123 | else if(mode==-3) 124 | final=(1.-2.*blend)*base*base+2.*base*blend; 125 | else if(mode==-2) 126 | final=maxa(base)<.5?2.*base*blend:1.-2.*(1.-base)*(1.-blend); 127 | else if(mode==0) 128 | final=base+blend; 129 | else if(mode==1) 130 | final=base*blend; 131 | else if(mode==2) 132 | final=1.-(1.-base)*(1.-blend); 133 | else if(mode==3) 134 | final=blend-base; 135 | else if(mode==4) 136 | final=base/blend; 137 | else if(mode==5) 138 | final=maxx(base+blend-1.,vec4(0.)); 139 | else if(mode==6) 140 | final=(base+blend/base)-.55; 141 | else if(mode==7) 142 | final=base+blend*base; 143 | else if(mode==8) 144 | final=mod(base,blend); 145 | else if(mode==9) 146 | final=1.-(base+blend/base)+.5; 147 | else if(mode==10) 148 | final=blend-base*blend; 149 | else if(mode==11) 150 | final=(base+blend/2.); 151 | final=mix(final*brightness,mix(maxx(final,vec4(1.)),final,contrast),.5); 152 | final=onMouse==0?final:onMouse==1?mix(base,final,uIntercept):mix(final,base,uIntercept); 153 | gl_FragColor=final; 154 | roundedBoxSDF(); 155 | } 156 | -------------------------------------------------------------------------------- /src/shaders/effect2/vertex.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vuv; 2 | void main() { 3 | gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.); 4 | vuv = uv; 5 | } -------------------------------------------------------------------------------- /src/shaders/effect3/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D uTexture[16]; 2 | uniform float scrollType,displaceAmount,uScroll,uSection,time; 3 | uniform bool isMulti,masker,noEffectGooey; 4 | uniform vec2 mousei; 5 | uniform float uIntercept,maskVal,aspect,noise_speed,metaball,discard_threshold,antialias_threshold,noise_height,noise_scale; 6 | varying vec2 vuv; 7 | 8 | #define SNOISEHOLDER 9 | #define SHAPEMODIFIER 10 | void main(){ 11 | vec2 uv=vuv; 12 | uv=uv*2.-1.; 13 | uv=masker?mix(uv,uv/max(1.,maskVal),uIntercept):uv/max(1.,maskVal); 14 | uv=uv*.5+.5; 15 | gl_FragColor=texture2D(uTexture[0],uv); 16 | vec2 uv2=noEffectGooey?vuv:uv; 17 | !isMulti; 18 | roundedBoxSDF(); 19 | } -------------------------------------------------------------------------------- /src/shaders/effect3/vertex.glsl: -------------------------------------------------------------------------------- 1 | uniform float uFrequencyX, uFrequencyY, uFrequencyZ, time, uIntercept; 2 | uniform int onMouse; 3 | varying vec2 vuv; 4 | void main() { 5 | vec3 uFrequency = vec3(uFrequencyX / 500., uFrequencyY / 500., uFrequencyZ * 10.0); 6 | vec4 modelPosition = modelMatrix * vec4(position, 1.0); 7 | float elevation = sin(modelPosition.x * uFrequency.x - time) * uFrequency.z / 1000.0; 8 | elevation += sin(modelPosition.y * uFrequency.y - time) * uFrequency.z / 1000.0; 9 | modelPosition.z += elevation; 10 | modelPosition = onMouse == 0 ? modelPosition : onMouse == 1 ? mix(modelMatrix * vec4(position, 1.0), modelPosition, uIntercept) : mix(modelPosition, modelMatrix * vec4(position, 1.0), uIntercept); 11 | gl_Position = projectionMatrix * viewMatrix * modelPosition; 12 | vuv = uv; 13 | } -------------------------------------------------------------------------------- /src/shaders/effect4/fragment.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D uTexture[16]; 2 | uniform float scrollType,displaceAmount,uScroll,uSection,time; 3 | uniform bool isMulti,masker,noEffectGooey,uColor; 4 | uniform vec2 mousei; 5 | varying float vWave; 6 | uniform float uIntercept,maskVal,aspect,noise_speed,metaball,discard_threshold,antialias_threshold,noise_height,noise_scale; 7 | varying vec2 vuv; 8 | #define SNOISEHOLDER 9 | #define SHAPEMODIFIER 10 | void main(){ 11 | vec2 uv=vuv; 12 | uv=uv*2.-1.; 13 | uv=masker?mix(uv,uv/max(1.,maskVal),uIntercept):uv/max(1.,maskVal); 14 | uv=uv*.5+.5; 15 | gl_FragColor=texture2D(uTexture[0],uv); 16 | vec2 uv2=noEffectGooey?vuv:uv; 17 | !isMulti; 18 | gl_FragColor=uColor?mix(gl_FragColor,vec4(1.),vWave):gl_FragColor; 19 | roundedBoxSDF(); 20 | } -------------------------------------------------------------------------------- /src/shaders/effect4/vertex.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vuv; 2 | varying float vWave; 3 | uniform float time,uFrequency,uAmplitude,uSpeed,uIntercept,scrollType,onMouse; 4 | #define SNOISEHOLDER 5 | void main(){ 6 | vuv=uv; 7 | vec3 pos=position; 8 | float noiseFreq=uFrequency; 9 | float noiseAmp=uAmplitude/10.; 10 | vec3 noisePos=vec3(pos.x*noiseFreq+time*uSpeed,pos.y,pos.z); 11 | pos.z+=snoise(noisePos)*noiseAmp; 12 | pos=onMouse==0.?pos:onMouse==1.?mix(position,pos,uIntercept):mix(pos,position,uIntercept); 13 | vWave=pos.z; 14 | gl_Position=projectionMatrix*modelViewMatrix*vec4(pos,1.); 15 | } -------------------------------------------------------------------------------- /src/shaders/effect5/fragment.glsl: -------------------------------------------------------------------------------- 1 | 2 | uniform sampler2D uTexture[16]; 3 | uniform float maskVal,uIntercept,displaceAmount,scrollType,time,a,b,onMouse,uScroll,uSection; 4 | uniform bool isMulti,masker,noEffectGooey; 5 | uniform vec2 mousei; 6 | uniform float aspect,noise_speed,metaball,discard_threshold,antialias_threshold,noise_height,noise_scale; 7 | uniform vec2 mouse,mousem; 8 | varying vec2 vuv; 9 | #define SNOISEHOLDER 10 | #define SHAPEMODIFIER 11 | float cnoise(vec2 P){return snoise(vec3(P,1.));} 12 | void main(){ 13 | vec2 uv=(vuv/1.1)+.05; 14 | uv=uv*2.-1.; 15 | uv=masker?mix(uv,uv/max(1.,maskVal),uIntercept):uv/max(1.,maskVal); 16 | uv=uv*.5+.5; 17 | float time=time*a; 18 | vec2 surface=vec2(cnoise(uv-(mouse/2.)/7.+.2*time)*.08,cnoise(uv-(mouse/2.)/7.+.2*time)*.08); 19 | surface=onMouse==0.?surface:onMouse==1.?mix(vec2(0.),surface,uIntercept):mix(surface,vec2(0.),uIntercept); 20 | uv+=refract(vec2(mousem),surface,b); 21 | gl_FragColor=texture2D(uTexture[0],uv); 22 | vec2 uv2=noEffectGooey?vuv:uv; 23 | !isMulti; 24 | roundedBoxSDF(); 25 | 26 | } -------------------------------------------------------------------------------- /src/shaders/effect5/vertex.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vuv; 2 | void main(){ 3 | gl_Position=projectionMatrix*viewMatrix*modelMatrix*vec4(position,1.); 4 | vuv=uv; 5 | } -------------------------------------------------------------------------------- /src/shaders/effect6/fragment.glsl: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | uniform sampler2D uTexture[16]; 4 | 5 | uniform float maskVal,time,uIntercept,displaceAmount,scrollType,onMouse,uScroll,uSection,aspect,noise_speed,metaball,discard_threshold,antialias_threshold,noise_height,noise_scale; 6 | uniform bool isMulti,masker,noEffectGooey; 7 | uniform vec2 mousei; 8 | varying vec2 vuv; 9 | 10 | uniform float noiseDetail; 11 | uniform float distortionAmount; 12 | uniform float scale,speed; 13 | 14 | #define SNOISEHOLDER 15 | #define SHAPEMODIFIER 16 | void main(){ 17 | vec2 uv=vuv; 18 | uv=uv*2.-1.; 19 | uv=masker?mix(uv,uv/max(1.,maskVal),uIntercept):uv/max(1.,maskVal); 20 | uv=uv*.5+.5; 21 | 22 | float x=(uv.x-.5)*scale*(noiseDetail/100.)*sin(time)*speed; 23 | float y=(uv.y-.5)*scale*(noiseDetail/100.)*cos(time)*speed; 24 | uv+=snoise(vec3(x,y,0.))*(distortionAmount/100.); 25 | gl_FragColor=texture2D(uTexture[0],uv); 26 | vec2 uv2=noEffectGooey?vuv:uv; 27 | !isMulti; 28 | roundedBoxSDF(); 29 | 30 | } -------------------------------------------------------------------------------- /src/shaders/effect6/vertex.glsl: -------------------------------------------------------------------------------- 1 | 2 | varying vec2 vuv; 3 | void main() 4 | { 5 | vec4 modelPosition = modelMatrix * vec4(position, 1.0); 6 | vec4 viewPosition = viewMatrix * modelPosition; 7 | vec4 projectedPosition = projectionMatrix * viewPosition; 8 | gl_Position = projectedPosition; 9 | vuv = uv; 10 | } 11 | -------------------------------------------------------------------------------- /src/shaders/effect7/fragment.glsl: -------------------------------------------------------------------------------- 1 | 2 | varying vec2 vuv; 3 | uniform float maskVal,time,uIntercept,displaceAmount,scrollType,onMouse,uScroll,uSection,aspect,noise_speed,metaball,discard_threshold,antialias_threshold,noise_height,noise_scale; 4 | uniform bool isMulti,masker,noEffectGooey; 5 | uniform vec2 mousei; 6 | uniform float rotation,pattern,scale,density,clustering,gapping,smoothness,styling,circular,mouseMoveEWX,mouseMoveEHY; 7 | uniform bool invert,autorotate,isTexture,mouseMove,gooey; 8 | uniform vec3 color; 9 | uniform sampler2D uTexture[16]; 10 | 11 | #define SNOISEHOLDER 12 | #define SHAPEMODIFIER 13 | void main() 14 | { 15 | vec2 uv=vuv; 16 | uv=uv*2.-1.; 17 | uv=masker?mix(uv,uv/max(1.,maskVal),uIntercept):uv/max(1.,maskVal); 18 | uv=uv*.5+.5; 19 | vec2 uvx=uv; 20 | 21 | uv-=vec2(.5,.5); 22 | 23 | float m=mouseMove?smoothstep(mouseMoveEWX,mouseMoveEHY,length(uvx-mousei)):1.; 24 | 25 | float rot=radians((rotation)); 26 | rot-=radians((autorotate?time:0.)); 27 | mat2 rotation_matrix=mat2(cos(rot),-sin(rot),sin(rot),cos(rot)); 28 | uv=rotation_matrix*uv; 29 | vec2 scaled_uv=(1.-scale+1.)*vec2(vuv.x,vuv.y/aspect); 30 | vec2 tile=fract(scaled_uv); 31 | float tile_dist=min(min(tile.x,1.-tile.x),min(tile.y,1.-tile.y)); 32 | float square_dist=length(floor(scaled_uv)); 33 | 34 | float edge=sin(time-square_dist*pattern); 35 | edge=mod(edge*edge,edge/edge); 36 | 37 | float value=mix(tile_dist,1.-tile_dist,step(density,edge)); 38 | edge=pow(abs(1.-edge*m),clustering*m)*gapping; 39 | 40 | value=smoothstep(edge-smoothness*m,edge,styling*value); 41 | 42 | value+=square_dist*circular; 43 | 44 | vec4 t=texture2D(uTexture[0],uvx); 45 | vec4 col=isTexture?texture2D(uTexture[2],uvx):vec4(color,1.); 46 | if(isMulti&&!gooey){ 47 | float c=(sin((uv.x*7.*snoise(vec3(uv,1.)))+(time))/15.*snoise(vec3(uv,1.)))+.01; 48 | float blend=uScroll-uSection; 49 | float blend2=1.-blend; 50 | vec4 imageA=texture2D(uTexture[0],vec2(uvx.x,uvx.y-(((texture2D(uTexture[0],uvx).r*displaceAmount)*blend)*2.)))*blend2; 51 | vec4 imageB=texture2D(uTexture[1],vec2(uvx.x,uvx.y+(((texture2D(uTexture[1],uvx).r*displaceAmount)*blend2)*2.)))*blend; 52 | gl_FragColor=scrollType==0.?mix(texture2D(uTexture[1],uvx),texture2D(uTexture[0],uvx),step((uScroll)-uSection,sin(c)+uvx.y)):imageA.bbra*blend+imageA*blend2+imageB.bbra*blend2+imageB*blend; 53 | gl_FragColor=invert?mix(gl_FragColor,col,value):mix(col,gl_FragColor,value); 54 | 55 | }else{ 56 | gl_FragColor=invert?mix(t,col,value):mix(col,t,value); 57 | 58 | } 59 | 60 | if(gooey){ 61 | vec2 pos=vec2(vuv.x,vuv.y/aspect); 62 | vec2 mouse=vec2(mousei.x,(mousei.y)/aspect); 63 | vec2 interpole=mix(vec2(0),vec2(metaball,noise_height),uIntercept); 64 | float noise=(snoise(vec3(pos*noise_scale,time*noise_speed))+1.)/2.; 65 | float val=noise*interpole.y; 66 | float u=1.-smoothstep(interpole.x,.0,distance(mouse,pos)); 67 | float mouseMetaball=clamp(1.-u,0.,1.); 68 | val+=mouseMetaball; 69 | float alpha=smoothstep(discard_threshold-antialias_threshold,discard_threshold,val); 70 | gl_FragColor=vec4(mix(gl_FragColor,invert?mix(texture2D(uTexture[1],uvx),col,value):mix(col,texture2D(uTexture[1],uvx),value),alpha)); 71 | } 72 | roundedBoxSDF(); 73 | } 74 | -------------------------------------------------------------------------------- /src/shaders/effect7/vertex.glsl: -------------------------------------------------------------------------------- 1 | 2 | varying vec2 vuv; 3 | void main() 4 | { 5 | vec4 modelPosition = modelMatrix * vec4(position, 1.0); 6 | vec4 viewPosition = viewMatrix * modelPosition; 7 | vec4 projectedPosition = projectionMatrix * viewPosition; 8 | gl_Position = projectedPosition; 9 | vuv = uv; 10 | } 11 | --------------------------------------------------------------------------------