Upload 27 files
Browse files- stripe-gradient-animation/.gitignore +216 -0
- stripe-gradient-animation/.idea/.gitignore +8 -0
- stripe-gradient-animation/.idea/modules.xml +8 -0
- stripe-gradient-animation/.idea/php.xml +4 -0
- stripe-gradient-animation/.idea/stripe-canvas-gradient.iml +8 -0
- stripe-gradient-animation/.idea/vcs.xml +6 -0
- stripe-gradient-animation/README.md +28 -0
- stripe-gradient-animation/dist/stripe-gradient.js +1 -0
- stripe-gradient-animation/index.html +65 -0
- stripe-gradient-animation/package-lock.json +0 -0
- stripe-gradient-animation/package.json +36 -0
- stripe-gradient-animation/src/Attribute.js +63 -0
- stripe-gradient-animation/src/Gradient.js +439 -0
- stripe-gradient-animation/src/Material.js +107 -0
- stripe-gradient-animation/src/Mesh.js +65 -0
- stripe-gradient-animation/src/MiniGL.js +117 -0
- stripe-gradient-animation/src/PlaneGeometry.js +110 -0
- stripe-gradient-animation/src/Shaders/Blend.glsl +177 -0
- stripe-gradient-animation/src/Shaders/Fragment.glsl +10 -0
- stripe-gradient-animation/src/Shaders/Noise.glsl +103 -0
- stripe-gradient-animation/src/Shaders/Vertex.glsl +76 -0
- stripe-gradient-animation/src/ShadersJs/Blend.js +178 -0
- stripe-gradient-animation/src/ShadersJs/Fragment.js +11 -0
- stripe-gradient-animation/src/ShadersJs/Noise.js +104 -0
- stripe-gradient-animation/src/ShadersJs/Vertex.js +77 -0
- stripe-gradient-animation/src/Uniform.js +107 -0
- stripe-gradient-animation/webpack.mix.js +4 -0
stripe-gradient-animation/.gitignore
ADDED
@@ -0,0 +1,216 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Project specific
|
2 |
+
/dist/mix-manifest.json
|
3 |
+
|
4 |
+
# Created by https://www.toptal.com/developers/gitignore/api/node,linux,macos,windows
|
5 |
+
# Edit at https://www.toptal.com/developers/gitignore?templates=node,linux,macos,windows
|
6 |
+
|
7 |
+
### Linux ###
|
8 |
+
*~
|
9 |
+
|
10 |
+
# temporary files which can be created if a process still has a handle open of a deleted file
|
11 |
+
.fuse_hidden*
|
12 |
+
|
13 |
+
# KDE directory preferences
|
14 |
+
.directory
|
15 |
+
|
16 |
+
# Linux trash folder which might appear on any partition or disk
|
17 |
+
.Trash-*
|
18 |
+
|
19 |
+
# .nfs files are created when an open file is removed but is still being accessed
|
20 |
+
.nfs*
|
21 |
+
|
22 |
+
### macOS ###
|
23 |
+
# General
|
24 |
+
.DS_Store
|
25 |
+
.AppleDouble
|
26 |
+
.LSOverride
|
27 |
+
|
28 |
+
# Icon must end with two \r
|
29 |
+
Icon
|
30 |
+
|
31 |
+
|
32 |
+
# Thumbnails
|
33 |
+
._*
|
34 |
+
|
35 |
+
# Files that might appear in the root of a volume
|
36 |
+
.DocumentRevisions-V100
|
37 |
+
.fseventsd
|
38 |
+
.Spotlight-V100
|
39 |
+
.TemporaryItems
|
40 |
+
.Trashes
|
41 |
+
.VolumeIcon.icns
|
42 |
+
.com.apple.timemachine.donotpresent
|
43 |
+
|
44 |
+
# Directories potentially created on remote AFP share
|
45 |
+
.AppleDB
|
46 |
+
.AppleDesktop
|
47 |
+
Network Trash Folder
|
48 |
+
Temporary Items
|
49 |
+
.apdisk
|
50 |
+
|
51 |
+
### Node ###
|
52 |
+
# Logs
|
53 |
+
logs
|
54 |
+
*.log
|
55 |
+
npm-debug.log*
|
56 |
+
yarn-debug.log*
|
57 |
+
yarn-error.log*
|
58 |
+
lerna-debug.log*
|
59 |
+
.pnpm-debug.log*
|
60 |
+
|
61 |
+
# Diagnostic reports (https://nodejs.org/api/report.html)
|
62 |
+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
63 |
+
|
64 |
+
# Runtime data
|
65 |
+
pids
|
66 |
+
*.pid
|
67 |
+
*.seed
|
68 |
+
*.pid.lock
|
69 |
+
|
70 |
+
# Directory for instrumented libs generated by jscoverage/JSCover
|
71 |
+
lib-cov
|
72 |
+
|
73 |
+
# Coverage directory used by tools like istanbul
|
74 |
+
coverage
|
75 |
+
*.lcov
|
76 |
+
|
77 |
+
# nyc test coverage
|
78 |
+
.nyc_output
|
79 |
+
|
80 |
+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
81 |
+
.grunt
|
82 |
+
|
83 |
+
# Bower dependency directory (https://bower.io/)
|
84 |
+
bower_components
|
85 |
+
|
86 |
+
# node-waf configuration
|
87 |
+
.lock-wscript
|
88 |
+
|
89 |
+
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
90 |
+
build/Release
|
91 |
+
|
92 |
+
# Dependency directories
|
93 |
+
node_modules/
|
94 |
+
jspm_packages/
|
95 |
+
|
96 |
+
# Snowpack dependency directory (https://snowpack.dev/)
|
97 |
+
web_modules/
|
98 |
+
|
99 |
+
# TypeScript cache
|
100 |
+
*.tsbuildinfo
|
101 |
+
|
102 |
+
# Optional npm cache directory
|
103 |
+
.npm
|
104 |
+
|
105 |
+
# Optional eslint cache
|
106 |
+
.eslintcache
|
107 |
+
|
108 |
+
# Optional stylelint cache
|
109 |
+
.stylelintcache
|
110 |
+
|
111 |
+
# Microbundle cache
|
112 |
+
.rpt2_cache/
|
113 |
+
.rts2_cache_cjs/
|
114 |
+
.rts2_cache_es/
|
115 |
+
.rts2_cache_umd/
|
116 |
+
|
117 |
+
# Optional REPL history
|
118 |
+
.node_repl_history
|
119 |
+
|
120 |
+
# Output of 'npm pack'
|
121 |
+
*.tgz
|
122 |
+
|
123 |
+
# Yarn Integrity file
|
124 |
+
.yarn-integrity
|
125 |
+
|
126 |
+
# dotenv environment variable files
|
127 |
+
.env
|
128 |
+
.env.development.local
|
129 |
+
.env.test.local
|
130 |
+
.env.production.local
|
131 |
+
.env.local
|
132 |
+
|
133 |
+
# parcel-bundler cache (https://parceljs.org/)
|
134 |
+
.cache
|
135 |
+
.parcel-cache
|
136 |
+
|
137 |
+
# Next.js build output
|
138 |
+
.next
|
139 |
+
out
|
140 |
+
|
141 |
+
# Nuxt.js build / generate output
|
142 |
+
.nuxt
|
143 |
+
|
144 |
+
# Gatsby files
|
145 |
+
.cache/
|
146 |
+
# Comment in the public line in if your project uses Gatsby and not Next.js
|
147 |
+
# https://nextjs.org/blog/next-9-1#public-directory-support
|
148 |
+
# public
|
149 |
+
|
150 |
+
# vuepress build output
|
151 |
+
.vuepress/dist
|
152 |
+
|
153 |
+
# vuepress v2.x temp and cache directory
|
154 |
+
.temp
|
155 |
+
|
156 |
+
# Docusaurus cache and generated files
|
157 |
+
.docusaurus
|
158 |
+
|
159 |
+
# Serverless directories
|
160 |
+
.serverless/
|
161 |
+
|
162 |
+
# FuseBox cache
|
163 |
+
.fusebox/
|
164 |
+
|
165 |
+
# DynamoDB Local files
|
166 |
+
.dynamodb/
|
167 |
+
|
168 |
+
# TernJS port file
|
169 |
+
.tern-port
|
170 |
+
|
171 |
+
# Stores VSCode versions used for testing VSCode extensions
|
172 |
+
.vscode-test
|
173 |
+
|
174 |
+
# yarn v2
|
175 |
+
.yarn/cache
|
176 |
+
.yarn/unplugged
|
177 |
+
.yarn/build-state.yml
|
178 |
+
.yarn/install-state.gz
|
179 |
+
.pnp.*
|
180 |
+
|
181 |
+
### Node Patch ###
|
182 |
+
# Serverless Webpack directories
|
183 |
+
.webpack/
|
184 |
+
|
185 |
+
# Optional stylelint cache
|
186 |
+
|
187 |
+
# SvelteKit build / generate output
|
188 |
+
.svelte-kit
|
189 |
+
|
190 |
+
### Windows ###
|
191 |
+
# Windows thumbnail cache files
|
192 |
+
Thumbs.db
|
193 |
+
Thumbs.db:encryptable
|
194 |
+
ehthumbs.db
|
195 |
+
ehthumbs_vista.db
|
196 |
+
|
197 |
+
# Dump file
|
198 |
+
*.stackdump
|
199 |
+
|
200 |
+
# Folder config file
|
201 |
+
[Dd]esktop.ini
|
202 |
+
|
203 |
+
# Recycle Bin used on file shares
|
204 |
+
$RECYCLE.BIN/
|
205 |
+
|
206 |
+
# Windows Installer files
|
207 |
+
*.cab
|
208 |
+
*.msi
|
209 |
+
*.msix
|
210 |
+
*.msm
|
211 |
+
*.msp
|
212 |
+
|
213 |
+
# Windows shortcuts
|
214 |
+
*.lnk
|
215 |
+
|
216 |
+
# End of https://www.toptal.com/developers/gitignore/api/node,linux,macos,windows
|
stripe-gradient-animation/.idea/.gitignore
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Default ignored files
|
2 |
+
/shelf/
|
3 |
+
/workspace.xml
|
4 |
+
# Editor-based HTTP Client requests
|
5 |
+
/httpRequests/
|
6 |
+
# Datasource local storage ignored files
|
7 |
+
/dataSources/
|
8 |
+
/dataSources.local.xml
|
stripe-gradient-animation/.idea/modules.xml
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<project version="4">
|
3 |
+
<component name="ProjectModuleManager">
|
4 |
+
<modules>
|
5 |
+
<module fileurl="file://$PROJECT_DIR$/.idea/stripe-canvas-gradient.iml" filepath="$PROJECT_DIR$/.idea/stripe-canvas-gradient.iml" />
|
6 |
+
</modules>
|
7 |
+
</component>
|
8 |
+
</project>
|
stripe-gradient-animation/.idea/php.xml
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<project version="4">
|
3 |
+
<component name="PhpProjectSharedConfiguration" php_language_level="7.2" />
|
4 |
+
</project>
|
stripe-gradient-animation/.idea/stripe-canvas-gradient.iml
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<module type="WEB_MODULE" version="4">
|
3 |
+
<component name="NewModuleRootManager">
|
4 |
+
<content url="file://$MODULE_DIR$" />
|
5 |
+
<orderEntry type="inheritedJdk" />
|
6 |
+
<orderEntry type="sourceFolder" forTests="false" />
|
7 |
+
</component>
|
8 |
+
</module>
|
stripe-gradient-animation/.idea/vcs.xml
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<project version="4">
|
3 |
+
<component name="VcsDirectoryMappings">
|
4 |
+
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
5 |
+
</component>
|
6 |
+
</project>
|
stripe-gradient-animation/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Stripe Gradient
|
2 |
+
|
3 |
+
A reverse engineered, and simplified javascript library to replicate the animated [Stripe](https://stripe.com/) gradients.
|
4 |
+
|
5 |
+
## Basic usage
|
6 |
+
|
7 |
+
**HTML**
|
8 |
+
|
9 |
+
```html
|
10 |
+
<canvas id="my-canvas-id"></canvas>
|
11 |
+
```
|
12 |
+
|
13 |
+
**JavasScript**
|
14 |
+
```javascript
|
15 |
+
new Gradient({
|
16 |
+
canvas: '#my-canvas-id',
|
17 |
+
colors: ['#a960ee', '#ff333d', '#90e0ff', '#ffcb57']
|
18 |
+
});
|
19 |
+
```
|
20 |
+
|
21 |
+
|
22 |
+
## jQuery ready
|
23 |
+
|
24 |
+
```javascript
|
25 |
+
$('#my-canvas-id').gradient({
|
26 |
+
colors: ['#a960ee', '#ff333d', '#90e0ff', '#ffcb57']
|
27 |
+
});
|
28 |
+
```
|
stripe-gradient-animation/dist/stripe-gradient.js
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
!function(){"use strict";function e(e,n){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null==n)return;var i,r,a=[],o=!0,s=!1;try{for(n=n.call(e);!(o=(i=n.next()).done)&&(a.push(i.value),!t||a.length!==t);o=!0);}catch(e){s=!0,r=e}finally{try{o||null==n.return||n.return()}finally{if(s)throw r}}return a}(e,n)||function(e,n){if(!e)return;if("string"==typeof e)return t(e,n);var i=Object.prototype.toString.call(e).slice(8,-1);"Object"===i&&e.constructor&&(i=e.constructor.name);if("Map"===i||"Set"===i)return Array.from(e);if("Arguments"===i||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(i))return t(e,n)}(e,n)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function t(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,i=new Array(t);n<t;n++)i[n]=e[n];return i}function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var a=function(){function t(e,i,a){var o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};n(this,t),r(this,"gl",void 0),r(this,"type",void 0),r(this,"value",void 0),r(this,"typeFn",void 0),r(this,"_typeMap",{float:"1f",int:"1i",vec2:"2fv",vec3:"3fv",vec4:"4fv",mat4:"Matrix4fv"}),Object.assign(this,o),this.gl=e,this.type=i,this.value=a,this.typeFn=this._typeMap[this.type]||this._typeMap.float,this.update()}var a,o,s;return a=t,(o=[{key:"update",value:function(e){if(this.value){var t=this.value,n=null;0===this.typeFn.indexOf("Matrix")&&(t=this.transpose,n=this.value),this.gl.getContext()["uniform".concat(this.typeFn)](e,t,n)}}},{key:"getDeclaration",value:function(t,n,i){if(this.excludeFrom!==n){if("array"===this.type)return"".concat(this.value[0].getDeclaration(t,n,this.value.length),"\nconst int ").concat(t,"_length = ").concat(this.value.length,";");if("struct"===this.type){var r=t.replace("u_","");r=r.charAt(0).toUpperCase()+r.slice(1);var a=Object.entries(this.value).map((function(t){var i=e(t,2),r=i[0];return i[1].getDeclaration(r,n).replace(/^uniform/,"")})).join("");return"uniform struct ".concat(r," {\n ").concat(a,"\n} ").concat(t).concat(i>0?"[".concat(i,"]"):"",";")}return"uniform ".concat(this.type," ").concat(t).concat(i>0?"[".concat(i,"]"):"",";")}}}])&&i(a.prototype,o),s&&i(a,s),Object.defineProperty(a,"prototype",{writable:!1}),t}();function o(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var l=function(){function e(t,n,i){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),s(this,"_class",e),s(this,"_canvas",void 0),s(this,"_context",void 0),s(this,"commonUniforms",{}),s(this,"meshes",[]),this.setCanvas(t);var r=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];this.commonUniforms={projectionMatrix:new a(this,"mat4",r),modelViewMatrix:new a(this,"mat4",r),resolution:new a(this,"vec2",[1,1]),aspectRatio:new a(this,"float",1)},this.setSize(n,i)}var t,n,i;return t=e,n=[{key:"setCanvas",value:function(e){this._canvas=e,this._context=e.getContext("webgl",{antialias:!0})}},{key:"getCanvas",value:function(){return this._canvas}},{key:"getContext",value:function(){return this._context}},{key:"setSize",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:640,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:480;this.getCanvas().width=e,this.getCanvas().height=t,this.getContext().viewport(0,0,e,t),this.commonUniforms.resolution.value=[e,t],this.commonUniforms.aspectRatio.value=e/t}},{key:"setOrthographicCamera",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:-2e3,r=arguments.length>4&&void 0!==arguments[4]?arguments[4]:2e3;this.commonUniforms.projectionMatrix.value=[2/this.getCanvas().width,0,0,0,0,2/this.getCanvas().height,0,0,0,0,2/(i-r),0,e,t,n,1]}},{key:"render",value:function(){this.getContext().clearColor(0,0,0,0),this.getContext().clearDepth(1),this.meshes.forEach((function(e){e.draw()}))}}],n&&o(t.prototype,n),i&&o(t,i),Object.defineProperty(t,"prototype",{writable:!1}),e}();function c(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null==n)return;var i,r,a=[],o=!0,s=!1;try{for(n=n.call(e);!(o=(i=n.next()).done)&&(a.push(i.value),!t||a.length!==t);o=!0);}catch(e){s=!0,r=e}finally{try{o||null==n.return||n.return()}finally{if(s)throw r}}return a}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return u(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return u(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function u(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,i=new Array(t);n<t;n++)i[n]=e[n];return i}function h(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function v(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function b(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var d=function(){function e(t,n,i){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{};h(this,e),b(this,"gl",void 0),b(this,"uniformInstances",[]),Object.assign(this,a),this.gl=t,this.uniforms=r;var o=this.gl.getContext(),s="\n precision highp float;\n ";this.vertexSource="\n ".concat(s,"\n attribute vec4 position;\n attribute vec2 uv;\n attribute vec2 uvNorm;\n ").concat(this._getUniformVariableDeclarations(this.gl.commonUniforms,"vertex"),"\n ").concat(this._getUniformVariableDeclarations(r,"vertex"),"\n ").concat(n,"\n "),this.Source="\n ".concat(s,"\n ").concat(this._getUniformVariableDeclarations(this.gl.commonUniforms,"fragment"),"\n ").concat(this._getUniformVariableDeclarations(r,"fragment"),"\n ").concat(i,"\n "),this.vertexShader=this._getShaderByType(o.VERTEX_SHADER,this.vertexSource),this.fragmentShader=this._getShaderByType(o.FRAGMENT_SHADER,this.Source),this.program=o.createProgram(),o.attachShader(this.program,this.vertexShader),o.attachShader(this.program,this.fragmentShader),o.linkProgram(this.program),o.getProgramParameter(this.program,o.LINK_STATUS)||console.error(o.getProgramInfoLog(this.program)),o.useProgram(this.program),this.attachUniforms(void 0,this.gl.commonUniforms),this.attachUniforms(void 0,this.uniforms)}var t,n,i;return t=e,(n=[{key:"_getShaderByType",value:function(e,t){var n=this.gl.getContext(),i=n.createShader(e);return n.shaderSource(i,t),n.compileShader(i),n.getShaderParameter(i,n.COMPILE_STATUS)||console.error(n.getShaderInfoLog(i)),i}},{key:"_getUniformVariableDeclarations",value:function(e,t){return Object.entries(e).map((function(e){var n=c(e,2),i=n[0];return n[1].getDeclaration(i,t)})).join("\n")}},{key:"attachUniforms",value:function(e,t){var n=this;e?"array"===t.type?t.value.forEach((function(t,i){n.attachUniforms("".concat(e,"[").concat(i,"]"),t)})):"struct"===t.type?Object.entries(t.value).forEach((function(t){var i=c(t,2),r=i[0],a=i[1];n.attachUniforms("".concat(e,".").concat(r),a)})):this.uniformInstances.push({uniform:t,location:this.gl.getContext().getUniformLocation(this.program,e)}):Object.entries(t).forEach((function(e){var t=c(e,2),i=t[0],r=t[1];n.attachUniforms(i,r)}))}}])&&v(t.prototype,n),i&&v(t,i),Object.defineProperty(t,"prototype",{writable:!1}),e}();function f(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null==n)return;var i,r,a=[],o=!0,s=!1;try{for(n=n.call(e);!(o=(i=n.next()).done)&&(a.push(i.value),!t||a.length!==t);o=!0);}catch(e){s=!0,r=e}finally{try{o||null==n.return||n.return()}finally{if(s)throw r}}return a}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return g(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return g(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function g(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,i=new Array(t);n<t;n++)i[n]=e[n];return i}function m(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function y(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function p(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var x=function(){function e(t,n,i){var r=this,a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};m(this,e),p(this,"gl",void 0),p(this,"wireframe",!1),p(this,"attributeInstances",[]),Object.assign(this,a),this.geometry=n,this.material=i,this.gl=t,Object.entries(this.geometry.attributes).forEach((function(e){var t=f(e,2),n=t[0],i=t[1];r.attributeInstances.push({attribute:i,location:i.attach(n,r.material.program)})})),this.gl.meshes.push(this)}var t,n,i;return t=e,(n=[{key:"draw",value:function(){var e=this.gl.getContext();e.useProgram(this.material.program),this.material.uniformInstances.forEach((function(e){var t=e.uniform,n=e.location;t.update(n)})),this.attributeInstances.forEach((function(e){var t=e.attribute,n=e.location;t.use(n)}));var t=this.wireframe?e.LINES:e.TRIANGLES;e.drawElements(t,this.geometry.attributes.index.values.length,e.UNSIGNED_SHORT,0)}},{key:"remove",value:function(){var e=this;this.gl.meshes=this.gl.meshes.filter((function(t){return t!=e}))}}])&&y(t.prototype,n),i&&y(t,i),Object.defineProperty(t,"prototype",{writable:!1}),e}();function w(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function C(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function _(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var S=function(){function e(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};w(this,e),_(this,"gl",void 0),_(this,"type",void 0),_(this,"buffer",void 0),_(this,"normalized",!1),Object.assign(this,n),this.gl=t,this.type=this.gl.getContext().FLOAT,this.buffer=this.gl.getContext().createBuffer(),this.update()}var t,n,i;return t=e,(n=[{key:"update",value:function(){if(this.values){var e=this.gl.getContext();e.bindBuffer(this.target,this.buffer),e.bufferData(this.target,this.values,e.STATIC_DRAW)}}},{key:"attach",value:function(e,t){var n=this.gl.getContext(),i=n.getAttribLocation(t,e);return this.target===n.ARRAY_BUFFER&&(n.enableVertexAttribArray(i),n.vertexAttribPointer(i,this.size,this.type,this.normalized,0,0)),i}},{key:"use",value:function(e){var t=this.gl.getContext();t.bindBuffer(this.target,this.buffer),this.target===t.ARRAY_BUFFER&&(t.enableVertexAttribArray(e),t.vertexAttribPointer(e,this.size,this.type,this.normalized,0,0))}}])&&C(t.prototype,n),i&&C(t,i),Object.defineProperty(t,"prototype",{writable:!1}),e}();function L(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function O(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function A(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var F=function(){function e(t,n,i,r,a,o){var s=arguments.length>6&&void 0!==arguments[6]?arguments[6]:{};L(this,e),A(this,"gl",void 0),A(this,"attributes",void 0),Object.assign(this,s),this.gl=t;var l=this.gl.getContext();l.createBuffer(),this.attributes={position:new S(this.gl,{target:l.ARRAY_BUFFER,size:3}),uv:new S(this.gl,{target:l.ARRAY_BUFFER,size:2}),uvNorm:new S(this.gl,{target:l.ARRAY_BUFFER,size:2}),index:new S(this.gl,{target:l.ELEMENT_ARRAY_BUFFER,size:3,type:l.UNSIGNED_SHORT})},this.setTopology(r,a),this.setSize(n,i,o)}var t,n,i;return t=e,n=[{key:"setTopology",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;this.xSegCount=e,this.ySegCount=t,this.vertexCount=(this.xSegCount+1)*(this.ySegCount+1),this.quadCount=this.xSegCount*this.ySegCount*2,this.attributes.uv.values=new Float32Array(2*this.vertexCount),this.attributes.uvNorm.values=new Float32Array(2*this.vertexCount),this.attributes.index.values=new Uint16Array(3*this.quadCount);for(var n=0;n<=this.ySegCount;n++)for(var i=0;i<=this.xSegCount;i++){var r=n*(this.xSegCount+1)+i;if(this.attributes.uv.values[2*r]=i/this.xSegCount,this.attributes.uv.values[2*r+1]=1-n/this.ySegCount,this.attributes.uvNorm.values[2*r]=i/this.xSegCount*2-1,this.attributes.uvNorm.values[2*r+1]=1-n/this.ySegCount*2,i<this.xSegCount&&n<this.ySegCount){var a=n*this.xSegCount+i;this.attributes.index.values[6*a]=r,this.attributes.index.values[6*a+1]=r+1+this.xSegCount,this.attributes.index.values[6*a+2]=r+1,this.attributes.index.values[6*a+3]=r+1,this.attributes.index.values[6*a+4]=r+1+this.xSegCount,this.attributes.index.values[6*a+5]=r+2+this.xSegCount}}this.attributes.uv.update(),this.attributes.uvNorm.update(),this.attributes.index.update()}},{key:"setSize",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"xz";this.width=e,this.height=t,this.orientation=n,this.attributes.position.values&&this.attributes.position.values.length===3*this.vertexCount||(this.attributes.position.values=new Float32Array(3*this.vertexCount));for(var i=e/-2,r=t/-2,a=e/this.xSegCount,o=t/this.ySegCount,s=0;s<=this.ySegCount;s++)for(var l=r+s*o,c=0;c<=this.xSegCount;c++){var u=i+c*a,h=s*(this.xSegCount+1)+c;this.attributes.position.values[3*h+"xyz".indexOf(n[0])]=u,this.attributes.position.values[3*h+"xyz".indexOf(n[1])]=-l}this.attributes.position.update()}}],n&&O(t.prototype,n),i&&O(t,i),Object.defineProperty(t,"prototype",{writable:!1}),e}();function j(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null==n)return;var i,r,a=[],o=!0,s=!1;try{for(n=n.call(e);!(o=(i=n.next()).done)&&(a.push(i.value),!t||a.length!==t);o=!0);}catch(e){s=!0,r=e}finally{try{o||null==n.return||n.return()}finally{if(s)throw r}}return a}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return z(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return z(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function z(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,i=new Array(t);n<t;n++)i[n]=e[n];return i}function D(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function k(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var E=function(){function e(t){if(function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),k(this,"_class",e),k(this,"vertexShader",null),k(this,"uniforms",null),k(this,"time",1253106),k(this,"mesh",null),k(this,"material",null),k(this,"geometry",null),k(this,"scrollingTimeout",null),k(this,"scrollingRefreshDelay",200),k(this,"scrollObserver",null),k(this,"width",null),k(this,"minWidth",1111),k(this,"height",600),k(this,"xSegCount",null),k(this,"ySegCount",null),k(this,"freqX",14e-5),k(this,"freqY",29e-5),k(this,"freqDelta",1e-5),k(this,"activeColors",[1,1,1,1]),k(this,"shaderFiles",{vertex:"varying vec3 v_color;\n\nvoid main() {\n float time = u_time * u_global.noiseSpeed;\n\n vec2 noiseCoord = resolution * uvNorm * u_global.noiseFreq;\n\n vec2 st = 1. - uvNorm.xy;\n\n //\n // Tilting the plane\n //\n\n // Front-to-back tilt\n float tilt = resolution.y / 2.0 * uvNorm.y;\n\n // Left-to-right angle\n float incline = resolution.x * uvNorm.x / 2.0 * u_vertDeform.incline;\n\n // Up-down shift to offset incline\n float offset = resolution.x / 2.0 * u_vertDeform.incline * mix(u_vertDeform.offsetBottom, u_vertDeform.offsetTop, uv.y);\n\n //\n // Vertex noise\n //\n\n float noise = snoise(vec3(\n noiseCoord.x * u_vertDeform.noiseFreq.x + time * u_vertDeform.noiseFlow,\n noiseCoord.y * u_vertDeform.noiseFreq.y,\n time * u_vertDeform.noiseSpeed + u_vertDeform.noiseSeed\n )) * u_vertDeform.noiseAmp;\n\n // Fade noise to zero at edges\n noise *= 1.0 - pow(abs(uvNorm.y), 2.0);\n\n // Clamp to 0\n noise = max(0.0, noise);\n\n vec3 pos = vec3(\n position.x,\n position.y + tilt + incline + noise - offset,\n position.z\n );\n\n //\n // Vertex color, to be passed to fragment shader\n //\n\n if (u_active_colors[0] == 1.) {\n v_color = u_baseColor;\n }\n\n for (int i = 0; i < u_waveLayers_length; i++) {\n if (u_active_colors[i + 1] == 1.) {\n WaveLayers layer = u_waveLayers[i];\n\n float noise = smoothstep(\n layer.noiseFloor,\n layer.noiseCeil,\n snoise(vec3(\n noiseCoord.x * layer.noiseFreq.x + time * layer.noiseFlow,\n noiseCoord.y * layer.noiseFreq.y,\n time * layer.noiseSpeed + layer.noiseSeed\n )) / 2.0 + 0.5\n );\n\n v_color = blendNormal(v_color, layer.color, pow(noise, 4.));\n }\n }\n\n //\n // Finish\n //\n\n gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);\n}\n",noise:"//\n// Description : Array and textureless GLSL 2D/3D/4D simplex\n// noise functions.\n// Author : Ian McEwan, Ashima Arts.\n// Maintainer : stegu\n// Lastmod : 20110822 (ijm)\n// License : Copyright (C) 2011 Ashima Arts. All rights reserved.\n// Distributed under the MIT License. See LICENSE file.\n// https://github.com/ashima/webgl-noise\n// https://github.com/stegu/webgl-noise\n//\n\nvec3 mod289(vec3 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n\nvec4 mod289(vec4 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n\nvec4 permute(vec4 x) {\n return mod289(((x*34.0)+1.0)*x);\n}\n\nvec4 taylorInvSqrt(vec4 r)\n{\n return 1.79284291400159 - 0.85373472095314 * r;\n}\n\nfloat snoise(vec3 v)\n{\n const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;\n const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\n\n// First corner\n vec3 i = floor(v + dot(v, C.yyy) );\n vec3 x0 = v - i + dot(i, C.xxx) ;\n\n// Other corners\n vec3 g = step(x0.yzx, x0.xyz);\n vec3 l = 1.0 - g;\n vec3 i1 = min( g.xyz, l.zxy );\n vec3 i2 = max( g.xyz, l.zxy );\n\n // x0 = x0 - 0.0 + 0.0 * C.xxx;\n // x1 = x0 - i1 + 1.0 * C.xxx;\n // x2 = x0 - i2 + 2.0 * C.xxx;\n // x3 = x0 - 1.0 + 3.0 * C.xxx;\n vec3 x1 = x0 - i1 + C.xxx;\n vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y\n vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y\n\n// Permutations\n i = mod289(i);\n vec4 p = permute( permute( permute(\n i.z + vec4(0.0, i1.z, i2.z, 1.0 ))\n + i.y + vec4(0.0, i1.y, i2.y, 1.0 ))\n + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));\n\n// Gradients: 7x7 points over a square, mapped onto an octahedron.\n// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)\n float n_ = 0.142857142857; // 1.0/7.0\n vec3 ns = n_ * D.wyz - D.xzx;\n\n vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)\n\n vec4 x_ = floor(j * ns.z);\n vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)\n\n vec4 x = x_ *ns.x + ns.yyyy;\n vec4 y = y_ *ns.x + ns.yyyy;\n vec4 h = 1.0 - abs(x) - abs(y);\n\n vec4 b0 = vec4( x.xy, y.xy );\n vec4 b1 = vec4( x.zw, y.zw );\n\n //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;\n //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;\n vec4 s0 = floor(b0)*2.0 + 1.0;\n vec4 s1 = floor(b1)*2.0 + 1.0;\n vec4 sh = -step(h, vec4(0.0));\n\n vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;\n vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;\n\n vec3 p0 = vec3(a0.xy,h.x);\n vec3 p1 = vec3(a0.zw,h.y);\n vec3 p2 = vec3(a1.xy,h.z);\n vec3 p3 = vec3(a1.zw,h.w);\n\n//Normalise gradients\n vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));\n p0 *= norm.x;\n p1 *= norm.y;\n p2 *= norm.z;\n p3 *= norm.w;\n\n// Mix final noise value\n vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\n m = m * m;\n return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),\n dot(p2,x2), dot(p3,x3) ) );\n}\n",blend:"//\n// https://github.com/jamieowen/glsl-blend\n//\n\n// Normal\n\nvec3 blendNormal(vec3 base, vec3 blend) {\n return blend;\n}\n\nvec3 blendNormal(vec3 base, vec3 blend, float opacity) {\n return (blendNormal(base, blend) * opacity + base * (1.0 - opacity));\n}\n\n// Screen\n\nfloat blendScreen(float base, float blend) {\n return 1.0-((1.0-base)*(1.0-blend));\n}\n\nvec3 blendScreen(vec3 base, vec3 blend) {\n return vec3(blendScreen(base.r,blend.r),blendScreen(base.g,blend.g),blendScreen(base.b,blend.b));\n}\n\nvec3 blendScreen(vec3 base, vec3 blend, float opacity) {\n return (blendScreen(base, blend) * opacity + base * (1.0 - opacity));\n}\n\n// Multiply\n\nvec3 blendMultiply(vec3 base, vec3 blend) {\n return base*blend;\n}\n\nvec3 blendMultiply(vec3 base, vec3 blend, float opacity) {\n return (blendMultiply(base, blend) * opacity + base * (1.0 - opacity));\n}\n\n// Overlay\n\nfloat blendOverlay(float base, float blend) {\n return base<0.5?(2.0*base*blend):(1.0-2.0*(1.0-base)*(1.0-blend));\n}\n\nvec3 blendOverlay(vec3 base, vec3 blend) {\n return vec3(blendOverlay(base.r,blend.r),blendOverlay(base.g,blend.g),blendOverlay(base.b,blend.b));\n}\n\nvec3 blendOverlay(vec3 base, vec3 blend, float opacity) {\n return (blendOverlay(base, blend) * opacity + base * (1.0 - opacity));\n}\n\n// Hard light\n\nvec3 blendHardLight(vec3 base, vec3 blend) {\n return blendOverlay(blend,base);\n}\n\nvec3 blendHardLight(vec3 base, vec3 blend, float opacity) {\n return (blendHardLight(base, blend) * opacity + base * (1.0 - opacity));\n}\n\n// Soft light\n\nfloat blendSoftLight(float base, float blend) {\n return (blend<0.5)?(2.0*base*blend+base*base*(1.0-2.0*blend)):(sqrt(base)*(2.0*blend-1.0)+2.0*base*(1.0-blend));\n}\n\nvec3 blendSoftLight(vec3 base, vec3 blend) {\n return vec3(blendSoftLight(base.r,blend.r),blendSoftLight(base.g,blend.g),blendSoftLight(base.b,blend.b));\n}\n\nvec3 blendSoftLight(vec3 base, vec3 blend, float opacity) {\n return (blendSoftLight(base, blend) * opacity + base * (1.0 - opacity));\n}\n\n// Color dodge\n\nfloat blendColorDodge(float base, float blend) {\n return (blend==1.0)?blend:min(base/(1.0-blend),1.0);\n}\n\nvec3 blendColorDodge(vec3 base, vec3 blend) {\n return vec3(blendColorDodge(base.r,blend.r),blendColorDodge(base.g,blend.g),blendColorDodge(base.b,blend.b));\n}\n\nvec3 blendColorDodge(vec3 base, vec3 blend, float opacity) {\n return (blendColorDodge(base, blend) * opacity + base * (1.0 - opacity));\n}\n\n// Color burn\n\nfloat blendColorBurn(float base, float blend) {\n return (blend==0.0)?blend:max((1.0-((1.0-base)/blend)),0.0);\n}\n\nvec3 blendColorBurn(vec3 base, vec3 blend) {\n return vec3(blendColorBurn(base.r,blend.r),blendColorBurn(base.g,blend.g),blendColorBurn(base.b,blend.b));\n}\n\nvec3 blendColorBurn(vec3 base, vec3 blend, float opacity) {\n return (blendColorBurn(base, blend) * opacity + base * (1.0 - opacity));\n}\n\n// Vivid Light\n\nfloat blendVividLight(float base, float blend) {\n return (blend<0.5)?blendColorBurn(base,(2.0*blend)):blendColorDodge(base,(2.0*(blend-0.5)));\n}\n\nvec3 blendVividLight(vec3 base, vec3 blend) {\n return vec3(blendVividLight(base.r,blend.r),blendVividLight(base.g,blend.g),blendVividLight(base.b,blend.b));\n}\n\nvec3 blendVividLight(vec3 base, vec3 blend, float opacity) {\n return (blendVividLight(base, blend) * opacity + base * (1.0 - opacity));\n}\n\n// Lighten\n\nfloat blendLighten(float base, float blend) {\n return max(blend,base);\n}\n\nvec3 blendLighten(vec3 base, vec3 blend) {\n return vec3(blendLighten(base.r,blend.r),blendLighten(base.g,blend.g),blendLighten(base.b,blend.b));\n}\n\nvec3 blendLighten(vec3 base, vec3 blend, float opacity) {\n return (blendLighten(base, blend) * opacity + base * (1.0 - opacity));\n}\n\n// Linear burn\n\nfloat blendLinearBurn(float base, float blend) {\n // Note : Same implementation as BlendSubtractf\n return max(base+blend-1.0,0.0);\n}\n\nvec3 blendLinearBurn(vec3 base, vec3 blend) {\n // Note : Same implementation as BlendSubtract\n return max(base+blend-vec3(1.0),vec3(0.0));\n}\n\nvec3 blendLinearBurn(vec3 base, vec3 blend, float opacity) {\n return (blendLinearBurn(base, blend) * opacity + base * (1.0 - opacity));\n}\n\n// Linear dodge\n\nfloat blendLinearDodge(float base, float blend) {\n // Note : Same implementation as BlendAddf\n return min(base+blend,1.0);\n}\n\nvec3 blendLinearDodge(vec3 base, vec3 blend) {\n // Note : Same implementation as BlendAdd\n return min(base+blend,vec3(1.0));\n}\n\nvec3 blendLinearDodge(vec3 base, vec3 blend, float opacity) {\n return (blendLinearDodge(base, blend) * opacity + base * (1.0 - opacity));\n}\n\n// Linear light\n\nfloat blendLinearLight(float base, float blend) {\n return blend<0.5?blendLinearBurn(base,(2.0*blend)):blendLinearDodge(base,(2.0*(blend-0.5)));\n}\n\nvec3 blendLinearLight(vec3 base, vec3 blend) {\n return vec3(blendLinearLight(base.r,blend.r),blendLinearLight(base.g,blend.g),blendLinearLight(base.b,blend.b));\n}\n\nvec3 blendLinearLight(vec3 base, vec3 blend, float opacity) {\n return (blendLinearLight(base, blend) * opacity + base * (1.0 - opacity));\n}\n",fragment:"varying vec3 v_color;\n\nvoid main() {\n vec3 color = v_color;\n if (u_darken_top == 1.0) {\n vec2 st = gl_FragCoord.xy/resolution.xy;\n color.g -= pow(st.y + sin(-12.0) * st.x, u_shadow_power) * 0.4;\n }\n gl_FragColor = vec4(color, 1.0);\n}\n"}),k(this,"options",{}),k(this,"_flags",{playing:!0}),k(this,"_canvas",void 0),k(this,"_context",void 0),k(this,"_minigl",void 0),this.options=t,this.setCanvas(this.findCanvas(this.getOption("canvas"))),!this.getCanvas())throw"Missing Canvas. Pass the canvas to the Gradient constructor.";this._minigl=new l(this.getCanvas(),this.getCanvas().offsetWidth,this.getCanvas().offsetHeight),this.init()}var t,n,i;return t=e,n=[{key:"getOption",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:void 0;return void 0===t&&e in this._class.defaultOptions&&(t=this._class.defaultOptions[e]),e in this.options?this.options[e]:t}},{key:"findCanvas",value:function(e){var t="string"==typeof e?document.querySelector(e):e;return t instanceof HTMLCanvasElement?t:null}},{key:"setCanvas",value:function(e){e?(this._canvas=e,this._context=e.getContext("webgl",{antialias:!0})):(this._canvas=null,this._context=null)}},{key:"getCanvas",value:function(){return this._canvas}},{key:"getContext",value:function(){return this._context}},{key:"setFlag",value:function(e,t){return this._flags[e]=t}},{key:"getFlag",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:void 0;return this._flags[e]||t}},{key:"handleScroll",value:function(){clearTimeout(this.scrollingTimeout),this.scrollingTimeout=setTimeout(this.handleScrollEnd,this.scrollingRefreshDelay),this.getFlag("playing")&&(this.setFlag("isScrolling",!0),this.pause())}},{key:"handleScrollEnd",value:function(){this.setFlag("isScrolling",!1),this.getFlag("isIntersecting")&&this.play()}},{key:"resize",value:function(){var e=j(this.getOption("density"),2),t=e[0],n=e[1];this.width=window.innerWidth,this._minigl.setSize(this.width,this.height),this._minigl.setOrthographicCamera(),this.xSegCount=Math.ceil(this.width*t),this.ySegCount=Math.ceil(this.height*n),this.mesh.geometry.setTopology(this.xSegCount,this.ySegCount),this.mesh.geometry.setSize(this.width,this.height),this.mesh.material.uniforms.u_shadow_power.value=this.width<600?5:6}},{key:"animate",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,t=!!window.document.hidden||!this.getFlag("playing")||parseInt(e,10)%2==0,n=this.getFlag("lastFrame",0);if(t||(this.time+=Math.min(e-n,1e3/15),n=this.setFlag("lastFrame",e),this.mesh.material.uniforms.u_time.value=this.time,this._minigl.render()),0!==n&&this.getOption("static"))return this._minigl.render(),this.disconnect();this.getFlag("playing")&&requestAnimationFrame(this.animate.bind(this))}},{key:"pause",value:function(){this.setFlag("playing",!1)}},{key:"play",value:function(){requestAnimationFrame(this.animate.bind(this)),this.setFlag("playing",!0)}},{key:"disconnect",value:function(){this.scrollObserver&&(window.removeEventListener("scroll",this.handleScroll),this.scrollObserver.disconnect()),window.removeEventListener("resize",this.resize)}},{key:"initMaterial",value:function(){var e=this.getOption("colors").map((function(e){if(4===e.length){var t=e.substr(1).split("").map((function(e){return e+e})).join("");e="#".concat(t)}return e&&"0x".concat(e.substr(1))})).filter(Boolean).map(this.normalizeColor);this.uniforms={u_time:new a(this._minigl,"float",0),u_shadow_power:new a(this._minigl,"float",10),u_darken_top:new a(this._minigl,"float",this.getCanvas().dataset.jsDarkenTop?1:0),u_active_colors:new a(this._minigl,"vec4",this.activeColors),u_global:new a(this._minigl,"struct",{noiseFreq:new a(this._minigl,"vec2",[this.freqX,this.freqY]),noiseSpeed:new a(this._minigl,"float",5e-6)}),u_vertDeform:new a(this._minigl,"struct",{incline:new a(this._minigl,"float",Math.sin(this.getOption("angle"))/Math.cos(this.getOption("angle"))),offsetTop:new a(this._minigl,"float",-.5),offsetBottom:new a(this._minigl,"float",-.5),noiseFreq:new a(this._minigl,"vec2",[3,4]),noiseAmp:new a(this._minigl,"float",this.getOption("amplitude")),noiseSpeed:new a(this._minigl,"float",10),noiseFlow:new a(this._minigl,"float",3),noiseSeed:new a(this._minigl,"float",this.seed)},{excludeFrom:"fragment"}),u_baseColor:new a(this._minigl,"vec3",e[0],{excludeFrom:"fragment"}),u_waveLayers:new a(this._minigl,"array",[],{excludeFrom:"fragment"})};for(var t=1;t<e.length;t+=1){var n=new a(this._minigl,"struct",{color:new a(this._minigl,"vec3",e[t]),noiseFreq:new a(this._minigl,"vec2",[2+t/e.length,3+t/e.length]),noiseSpeed:new a(this._minigl,"float",11+.3*t),noiseFlow:new a(this._minigl,"float",6.5+.3*t),noiseSeed:new a(this._minigl,"float",this.seed+10*t),noiseFloor:new a(this._minigl,"float",.1),noiseCeil:new a(this._minigl,"float",.63+.07*t)});this.uniforms.u_waveLayers.value.push(n)}return this.vertexShader=[this.shaderFiles.noise,this.shaderFiles.blend,this.shaderFiles.vertex].join("\n\n"),new d(this._minigl,this.vertexShader,this.shaderFiles.fragment,this.uniforms)}},{key:"initMesh",value:function(){this.material=this.initMaterial(),this.geometry=new F(this._minigl),this.mesh=new x(this._minigl,this.geometry,this.material),this.mesh.wireframe=this.getOption("wireframe")}},{key:"updateFrequency",value:function(e){this.freqX+=e,this.freqY+=e}},{key:"toggleColor",value:function(e){this.activeColors[e]=0===this.activeColors[e]?1:0}},{key:"init",value:function(){var e=this.getOption("loadedClass");e&&this.getCanvas().classList.add(e),this.initMesh(),this.resize(),requestAnimationFrame(this.animate.bind(this)),window.addEventListener("resize",this.resize)}},{key:"normalizeColor",value:function(e){return[(e>>16&255)/255,(e>>8&255)/255,(255&e)/255]}}],n&&D(t.prototype,n),i&&D(t,i),Object.defineProperty(t,"prototype",{writable:!1}),e}();k(E,"defaultOptions",{canvas:null,colors:["#f00","#0f0","#00f"],wireframe:!1,density:[.06,.16],angle:0,amplitude:320,static:!1,loadedClass:"is-loaded",zoom:1,speed:5,rotation:0}),window.Gradient=E,window.jQuery&&(jQuery.fn.gradient=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return e.canvas=this.get(0),this._gradient=new E(e),this})}();
|
stripe-gradient-animation/index.html
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6 |
+
<title>Stripe Gradient Animation Example</title>
|
7 |
+
<link href="https://www.jqueryscript.net/css/jquerysctipttop.css" rel="stylesheet" type="text/css">
|
8 |
+
<style>
|
9 |
+
html,* { font-family: 'Inter'; box-sizing: border-box; }
|
10 |
+
body { background-color: #fafafa; line-height:1.6;}
|
11 |
+
.lead { font-size: 1.5rem; font-weight: 300; }
|
12 |
+
.container { margin: 150px auto; max-width: 960px; }
|
13 |
+
|
14 |
+
canvas#demo {
|
15 |
+
height: 100vh;
|
16 |
+
margin: 0;
|
17 |
+
padding: 0;
|
18 |
+
width: 100%;
|
19 |
+
}
|
20 |
+
</style>
|
21 |
+
</head>
|
22 |
+
<body style="margin: 0; padding: 0; line-height: 0 !important;">
|
23 |
+
<canvas id="demo"></canvas>
|
24 |
+
<script src="https://code.jquery.com/jquery-3.6.0.slim.min.js"></script>
|
25 |
+
<script src="./dist/stripe-gradient.js"></script>
|
26 |
+
<script>
|
27 |
+
(function() {
|
28 |
+
'use strict';
|
29 |
+
|
30 |
+
$('#demo').gradient({
|
31 |
+
colors: ['#a960ee', '#ff333d', '#90e0ff', '#ffcb57']
|
32 |
+
});
|
33 |
+
|
34 |
+
})();
|
35 |
+
</script>
|
36 |
+
<script type="text/javascript">
|
37 |
+
|
38 |
+
var _gaq = _gaq || [];
|
39 |
+
_gaq.push(['_setAccount', 'UA-36251023-1']);
|
40 |
+
_gaq.push(['_setDomainName', 'jqueryscript.net']);
|
41 |
+
_gaq.push(['_trackPageview']);
|
42 |
+
|
43 |
+
(function() {
|
44 |
+
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
45 |
+
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
46 |
+
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
47 |
+
})();
|
48 |
+
|
49 |
+
</script>
|
50 |
+
<script>
|
51 |
+
try {
|
52 |
+
fetch(new Request("https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js", { method: 'HEAD', mode: 'no-cors' })).then(function(response) {
|
53 |
+
return true;
|
54 |
+
}).catch(function(e) {
|
55 |
+
var carbonScript = document.createElement("script");
|
56 |
+
carbonScript.src = "//cdn.carbonads.com/carbon.js?serve=CK7DKKQU&placement=wwwjqueryscriptnet";
|
57 |
+
carbonScript.id = "_carbonads_js";
|
58 |
+
document.getElementById("carbon-block").appendChild(carbonScript);
|
59 |
+
});
|
60 |
+
} catch (error) {
|
61 |
+
console.log(error);
|
62 |
+
}
|
63 |
+
</script>
|
64 |
+
</body>
|
65 |
+
</html>
|
stripe-gradient-animation/package-lock.json
ADDED
The diff for this file is too large to render.
See raw diff
|
|
stripe-gradient-animation/package.json
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "@thelevicole/stripe-gradient",
|
3 |
+
"version": "1.0.0",
|
4 |
+
"description": "A reverse engineered, and simplified javascript library to replicate the animated Stripe gradients.",
|
5 |
+
"main": "dist/stripe-gradient.js",
|
6 |
+
"keywords": [
|
7 |
+
"stripe",
|
8 |
+
"gradient",
|
9 |
+
"canvas",
|
10 |
+
"animation"
|
11 |
+
],
|
12 |
+
"browserslist": [
|
13 |
+
"last 3 version",
|
14 |
+
"> 1%",
|
15 |
+
"ie 11"
|
16 |
+
],
|
17 |
+
"repository": {
|
18 |
+
"type": "git",
|
19 |
+
"url": "git+https://github.com/thelevicole/stripe-gradient.git"
|
20 |
+
},
|
21 |
+
"author": {
|
22 |
+
"name": "Levi Cole",
|
23 |
+
"email": "[email protected]"
|
24 |
+
},
|
25 |
+
"bugs": {
|
26 |
+
"url": "https://github.com/thelevicole/stripe-gradient/issues"
|
27 |
+
},
|
28 |
+
"homepage": "https://thelevicole.com/stripe-gradient/",
|
29 |
+
"devDependencies": {
|
30 |
+
"laravel-mix": "^6.0.43"
|
31 |
+
},
|
32 |
+
"scripts": {
|
33 |
+
"build": "mix --production",
|
34 |
+
"watch": "mix --production -- --watch --progress"
|
35 |
+
}
|
36 |
+
}
|
stripe-gradient-animation/src/Attribute.js
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export default class Attribute {
|
2 |
+
|
3 |
+
/**
|
4 |
+
* The parent MiniGL controller.
|
5 |
+
*
|
6 |
+
* @type {MiniGL}
|
7 |
+
* @private
|
8 |
+
*/
|
9 |
+
gl;
|
10 |
+
|
11 |
+
type;
|
12 |
+
|
13 |
+
buffer;
|
14 |
+
|
15 |
+
normalized = false;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @param {MiniGL} minigl
|
19 |
+
* @param {object} properties
|
20 |
+
*/
|
21 |
+
constructor(minigl, properties = {}) {
|
22 |
+
|
23 |
+
// Add additional properties.
|
24 |
+
Object.assign(this, properties);
|
25 |
+
|
26 |
+
// Set required properties.
|
27 |
+
this.gl = minigl;
|
28 |
+
this.type = this.gl.getContext().FLOAT;
|
29 |
+
this.buffer = this.gl.getContext().createBuffer();
|
30 |
+
|
31 |
+
this.update();
|
32 |
+
}
|
33 |
+
|
34 |
+
update() {
|
35 |
+
if (this.values) {
|
36 |
+
const context = this.gl.getContext();
|
37 |
+
context.bindBuffer(this.target, this.buffer);
|
38 |
+
context.bufferData(this.target, this.values, context.STATIC_DRAW);
|
39 |
+
}
|
40 |
+
}
|
41 |
+
|
42 |
+
attach(e, t) {
|
43 |
+
const context = this.gl.getContext();
|
44 |
+
const n = context.getAttribLocation(t, e);
|
45 |
+
|
46 |
+
if (this.target === context.ARRAY_BUFFER) {
|
47 |
+
context.enableVertexAttribArray(n);
|
48 |
+
context.vertexAttribPointer(n, this.size, this.type, this.normalized, 0, 0);
|
49 |
+
}
|
50 |
+
|
51 |
+
return n;
|
52 |
+
}
|
53 |
+
|
54 |
+
use(e) {
|
55 |
+
const context = this.gl.getContext();
|
56 |
+
context.bindBuffer(this.target, this.buffer);
|
57 |
+
if (this.target === context.ARRAY_BUFFER) {
|
58 |
+
context.enableVertexAttribArray(e);
|
59 |
+
context.vertexAttribPointer(e, this.size, this.type, this.normalized, 0, 0);
|
60 |
+
}
|
61 |
+
}
|
62 |
+
|
63 |
+
}
|
stripe-gradient-animation/src/Gradient.js
ADDED
@@ -0,0 +1,439 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import MiniGL from './MiniGL.js';
|
2 |
+
import Blend from './ShadersJs/Blend.js';
|
3 |
+
import Fragment from './ShadersJs/Fragment.js';
|
4 |
+
import Noise from './ShadersJs/Noise.js';
|
5 |
+
import Vertex from './ShadersJs/Vertex.js';
|
6 |
+
import Uniform from './Uniform.js';
|
7 |
+
import Material from './Material.js';
|
8 |
+
import Mesh from './Mesh.js';
|
9 |
+
import PlaneGeometry from './PlaneGeometry.js';
|
10 |
+
|
11 |
+
class Gradient {
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Class reference used primarily for static properties.
|
15 |
+
*
|
16 |
+
* @type {Gradient}
|
17 |
+
*/
|
18 |
+
_class = Gradient;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Default options used if user doesn't provide a value.
|
22 |
+
*
|
23 |
+
* @type {object}
|
24 |
+
*/
|
25 |
+
static defaultOptions = {
|
26 |
+
canvas: null,
|
27 |
+
colors: ['#f00', '#0f0', '#00f'],
|
28 |
+
wireframe: false,
|
29 |
+
density: [.06, .16],
|
30 |
+
|
31 |
+
angle: 0,
|
32 |
+
amplitude: 320,
|
33 |
+
static: false, // Enable non-animating gradient
|
34 |
+
|
35 |
+
loadedClass: 'is-loaded',
|
36 |
+
|
37 |
+
zoom: 1, // @todo not used.
|
38 |
+
speed: 5, // @todo not used.
|
39 |
+
rotation: 0, // @todo not used.
|
40 |
+
};
|
41 |
+
|
42 |
+
vertexShader = null;
|
43 |
+
uniforms = null;
|
44 |
+
time = 1253106; // @todo work out why this number has been choosen.
|
45 |
+
mesh = null;
|
46 |
+
material = null;
|
47 |
+
geometry = null;
|
48 |
+
|
49 |
+
// @todo tidy up these properties
|
50 |
+
scrollingTimeout = null;
|
51 |
+
scrollingRefreshDelay = 200;
|
52 |
+
scrollObserver = null;
|
53 |
+
width = null;
|
54 |
+
minWidth = 1111;
|
55 |
+
height = 600;
|
56 |
+
xSegCount = null;
|
57 |
+
ySegCount = null;
|
58 |
+
freqX = 0.00014;
|
59 |
+
freqY = 0.00029;
|
60 |
+
freqDelta = 0.00001;
|
61 |
+
activeColors = [1, 1, 1, 1];
|
62 |
+
|
63 |
+
/**
|
64 |
+
* @type {{fragment: string, vertex: string, blend: string, noise: string}}
|
65 |
+
*/
|
66 |
+
shaderFiles = {
|
67 |
+
vertex: Vertex,
|
68 |
+
noise: Noise,
|
69 |
+
blend: Blend,
|
70 |
+
fragment: Fragment
|
71 |
+
};
|
72 |
+
|
73 |
+
/**
|
74 |
+
* User defined options
|
75 |
+
*
|
76 |
+
* @type {object}
|
77 |
+
*/
|
78 |
+
options = {};
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Store arbitrary flags consisting of mainly boolean values but in some cases can be any data type.
|
82 |
+
* @type {object}
|
83 |
+
* @private
|
84 |
+
*/
|
85 |
+
_flags = {
|
86 |
+
playing: true // autoplay on init
|
87 |
+
};
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Cached canvas element.
|
91 |
+
*
|
92 |
+
* @type {HTMLCanvasElement|null}
|
93 |
+
* @private
|
94 |
+
*/
|
95 |
+
_canvas;
|
96 |
+
|
97 |
+
/**
|
98 |
+
* @type {WebGLRenderingContext|null}
|
99 |
+
* @private
|
100 |
+
*/
|
101 |
+
_context;
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Cached MiniGL instance.
|
105 |
+
*
|
106 |
+
* @type {MiniGL}
|
107 |
+
* @private
|
108 |
+
*/
|
109 |
+
_minigl;
|
110 |
+
|
111 |
+
/**
|
112 |
+
* @param {object} options
|
113 |
+
*/
|
114 |
+
constructor(options) {
|
115 |
+
this.options = options;
|
116 |
+
|
117 |
+
// Find and store the canvas element.
|
118 |
+
this.setCanvas(this.findCanvas(this.getOption('canvas')));
|
119 |
+
|
120 |
+
// Bail if no canvas element.
|
121 |
+
if (!this.getCanvas()) {
|
122 |
+
throw 'Missing Canvas. Pass the canvas to the Gradient constructor.';
|
123 |
+
}
|
124 |
+
|
125 |
+
// Initiate the MiniGL controller.
|
126 |
+
this._minigl = new MiniGL(this.getCanvas(), this.getCanvas().offsetWidth, this.getCanvas().offsetHeight);
|
127 |
+
|
128 |
+
// Initiate the canvas gradient.
|
129 |
+
this.init();
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Get a user or default option.
|
134 |
+
*
|
135 |
+
* @param {string} name
|
136 |
+
* @param defaultValue
|
137 |
+
* @returns {*}
|
138 |
+
*/
|
139 |
+
getOption(name, defaultValue = undefined) {
|
140 |
+
if (defaultValue === undefined && name in this._class.defaultOptions) {
|
141 |
+
defaultValue = this._class.defaultOptions[name];
|
142 |
+
}
|
143 |
+
|
144 |
+
return name in this.options ? this.options[name] : defaultValue;
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* Get the canvas element and cache as private property.
|
149 |
+
*
|
150 |
+
* @param {string|HTMLCanvasElement} selector
|
151 |
+
* @returns {HTMLCanvasElement|null}
|
152 |
+
*/
|
153 |
+
findCanvas(selector) {
|
154 |
+
const canvas = typeof selector === 'string' ? document.querySelector(selector) : selector;
|
155 |
+
|
156 |
+
if (canvas instanceof HTMLCanvasElement) {
|
157 |
+
return canvas;
|
158 |
+
}
|
159 |
+
|
160 |
+
return null;
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* Sets the `_canvas` and `_context` properties.
|
165 |
+
*
|
166 |
+
* @param {HTMLCanvasElement} canvas
|
167 |
+
*/
|
168 |
+
setCanvas(canvas) {
|
169 |
+
if (canvas) {
|
170 |
+
this._canvas = canvas;
|
171 |
+
this._context = canvas.getContext('webgl', {
|
172 |
+
antialias: true
|
173 |
+
});
|
174 |
+
} else {
|
175 |
+
this._canvas = null;
|
176 |
+
this._context = null;
|
177 |
+
}
|
178 |
+
}
|
179 |
+
|
180 |
+
/**
|
181 |
+
* @return {HTMLCanvasElement}
|
182 |
+
*/
|
183 |
+
getCanvas() {
|
184 |
+
return this._canvas;
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* @return {WebGLRenderingContext}
|
189 |
+
*/
|
190 |
+
getContext() {
|
191 |
+
return this._context;
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* @param {string} name
|
196 |
+
* @param {*} value
|
197 |
+
* @return {*}
|
198 |
+
*/
|
199 |
+
setFlag(name, value) {
|
200 |
+
return this._flags[name] = value;
|
201 |
+
}
|
202 |
+
|
203 |
+
/**
|
204 |
+
* @param {string} name
|
205 |
+
* @param defaultValue
|
206 |
+
* @return {boolean|undefined}
|
207 |
+
*/
|
208 |
+
getFlag(name, defaultValue = undefined) {
|
209 |
+
return this._flags[name] || defaultValue;
|
210 |
+
}
|
211 |
+
|
212 |
+
handleScroll() {
|
213 |
+
clearTimeout(this.scrollingTimeout);
|
214 |
+
this.scrollingTimeout = setTimeout(this.handleScrollEnd, this.scrollingRefreshDelay);
|
215 |
+
|
216 |
+
if (this.getFlag('playing')) {
|
217 |
+
this.setFlag('isScrolling', true);
|
218 |
+
this.pause();
|
219 |
+
}
|
220 |
+
}
|
221 |
+
|
222 |
+
handleScrollEnd() {
|
223 |
+
this.setFlag('isScrolling', false);
|
224 |
+
|
225 |
+
if (this.getFlag('isIntersecting')) {
|
226 |
+
this.play();
|
227 |
+
}
|
228 |
+
}
|
229 |
+
|
230 |
+
/**
|
231 |
+
* @todo Update resize method to use canvas size not window.
|
232 |
+
*/
|
233 |
+
resize() {
|
234 |
+
const [ densityX, densityY ] = this.getOption('density');
|
235 |
+
this.width = window.innerWidth;
|
236 |
+
this._minigl.setSize(this.width, this.height);
|
237 |
+
this._minigl.setOrthographicCamera();
|
238 |
+
this.xSegCount = Math.ceil(this.width * densityX);
|
239 |
+
this.ySegCount = Math.ceil(this.height * densityY);
|
240 |
+
this.mesh.geometry.setTopology(this.xSegCount, this.ySegCount);
|
241 |
+
this.mesh.geometry.setSize(this.width, this.height);
|
242 |
+
this.mesh.material.uniforms.u_shadow_power.value = this.width < 600 ? 5 : 6;
|
243 |
+
}
|
244 |
+
|
245 |
+
animate(event = 0) {
|
246 |
+
const shouldSkipFrame = !!window.document.hidden || (!this.getFlag('playing') || parseInt(event, 10) % 2 === 0);
|
247 |
+
let lastFrame = this.getFlag('lastFrame', 0);
|
248 |
+
|
249 |
+
if (!shouldSkipFrame) {
|
250 |
+
this.time += Math.min(event - lastFrame, 1000 / 15);
|
251 |
+
lastFrame = this.setFlag('lastFrame', event);
|
252 |
+
this.mesh.material.uniforms.u_time.value = this.time;
|
253 |
+
this._minigl.render();
|
254 |
+
}
|
255 |
+
|
256 |
+
// @todo support static gradient.
|
257 |
+
if (lastFrame !== 0 && this.getOption('static')) {
|
258 |
+
this._minigl.render();
|
259 |
+
return this.disconnect();
|
260 |
+
}
|
261 |
+
|
262 |
+
if (/*this.getFlag('isIntersecting') && */this.getFlag('playing')) {
|
263 |
+
requestAnimationFrame(this.animate.bind(this));
|
264 |
+
}
|
265 |
+
}
|
266 |
+
|
267 |
+
/**
|
268 |
+
* Pause the animation.
|
269 |
+
*/
|
270 |
+
pause() {
|
271 |
+
this.setFlag('playing', false);
|
272 |
+
}
|
273 |
+
|
274 |
+
/**
|
275 |
+
* Start or continue the animation.
|
276 |
+
*/
|
277 |
+
play() {
|
278 |
+
requestAnimationFrame(this.animate.bind(this));
|
279 |
+
this.setFlag('playing', true);
|
280 |
+
}
|
281 |
+
|
282 |
+
disconnect() {
|
283 |
+
if (this.scrollObserver) {
|
284 |
+
window.removeEventListener("scroll", this.handleScroll);
|
285 |
+
this.scrollObserver.disconnect();
|
286 |
+
}
|
287 |
+
|
288 |
+
window.removeEventListener("resize", this.resize);
|
289 |
+
}
|
290 |
+
|
291 |
+
initMaterial() {
|
292 |
+
|
293 |
+
/**
|
294 |
+
* @type {array[]}
|
295 |
+
*/
|
296 |
+
const colors = this.getOption('colors').map(hex => {
|
297 |
+
|
298 |
+
// Check if shorthand hex value was used and double the length so the conversion in normalizeColor will work.
|
299 |
+
if (hex.length === 4) {
|
300 |
+
const hexTemp = hex.substr(1).split('').map(hexTemp => hexTemp + hexTemp).join('');
|
301 |
+
hex = `#${hexTemp}`
|
302 |
+
}
|
303 |
+
|
304 |
+
return hex && `0x${hex.substr(1)}`;
|
305 |
+
}).filter(Boolean).map(this.normalizeColor);
|
306 |
+
|
307 |
+
this.uniforms = {
|
308 |
+
u_time: new Uniform(this._minigl, 'float',0),
|
309 |
+
u_shadow_power: new Uniform(this._minigl, 'float', 10),
|
310 |
+
u_darken_top: new Uniform(this._minigl, 'float', this.getCanvas().dataset.jsDarkenTop ? 1 : 0),
|
311 |
+
u_active_colors: new Uniform(this._minigl, 'vec4', this.activeColors),
|
312 |
+
|
313 |
+
u_global: new Uniform(this._minigl, 'struct', {
|
314 |
+
noiseFreq: new Uniform(this._minigl, 'vec2', [this.freqX, this.freqY]),
|
315 |
+
noiseSpeed: new Uniform(this._minigl, 'float',0.000005)
|
316 |
+
}),
|
317 |
+
|
318 |
+
u_vertDeform: new Uniform(this._minigl, 'struct', {
|
319 |
+
incline: new Uniform(this._minigl, 'float', Math.sin(this.getOption('angle')) / Math.cos(this.getOption('angle'))),
|
320 |
+
offsetTop: new Uniform(this._minigl, 'float', -0.5),
|
321 |
+
offsetBottom: new Uniform(this._minigl, 'float', -0.5),
|
322 |
+
noiseFreq: new Uniform(this._minigl, 'vec2', [3, 4]),
|
323 |
+
noiseAmp: new Uniform(this._minigl, 'float', this.getOption('amplitude')),
|
324 |
+
noiseSpeed: new Uniform(this._minigl, 'float', 10),
|
325 |
+
noiseFlow: new Uniform(this._minigl, 'float', 3),
|
326 |
+
noiseSeed: new Uniform(this._minigl, 'float', this.seed)
|
327 |
+
}, {
|
328 |
+
excludeFrom: 'fragment'
|
329 |
+
}),
|
330 |
+
|
331 |
+
u_baseColor: new Uniform(this._minigl, 'vec3', colors[0], {
|
332 |
+
excludeFrom: 'fragment'
|
333 |
+
}),
|
334 |
+
|
335 |
+
u_waveLayers: new Uniform(this._minigl, 'array', [], {
|
336 |
+
excludeFrom: 'fragment'
|
337 |
+
})
|
338 |
+
};
|
339 |
+
|
340 |
+
for (let e = 1; e < colors.length; e += 1) {
|
341 |
+
const waveLayerUniform = new Uniform(this._minigl, 'struct', {
|
342 |
+
color: new Uniform(this._minigl, 'vec3', colors[e]),
|
343 |
+
noiseFreq: new Uniform(this._minigl, 'vec2', [2 + e / colors.length, 3 + e / colors.length]),
|
344 |
+
noiseSpeed: new Uniform(this._minigl, 'float', 11 + 0.3 * e),
|
345 |
+
noiseFlow: new Uniform(this._minigl, 'float', 6.5 + 0.3 * e),
|
346 |
+
noiseSeed: new Uniform(this._minigl, 'float', this.seed + 10 * e),
|
347 |
+
noiseFloor: new Uniform(this._minigl, 'float', 0.1),
|
348 |
+
noiseCeil: new Uniform(this._minigl, 'float', 0.63 + 0.07 * e)
|
349 |
+
});
|
350 |
+
|
351 |
+
this.uniforms.u_waveLayers.value.push(waveLayerUniform);
|
352 |
+
}
|
353 |
+
this.vertexShader = [
|
354 |
+
this.shaderFiles.noise,
|
355 |
+
this.shaderFiles.blend,
|
356 |
+
this.shaderFiles.vertex
|
357 |
+
].join("\n\n");
|
358 |
+
|
359 |
+
return new Material(this._minigl, this.vertexShader, this.shaderFiles.fragment, this.uniforms);
|
360 |
+
}
|
361 |
+
|
362 |
+
initMesh() {
|
363 |
+
this.material = this.initMaterial();
|
364 |
+
this.geometry = new PlaneGeometry(this._minigl);
|
365 |
+
|
366 |
+
this.mesh = new Mesh(this._minigl, this.geometry, this.material);
|
367 |
+
this.mesh.wireframe = this.getOption('wireframe');
|
368 |
+
}
|
369 |
+
|
370 |
+
updateFrequency(e) {
|
371 |
+
this.freqX += e;
|
372 |
+
this.freqY += e;
|
373 |
+
}
|
374 |
+
|
375 |
+
toggleColor(index) {
|
376 |
+
this.activeColors[index] = this.activeColors[index] === 0 ? 1 : 0;
|
377 |
+
}
|
378 |
+
|
379 |
+
init() {
|
380 |
+
|
381 |
+
// Add loaded class.
|
382 |
+
const loadedClass = this.getOption('loadedClass');
|
383 |
+
if (loadedClass) {
|
384 |
+
this.getCanvas().classList.add(loadedClass);
|
385 |
+
}
|
386 |
+
|
387 |
+
// @todo add scroll observer.
|
388 |
+
//
|
389 |
+
// this.scrollObserver = await s.create(.1, false),
|
390 |
+
// this.scrollObserver.observe(this.getCanvas());
|
391 |
+
//
|
392 |
+
// this.scrollObserver.onSeparate(() => {
|
393 |
+
// window.removeEventListener("scroll", this.handleScroll);
|
394 |
+
//
|
395 |
+
// this.setFlag('isIntersecting', false);
|
396 |
+
//
|
397 |
+
// if (this.getFlag('playing')) {
|
398 |
+
// this.pause();
|
399 |
+
// }
|
400 |
+
// });
|
401 |
+
//
|
402 |
+
// this.scrollObserver.onIntersect(() => {
|
403 |
+
// window.addEventListener("scroll", this.handleScroll);
|
404 |
+
//
|
405 |
+
// this.setFlag('isIntersecting', true);
|
406 |
+
//
|
407 |
+
// this.addIsLoadedClass();
|
408 |
+
// this.play();
|
409 |
+
// });
|
410 |
+
|
411 |
+
this.initMesh();
|
412 |
+
this.resize();
|
413 |
+
requestAnimationFrame(this.animate.bind(this));
|
414 |
+
window.addEventListener('resize', this.resize);
|
415 |
+
}
|
416 |
+
|
417 |
+
/**
|
418 |
+
* @param {string} hexCode
|
419 |
+
* @return {number[]}
|
420 |
+
*/
|
421 |
+
normalizeColor(hexCode) {
|
422 |
+
return [
|
423 |
+
(hexCode >> 16 & 255) / 255,
|
424 |
+
(hexCode >> 8 & 255) / 255,
|
425 |
+
(255 & hexCode) / 255
|
426 |
+
];
|
427 |
+
}
|
428 |
+
|
429 |
+
}
|
430 |
+
|
431 |
+
window.Gradient = Gradient;
|
432 |
+
|
433 |
+
if (window.jQuery) {
|
434 |
+
jQuery.fn.gradient = function(options = {}) {
|
435 |
+
options.canvas = this.get(0);
|
436 |
+
this._gradient = new Gradient(options);
|
437 |
+
return this;
|
438 |
+
};
|
439 |
+
}
|
stripe-gradient-animation/src/Material.js
ADDED
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import Attribute from './Attribute.js';
|
2 |
+
|
3 |
+
export default class Material {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* The parent MiniGL controller.
|
7 |
+
*
|
8 |
+
* @type {MiniGL}
|
9 |
+
* @private
|
10 |
+
*/
|
11 |
+
gl;
|
12 |
+
|
13 |
+
uniformInstances = [];
|
14 |
+
|
15 |
+
/**
|
16 |
+
*
|
17 |
+
* @param {MiniGL} minigl
|
18 |
+
* @param {object} properties
|
19 |
+
*/
|
20 |
+
constructor(minigl, vertexShaders, fragments, uniforms = {}, properties = {}) {
|
21 |
+
|
22 |
+
// Add additional properties.
|
23 |
+
Object.assign(this, properties);
|
24 |
+
|
25 |
+
// Set required properties.
|
26 |
+
this.gl = minigl;
|
27 |
+
this.uniforms = uniforms;
|
28 |
+
|
29 |
+
const context = this.gl.getContext();
|
30 |
+
|
31 |
+
const prefix = `
|
32 |
+
precision highp float;
|
33 |
+
`;
|
34 |
+
|
35 |
+
this.vertexSource = `
|
36 |
+
${prefix}
|
37 |
+
attribute vec4 position;
|
38 |
+
attribute vec2 uv;
|
39 |
+
attribute vec2 uvNorm;
|
40 |
+
${this._getUniformVariableDeclarations(this.gl.commonUniforms,"vertex")}
|
41 |
+
${this._getUniformVariableDeclarations(uniforms,"vertex")}
|
42 |
+
${vertexShaders}
|
43 |
+
`;
|
44 |
+
|
45 |
+
this.Source = `
|
46 |
+
${prefix}
|
47 |
+
${this._getUniformVariableDeclarations(this.gl.commonUniforms,"fragment")}
|
48 |
+
${this._getUniformVariableDeclarations(uniforms,"fragment")}
|
49 |
+
${fragments}
|
50 |
+
`;
|
51 |
+
|
52 |
+
this.vertexShader = this._getShaderByType(context.VERTEX_SHADER, this.vertexSource);
|
53 |
+
this.fragmentShader = this._getShaderByType(context.FRAGMENT_SHADER, this.Source);
|
54 |
+
this.program = context.createProgram();
|
55 |
+
|
56 |
+
context.attachShader(this.program, this.vertexShader);
|
57 |
+
context.attachShader(this.program, this.fragmentShader);
|
58 |
+
context.linkProgram(this.program);
|
59 |
+
context.getProgramParameter(this.program, context.LINK_STATUS) || console.error(context.getProgramInfoLog(this.program));
|
60 |
+
context.useProgram(this.program);
|
61 |
+
|
62 |
+
this.attachUniforms(void 0, this.gl.commonUniforms);
|
63 |
+
this.attachUniforms(void 0, this.uniforms);
|
64 |
+
|
65 |
+
}
|
66 |
+
|
67 |
+
_getShaderByType(type, source) {
|
68 |
+
const context = this.gl.getContext();
|
69 |
+
const shader = context.createShader(type);
|
70 |
+
context.shaderSource(shader, source);
|
71 |
+
context.compileShader(shader);
|
72 |
+
|
73 |
+
if (!context.getShaderParameter(shader, context.COMPILE_STATUS)) {
|
74 |
+
console.error(context.getShaderInfoLog(shader));
|
75 |
+
}
|
76 |
+
|
77 |
+
return shader;
|
78 |
+
}
|
79 |
+
|
80 |
+
_getUniformVariableDeclarations(uniforms, type) {
|
81 |
+
return Object.entries(uniforms).map(([uniform, value]) => {
|
82 |
+
return value.getDeclaration(uniform, type);
|
83 |
+
}).join("\n");
|
84 |
+
}
|
85 |
+
|
86 |
+
attachUniforms(name, uniforms) {
|
87 |
+
if (!name) {
|
88 |
+
Object.entries(uniforms).forEach(([name, uniform]) => {
|
89 |
+
this.attachUniforms(name, uniform);
|
90 |
+
});
|
91 |
+
} else if (uniforms.type === 'array') {
|
92 |
+
uniforms.value.forEach((uniform, i) => {
|
93 |
+
this.attachUniforms(`${name}[${i}]`, uniform);
|
94 |
+
});
|
95 |
+
} else if (uniforms.type === 'struct') {
|
96 |
+
Object.entries(uniforms.value).forEach(([uniform, i]) => {
|
97 |
+
this.attachUniforms(`${name}.${uniform}`, i);
|
98 |
+
});
|
99 |
+
} else {
|
100 |
+
this.uniformInstances.push({
|
101 |
+
uniform: uniforms,
|
102 |
+
location: this.gl.getContext().getUniformLocation(this.program, name)
|
103 |
+
});
|
104 |
+
}
|
105 |
+
}
|
106 |
+
|
107 |
+
}
|
stripe-gradient-animation/src/Mesh.js
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export default class Mesh {
|
2 |
+
|
3 |
+
/**
|
4 |
+
* The parent MiniGL controller.
|
5 |
+
*
|
6 |
+
* @type {MiniGL}
|
7 |
+
* @private
|
8 |
+
*/
|
9 |
+
gl;
|
10 |
+
|
11 |
+
wireframe = false;
|
12 |
+
attributeInstances = [];
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @param {MiniGL} minigl
|
16 |
+
* @param geometry
|
17 |
+
* @param material
|
18 |
+
* @param {object} properties
|
19 |
+
*/
|
20 |
+
constructor(minigl, geometry, material, properties = {}) {
|
21 |
+
|
22 |
+
// Add additional properties.
|
23 |
+
Object.assign(this, properties);
|
24 |
+
|
25 |
+
// Set required properties.
|
26 |
+
this.geometry = geometry;
|
27 |
+
this.material = material;
|
28 |
+
this.gl = minigl;
|
29 |
+
|
30 |
+
// Build `attributeInstances` array.
|
31 |
+
Object.entries(this.geometry.attributes).forEach(([e, attribute]) => {
|
32 |
+
this.attributeInstances.push({
|
33 |
+
attribute: attribute,
|
34 |
+
location: attribute.attach(e, this.material.program)
|
35 |
+
});
|
36 |
+
});
|
37 |
+
|
38 |
+
// Add mesh to MiniGL controller.
|
39 |
+
this.gl.meshes.push(this);
|
40 |
+
}
|
41 |
+
|
42 |
+
|
43 |
+
draw() {
|
44 |
+
const context = this.gl.getContext();
|
45 |
+
|
46 |
+
context.useProgram(this.material.program);
|
47 |
+
|
48 |
+
this.material.uniformInstances.forEach(({uniform: uniform, location: location}) => {
|
49 |
+
uniform.update(location);
|
50 |
+
});
|
51 |
+
|
52 |
+
this.attributeInstances.forEach(({attribute: attribute, location: location}) => {
|
53 |
+
attribute.use(location);
|
54 |
+
});
|
55 |
+
|
56 |
+
const mode = this.wireframe ? context.LINES : context.TRIANGLES;
|
57 |
+
|
58 |
+
context.drawElements(mode, this.geometry.attributes.index.values.length, context.UNSIGNED_SHORT, 0);
|
59 |
+
}
|
60 |
+
|
61 |
+
remove() {
|
62 |
+
this.gl.meshes = this.gl.meshes.filter(mesh => mesh != this);
|
63 |
+
}
|
64 |
+
|
65 |
+
}
|
stripe-gradient-animation/src/MiniGL.js
ADDED
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import Attribute from './Attribute.js';
|
2 |
+
import Material from './Material.js';
|
3 |
+
import Mesh from './Mesh.js';
|
4 |
+
import PlaneGeometry from './PlaneGeometry.js';
|
5 |
+
import Uniform from './Uniform.js';
|
6 |
+
|
7 |
+
export default class MiniGL {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Class reference.
|
11 |
+
*
|
12 |
+
* @type {MiniGL}
|
13 |
+
*/
|
14 |
+
_class = MiniGL;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @type {HTMLCanvasElement}
|
18 |
+
* @private
|
19 |
+
*/
|
20 |
+
_canvas;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @type {WebGLRenderingContext}
|
24 |
+
* @private
|
25 |
+
*/
|
26 |
+
_context;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @type {object}
|
30 |
+
*/
|
31 |
+
commonUniforms = {};
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @type {array}
|
35 |
+
*/
|
36 |
+
meshes = [];
|
37 |
+
|
38 |
+
/**
|
39 |
+
* @param {HTMLCanvasElement} canvas
|
40 |
+
* @param {null|Number} width
|
41 |
+
* @param {null|Number} height
|
42 |
+
*/
|
43 |
+
constructor(canvas, width, height) {
|
44 |
+
this.setCanvas(canvas);
|
45 |
+
|
46 |
+
const matrix = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
|
47 |
+
|
48 |
+
this.commonUniforms = {
|
49 |
+
projectionMatrix: new Uniform(this, 'mat4', matrix),
|
50 |
+
modelViewMatrix: new Uniform(this, 'mat4', matrix),
|
51 |
+
resolution: new Uniform(this, 'vec2', [1, 1]),
|
52 |
+
aspectRatio: new Uniform(this, 'float', 1)
|
53 |
+
};
|
54 |
+
|
55 |
+
this.setSize(width, height);
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Sets the `_canvas` and `_context` properties.
|
60 |
+
*
|
61 |
+
* @param {HTMLCanvasElement} canvas
|
62 |
+
*/
|
63 |
+
setCanvas(canvas) {
|
64 |
+
this._canvas = canvas;
|
65 |
+
this._context = canvas.getContext('webgl', {
|
66 |
+
antialias: true
|
67 |
+
});
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* @return {HTMLCanvasElement}
|
72 |
+
*/
|
73 |
+
getCanvas() {
|
74 |
+
return this._canvas;
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* @return {WebGLRenderingContext}
|
79 |
+
*/
|
80 |
+
getContext() {
|
81 |
+
return this._context;
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Set the canvas and viewport size.
|
86 |
+
*
|
87 |
+
* @param {Number} width
|
88 |
+
* @param {Number} height
|
89 |
+
*/
|
90 |
+
setSize(width = 640, height = 480) {
|
91 |
+
this.getCanvas().width = width;
|
92 |
+
this.getCanvas().height = height;
|
93 |
+
this.getContext().viewport(0, 0, width, height);
|
94 |
+
this.commonUniforms.resolution.value = [width, height];
|
95 |
+
this.commonUniforms.aspectRatio.value = width / height;
|
96 |
+
}
|
97 |
+
|
98 |
+
setOrthographicCamera(left = 0, right = 0, top = 0, bottom = -2000, distance = 2000) {
|
99 |
+
this.commonUniforms.projectionMatrix.value = [
|
100 |
+
2 / this.getCanvas().width,
|
101 |
+
0, 0, 0, 0,
|
102 |
+
2 / this.getCanvas().height,
|
103 |
+
0, 0, 0, 0,
|
104 |
+
2 / (bottom - distance),
|
105 |
+
0, left, right, top, 1
|
106 |
+
];
|
107 |
+
}
|
108 |
+
|
109 |
+
render() {
|
110 |
+
this.getContext().clearColor(0, 0, 0, 0);
|
111 |
+
this.getContext().clearDepth(1);
|
112 |
+
this.meshes.forEach(mesh => {
|
113 |
+
mesh.draw();
|
114 |
+
});
|
115 |
+
}
|
116 |
+
|
117 |
+
}
|
stripe-gradient-animation/src/PlaneGeometry.js
ADDED
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import Attribute from './Attribute.js';
|
2 |
+
|
3 |
+
export default class PlaneGeometry {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* The parent MiniGL controller.
|
7 |
+
*
|
8 |
+
* @type {MiniGL}
|
9 |
+
* @private
|
10 |
+
*/
|
11 |
+
gl;
|
12 |
+
|
13 |
+
attributes;
|
14 |
+
|
15 |
+
/**
|
16 |
+
*
|
17 |
+
* @param {MiniGL} minigl
|
18 |
+
* @param width
|
19 |
+
* @param height
|
20 |
+
* @param n
|
21 |
+
* @param i
|
22 |
+
* @param orientation
|
23 |
+
* @param {object} properties
|
24 |
+
*/
|
25 |
+
constructor(minigl, width, height, n, i, orientation, properties = {}) {
|
26 |
+
|
27 |
+
// Add additional properties.
|
28 |
+
Object.assign(this, properties);
|
29 |
+
|
30 |
+
// Set required properties.
|
31 |
+
this.gl = minigl;
|
32 |
+
|
33 |
+
const context = this.gl.getContext();
|
34 |
+
|
35 |
+
context.createBuffer();
|
36 |
+
|
37 |
+
this.attributes = {
|
38 |
+
position: new Attribute(this.gl, {
|
39 |
+
target: context.ARRAY_BUFFER,
|
40 |
+
size: 3
|
41 |
+
}),
|
42 |
+
uv: new Attribute(this.gl, {
|
43 |
+
target: context.ARRAY_BUFFER,
|
44 |
+
size: 2
|
45 |
+
}),
|
46 |
+
uvNorm: new Attribute(this.gl, {
|
47 |
+
target: context.ARRAY_BUFFER,
|
48 |
+
size: 2
|
49 |
+
}),
|
50 |
+
index: new Attribute(this.gl, {
|
51 |
+
target: context.ELEMENT_ARRAY_BUFFER,
|
52 |
+
size: 3,
|
53 |
+
type: context.UNSIGNED_SHORT
|
54 |
+
})
|
55 |
+
};
|
56 |
+
|
57 |
+
this.setTopology(n, i);
|
58 |
+
this.setSize(width, height, orientation);
|
59 |
+
}
|
60 |
+
|
61 |
+
setTopology(e = 1, t = 1) {
|
62 |
+
this.xSegCount = e;
|
63 |
+
this.ySegCount = t;
|
64 |
+
this.vertexCount = (this.xSegCount + 1) * (this.ySegCount + 1);
|
65 |
+
this.quadCount = this.xSegCount * this.ySegCount * 2;
|
66 |
+
this.attributes.uv.values = new Float32Array(2 * this.vertexCount);
|
67 |
+
this.attributes.uvNorm.values = new Float32Array(2 * this.vertexCount);
|
68 |
+
this.attributes.index.values = new Uint16Array(3 * this.quadCount);
|
69 |
+
|
70 |
+
for (let e = 0; e <= this.ySegCount; e++) {
|
71 |
+
for (let t = 0; t <= this.xSegCount; t++) {
|
72 |
+
const i = e * (this.xSegCount + 1) + t;
|
73 |
+
if (this.attributes.uv.values[2 * i] = t / this.xSegCount, this.attributes.uv.values[2 * i + 1] = 1 - e / this.ySegCount, this.attributes.uvNorm.values[2 * i] = t / this.xSegCount * 2 - 1, this.attributes.uvNorm.values[2 * i + 1] = 1 - e / this.ySegCount * 2, t < this.xSegCount && e < this.ySegCount) {
|
74 |
+
const s = e * this.xSegCount + t;
|
75 |
+
this.attributes.index.values[6 * s] = i, this.attributes.index.values[6 * s + 1] = i + 1 + this.xSegCount, this.attributes.index.values[6 * s + 2] = i + 1, this.attributes.index.values[6 * s + 3] = i + 1, this.attributes.index.values[6 * s + 4] = i + 1 + this.xSegCount, this.attributes.index.values[6 * s + 5] = i + 2 + this.xSegCount
|
76 |
+
}
|
77 |
+
}
|
78 |
+
}
|
79 |
+
|
80 |
+
this.attributes.uv.update();
|
81 |
+
this.attributes.uvNorm.update();
|
82 |
+
this.attributes.index.update();
|
83 |
+
}
|
84 |
+
|
85 |
+
setSize(width = 1, height = 1, orientation = 'xz') {
|
86 |
+
this.width = width;
|
87 |
+
this.height = height;
|
88 |
+
this.orientation = orientation;
|
89 |
+
|
90 |
+
this.attributes.position.values && this.attributes.position.values.length === 3 * this.vertexCount || (this.attributes.position.values = new Float32Array(3 * this.vertexCount));
|
91 |
+
const o = width / -2;
|
92 |
+
const r = height / -2;
|
93 |
+
const segment_width = width / this.xSegCount;
|
94 |
+
const segment_height = height / this.ySegCount;
|
95 |
+
|
96 |
+
for (let yIndex = 0; yIndex <= this.ySegCount; yIndex++) {
|
97 |
+
const t = r + yIndex * segment_height;
|
98 |
+
for (let xIndex = 0; xIndex <= this.xSegCount; xIndex++) {
|
99 |
+
const r = o + xIndex * segment_width;
|
100 |
+
const l = yIndex * (this.xSegCount + 1) + xIndex;
|
101 |
+
|
102 |
+
this.attributes.position.values[3 * l + 'xyz'.indexOf(orientation[0])] = r;
|
103 |
+
this.attributes.position.values[3 * l + 'xyz'.indexOf(orientation[1])] = -t;
|
104 |
+
}
|
105 |
+
}
|
106 |
+
|
107 |
+
this.attributes.position.update();
|
108 |
+
}
|
109 |
+
|
110 |
+
}
|
stripe-gradient-animation/src/Shaders/Blend.glsl
ADDED
@@ -0,0 +1,177 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
//
|
2 |
+
// https://github.com/jamieowen/glsl-blend
|
3 |
+
//
|
4 |
+
|
5 |
+
// Normal
|
6 |
+
|
7 |
+
vec3 blendNormal(vec3 base, vec3 blend) {
|
8 |
+
return blend;
|
9 |
+
}
|
10 |
+
|
11 |
+
vec3 blendNormal(vec3 base, vec3 blend, float opacity) {
|
12 |
+
return (blendNormal(base, blend) * opacity + base * (1.0 - opacity));
|
13 |
+
}
|
14 |
+
|
15 |
+
// Screen
|
16 |
+
|
17 |
+
float blendScreen(float base, float blend) {
|
18 |
+
return 1.0-((1.0-base)*(1.0-blend));
|
19 |
+
}
|
20 |
+
|
21 |
+
vec3 blendScreen(vec3 base, vec3 blend) {
|
22 |
+
return vec3(blendScreen(base.r,blend.r),blendScreen(base.g,blend.g),blendScreen(base.b,blend.b));
|
23 |
+
}
|
24 |
+
|
25 |
+
vec3 blendScreen(vec3 base, vec3 blend, float opacity) {
|
26 |
+
return (blendScreen(base, blend) * opacity + base * (1.0 - opacity));
|
27 |
+
}
|
28 |
+
|
29 |
+
// Multiply
|
30 |
+
|
31 |
+
vec3 blendMultiply(vec3 base, vec3 blend) {
|
32 |
+
return base*blend;
|
33 |
+
}
|
34 |
+
|
35 |
+
vec3 blendMultiply(vec3 base, vec3 blend, float opacity) {
|
36 |
+
return (blendMultiply(base, blend) * opacity + base * (1.0 - opacity));
|
37 |
+
}
|
38 |
+
|
39 |
+
// Overlay
|
40 |
+
|
41 |
+
float blendOverlay(float base, float blend) {
|
42 |
+
return base<0.5?(2.0*base*blend):(1.0-2.0*(1.0-base)*(1.0-blend));
|
43 |
+
}
|
44 |
+
|
45 |
+
vec3 blendOverlay(vec3 base, vec3 blend) {
|
46 |
+
return vec3(blendOverlay(base.r,blend.r),blendOverlay(base.g,blend.g),blendOverlay(base.b,blend.b));
|
47 |
+
}
|
48 |
+
|
49 |
+
vec3 blendOverlay(vec3 base, vec3 blend, float opacity) {
|
50 |
+
return (blendOverlay(base, blend) * opacity + base * (1.0 - opacity));
|
51 |
+
}
|
52 |
+
|
53 |
+
// Hard light
|
54 |
+
|
55 |
+
vec3 blendHardLight(vec3 base, vec3 blend) {
|
56 |
+
return blendOverlay(blend,base);
|
57 |
+
}
|
58 |
+
|
59 |
+
vec3 blendHardLight(vec3 base, vec3 blend, float opacity) {
|
60 |
+
return (blendHardLight(base, blend) * opacity + base * (1.0 - opacity));
|
61 |
+
}
|
62 |
+
|
63 |
+
// Soft light
|
64 |
+
|
65 |
+
float blendSoftLight(float base, float blend) {
|
66 |
+
return (blend<0.5)?(2.0*base*blend+base*base*(1.0-2.0*blend)):(sqrt(base)*(2.0*blend-1.0)+2.0*base*(1.0-blend));
|
67 |
+
}
|
68 |
+
|
69 |
+
vec3 blendSoftLight(vec3 base, vec3 blend) {
|
70 |
+
return vec3(blendSoftLight(base.r,blend.r),blendSoftLight(base.g,blend.g),blendSoftLight(base.b,blend.b));
|
71 |
+
}
|
72 |
+
|
73 |
+
vec3 blendSoftLight(vec3 base, vec3 blend, float opacity) {
|
74 |
+
return (blendSoftLight(base, blend) * opacity + base * (1.0 - opacity));
|
75 |
+
}
|
76 |
+
|
77 |
+
// Color dodge
|
78 |
+
|
79 |
+
float blendColorDodge(float base, float blend) {
|
80 |
+
return (blend==1.0)?blend:min(base/(1.0-blend),1.0);
|
81 |
+
}
|
82 |
+
|
83 |
+
vec3 blendColorDodge(vec3 base, vec3 blend) {
|
84 |
+
return vec3(blendColorDodge(base.r,blend.r),blendColorDodge(base.g,blend.g),blendColorDodge(base.b,blend.b));
|
85 |
+
}
|
86 |
+
|
87 |
+
vec3 blendColorDodge(vec3 base, vec3 blend, float opacity) {
|
88 |
+
return (blendColorDodge(base, blend) * opacity + base * (1.0 - opacity));
|
89 |
+
}
|
90 |
+
|
91 |
+
// Color burn
|
92 |
+
|
93 |
+
float blendColorBurn(float base, float blend) {
|
94 |
+
return (blend==0.0)?blend:max((1.0-((1.0-base)/blend)),0.0);
|
95 |
+
}
|
96 |
+
|
97 |
+
vec3 blendColorBurn(vec3 base, vec3 blend) {
|
98 |
+
return vec3(blendColorBurn(base.r,blend.r),blendColorBurn(base.g,blend.g),blendColorBurn(base.b,blend.b));
|
99 |
+
}
|
100 |
+
|
101 |
+
vec3 blendColorBurn(vec3 base, vec3 blend, float opacity) {
|
102 |
+
return (blendColorBurn(base, blend) * opacity + base * (1.0 - opacity));
|
103 |
+
}
|
104 |
+
|
105 |
+
// Vivid Light
|
106 |
+
|
107 |
+
float blendVividLight(float base, float blend) {
|
108 |
+
return (blend<0.5)?blendColorBurn(base,(2.0*blend)):blendColorDodge(base,(2.0*(blend-0.5)));
|
109 |
+
}
|
110 |
+
|
111 |
+
vec3 blendVividLight(vec3 base, vec3 blend) {
|
112 |
+
return vec3(blendVividLight(base.r,blend.r),blendVividLight(base.g,blend.g),blendVividLight(base.b,blend.b));
|
113 |
+
}
|
114 |
+
|
115 |
+
vec3 blendVividLight(vec3 base, vec3 blend, float opacity) {
|
116 |
+
return (blendVividLight(base, blend) * opacity + base * (1.0 - opacity));
|
117 |
+
}
|
118 |
+
|
119 |
+
// Lighten
|
120 |
+
|
121 |
+
float blendLighten(float base, float blend) {
|
122 |
+
return max(blend,base);
|
123 |
+
}
|
124 |
+
|
125 |
+
vec3 blendLighten(vec3 base, vec3 blend) {
|
126 |
+
return vec3(blendLighten(base.r,blend.r),blendLighten(base.g,blend.g),blendLighten(base.b,blend.b));
|
127 |
+
}
|
128 |
+
|
129 |
+
vec3 blendLighten(vec3 base, vec3 blend, float opacity) {
|
130 |
+
return (blendLighten(base, blend) * opacity + base * (1.0 - opacity));
|
131 |
+
}
|
132 |
+
|
133 |
+
// Linear burn
|
134 |
+
|
135 |
+
float blendLinearBurn(float base, float blend) {
|
136 |
+
// Note : Same implementation as BlendSubtractf
|
137 |
+
return max(base+blend-1.0,0.0);
|
138 |
+
}
|
139 |
+
|
140 |
+
vec3 blendLinearBurn(vec3 base, vec3 blend) {
|
141 |
+
// Note : Same implementation as BlendSubtract
|
142 |
+
return max(base+blend-vec3(1.0),vec3(0.0));
|
143 |
+
}
|
144 |
+
|
145 |
+
vec3 blendLinearBurn(vec3 base, vec3 blend, float opacity) {
|
146 |
+
return (blendLinearBurn(base, blend) * opacity + base * (1.0 - opacity));
|
147 |
+
}
|
148 |
+
|
149 |
+
// Linear dodge
|
150 |
+
|
151 |
+
float blendLinearDodge(float base, float blend) {
|
152 |
+
// Note : Same implementation as BlendAddf
|
153 |
+
return min(base+blend,1.0);
|
154 |
+
}
|
155 |
+
|
156 |
+
vec3 blendLinearDodge(vec3 base, vec3 blend) {
|
157 |
+
// Note : Same implementation as BlendAdd
|
158 |
+
return min(base+blend,vec3(1.0));
|
159 |
+
}
|
160 |
+
|
161 |
+
vec3 blendLinearDodge(vec3 base, vec3 blend, float opacity) {
|
162 |
+
return (blendLinearDodge(base, blend) * opacity + base * (1.0 - opacity));
|
163 |
+
}
|
164 |
+
|
165 |
+
// Linear light
|
166 |
+
|
167 |
+
float blendLinearLight(float base, float blend) {
|
168 |
+
return blend<0.5?blendLinearBurn(base,(2.0*blend)):blendLinearDodge(base,(2.0*(blend-0.5)));
|
169 |
+
}
|
170 |
+
|
171 |
+
vec3 blendLinearLight(vec3 base, vec3 blend) {
|
172 |
+
return vec3(blendLinearLight(base.r,blend.r),blendLinearLight(base.g,blend.g),blendLinearLight(base.b,blend.b));
|
173 |
+
}
|
174 |
+
|
175 |
+
vec3 blendLinearLight(vec3 base, vec3 blend, float opacity) {
|
176 |
+
return (blendLinearLight(base, blend) * opacity + base * (1.0 - opacity));
|
177 |
+
}
|
stripe-gradient-animation/src/Shaders/Fragment.glsl
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
varying vec3 v_color;
|
2 |
+
|
3 |
+
void main() {
|
4 |
+
vec3 color = v_color;
|
5 |
+
if (u_darken_top == 1.0) {
|
6 |
+
vec2 st = gl_FragCoord.xy/resolution.xy;
|
7 |
+
color.g -= pow(st.y + sin(-12.0) * st.x, u_shadow_power) * 0.4;
|
8 |
+
}
|
9 |
+
gl_FragColor = vec4(color, 1.0);
|
10 |
+
}
|
stripe-gradient-animation/src/Shaders/Noise.glsl
ADDED
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
//
|
2 |
+
// Description : Array and textureless GLSL 2D/3D/4D simplex
|
3 |
+
// noise functions.
|
4 |
+
// Author : Ian McEwan, Ashima Arts.
|
5 |
+
// Maintainer : stegu
|
6 |
+
// Lastmod : 20110822 (ijm)
|
7 |
+
// License : Copyright (C) 2011 Ashima Arts. All rights reserved.
|
8 |
+
// Distributed under the MIT License. See LICENSE file.
|
9 |
+
// https://github.com/ashima/webgl-noise
|
10 |
+
// https://github.com/stegu/webgl-noise
|
11 |
+
//
|
12 |
+
|
13 |
+
vec3 mod289(vec3 x) {
|
14 |
+
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
15 |
+
}
|
16 |
+
|
17 |
+
vec4 mod289(vec4 x) {
|
18 |
+
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
19 |
+
}
|
20 |
+
|
21 |
+
vec4 permute(vec4 x) {
|
22 |
+
return mod289(((x*34.0)+1.0)*x);
|
23 |
+
}
|
24 |
+
|
25 |
+
vec4 taylorInvSqrt(vec4 r)
|
26 |
+
{
|
27 |
+
return 1.79284291400159 - 0.85373472095314 * r;
|
28 |
+
}
|
29 |
+
|
30 |
+
float snoise(vec3 v)
|
31 |
+
{
|
32 |
+
const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;
|
33 |
+
const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
|
34 |
+
|
35 |
+
// First corner
|
36 |
+
vec3 i = floor(v + dot(v, C.yyy) );
|
37 |
+
vec3 x0 = v - i + dot(i, C.xxx) ;
|
38 |
+
|
39 |
+
// Other corners
|
40 |
+
vec3 g = step(x0.yzx, x0.xyz);
|
41 |
+
vec3 l = 1.0 - g;
|
42 |
+
vec3 i1 = min( g.xyz, l.zxy );
|
43 |
+
vec3 i2 = max( g.xyz, l.zxy );
|
44 |
+
|
45 |
+
// x0 = x0 - 0.0 + 0.0 * C.xxx;
|
46 |
+
// x1 = x0 - i1 + 1.0 * C.xxx;
|
47 |
+
// x2 = x0 - i2 + 2.0 * C.xxx;
|
48 |
+
// x3 = x0 - 1.0 + 3.0 * C.xxx;
|
49 |
+
vec3 x1 = x0 - i1 + C.xxx;
|
50 |
+
vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
|
51 |
+
vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y
|
52 |
+
|
53 |
+
// Permutations
|
54 |
+
i = mod289(i);
|
55 |
+
vec4 p = permute( permute( permute(
|
56 |
+
i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
|
57 |
+
+ i.y + vec4(0.0, i1.y, i2.y, 1.0 ))
|
58 |
+
+ i.x + vec4(0.0, i1.x, i2.x, 1.0 ));
|
59 |
+
|
60 |
+
// Gradients: 7x7 points over a square, mapped onto an octahedron.
|
61 |
+
// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
|
62 |
+
float n_ = 0.142857142857; // 1.0/7.0
|
63 |
+
vec3 ns = n_ * D.wyz - D.xzx;
|
64 |
+
|
65 |
+
vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)
|
66 |
+
|
67 |
+
vec4 x_ = floor(j * ns.z);
|
68 |
+
vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)
|
69 |
+
|
70 |
+
vec4 x = x_ *ns.x + ns.yyyy;
|
71 |
+
vec4 y = y_ *ns.x + ns.yyyy;
|
72 |
+
vec4 h = 1.0 - abs(x) - abs(y);
|
73 |
+
|
74 |
+
vec4 b0 = vec4( x.xy, y.xy );
|
75 |
+
vec4 b1 = vec4( x.zw, y.zw );
|
76 |
+
|
77 |
+
//vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
|
78 |
+
//vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
|
79 |
+
vec4 s0 = floor(b0)*2.0 + 1.0;
|
80 |
+
vec4 s1 = floor(b1)*2.0 + 1.0;
|
81 |
+
vec4 sh = -step(h, vec4(0.0));
|
82 |
+
|
83 |
+
vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
|
84 |
+
vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;
|
85 |
+
|
86 |
+
vec3 p0 = vec3(a0.xy,h.x);
|
87 |
+
vec3 p1 = vec3(a0.zw,h.y);
|
88 |
+
vec3 p2 = vec3(a1.xy,h.z);
|
89 |
+
vec3 p3 = vec3(a1.zw,h.w);
|
90 |
+
|
91 |
+
//Normalise gradients
|
92 |
+
vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
|
93 |
+
p0 *= norm.x;
|
94 |
+
p1 *= norm.y;
|
95 |
+
p2 *= norm.z;
|
96 |
+
p3 *= norm.w;
|
97 |
+
|
98 |
+
// Mix final noise value
|
99 |
+
vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
|
100 |
+
m = m * m;
|
101 |
+
return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),
|
102 |
+
dot(p2,x2), dot(p3,x3) ) );
|
103 |
+
}
|
stripe-gradient-animation/src/Shaders/Vertex.glsl
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
varying vec3 v_color;
|
2 |
+
|
3 |
+
void main() {
|
4 |
+
float time = u_time * u_global.noiseSpeed;
|
5 |
+
|
6 |
+
vec2 noiseCoord = resolution * uvNorm * u_global.noiseFreq;
|
7 |
+
|
8 |
+
vec2 st = 1. - uvNorm.xy;
|
9 |
+
|
10 |
+
//
|
11 |
+
// Tilting the plane
|
12 |
+
//
|
13 |
+
|
14 |
+
// Front-to-back tilt
|
15 |
+
float tilt = resolution.y / 2.0 * uvNorm.y;
|
16 |
+
|
17 |
+
// Left-to-right angle
|
18 |
+
float incline = resolution.x * uvNorm.x / 2.0 * u_vertDeform.incline;
|
19 |
+
|
20 |
+
// Up-down shift to offset incline
|
21 |
+
float offset = resolution.x / 2.0 * u_vertDeform.incline * mix(u_vertDeform.offsetBottom, u_vertDeform.offsetTop, uv.y);
|
22 |
+
|
23 |
+
//
|
24 |
+
// Vertex noise
|
25 |
+
//
|
26 |
+
|
27 |
+
float noise = snoise(vec3(
|
28 |
+
noiseCoord.x * u_vertDeform.noiseFreq.x + time * u_vertDeform.noiseFlow,
|
29 |
+
noiseCoord.y * u_vertDeform.noiseFreq.y,
|
30 |
+
time * u_vertDeform.noiseSpeed + u_vertDeform.noiseSeed
|
31 |
+
)) * u_vertDeform.noiseAmp;
|
32 |
+
|
33 |
+
// Fade noise to zero at edges
|
34 |
+
noise *= 1.0 - pow(abs(uvNorm.y), 2.0);
|
35 |
+
|
36 |
+
// Clamp to 0
|
37 |
+
noise = max(0.0, noise);
|
38 |
+
|
39 |
+
vec3 pos = vec3(
|
40 |
+
position.x,
|
41 |
+
position.y + tilt + incline + noise - offset,
|
42 |
+
position.z
|
43 |
+
);
|
44 |
+
|
45 |
+
//
|
46 |
+
// Vertex color, to be passed to fragment shader
|
47 |
+
//
|
48 |
+
|
49 |
+
if (u_active_colors[0] == 1.) {
|
50 |
+
v_color = u_baseColor;
|
51 |
+
}
|
52 |
+
|
53 |
+
for (int i = 0; i < u_waveLayers_length; i++) {
|
54 |
+
if (u_active_colors[i + 1] == 1.) {
|
55 |
+
WaveLayers layer = u_waveLayers[i];
|
56 |
+
|
57 |
+
float noise = smoothstep(
|
58 |
+
layer.noiseFloor,
|
59 |
+
layer.noiseCeil,
|
60 |
+
snoise(vec3(
|
61 |
+
noiseCoord.x * layer.noiseFreq.x + time * layer.noiseFlow,
|
62 |
+
noiseCoord.y * layer.noiseFreq.y,
|
63 |
+
time * layer.noiseSpeed + layer.noiseSeed
|
64 |
+
)) / 2.0 + 0.5
|
65 |
+
);
|
66 |
+
|
67 |
+
v_color = blendNormal(v_color, layer.color, pow(noise, 4.));
|
68 |
+
}
|
69 |
+
}
|
70 |
+
|
71 |
+
//
|
72 |
+
// Finish
|
73 |
+
//
|
74 |
+
|
75 |
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
|
76 |
+
}
|
stripe-gradient-animation/src/ShadersJs/Blend.js
ADDED
@@ -0,0 +1,178 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export default `//
|
2 |
+
// https://github.com/jamieowen/glsl-blend
|
3 |
+
//
|
4 |
+
|
5 |
+
// Normal
|
6 |
+
|
7 |
+
vec3 blendNormal(vec3 base, vec3 blend) {
|
8 |
+
return blend;
|
9 |
+
}
|
10 |
+
|
11 |
+
vec3 blendNormal(vec3 base, vec3 blend, float opacity) {
|
12 |
+
return (blendNormal(base, blend) * opacity + base * (1.0 - opacity));
|
13 |
+
}
|
14 |
+
|
15 |
+
// Screen
|
16 |
+
|
17 |
+
float blendScreen(float base, float blend) {
|
18 |
+
return 1.0-((1.0-base)*(1.0-blend));
|
19 |
+
}
|
20 |
+
|
21 |
+
vec3 blendScreen(vec3 base, vec3 blend) {
|
22 |
+
return vec3(blendScreen(base.r,blend.r),blendScreen(base.g,blend.g),blendScreen(base.b,blend.b));
|
23 |
+
}
|
24 |
+
|
25 |
+
vec3 blendScreen(vec3 base, vec3 blend, float opacity) {
|
26 |
+
return (blendScreen(base, blend) * opacity + base * (1.0 - opacity));
|
27 |
+
}
|
28 |
+
|
29 |
+
// Multiply
|
30 |
+
|
31 |
+
vec3 blendMultiply(vec3 base, vec3 blend) {
|
32 |
+
return base*blend;
|
33 |
+
}
|
34 |
+
|
35 |
+
vec3 blendMultiply(vec3 base, vec3 blend, float opacity) {
|
36 |
+
return (blendMultiply(base, blend) * opacity + base * (1.0 - opacity));
|
37 |
+
}
|
38 |
+
|
39 |
+
// Overlay
|
40 |
+
|
41 |
+
float blendOverlay(float base, float blend) {
|
42 |
+
return base<0.5?(2.0*base*blend):(1.0-2.0*(1.0-base)*(1.0-blend));
|
43 |
+
}
|
44 |
+
|
45 |
+
vec3 blendOverlay(vec3 base, vec3 blend) {
|
46 |
+
return vec3(blendOverlay(base.r,blend.r),blendOverlay(base.g,blend.g),blendOverlay(base.b,blend.b));
|
47 |
+
}
|
48 |
+
|
49 |
+
vec3 blendOverlay(vec3 base, vec3 blend, float opacity) {
|
50 |
+
return (blendOverlay(base, blend) * opacity + base * (1.0 - opacity));
|
51 |
+
}
|
52 |
+
|
53 |
+
// Hard light
|
54 |
+
|
55 |
+
vec3 blendHardLight(vec3 base, vec3 blend) {
|
56 |
+
return blendOverlay(blend,base);
|
57 |
+
}
|
58 |
+
|
59 |
+
vec3 blendHardLight(vec3 base, vec3 blend, float opacity) {
|
60 |
+
return (blendHardLight(base, blend) * opacity + base * (1.0 - opacity));
|
61 |
+
}
|
62 |
+
|
63 |
+
// Soft light
|
64 |
+
|
65 |
+
float blendSoftLight(float base, float blend) {
|
66 |
+
return (blend<0.5)?(2.0*base*blend+base*base*(1.0-2.0*blend)):(sqrt(base)*(2.0*blend-1.0)+2.0*base*(1.0-blend));
|
67 |
+
}
|
68 |
+
|
69 |
+
vec3 blendSoftLight(vec3 base, vec3 blend) {
|
70 |
+
return vec3(blendSoftLight(base.r,blend.r),blendSoftLight(base.g,blend.g),blendSoftLight(base.b,blend.b));
|
71 |
+
}
|
72 |
+
|
73 |
+
vec3 blendSoftLight(vec3 base, vec3 blend, float opacity) {
|
74 |
+
return (blendSoftLight(base, blend) * opacity + base * (1.0 - opacity));
|
75 |
+
}
|
76 |
+
|
77 |
+
// Color dodge
|
78 |
+
|
79 |
+
float blendColorDodge(float base, float blend) {
|
80 |
+
return (blend==1.0)?blend:min(base/(1.0-blend),1.0);
|
81 |
+
}
|
82 |
+
|
83 |
+
vec3 blendColorDodge(vec3 base, vec3 blend) {
|
84 |
+
return vec3(blendColorDodge(base.r,blend.r),blendColorDodge(base.g,blend.g),blendColorDodge(base.b,blend.b));
|
85 |
+
}
|
86 |
+
|
87 |
+
vec3 blendColorDodge(vec3 base, vec3 blend, float opacity) {
|
88 |
+
return (blendColorDodge(base, blend) * opacity + base * (1.0 - opacity));
|
89 |
+
}
|
90 |
+
|
91 |
+
// Color burn
|
92 |
+
|
93 |
+
float blendColorBurn(float base, float blend) {
|
94 |
+
return (blend==0.0)?blend:max((1.0-((1.0-base)/blend)),0.0);
|
95 |
+
}
|
96 |
+
|
97 |
+
vec3 blendColorBurn(vec3 base, vec3 blend) {
|
98 |
+
return vec3(blendColorBurn(base.r,blend.r),blendColorBurn(base.g,blend.g),blendColorBurn(base.b,blend.b));
|
99 |
+
}
|
100 |
+
|
101 |
+
vec3 blendColorBurn(vec3 base, vec3 blend, float opacity) {
|
102 |
+
return (blendColorBurn(base, blend) * opacity + base * (1.0 - opacity));
|
103 |
+
}
|
104 |
+
|
105 |
+
// Vivid Light
|
106 |
+
|
107 |
+
float blendVividLight(float base, float blend) {
|
108 |
+
return (blend<0.5)?blendColorBurn(base,(2.0*blend)):blendColorDodge(base,(2.0*(blend-0.5)));
|
109 |
+
}
|
110 |
+
|
111 |
+
vec3 blendVividLight(vec3 base, vec3 blend) {
|
112 |
+
return vec3(blendVividLight(base.r,blend.r),blendVividLight(base.g,blend.g),blendVividLight(base.b,blend.b));
|
113 |
+
}
|
114 |
+
|
115 |
+
vec3 blendVividLight(vec3 base, vec3 blend, float opacity) {
|
116 |
+
return (blendVividLight(base, blend) * opacity + base * (1.0 - opacity));
|
117 |
+
}
|
118 |
+
|
119 |
+
// Lighten
|
120 |
+
|
121 |
+
float blendLighten(float base, float blend) {
|
122 |
+
return max(blend,base);
|
123 |
+
}
|
124 |
+
|
125 |
+
vec3 blendLighten(vec3 base, vec3 blend) {
|
126 |
+
return vec3(blendLighten(base.r,blend.r),blendLighten(base.g,blend.g),blendLighten(base.b,blend.b));
|
127 |
+
}
|
128 |
+
|
129 |
+
vec3 blendLighten(vec3 base, vec3 blend, float opacity) {
|
130 |
+
return (blendLighten(base, blend) * opacity + base * (1.0 - opacity));
|
131 |
+
}
|
132 |
+
|
133 |
+
// Linear burn
|
134 |
+
|
135 |
+
float blendLinearBurn(float base, float blend) {
|
136 |
+
// Note : Same implementation as BlendSubtractf
|
137 |
+
return max(base+blend-1.0,0.0);
|
138 |
+
}
|
139 |
+
|
140 |
+
vec3 blendLinearBurn(vec3 base, vec3 blend) {
|
141 |
+
// Note : Same implementation as BlendSubtract
|
142 |
+
return max(base+blend-vec3(1.0),vec3(0.0));
|
143 |
+
}
|
144 |
+
|
145 |
+
vec3 blendLinearBurn(vec3 base, vec3 blend, float opacity) {
|
146 |
+
return (blendLinearBurn(base, blend) * opacity + base * (1.0 - opacity));
|
147 |
+
}
|
148 |
+
|
149 |
+
// Linear dodge
|
150 |
+
|
151 |
+
float blendLinearDodge(float base, float blend) {
|
152 |
+
// Note : Same implementation as BlendAddf
|
153 |
+
return min(base+blend,1.0);
|
154 |
+
}
|
155 |
+
|
156 |
+
vec3 blendLinearDodge(vec3 base, vec3 blend) {
|
157 |
+
// Note : Same implementation as BlendAdd
|
158 |
+
return min(base+blend,vec3(1.0));
|
159 |
+
}
|
160 |
+
|
161 |
+
vec3 blendLinearDodge(vec3 base, vec3 blend, float opacity) {
|
162 |
+
return (blendLinearDodge(base, blend) * opacity + base * (1.0 - opacity));
|
163 |
+
}
|
164 |
+
|
165 |
+
// Linear light
|
166 |
+
|
167 |
+
float blendLinearLight(float base, float blend) {
|
168 |
+
return blend<0.5?blendLinearBurn(base,(2.0*blend)):blendLinearDodge(base,(2.0*(blend-0.5)));
|
169 |
+
}
|
170 |
+
|
171 |
+
vec3 blendLinearLight(vec3 base, vec3 blend) {
|
172 |
+
return vec3(blendLinearLight(base.r,blend.r),blendLinearLight(base.g,blend.g),blendLinearLight(base.b,blend.b));
|
173 |
+
}
|
174 |
+
|
175 |
+
vec3 blendLinearLight(vec3 base, vec3 blend, float opacity) {
|
176 |
+
return (blendLinearLight(base, blend) * opacity + base * (1.0 - opacity));
|
177 |
+
}
|
178 |
+
`;
|
stripe-gradient-animation/src/ShadersJs/Fragment.js
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export default `varying vec3 v_color;
|
2 |
+
|
3 |
+
void main() {
|
4 |
+
vec3 color = v_color;
|
5 |
+
if (u_darken_top == 1.0) {
|
6 |
+
vec2 st = gl_FragCoord.xy/resolution.xy;
|
7 |
+
color.g -= pow(st.y + sin(-12.0) * st.x, u_shadow_power) * 0.4;
|
8 |
+
}
|
9 |
+
gl_FragColor = vec4(color, 1.0);
|
10 |
+
}
|
11 |
+
`;
|
stripe-gradient-animation/src/ShadersJs/Noise.js
ADDED
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export default `//
|
2 |
+
// Description : Array and textureless GLSL 2D/3D/4D simplex
|
3 |
+
// noise functions.
|
4 |
+
// Author : Ian McEwan, Ashima Arts.
|
5 |
+
// Maintainer : stegu
|
6 |
+
// Lastmod : 20110822 (ijm)
|
7 |
+
// License : Copyright (C) 2011 Ashima Arts. All rights reserved.
|
8 |
+
// Distributed under the MIT License. See LICENSE file.
|
9 |
+
// https://github.com/ashima/webgl-noise
|
10 |
+
// https://github.com/stegu/webgl-noise
|
11 |
+
//
|
12 |
+
|
13 |
+
vec3 mod289(vec3 x) {
|
14 |
+
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
15 |
+
}
|
16 |
+
|
17 |
+
vec4 mod289(vec4 x) {
|
18 |
+
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
19 |
+
}
|
20 |
+
|
21 |
+
vec4 permute(vec4 x) {
|
22 |
+
return mod289(((x*34.0)+1.0)*x);
|
23 |
+
}
|
24 |
+
|
25 |
+
vec4 taylorInvSqrt(vec4 r)
|
26 |
+
{
|
27 |
+
return 1.79284291400159 - 0.85373472095314 * r;
|
28 |
+
}
|
29 |
+
|
30 |
+
float snoise(vec3 v)
|
31 |
+
{
|
32 |
+
const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;
|
33 |
+
const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
|
34 |
+
|
35 |
+
// First corner
|
36 |
+
vec3 i = floor(v + dot(v, C.yyy) );
|
37 |
+
vec3 x0 = v - i + dot(i, C.xxx) ;
|
38 |
+
|
39 |
+
// Other corners
|
40 |
+
vec3 g = step(x0.yzx, x0.xyz);
|
41 |
+
vec3 l = 1.0 - g;
|
42 |
+
vec3 i1 = min( g.xyz, l.zxy );
|
43 |
+
vec3 i2 = max( g.xyz, l.zxy );
|
44 |
+
|
45 |
+
// x0 = x0 - 0.0 + 0.0 * C.xxx;
|
46 |
+
// x1 = x0 - i1 + 1.0 * C.xxx;
|
47 |
+
// x2 = x0 - i2 + 2.0 * C.xxx;
|
48 |
+
// x3 = x0 - 1.0 + 3.0 * C.xxx;
|
49 |
+
vec3 x1 = x0 - i1 + C.xxx;
|
50 |
+
vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
|
51 |
+
vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y
|
52 |
+
|
53 |
+
// Permutations
|
54 |
+
i = mod289(i);
|
55 |
+
vec4 p = permute( permute( permute(
|
56 |
+
i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
|
57 |
+
+ i.y + vec4(0.0, i1.y, i2.y, 1.0 ))
|
58 |
+
+ i.x + vec4(0.0, i1.x, i2.x, 1.0 ));
|
59 |
+
|
60 |
+
// Gradients: 7x7 points over a square, mapped onto an octahedron.
|
61 |
+
// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
|
62 |
+
float n_ = 0.142857142857; // 1.0/7.0
|
63 |
+
vec3 ns = n_ * D.wyz - D.xzx;
|
64 |
+
|
65 |
+
vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)
|
66 |
+
|
67 |
+
vec4 x_ = floor(j * ns.z);
|
68 |
+
vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)
|
69 |
+
|
70 |
+
vec4 x = x_ *ns.x + ns.yyyy;
|
71 |
+
vec4 y = y_ *ns.x + ns.yyyy;
|
72 |
+
vec4 h = 1.0 - abs(x) - abs(y);
|
73 |
+
|
74 |
+
vec4 b0 = vec4( x.xy, y.xy );
|
75 |
+
vec4 b1 = vec4( x.zw, y.zw );
|
76 |
+
|
77 |
+
//vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
|
78 |
+
//vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
|
79 |
+
vec4 s0 = floor(b0)*2.0 + 1.0;
|
80 |
+
vec4 s1 = floor(b1)*2.0 + 1.0;
|
81 |
+
vec4 sh = -step(h, vec4(0.0));
|
82 |
+
|
83 |
+
vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
|
84 |
+
vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;
|
85 |
+
|
86 |
+
vec3 p0 = vec3(a0.xy,h.x);
|
87 |
+
vec3 p1 = vec3(a0.zw,h.y);
|
88 |
+
vec3 p2 = vec3(a1.xy,h.z);
|
89 |
+
vec3 p3 = vec3(a1.zw,h.w);
|
90 |
+
|
91 |
+
//Normalise gradients
|
92 |
+
vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
|
93 |
+
p0 *= norm.x;
|
94 |
+
p1 *= norm.y;
|
95 |
+
p2 *= norm.z;
|
96 |
+
p3 *= norm.w;
|
97 |
+
|
98 |
+
// Mix final noise value
|
99 |
+
vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
|
100 |
+
m = m * m;
|
101 |
+
return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),
|
102 |
+
dot(p2,x2), dot(p3,x3) ) );
|
103 |
+
}
|
104 |
+
`;
|
stripe-gradient-animation/src/ShadersJs/Vertex.js
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export default `varying vec3 v_color;
|
2 |
+
|
3 |
+
void main() {
|
4 |
+
float time = u_time * u_global.noiseSpeed;
|
5 |
+
|
6 |
+
vec2 noiseCoord = resolution * uvNorm * u_global.noiseFreq;
|
7 |
+
|
8 |
+
vec2 st = 1. - uvNorm.xy;
|
9 |
+
|
10 |
+
//
|
11 |
+
// Tilting the plane
|
12 |
+
//
|
13 |
+
|
14 |
+
// Front-to-back tilt
|
15 |
+
float tilt = resolution.y / 2.0 * uvNorm.y;
|
16 |
+
|
17 |
+
// Left-to-right angle
|
18 |
+
float incline = resolution.x * uvNorm.x / 2.0 * u_vertDeform.incline;
|
19 |
+
|
20 |
+
// Up-down shift to offset incline
|
21 |
+
float offset = resolution.x / 2.0 * u_vertDeform.incline * mix(u_vertDeform.offsetBottom, u_vertDeform.offsetTop, uv.y);
|
22 |
+
|
23 |
+
//
|
24 |
+
// Vertex noise
|
25 |
+
//
|
26 |
+
|
27 |
+
float noise = snoise(vec3(
|
28 |
+
noiseCoord.x * u_vertDeform.noiseFreq.x + time * u_vertDeform.noiseFlow,
|
29 |
+
noiseCoord.y * u_vertDeform.noiseFreq.y,
|
30 |
+
time * u_vertDeform.noiseSpeed + u_vertDeform.noiseSeed
|
31 |
+
)) * u_vertDeform.noiseAmp;
|
32 |
+
|
33 |
+
// Fade noise to zero at edges
|
34 |
+
noise *= 1.0 - pow(abs(uvNorm.y), 2.0);
|
35 |
+
|
36 |
+
// Clamp to 0
|
37 |
+
noise = max(0.0, noise);
|
38 |
+
|
39 |
+
vec3 pos = vec3(
|
40 |
+
position.x,
|
41 |
+
position.y + tilt + incline + noise - offset,
|
42 |
+
position.z
|
43 |
+
);
|
44 |
+
|
45 |
+
//
|
46 |
+
// Vertex color, to be passed to fragment shader
|
47 |
+
//
|
48 |
+
|
49 |
+
if (u_active_colors[0] == 1.) {
|
50 |
+
v_color = u_baseColor;
|
51 |
+
}
|
52 |
+
|
53 |
+
for (int i = 0; i < u_waveLayers_length; i++) {
|
54 |
+
if (u_active_colors[i + 1] == 1.) {
|
55 |
+
WaveLayers layer = u_waveLayers[i];
|
56 |
+
|
57 |
+
float noise = smoothstep(
|
58 |
+
layer.noiseFloor,
|
59 |
+
layer.noiseCeil,
|
60 |
+
snoise(vec3(
|
61 |
+
noiseCoord.x * layer.noiseFreq.x + time * layer.noiseFlow,
|
62 |
+
noiseCoord.y * layer.noiseFreq.y,
|
63 |
+
time * layer.noiseSpeed + layer.noiseSeed
|
64 |
+
)) / 2.0 + 0.5
|
65 |
+
);
|
66 |
+
|
67 |
+
v_color = blendNormal(v_color, layer.color, pow(noise, 4.));
|
68 |
+
}
|
69 |
+
}
|
70 |
+
|
71 |
+
//
|
72 |
+
// Finish
|
73 |
+
//
|
74 |
+
|
75 |
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
|
76 |
+
}
|
77 |
+
`;
|
stripe-gradient-animation/src/Uniform.js
ADDED
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export default class Uniform {
|
2 |
+
|
3 |
+
/**
|
4 |
+
* The parent MiniGL controller.
|
5 |
+
*
|
6 |
+
* @type {MiniGL}
|
7 |
+
* @private
|
8 |
+
*/
|
9 |
+
gl;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @type {string}
|
13 |
+
*/
|
14 |
+
type;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @type {*}
|
18 |
+
*/
|
19 |
+
value;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* The mapped type function.
|
23 |
+
*
|
24 |
+
* @type {string}
|
25 |
+
*/
|
26 |
+
typeFn;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Type function mappings.
|
30 |
+
*
|
31 |
+
* @type {object}
|
32 |
+
* @private
|
33 |
+
*/
|
34 |
+
_typeMap = {
|
35 |
+
float: '1f',
|
36 |
+
int: '1i',
|
37 |
+
vec2: '2fv',
|
38 |
+
vec3: '3fv',
|
39 |
+
vec4: '4fv',
|
40 |
+
mat4: 'Matrix4fv'
|
41 |
+
};
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @param {MiniGL} minigl
|
45 |
+
* @param {string} type
|
46 |
+
* @param {*} value
|
47 |
+
* @param {object} properties
|
48 |
+
*/
|
49 |
+
constructor(minigl, type, value, properties = {}) {
|
50 |
+
|
51 |
+
// Add additional properties i.e. excludeFrom, transpose... etc
|
52 |
+
Object.assign(this, properties);
|
53 |
+
|
54 |
+
// Set required properties.
|
55 |
+
this.gl = minigl;
|
56 |
+
this.type = type;
|
57 |
+
this.value = value;
|
58 |
+
|
59 |
+
// Get type function from map.
|
60 |
+
this.typeFn = this._typeMap[this.type] || this._typeMap.float;
|
61 |
+
|
62 |
+
// Update.
|
63 |
+
this.update();
|
64 |
+
}
|
65 |
+
|
66 |
+
update(value) {
|
67 |
+
if (this.value) {
|
68 |
+
|
69 |
+
var paramB = this.value;
|
70 |
+
var paramC = null;
|
71 |
+
|
72 |
+
if (this.typeFn.indexOf('Matrix') === 0) {
|
73 |
+
paramB = this.transpose;
|
74 |
+
paramC = this.value;
|
75 |
+
}
|
76 |
+
|
77 |
+
this.gl.getContext()[`uniform${this.typeFn}`](value, paramB, paramC);
|
78 |
+
}
|
79 |
+
}
|
80 |
+
|
81 |
+
getDeclaration(name, type, length) {
|
82 |
+
if (this.excludeFrom !== type) {
|
83 |
+
|
84 |
+
if (this.type === 'array') {
|
85 |
+
return `${this.value[0].getDeclaration(name, type, this.value.length)}
|
86 |
+
const int ${name}_length = ${this.value.length};`;
|
87 |
+
}
|
88 |
+
|
89 |
+
if (this.type === 'struct') {
|
90 |
+
let namePrefix = name.replace('u_', '');
|
91 |
+
namePrefix = namePrefix.charAt(0).toUpperCase() + namePrefix.slice(1);
|
92 |
+
|
93 |
+
const declaration = Object.entries(this.value).map(([name, uniform]) => {
|
94 |
+
return uniform.getDeclaration(name, type).replace(/^uniform/, '');
|
95 |
+
}).join('');
|
96 |
+
|
97 |
+
return `uniform struct ${namePrefix} {
|
98 |
+
${declaration}
|
99 |
+
} ${name}${ length > 0 ? `[${length}]` : '' };`;
|
100 |
+
|
101 |
+
}
|
102 |
+
|
103 |
+
return `uniform ${this.type} ${name}${ length > 0 ? `[${length}]` : '' };`
|
104 |
+
}
|
105 |
+
}
|
106 |
+
|
107 |
+
}
|
stripe-gradient-animation/webpack.mix.js
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
const mix = require( 'laravel-mix' );
|
2 |
+
|
3 |
+
mix.setPublicPath( './dist' );
|
4 |
+
mix.js( 'src/Gradient.js', 'stripe-gradient.js' );
|