Repository: codrops/ScrollSpiral
Branch: master
Commit: 3889131fea11
Files: 23
Total size: 73.6 KB
Directory structure:
gitextract_uisuplp9/
├── .gitignore
├── README.md
├── css/
│ ├── demo.css
│ └── normalize.css
├── index.html
├── index2.html
├── index3.html
├── index4.html
├── index5.html
├── index6.html
├── index7.html
├── index8.html
├── index9.html
├── js/
│ ├── demo1.js
│ ├── demo2.js
│ ├── demo3.js
│ ├── demo4.js
│ ├── demo5.js
│ ├── demo6.js
│ ├── demo7.js
│ ├── demo8.js
│ └── demo9.js
└── psd/
└── gradient_map.psd
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
*.DS_Store
# Windows thumbnail cache files
Thumbs.db
ehthumbs.db
ehthumbs_vista.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Windows shortcuts
*.lnk
# Dropbox settings and caches
.dropbox
.dropbox.attr
.dropbox.cache
================================================
FILE: README.md
================================================
# WebGL Scroll Spiral
Some decorative background scroll effects for websites using WebGL and regl. By Xoihazard.

[Article on Codrops](https://tympanus.net/codrops/?p=30761)
[Demo](https://tympanus.net/Development/ScrollSpiral/)
## Credits
- [Official regl website](http://regl.party)
- Images copyright by [RuleByArt](https://creativemarket.com/RuleByArt?u=codrops). Purchase on Creative Market: [Flight](https://creativemarket.com/RuleByArt/468537-Flight?u=codrops) and [Surface Shapes](https://creativemarket.com/RuleByArt/32279-Surface-Shapes?u=codrops)
## License
This resource can be used freely if integrated or build upon in personal or commercial projects such as websites, web apps and web templates intended for sale. It is not allowed to take the resource "as-is" and sell it, redistribute, re-publish it, or sell "pluginized" versions of it. Free plugins built using this resource should have a visible mention and link to the original work. Always consider the licenses of all included libraries, scripts and images used.
## Misc
Follow Codrops: [Twitter](http://www.twitter.com/codrops), [Facebook](http://www.facebook.com/codrops), [Google+](https://plus.google.com/101095823814290637419), [GitHub](https://github.com/codrops), [Pinterest](http://www.pinterest.com/codrops/), [Instagram](https://www.instagram.com/codropsss/)
[© Codrops 2017](http://www.codrops.com)
================================================
FILE: css/demo.css
================================================
*,
*::after,
*::before {
box-sizing: border-box;
}
body {
font-family: 'Roboto Mono', monospace;
color: #fff;
background: #000;
}
a {
text-decoration: none;
color: #fff;
outline: none;
}
a:hover,
a:focus {
color: #fff;
}
.hidden {
position: absolute;
overflow: hidden;
width: 0;
height: 0;
pointer-events: none;
}
/* Overlay */
main::before {
content: '';
position: fixed;
z-index: -1;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
background: rgba(0,0,0,0.4);
}
/* Icons */
.icon {
display: block;
width: 1.5em;
height: 1.5em;
margin: 0 auto;
fill: currentColor;
}
/* Page Loader */
.js .loading::before {
content: '';
position: fixed;
z-index: 1000;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #000;
}
.js .loading::after {
content: '';
position: fixed;
z-index: 1001;
top: 50%;
left: 50%;
width: 50px;
height: 50px;
margin: -25px 0 0 -25px;
pointer-events: none;
border-radius: 50%;
background: #3b3b3b;
animation: loaderAnim 0.8s ease-out infinite alternate forwards;
}
@keyframes loaderAnim {
to {
transform: scale3d(0.5,0.5,1);
}
}
.content {
display: flex;
flex-wrap: wrap;
min-height: 100vh;
}
.content--main {
min-height: 500vh;
}
.content--main::before,
.content--main::after {
position: fixed;
left: 50%;
}
.content--main::before {
content: '';
bottom: 3em;
height: 1.5em;
width: 1px;
background: #fff;
}
.content--main::after {
content: 'Scroll';
position: fixed;
bottom: 0;
width: 6em;
text-align: center;
margin: 0 0 1.5em -3em;
font-size: 0.75em;
text-transform: uppercase;
letter-spacing: 2px;
text-indent: 2px;
}
.content--header {
position: relative;
z-index: 11;
align-items: flex-start;
width: 100%;
padding: 1.5em;
}
.content__top {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
width: 100%;
}
.main-title {
font-size: 1em;
font-weight: normal;
margin: 0;
padding: 0;
}
.main-tagline {
font-size: 0.865em;
margin: 0 1em;
opacity: 0.8;
}
.main-tagline::before,
.main-tagline::after {
content: ' // ';
}
.github {
font-size: 0.865em;
}
/* Top Navigation Style */
.codrops-links {
position: relative;
display: flex;
justify-content: center;
margin: 0 0 0 auto;
text-align: center;
white-space: nowrap;
}
.codrops-icon {
display: inline-block;
margin: 0.25em;
padding: 0.5em;
}
/* Demo links */
.demos {
position: fixed;
top: 6em;
left: 0;
display: flex;
flex-direction: column;
align-items: flex-start;
padding: 0 1.25em;
}
.demo {
font-size: 0.865em;
position: relative;
margin: 0 1em 0.5em 0;
padding: 0 0 0.25em 0.25em;
white-space: nowrap;
}
.demo:hover,
.demo--current {
text-decoration: underline;
}
/* Related demos */
.content--related {
position: relative;
z-index: 10;
justify-content: center;
padding: 3em 1.5em;
text-align: center;
background: #000;
align-content: center;
}
.content--related a,
.github {
text-decoration: underline;
}
.content--related a:hover,
.content--related a:focus,
.github:hover,
.github:focus {
text-decoration: none;
}
.content__text {
font-size: 0.865em;
font-weight: normal;
width: 100%;
margin: 0 0 1em 0;
}
.content__text:first-child {
margin: 0 0 5em 0;
}
.media-item {
display: inline-block;
padding: 1em;
vertical-align: top;
transition: color 0.3s;
}
.media-item__img {
max-width: 100%;
opacity: 0.6;
transition: opacity 0.3s;
}
.media-item:hover .media-item__img,
.media-item:focus .media-item__img {
opacity: 1;
}
.media-item__title {
font-size: 0.865em;
font-weight: normal;
max-width: 200px;
margin: 0;
padding: 0.5em;
}
#webgl {
position: fixed;
z-index: -1;
top: 0;
left: 0;
display: block;
width: 100vw;
height: 100vh;
}
/* Colors for demos */
/* Demo 2 */
.demo-2 {
background: #5ae6ae;
}
.demo-2 main::before {
background: rgba(60, 145, 110, 0.3);
}
.demo-2 .content--related {
background: #5ae6ae;
}
/* Demo 3 */
.demo-3 {
background: #d8d9cd;
}
.demo-3 main::before {
background: rgba(169, 175, 66, 0.3);
}
.demo-3 .content--related {
background: #d8d9cd;
}
/* Demo 4 */
.demo-4 {
background: #babed1;
}
.demo-4 main::before {
background: rgba(175, 179, 194, 0.3);
}
.demo-4 .content--related {
background: #babed1;
}
/* Demo 5 */
.demo-5 {
background: #000;
}
.demo-5 main::before {
background: rgba(0,0,0,0.4);
}
.demo-5 .content--related {
background: #000;
}
/* Demo 6 */
.demo-6 {
background: #e8dac5;
}
.demo-6 main::before {
background: rgba(0, 0, 0, 0.3);
}
.demo-6 .content--related {
background: #e8dac5;
}
/* Demo 7 */
.demo-7 {
background: #000;
}
.demo-7 main::before {
background: rgba(0, 0, 0, 0.6);
}
.demo-7 .content--related {
background: #000;
}
/* Demo 8 */
.demo-8 {
background: #232121;
}
.demo-8 main::before {
background: rgba(84, 115, 243, 0.3);
}
.demo-8 .content--related {
background: #232121;
}
/* Demo 9 */
.demo-9 {
background: #232121;
}
.demo-9 main::before {
background: rgba(0, 0, 0, 0.3);
}
.demo-9 .content--related {
background: #2a2acf;
}
@media screen and (max-width: 40em) {
.content--header {
padding: 1em 0.5em 0;
}
.content__top {
display: block;
text-align: center;
}
.main-tagline {
margin: 0;
}
.demos {
position: relative;
width: 100%;
margin: 0;
padding: 0.5em;
transform: none;
top: auto;
display: block;
}
}
================================================
FILE: css/normalize.css
================================================
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block;}audio,canvas,video{display:inline-block;}audio:not([controls]){display:none;height:0;}[hidden]{display:none;}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;}body{margin:0;}a:focus{outline:thin dotted;}a:active,a:hover{outline:0;}h1{font-size:2em;margin:0.67em 0;}abbr[title]{border-bottom:1px dotted;}b,strong{font-weight:bold;}dfn{font-style:italic;}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0;}mark{background:#ff0;color:#000;}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em;}pre{white-space:pre-wrap;}q{quotes:"\201C" "\201D" "\2018" "\2019";}small{font-size:80%;}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sup{top:-0.5em;}sub{bottom:-0.25em;}img{border:0;}svg:not(:root){overflow:hidden;}figure{margin:0;}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em;}legend{border:0;padding:0;}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0;}button,input{line-height:normal;}button,select{text-transform:none;}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;}button[disabled],html input[disabled]{cursor:default;}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none;}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}textarea{overflow:auto;vertical-align:top;}table{border-collapse:collapse;border-spacing:0;}
================================================
FILE: index.html
================================================
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>WebGL Scroll Spiral | Demo 1 | Codrops</title>
<meta name="description" content="Some decorative background scroll effects for websites using WebGL and regl" />
<meta name="keywords" content="regl, webgl, background, website, decorative, scroll effect, spiral, distortion " />
<meta name="author" content="Codrops" />
<link rel="shortcut icon" href="favicon.ico">
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono:400,700" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="css/normalize.css" />
<link rel="stylesheet" type="text/css" href="css/demo.css" />
<script>document.documentElement.className = 'js';</script>
</head>
<body class="demo-1 loading">
<canvas id="webgl"></canvas>
<svg class="hidden">
<symbol id="icon-arrow" viewBox="0 0 24 24">
<title>arrow</title>
<polygon points="6.3,12.8 20.9,12.8 20.9,11.2 6.3,11.2 10.2,7.2 9,6 3.1,12 9,18 10.2,16.8 " />
</symbol>
<symbol id="icon-drop" viewBox="0 0 24 24">
<title>drop</title>
<path d="M12,21c-3.6,0-6.6-3-6.6-6.6C5.4,11,10.8,4,11.4,3.2C11.6,3.1,11.8,3,12,3s0.4,0.1,0.6,0.3c0.6,0.8,6.1,7.8,6.1,11.2C18.6,18.1,15.6,21,12,21zM12,4.8c-1.8,2.4-5.2,7.4-5.2,9.6c0,2.9,2.3,5.2,5.2,5.2s5.2-2.3,5.2-5.2C17.2,12.2,13.8,7.3,12,4.8z" />
<path d="M12,18.2c-0.4,0-0.7-0.3-0.7-0.7s0.3-0.7,0.7-0.7c1.3,0,2.4-1.1,2.4-2.4c0-0.4,0.3-0.7,0.7-0.7c0.4,0,0.7,0.3,0.7,0.7C15.8,16.5,14.1,18.2,12,18.2z" />
</symbol>
</svg>
<main>
<header class="content content--header">
<div class="content__top">
<h1 class="main-title">Scroll Spirals</h1>
<p class="main-tagline">Decorative Background Effects with WebGL</p>
<a class="github" href="https://github.com/codrops/ScrollSpiral/">GitHub</a>
<div class="codrops-links">
<a class="codrops-icon codrops-icon--prev" href="https://tympanus.net/Development/DeveloperDesignerPageLayout/" title="Previous Demo"><svg class="icon icon--arrow"><use xlink:href="#icon-arrow"></use></svg></a>
<a class="codrops-icon codrops-icon--drop" href="https://tympanus.net/codrops/?p=30761" title="Back to the article"><svg class="icon icon--drop"><use xlink:href="#icon-drop"></use></svg></a>
</div>
<nav class="demos">
<a class="demo demo--current" href="index.html">Demo 1</a>
<a class="demo" href="index2.html">Demo 2</a>
<a class="demo" href="index3.html">Demo 3</a>
<a class="demo" href="index4.html">Demo 4</a>
<a class="demo" href="index5.html">Demo 5</a>
<a class="demo" href="index6.html">Demo 6</a>
<a class="demo" href="index7.html">Demo 7</a>
<a class="demo" href="index8.html">Demo 8</a>
<a class="demo" href="index9.html">Demo 9</a>
</nav>
</div>
</header>
<section class="content content--main"></section>
<section class="content content--related">
<p class="content__text">This demo is powered by <a href="http://regl.party/">regl — declarative and stateless webgl</a></p>
<h3 class="content__text">If you enjoyed this demo you might also like:</h3>
<a class="media-item" href="https://tympanus.net/Development/AnimatedHeaderBackgrounds/">
<img class="media-item__img" src="img/related/AnimatedHeaderBackgrounds.png">
<h3 class="media-item__title">Animated Background Headers</h3>
</a>
<a class="media-item" href="https://tympanus.net/Tutorials/PrismEffectSlider/">
<img class="media-item__img" src="img/related/PrismEffectSlider.jpg">
<h3 class="media-item__title">Prism Effect Slider</h3>
</a>
</section>
</main>
<script src="js/regl.min.js"></script>
<script type="x-shader/x-fragment" id="fragmentShader">
#define TWO_PI 6.2831853072
#define PI 3.14159265359
precision highp float;
uniform float globaltime;
uniform vec2 resolution;
uniform float aspect;
uniform float scroll;
uniform float velocity;
const float timescale = 0.15;
const float displace = 0.03;
const float gridSize = 20.0;
const int layers = 3;
const float detail = 2.0;
const float wave = 1.0;
vec2 rotate(vec2 v, float angle) {
float c = cos(angle);
float s = sin(angle);
return v * mat2(c, -s, s, c);
}
vec3 coordToHex(vec2 coord, float scale, float angle) {
vec2 c = rotate(coord, angle);
float q = (1.0 / 3.0 * sqrt(3.0) * c.x - 1.0 / 3.0 * c.y) * scale;
float r = 2.0 / 3.0 * c.y * scale;
return vec3(q, r, -q - r);
}
vec3 hexToCell(vec3 hex, float m) {
return fract(hex / m) * 2.0 - 1.0;
}
float absMax(vec3 v) {
return max(max(abs(v.x), abs(v.y)), abs(v.z));
}
float nsin(float value) {
return sin(value * TWO_PI) * 0.5 + 0.5;
}
float hexToFloat(vec3 hex, float amt) {
return mix(absMax(hex), 1.0 - length(hex) / sqrt(3.0), amt);
}
float calc(vec3 hex, float time, float len) {
float value = 0.0;
for (int i = 0; i < layers; i++) {
vec3 cell = hexToCell(hex, 1.0 + float(i));
value += nsin(
hexToFloat(
cell,
nsin(len * wave + time + float(i) / float(layers))
) * detail + nsin(time * 0.5)
);
}
return value / float(layers);
}
void main(void) {
vec2 tx = (gl_FragCoord.xy / resolution.xy - 0.5) * vec2(aspect, 1.0) * 2.0;
float time = globaltime * timescale - scroll;
float invScroll = 1.0 - scroll;
float rgb[3];
float len = 1.0 - length(tx) * 0.3;
float zoom = nsin(time * 0.1) + len * velocity * 3.0;
float angle = TWO_PI * nsin(time * 0.05) + PI * len * scroll;
vec3 hex = coordToHex(tx, gridSize * zoom, angle);
for (int i = 0; i < 3; i++) {
float time2 = time + float(i) * displace * invScroll;
rgb[i] = pow(calc(hex, time2, len), 3.0) * (0.2 + 0.8 * sin(PI * len * 0.5));
}
gl_FragColor = vec4(
rgb[0] * (1.0 - scroll * 0.2),
rgb[1] * invScroll,
(rgb[2] + 0.2) * invScroll,
1.0
);
}
</script>
<script src="js/demo1.js"></script>
</body>
</html>
================================================
FILE: index2.html
================================================
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>WebGL Scroll Spiral | Demo 2 | Codrops</title>
<meta name="description" content="Some decorative background scroll effects for websites using WebGL and regl" />
<meta name="keywords" content="regl, webgl, background, website, decorative, scroll effect, spiral, distortion " />
<meta name="author" content="Codrops" />
<link rel="shortcut icon" href="favicon.ico">
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono:400,700" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="css/normalize.css" />
<link rel="stylesheet" type="text/css" href="css/demo.css" />
<script>document.documentElement.className = 'js';</script>
</head>
<body class="demo-2 loading">
<canvas id="webgl"></canvas>
<svg class="hidden">
<symbol id="icon-arrow" viewBox="0 0 24 24">
<title>arrow</title>
<polygon points="6.3,12.8 20.9,12.8 20.9,11.2 6.3,11.2 10.2,7.2 9,6 3.1,12 9,18 10.2,16.8 " />
</symbol>
<symbol id="icon-drop" viewBox="0 0 24 24">
<title>drop</title>
<path d="M12,21c-3.6,0-6.6-3-6.6-6.6C5.4,11,10.8,4,11.4,3.2C11.6,3.1,11.8,3,12,3s0.4,0.1,0.6,0.3c0.6,0.8,6.1,7.8,6.1,11.2C18.6,18.1,15.6,21,12,21zM12,4.8c-1.8,2.4-5.2,7.4-5.2,9.6c0,2.9,2.3,5.2,5.2,5.2s5.2-2.3,5.2-5.2C17.2,12.2,13.8,7.3,12,4.8z" />
<path d="M12,18.2c-0.4,0-0.7-0.3-0.7-0.7s0.3-0.7,0.7-0.7c1.3,0,2.4-1.1,2.4-2.4c0-0.4,0.3-0.7,0.7-0.7c0.4,0,0.7,0.3,0.7,0.7C15.8,16.5,14.1,18.2,12,18.2z" />
</symbol>
</svg>
<main>
<header class="content content--header">
<div class="content__top">
<h1 class="main-title">Scroll Spirals</h1>
<p class="main-tagline">Decorative Background Effects with WebGL</p>
<a class="github" href="https://github.com/codrops/ScrollSpiral/">GitHub</a>
<div class="codrops-links">
<a class="codrops-icon codrops-icon--prev" href="https://tympanus.net/Development/DeveloperDesignerPageLayout/" title="Previous Demo"><svg class="icon icon--arrow"><use xlink:href="#icon-arrow"></use></svg></a>
<a class="codrops-icon codrops-icon--drop" href="https://tympanus.net/codrops/?p=30761" title="Back to the article"><svg class="icon icon--drop"><use xlink:href="#icon-drop"></use></svg></a>
</div>
<nav class="demos">
<a class="demo" href="index.html">Demo 1</a>
<a class="demo demo--current" href="index2.html">Demo 2</a>
<a class="demo" href="index3.html">Demo 3</a>
<a class="demo" href="index4.html">Demo 4</a>
<a class="demo" href="index5.html">Demo 5</a>
<a class="demo" href="index6.html">Demo 6</a>
<a class="demo" href="index7.html">Demo 7</a>
<a class="demo" href="index8.html">Demo 8</a>
<a class="demo" href="index9.html">Demo 9</a>
</nav>
</div>
</header>
<section class="content content--main"></section>
<section class="content content--related">
<p class="content__text">This demo is powered by <a href="http://regl.party/">regl — declarative and stateless webgl</a></p>
<h3 class="content__text">If you enjoyed this demo you might also like:</h3>
<a class="media-item" href="https://tympanus.net/Development/AnimatedHeaderBackgrounds/">
<img class="media-item__img" src="img/related/AnimatedHeaderBackgrounds.png">
<h3 class="media-item__title">Animated Background Headers</h3>
</a>
<a class="media-item" href="https://tympanus.net/Tutorials/PrismEffectSlider/">
<img class="media-item__img" src="img/related/PrismEffectSlider.jpg">
<h3 class="media-item__title">Prism Effect Slider</h3>
</a>
</section>
</main>
<script src="js/regl.min.js"></script>
<script type="x-shader/x-fragment" id="fragmentShader">
#define TWO_PI 6.2831853072
#define PI 3.14159265359
precision highp float;
uniform float globaltime;
uniform vec2 resolution;
uniform float aspect;
uniform float scroll;
uniform float velocity;
uniform sampler2D texture;
const float timescale = 0.1;
const float twist = 2.0;
vec2 rotate(vec2 v, float angle) {
float c = cos(angle);
float s = sin(angle);
return v * mat2(c, -s, s, c);
}
float nsin(float value) {
return sin(value * TWO_PI) * 0.5 + 0.5;
}
void main(void) {
float time = globaltime * timescale;
vec2 center = vec2(sin(TWO_PI * time * 0.2), cos(TWO_PI * time * 0.2)) * nsin(time * 0.3) * 0.5;
vec2 tx = (gl_FragCoord.xy / resolution.xy - 0.5 - center) * vec2(aspect, 1.0);
float len = 1.0 - length(tx);
float zoom = 1.0 + scroll - len * 3.0 * (1.0 - scroll) + len * velocity * 2.0;
vec4 imgColor = texture2D(
texture,
rotate(
(tx + center) * vec2(1.0, -1.0) * zoom,
twist * TWO_PI * nsin(len + time) * scroll + time
) + 0.5
);
gl_FragColor = imgColor;
}
</script>
<script src="js/demo2.js"></script>
</body>
</html>
================================================
FILE: index3.html
================================================
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>WebGL Scroll Spiral | Demo 2 | Codrops</title>
<meta name="description" content="Some decorative background scroll effects for websites using WebGL and regl" />
<meta name="keywords" content="regl, webgl, background, website, decorative, scroll effect, spiral, distortion " />
<meta name="author" content="Codrops" />
<link rel="shortcut icon" href="favicon.ico">
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono:400,700" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="css/normalize.css" />
<link rel="stylesheet" type="text/css" href="css/demo.css" />
<script>document.documentElement.className = 'js';</script>
</head>
<body class="demo-3 loading">
<canvas id="webgl"></canvas>
<svg class="hidden">
<symbol id="icon-arrow" viewBox="0 0 24 24">
<title>arrow</title>
<polygon points="6.3,12.8 20.9,12.8 20.9,11.2 6.3,11.2 10.2,7.2 9,6 3.1,12 9,18 10.2,16.8 " />
</symbol>
<symbol id="icon-drop" viewBox="0 0 24 24">
<title>drop</title>
<path d="M12,21c-3.6,0-6.6-3-6.6-6.6C5.4,11,10.8,4,11.4,3.2C11.6,3.1,11.8,3,12,3s0.4,0.1,0.6,0.3c0.6,0.8,6.1,7.8,6.1,11.2C18.6,18.1,15.6,21,12,21zM12,4.8c-1.8,2.4-5.2,7.4-5.2,9.6c0,2.9,2.3,5.2,5.2,5.2s5.2-2.3,5.2-5.2C17.2,12.2,13.8,7.3,12,4.8z" />
<path d="M12,18.2c-0.4,0-0.7-0.3-0.7-0.7s0.3-0.7,0.7-0.7c1.3,0,2.4-1.1,2.4-2.4c0-0.4,0.3-0.7,0.7-0.7c0.4,0,0.7,0.3,0.7,0.7C15.8,16.5,14.1,18.2,12,18.2z" />
</symbol>
</svg>
<main>
<header class="content content--header">
<div class="content__top">
<h1 class="main-title">Scroll Spirals</h1>
<p class="main-tagline">Decorative Background Effects with WebGL</p>
<a class="github" href="https://github.com/codrops/ScrollSpiral/">GitHub</a>
<div class="codrops-links">
<a class="codrops-icon codrops-icon--prev" href="https://tympanus.net/Development/DeveloperDesignerPageLayout/" title="Previous Demo"><svg class="icon icon--arrow"><use xlink:href="#icon-arrow"></use></svg></a>
<a class="codrops-icon codrops-icon--drop" href="https://tympanus.net/codrops/?p=30761" title="Back to the article"><svg class="icon icon--drop"><use xlink:href="#icon-drop"></use></svg></a>
</div>
<nav class="demos">
<a class="demo" href="index.html">Demo 1</a>
<a class="demo" href="index2.html">Demo 2</a>
<a class="demo demo--current" href="index3.html">Demo 3</a>
<a class="demo" href="index4.html">Demo 4</a>
<a class="demo" href="index5.html">Demo 5</a>
<a class="demo" href="index6.html">Demo 6</a>
<a class="demo" href="index7.html">Demo 7</a>
<a class="demo" href="index8.html">Demo 8</a>
<a class="demo" href="index9.html">Demo 9</a>
</nav>
</div>
</header>
<section class="content content--main"></section>
<section class="content content--related">
<p class="content__text">This demo is powered by <a href="http://regl.party/">regl — declarative and stateless webgl</a></p>
<h3 class="content__text">If you enjoyed this demo you might also like:</h3>
<a class="media-item" href="https://tympanus.net/Development/AnimatedHeaderBackgrounds/">
<img class="media-item__img" src="img/related/AnimatedHeaderBackgrounds.png">
<h3 class="media-item__title">Animated Background Headers</h3>
</a>
<a class="media-item" href="https://tympanus.net/Tutorials/PrismEffectSlider/">
<img class="media-item__img" src="img/related/PrismEffectSlider.jpg">
<h3 class="media-item__title">Prism Effect Slider</h3>
</a>
</section>
</main>
<script src="js/regl.min.js"></script>
<script type="x-shader/x-fragment" id="fragmentShader">
#define TWO_PI 6.2831853072
#define PI 3.14159265359
precision highp float;
uniform float globaltime;
uniform vec2 resolution;
uniform float aspect;
uniform float scroll;
uniform float velocity;
uniform sampler2D texture;
const float timescale = 0.1;
const float twist = 2.0;
vec2 rotate(vec2 v, float angle) {
float c = cos(angle);
float s = sin(angle);
return v * mat2(c, -s, s, c);
}
float nsin(float value) {
return sin(value * TWO_PI) * 0.5 + 0.5;
}
void main(void) {
float time = globaltime * timescale;
vec2 center = vec2(sin(TWO_PI * time * 0.2), cos(TWO_PI * time * 0.2)) * nsin(time * 0.3) * 0.5;
vec2 tx = (gl_FragCoord.xy / resolution.xy - 0.5 - center) * vec2(aspect, 1.0);
float len = 1.0 - length(tx);
float zoom = 0.0 + scroll - len * 2.0 * (1.0 - scroll) + len * velocity;
vec4 imgColor = texture2D(
texture,
rotate(
(tx + center) * vec2(1.0, -1.0) * zoom,
twist * TWO_PI * nsin(len + time) * scroll + time
) + 0.5
);
gl_FragColor = imgColor;
}
</script>
<script src="js/demo3.js"></script>
</body>
</html>
================================================
FILE: index4.html
================================================
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>WebGL Scroll Spiral | Demo 2 | Codrops</title>
<meta name="description" content="Some decorative background scroll effects for websites using WebGL and regl" />
<meta name="keywords" content="regl, webgl, background, website, decorative, scroll effect, spiral, distortion " />
<meta name="author" content="Codrops" />
<link rel="shortcut icon" href="favicon.ico">
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono:400,700" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="css/normalize.css" />
<link rel="stylesheet" type="text/css" href="css/demo.css" />
<script>document.documentElement.className = 'js';</script>
</head>
<body class="demo-4 loading">
<canvas id="webgl"></canvas>
<svg class="hidden">
<symbol id="icon-arrow" viewBox="0 0 24 24">
<title>arrow</title>
<polygon points="6.3,12.8 20.9,12.8 20.9,11.2 6.3,11.2 10.2,7.2 9,6 3.1,12 9,18 10.2,16.8 " />
</symbol>
<symbol id="icon-drop" viewBox="0 0 24 24">
<title>drop</title>
<path d="M12,21c-3.6,0-6.6-3-6.6-6.6C5.4,11,10.8,4,11.4,3.2C11.6,3.1,11.8,3,12,3s0.4,0.1,0.6,0.3c0.6,0.8,6.1,7.8,6.1,11.2C18.6,18.1,15.6,21,12,21zM12,4.8c-1.8,2.4-5.2,7.4-5.2,9.6c0,2.9,2.3,5.2,5.2,5.2s5.2-2.3,5.2-5.2C17.2,12.2,13.8,7.3,12,4.8z" />
<path d="M12,18.2c-0.4,0-0.7-0.3-0.7-0.7s0.3-0.7,0.7-0.7c1.3,0,2.4-1.1,2.4-2.4c0-0.4,0.3-0.7,0.7-0.7c0.4,0,0.7,0.3,0.7,0.7C15.8,16.5,14.1,18.2,12,18.2z" />
</symbol>
</svg>
<main>
<header class="content content--header">
<div class="content__top">
<h1 class="main-title">Scroll Spirals</h1>
<p class="main-tagline">Decorative Background Effects with WebGL</p>
<a class="github" href="https://github.com/codrops/ScrollSpiral/">GitHub</a>
<div class="codrops-links">
<a class="codrops-icon codrops-icon--prev" href="https://tympanus.net/Development/DeveloperDesignerPageLayout/" title="Previous Demo"><svg class="icon icon--arrow"><use xlink:href="#icon-arrow"></use></svg></a>
<a class="codrops-icon codrops-icon--drop" href="https://tympanus.net/codrops/?p=30761" title="Back to the article"><svg class="icon icon--drop"><use xlink:href="#icon-drop"></use></svg></a>
</div>
<nav class="demos">
<a class="demo" href="index.html">Demo 1</a>
<a class="demo" href="index2.html">Demo 2</a>
<a class="demo" href="index3.html">Demo 3</a>
<a class="demo demo--current" href="index4.html">Demo 4</a>
<a class="demo" href="index5.html">Demo 5</a>
<a class="demo" href="index6.html">Demo 6</a>
<a class="demo" href="index7.html">Demo 7</a>
<a class="demo" href="index8.html">Demo 8</a>
<a class="demo" href="index9.html">Demo 9</a>
</nav>
</div>
</header>
<section class="content content--main"></section>
<section class="content content--related">
<p class="content__text">This demo is powered by <a href="http://regl.party/">regl — declarative and stateless webgl</a></p>
<h3 class="content__text">If you enjoyed this demo you might also like:</h3>
<a class="media-item" href="https://tympanus.net/Development/AnimatedHeaderBackgrounds/">
<img class="media-item__img" src="img/related/AnimatedHeaderBackgrounds.png">
<h3 class="media-item__title">Animated Background Headers</h3>
</a>
<a class="media-item" href="https://tympanus.net/Tutorials/PrismEffectSlider/">
<img class="media-item__img" src="img/related/PrismEffectSlider.jpg">
<h3 class="media-item__title">Prism Effect Slider</h3>
</a>
</section>
</main>
<script src="js/regl.min.js"></script>
<script type="x-shader/x-fragment" id="fragmentShader">
#define TWO_PI 6.2831853072
#define PI 3.14159265359
precision highp float;
uniform float globaltime;
uniform vec2 resolution;
uniform float aspect;
uniform float scroll;
uniform float velocity;
uniform sampler2D texture;
const float timescale = 0.1;
const float twist = 2.0;
vec2 rotate(vec2 v, float angle) {
float c = cos(angle);
float s = sin(angle);
return v * mat2(c, -s, s, c);
}
float nsin(float value) {
return sin(value * TWO_PI) * 0.5 + 0.5;
}
void main(void) {
float time = globaltime * timescale;
vec2 center = vec2(sin(TWO_PI * time * 0.2), cos(TWO_PI * time * 0.2)) * nsin(time * 0.3) * 0.5;
vec2 tx = (gl_FragCoord.xy / resolution.xy - 0.5 - center) * vec2(aspect, 1.0);
float len = length(tx);
float zoom = 1.0 + scroll - len * 10.0 * (1.0 - scroll) + len * velocity * 10.0;
vec4 imgColor = texture2D(
texture,
rotate(
(tx + center) * vec2(1.0, -1.0) * zoom,
twist * TWO_PI * nsin(len + time) * scroll + time
) + 0.5
);
gl_FragColor = imgColor;
}
</script>
<script src="js/demo4.js"></script>
</body>
</html>
================================================
FILE: index5.html
================================================
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>WebGL Scroll Spiral | Demo 2 | Codrops</title>
<meta name="description" content="Some decorative background scroll effects for websites using WebGL and regl" />
<meta name="keywords" content="regl, webgl, background, website, decorative, scroll effect, spiral, distortion " />
<meta name="author" content="Codrops" />
<link rel="shortcut icon" href="favicon.ico">
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono:400,700" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="css/normalize.css" />
<link rel="stylesheet" type="text/css" href="css/demo.css" />
<script>document.documentElement.className = 'js';</script>
</head>
<body class="demo-5 loading">
<canvas id="webgl"></canvas>
<svg class="hidden">
<symbol id="icon-arrow" viewBox="0 0 24 24">
<title>arrow</title>
<polygon points="6.3,12.8 20.9,12.8 20.9,11.2 6.3,11.2 10.2,7.2 9,6 3.1,12 9,18 10.2,16.8 " />
</symbol>
<symbol id="icon-drop" viewBox="0 0 24 24">
<title>drop</title>
<path d="M12,21c-3.6,0-6.6-3-6.6-6.6C5.4,11,10.8,4,11.4,3.2C11.6,3.1,11.8,3,12,3s0.4,0.1,0.6,0.3c0.6,0.8,6.1,7.8,6.1,11.2C18.6,18.1,15.6,21,12,21zM12,4.8c-1.8,2.4-5.2,7.4-5.2,9.6c0,2.9,2.3,5.2,5.2,5.2s5.2-2.3,5.2-5.2C17.2,12.2,13.8,7.3,12,4.8z" />
<path d="M12,18.2c-0.4,0-0.7-0.3-0.7-0.7s0.3-0.7,0.7-0.7c1.3,0,2.4-1.1,2.4-2.4c0-0.4,0.3-0.7,0.7-0.7c0.4,0,0.7,0.3,0.7,0.7C15.8,16.5,14.1,18.2,12,18.2z" />
</symbol>
</svg>
<main>
<header class="content content--header">
<div class="content__top">
<h1 class="main-title">Scroll Spirals</h1>
<p class="main-tagline">Decorative Background Effects with WebGL</p>
<a class="github" href="https://github.com/codrops/ScrollSpiral/">GitHub</a>
<div class="codrops-links">
<a class="codrops-icon codrops-icon--prev" href="https://tympanus.net/Development/DeveloperDesignerPageLayout/" title="Previous Demo"><svg class="icon icon--arrow"><use xlink:href="#icon-arrow"></use></svg></a>
<a class="codrops-icon codrops-icon--drop" href="https://tympanus.net/codrops/?p=30761" title="Back to the article"><svg class="icon icon--drop"><use xlink:href="#icon-drop"></use></svg></a>
</div>
<nav class="demos">
<a class="demo" href="index.html">Demo 1</a>
<a class="demo" href="index2.html">Demo 2</a>
<a class="demo" href="index3.html">Demo 3</a>
<a class="demo" href="index4.html">Demo 4</a>
<a class="demo demo--current" href="index5.html">Demo 5</a>
<a class="demo" href="index6.html">Demo 6</a>
<a class="demo" href="index7.html">Demo 7</a>
<a class="demo" href="index8.html">Demo 8</a>
<a class="demo" href="index9.html">Demo 9</a>
</nav>
</div>
</header>
<section class="content content--main"></section>
<section class="content content--related">
<p class="content__text">This demo is powered by <a href="http://regl.party/">regl — declarative and stateless webgl</a></p>
<h3 class="content__text">If you enjoyed this demo you might also like:</h3>
<a class="media-item" href="https://tympanus.net/Development/AnimatedHeaderBackgrounds/">
<img class="media-item__img" src="img/related/AnimatedHeaderBackgrounds.png">
<h3 class="media-item__title">Animated Background Headers</h3>
</a>
<a class="media-item" href="https://tympanus.net/Tutorials/PrismEffectSlider/">
<img class="media-item__img" src="img/related/PrismEffectSlider.jpg">
<h3 class="media-item__title">Prism Effect Slider</h3>
</a>
</section>
</main>
<script src="js/regl.min.js"></script>
<script type="x-shader/x-fragment" id="fragmentShader">
#define TWO_PI 6.2831853072
#define PI 3.14159265359
precision highp float;
uniform float globaltime;
uniform vec2 resolution;
uniform float aspect;
uniform float scroll;
uniform float velocity;
uniform sampler2D texture;
const float timescale = 0.1;
const float twist = 2.0;
vec2 rotate(vec2 v, float angle) {
float c = cos(angle);
float s = sin(angle);
return v * mat2(c, -s, s, c);
}
float nsin(float value) {
return sin(value * TWO_PI) * 0.5 + 0.5;
}
void main(void) {
float time = globaltime * timescale;
vec2 center = vec2(sin(TWO_PI * time * 0.2), cos(TWO_PI * time * 0.2)) * nsin(time * 0.3) * 0.5;
vec2 tx = (gl_FragCoord.xy / resolution.xy - 0.5 - center) * vec2(aspect, 1.0);
float len = 1.0 - length(tx);
float zoom = 1.0 + scroll - len * 3.0 * (1.0 - scroll) + len * velocity * 10.0;
vec4 imgColor = texture2D(
texture,
rotate(
(tx + center) * vec2(1.0, -1.0) * zoom,
twist * TWO_PI * nsin(len + time) * scroll + time
) + 0.5
);
gl_FragColor = imgColor;
}
</script>
<script src="js/demo5.js"></script>
</body>
</html>
================================================
FILE: index6.html
================================================
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>WebGL Scroll Spiral | Demo 3 | Codrops</title>
<meta name="description" content="Some decorative background scroll effects for websites using WebGL and regl" />
<meta name="keywords" content="regl, webgl, background, website, decorative, scroll effect, spiral, distortion " />
<meta name="author" content="Codrops" />
<link rel="shortcut icon" href="favicon.ico">
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono:400,700" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="css/normalize.css" />
<link rel="stylesheet" type="text/css" href="css/demo.css" />
<script>document.documentElement.className = 'js';</script>
</head>
<body class="demo-6 loading">
<canvas id="webgl"></canvas>
<svg class="hidden">
<symbol id="icon-arrow" viewBox="0 0 24 24">
<title>arrow</title>
<polygon points="6.3,12.8 20.9,12.8 20.9,11.2 6.3,11.2 10.2,7.2 9,6 3.1,12 9,18 10.2,16.8 " />
</symbol>
<symbol id="icon-drop" viewBox="0 0 24 24">
<title>drop</title>
<path d="M12,21c-3.6,0-6.6-3-6.6-6.6C5.4,11,10.8,4,11.4,3.2C11.6,3.1,11.8,3,12,3s0.4,0.1,0.6,0.3c0.6,0.8,6.1,7.8,6.1,11.2C18.6,18.1,15.6,21,12,21zM12,4.8c-1.8,2.4-5.2,7.4-5.2,9.6c0,2.9,2.3,5.2,5.2,5.2s5.2-2.3,5.2-5.2C17.2,12.2,13.8,7.3,12,4.8z" />
<path d="M12,18.2c-0.4,0-0.7-0.3-0.7-0.7s0.3-0.7,0.7-0.7c1.3,0,2.4-1.1,2.4-2.4c0-0.4,0.3-0.7,0.7-0.7c0.4,0,0.7,0.3,0.7,0.7C15.8,16.5,14.1,18.2,12,18.2z" />
</symbol>
</svg>
<main>
<header class="content content--header">
<div class="content__top">
<h1 class="main-title">Scroll Spirals</h1>
<p class="main-tagline">Decorative Background Effects with WebGL</p>
<a class="github" href="https://github.com/codrops/ScrollSpiral/">GitHub</a>
<div class="codrops-links">
<a class="codrops-icon codrops-icon--prev" href="https://tympanus.net/Development/DeveloperDesignerPageLayout/" title="Previous Demo"><svg class="icon icon--arrow"><use xlink:href="#icon-arrow"></use></svg></a>
<a class="codrops-icon codrops-icon--drop" href="https://tympanus.net/codrops/?p=30761" title="Back to the article"><svg class="icon icon--drop"><use xlink:href="#icon-drop"></use></svg></a>
</div>
<nav class="demos">
<a class="demo" href="index.html">Demo 1</a>
<a class="demo" href="index2.html">Demo 2</a>
<a class="demo" href="index3.html">Demo 3</a>
<a class="demo" href="index4.html">Demo 4</a>
<a class="demo" href="index5.html">Demo 5</a>
<a class="demo demo--current" href="index6.html">Demo 6</a>
<a class="demo" href="index7.html">Demo 7</a>
<a class="demo" href="index8.html">Demo 8</a>
<a class="demo" href="index9.html">Demo 9</a>
</nav>
</div>
</header>
<section class="content content--main"></section>
<section class="content content--related">
<p class="content__text">This demo is powered by <a href="http://regl.party/">regl — declarative and stateless webgl</a></p>
<h3 class="content__text">If you enjoyed this demo you might also like:</h3>
<a class="media-item" href="https://tympanus.net/Development/AnimatedHeaderBackgrounds/">
<img class="media-item__img" src="img/related/AnimatedHeaderBackgrounds.png">
<h3 class="media-item__title">Animated Background Headers</h3>
</a>
<a class="media-item" href="https://tympanus.net/Tutorials/PrismEffectSlider/">
<img class="media-item__img" src="img/related/PrismEffectSlider.jpg">
<h3 class="media-item__title">Prism Effect Slider</h3>
</a>
</section>
</main>
<script src="js/regl.min.js"></script>
<script type="x-shader/x-fragment" id="fragmentShader">
#define TWO_PI 6.2831853072
#define PI 3.14159265359
precision highp float;
uniform float globaltime;
uniform vec2 resolution;
uniform float aspect;
uniform float scroll;
uniform float velocity;
uniform sampler2D gradient;
const float timescale = 0.05;
float nsin(float value) {
return sin(value * TWO_PI) * 0.5 + 0.5;
}
vec2 rotate(vec2 v, float angle) {
float c = cos(angle);
float s = sin(angle);
return v * mat2(c, -s, s, c);
}
vec3 coordToHex(vec2 coord, float scale, float angle) {
vec2 c = rotate(coord, angle);
float q = (1.0 / 3.0 * sqrt(3.0) * c.x - 1.0 / 3.0 * c.y) * scale;
float r = 2.0 / 3.0 * c.y * scale;
return vec3(q, r, -q - r);
}
vec3 hexToCell(vec3 hex, float m) {
return fract(hex / m) * 2.0 - 1.0;
}
float absMax(vec3 v) {
return max(max(abs(v.x), abs(v.y)), abs(v.z));
}
float hexToFloat(vec3 hex, float amt) {
return mix(absMax(hex), 1.0 - length(hex) / sqrt(3.0), amt);
}
int getHexDir(vec3 hex) {
if (mod(floor(hex.x) - floor(hex.y) - floor(hex.z), 2.0) == 0.0) {
return 0;
} else {
return 1;
}
}
int getHexType(vec3 hex) {
if (mod(floor(hex.x) - floor(hex.y) - floor(hex.z), 3.0) == 0.0) {
return 0;
} else if (mod(floor(hex.x) - floor(hex.y) - floor(hex.z) - 1.0, 3.0) == 0.0) {
return 1;
} else {
return 2;
}
}
vec3 divideHex(vec3 hex, inout int age, float time) {
vec3 cell;
int dir = 0, type = 0;
float scale = 0.0;
for (int i = 0; i < 4; i++) {
scale = 1.0 + float(type) * nsin(time);
cell = hexToCell(hex * scale, 1.0);
dir = getHexDir(hex);
type = getHexType(hex);
hex = cell;
if (dir == 1 && type == 1) {
age = i;
break;
}
}
return cell;
}
void main(void) {
float time = globaltime * timescale;
vec2 center = vec2(sin(TWO_PI * time * 0.5), cos(TWO_PI * time * 0.5)) * nsin(time * 0.3) * 0.3;
vec2 tx = (gl_FragCoord.xy / resolution.xy - 0.5 + center) * vec2(aspect, 1.0) * 2.0;
float len = 1.0 - length(tx - center * 2.0) * 0.3;
float zoom = 15.0 + scroll * 0.5 * 20.0;
float angle = PI * scroll * len;
float value = 0.0;
int age = 0;
vec3 hex = coordToHex(tx, zoom, angle);
vec3 cell = divideHex(hex, age, time * 0.1);
float shift = float(age) / 3.0;
value = nsin(
hexToFloat(cell, nsin(time + shift)) * 0.1 * nsin(time * 0.5 + shift)
+ shift
+ time
) * len;
gl_FragColor = texture2D(gradient, vec2(0.0, value));
}
</script>
<script src="js/demo6.js"></script>
</body>
</html>
================================================
FILE: index7.html
================================================
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>WebGL Scroll Spiral | Demo 3 | Codrops</title>
<meta name="description" content="Some decorative background scroll effects for websites using WebGL and regl" />
<meta name="keywords" content="regl, webgl, background, website, decorative, scroll effect, spiral, distortion " />
<meta name="author" content="Codrops" />
<link rel="shortcut icon" href="favicon.ico">
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono:400,700" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="css/normalize.css" />
<link rel="stylesheet" type="text/css" href="css/demo.css" />
<script>document.documentElement.className = 'js';</script>
</head>
<body class="demo-7 loading">
<canvas id="webgl"></canvas>
<svg class="hidden">
<symbol id="icon-arrow" viewBox="0 0 24 24">
<title>arrow</title>
<polygon points="6.3,12.8 20.9,12.8 20.9,11.2 6.3,11.2 10.2,7.2 9,6 3.1,12 9,18 10.2,16.8 " />
</symbol>
<symbol id="icon-drop" viewBox="0 0 24 24">
<title>drop</title>
<path d="M12,21c-3.6,0-6.6-3-6.6-6.6C5.4,11,10.8,4,11.4,3.2C11.6,3.1,11.8,3,12,3s0.4,0.1,0.6,0.3c0.6,0.8,6.1,7.8,6.1,11.2C18.6,18.1,15.6,21,12,21zM12,4.8c-1.8,2.4-5.2,7.4-5.2,9.6c0,2.9,2.3,5.2,5.2,5.2s5.2-2.3,5.2-5.2C17.2,12.2,13.8,7.3,12,4.8z" />
<path d="M12,18.2c-0.4,0-0.7-0.3-0.7-0.7s0.3-0.7,0.7-0.7c1.3,0,2.4-1.1,2.4-2.4c0-0.4,0.3-0.7,0.7-0.7c0.4,0,0.7,0.3,0.7,0.7C15.8,16.5,14.1,18.2,12,18.2z" />
</symbol>
</svg>
<main>
<header class="content content--header">
<div class="content__top">
<h1 class="main-title">Scroll Spirals</h1>
<p class="main-tagline">Decorative Background Effects with WebGL</p>
<a class="github" href="https://github.com/codrops/ScrollSpiral/">GitHub</a>
<div class="codrops-links">
<a class="codrops-icon codrops-icon--prev" href="https://tympanus.net/Development/DeveloperDesignerPageLayout/" title="Previous Demo"><svg class="icon icon--arrow"><use xlink:href="#icon-arrow"></use></svg></a>
<a class="codrops-icon codrops-icon--drop" href="https://tympanus.net/codrops/?p=30761" title="Back to the article"><svg class="icon icon--drop"><use xlink:href="#icon-drop"></use></svg></a>
</div>
<nav class="demos">
<a class="demo" href="index.html">Demo 1</a>
<a class="demo" href="index2.html">Demo 2</a>
<a class="demo" href="index3.html">Demo 3</a>
<a class="demo" href="index4.html">Demo 4</a>
<a class="demo" href="index5.html">Demo 5</a>
<a class="demo" href="index6.html">Demo 6</a>
<a class="demo demo--current" href="index7.html">Demo 7</a>
<a class="demo" href="index8.html">Demo 8</a>
<a class="demo" href="index9.html">Demo 9</a>
</nav>
</div>
</header>
<section class="content content--main"></section>
<section class="content content--related">
<p class="content__text">This demo is powered by <a href="http://regl.party/">regl — declarative and stateless webgl</a></p>
<h3 class="content__text">If you enjoyed this demo you might also like:</h3>
<a class="media-item" href="https://tympanus.net/Development/AnimatedHeaderBackgrounds/">
<img class="media-item__img" src="img/related/AnimatedHeaderBackgrounds.png">
<h3 class="media-item__title">Animated Background Headers</h3>
</a>
<a class="media-item" href="https://tympanus.net/Tutorials/PrismEffectSlider/">
<img class="media-item__img" src="img/related/PrismEffectSlider.jpg">
<h3 class="media-item__title">Prism Effect Slider</h3>
</a>
</section>
</main>
<script src="js/regl.min.js"></script>
<script type="x-shader/x-fragment" id="fragmentShader">
#define TWO_PI 6.2831853072
#define PI 3.14159265359
precision highp float;
uniform float globaltime;
uniform vec2 resolution;
uniform float aspect;
uniform float scroll;
uniform float velocity;
uniform sampler2D gradient;
const float timescale = 0.05;
float nsin(float value) {
return sin(value * TWO_PI) * 0.5 + 0.5;
}
vec2 rotate(vec2 v, float angle) {
float c = cos(angle);
float s = sin(angle);
return v * mat2(c, -s, s, c);
}
vec3 coordToHex(vec2 coord, float scale, float angle) {
vec2 c = rotate(coord, angle);
float q = (1.0 / 3.0 * sqrt(3.0) * c.x - 1.0 / 3.0 * c.y) * scale;
float r = 2.0 / 3.0 * c.y * scale;
return vec3(q, r, -q - r);
}
vec3 hexToCell(vec3 hex, float m) {
return fract(hex / m) * 2.0 - 1.0;
}
float absMax(vec3 v) {
return max(max(abs(v.x), abs(v.y)), abs(v.z));
}
float hexToFloat(vec3 hex, float amt) {
return mix(absMax(hex), 1.0 - length(hex) / sqrt(3.0), amt);
}
int getHexDir(vec3 hex) {
if (mod(floor(hex.x) - floor(hex.y) - floor(hex.z), 2.0) == 0.0) {
return 0;
} else {
return 1;
}
}
int getHexType(vec3 hex) {
if (mod(floor(hex.x) - floor(hex.y) - floor(hex.z), 3.0) == 0.0) {
return 0;
} else if (mod(floor(hex.x) - floor(hex.y) - floor(hex.z) - 1.0, 3.0) == 0.0) {
return 1;
} else {
return 2;
}
}
vec3 divideHex(vec3 hex, inout int age, float time) {
vec3 cell;
int dir = 0, type = 0;
float scale = 0.0;
for (int i = 0; i < 4; i++) {
scale = 1.0 + float(type) * nsin(time);
cell = hexToCell(hex * scale, 1.0);
dir = getHexDir(hex);
type = getHexType(hex);
hex = cell;
if (dir == 1 && type == 1) {
age = i;
break;
}
}
return cell;
}
void main(void) {
float time = globaltime * timescale;
vec2 center = vec2(sin(TWO_PI * time * 0.5), cos(TWO_PI * time * 0.5)) * nsin(time * 0.3) * 0.5;
vec2 tx = (gl_FragCoord.xy / resolution.xy - 0.5 + center) * vec2(aspect, 1.0) * 2.0;
float len = 1.0 - length(tx - center * 2.0) * 0.3;
float zoom = 5.0 + scroll * 0.5 * 10.0;
float angle = PI * scroll * len;
float value = 0.0;
int age = 0;
vec3 hex = coordToHex(tx, zoom, angle);
vec3 cell = divideHex(hex, age, time * 0.1);
float shift = float(age) / 3.0;
value = nsin(
hexToFloat(cell, nsin(time + shift)) * 0.1 * nsin(time * 0.5 + shift)
+ shift
+ time
) * len;
gl_FragColor = texture2D(gradient, vec2(0.0, value));
}
</script>
<script src="js/demo7.js"></script>
</body>
</html>
================================================
FILE: index8.html
================================================
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>WebGL Scroll Spiral | Demo 3 | Codrops</title>
<meta name="description" content="Some decorative background scroll effects for websites using WebGL and regl" />
<meta name="keywords" content="regl, webgl, background, website, decorative, scroll effect, spiral, distortion " />
<meta name="author" content="Codrops" />
<link rel="shortcut icon" href="favicon.ico">
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono:400,700" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="css/normalize.css" />
<link rel="stylesheet" type="text/css" href="css/demo.css" />
<script>document.documentElement.className = 'js';</script>
</head>
<body class="demo-8 loading">
<canvas id="webgl"></canvas>
<svg class="hidden">
<symbol id="icon-arrow" viewBox="0 0 24 24">
<title>arrow</title>
<polygon points="6.3,12.8 20.9,12.8 20.9,11.2 6.3,11.2 10.2,7.2 9,6 3.1,12 9,18 10.2,16.8 " />
</symbol>
<symbol id="icon-drop" viewBox="0 0 24 24">
<title>drop</title>
<path d="M12,21c-3.6,0-6.6-3-6.6-6.6C5.4,11,10.8,4,11.4,3.2C11.6,3.1,11.8,3,12,3s0.4,0.1,0.6,0.3c0.6,0.8,6.1,7.8,6.1,11.2C18.6,18.1,15.6,21,12,21zM12,4.8c-1.8,2.4-5.2,7.4-5.2,9.6c0,2.9,2.3,5.2,5.2,5.2s5.2-2.3,5.2-5.2C17.2,12.2,13.8,7.3,12,4.8z" />
<path d="M12,18.2c-0.4,0-0.7-0.3-0.7-0.7s0.3-0.7,0.7-0.7c1.3,0,2.4-1.1,2.4-2.4c0-0.4,0.3-0.7,0.7-0.7c0.4,0,0.7,0.3,0.7,0.7C15.8,16.5,14.1,18.2,12,18.2z" />
</symbol>
</svg>
<main>
<header class="content content--header">
<div class="content__top">
<h1 class="main-title">Scroll Spirals</h1>
<p class="main-tagline">Decorative Background Effects with WebGL</p>
<a class="github" href="https://github.com/codrops/ScrollSpiral/">GitHub</a>
<div class="codrops-links">
<a class="codrops-icon codrops-icon--prev" href="https://tympanus.net/Development/DeveloperDesignerPageLayout/" title="Previous Demo"><svg class="icon icon--arrow"><use xlink:href="#icon-arrow"></use></svg></a>
<a class="codrops-icon codrops-icon--drop" href="https://tympanus.net/codrops/?p=30761" title="Back to the article"><svg class="icon icon--drop"><use xlink:href="#icon-drop"></use></svg></a>
</div>
<nav class="demos">
<a class="demo" href="index.html">Demo 1</a>
<a class="demo" href="index2.html">Demo 2</a>
<a class="demo" href="index3.html">Demo 3</a>
<a class="demo" href="index4.html">Demo 4</a>
<a class="demo" href="index5.html">Demo 5</a>
<a class="demo" href="index6.html">Demo 6</a>
<a class="demo" href="index7.html">Demo 7</a>
<a class="demo demo--current" href="index8.html">Demo 8</a>
<a class="demo" href="index9.html">Demo 9</a>
</nav>
</div>
</header>
<section class="content"></section>
<section class="content"></section>
<section class="content"></section>
<section class="content"></section>
<section class="content content--related">
<p class="content__text">This demo is powered by <a href="http://regl.party/">regl — declarative and stateless webgl</a></p>
<h3 class="content__text">If you enjoyed this demo you might also like:</h3>
<a class="media-item" href="https://tympanus.net/Development/AnimatedHeaderBackgrounds/">
<img class="media-item__img" src="img/related/AnimatedHeaderBackgrounds.png">
<h3 class="media-item__title">Animated Background Headers</h3>
</a>
<a class="media-item" href="https://tympanus.net/Tutorials/PrismEffectSlider/">
<img class="media-item__img" src="img/related/PrismEffectSlider.jpg">
<h3 class="media-item__title">Prism Effect Slider</h3>
</a>
</section>
</main>
<script src="js/regl.min.js"></script>
<script type="x-shader/x-fragment" id="fragmentShader">
#define TWO_PI 6.2831853072
#define PI 3.14159265359
precision highp float;
uniform float globaltime;
uniform vec2 resolution;
uniform float aspect;
uniform float scroll;
uniform float velocity;
uniform sampler2D gradient;
const float timescale = 0.05;
float nsin(float value) {
return sin(value * TWO_PI) * 0.5 + 0.5;
}
vec2 rotate(vec2 v, float angle) {
float c = cos(angle);
float s = sin(angle);
return v * mat2(c, -s, s, c);
}
vec3 coordToHex(vec2 coord, float scale, float angle) {
vec2 c = rotate(coord, angle);
float q = (1.0 / 3.0 * sqrt(3.0) * c.x - 1.0 / 3.0 * c.y) * scale;
float r = 2.0 / 3.0 * c.y * scale;
return vec3(q, r, -q - r);
}
vec3 hexToCell(vec3 hex, float m) {
return fract(hex / m) * 2.0 - 1.0;
}
float absMax(vec3 v) {
return max(max(abs(v.x), abs(v.y)), abs(v.z));
}
float hexToFloat(vec3 hex, float amt) {
return mix(absMax(hex), 1.0 - length(hex) / sqrt(3.0), amt);
}
int getHexDir(vec3 hex) {
if (mod(floor(hex.x) - floor(hex.y) - floor(hex.z), 2.0) == 0.0) {
return 0;
} else {
return 1;
}
}
int getHexType(vec3 hex) {
if (mod(floor(hex.x) - floor(hex.y) - floor(hex.z), 3.0) == 0.0) {
return 0;
} else if (mod(floor(hex.x) - floor(hex.y) - floor(hex.z) - 1.0, 3.0) == 0.0) {
return 1;
} else {
return 2;
}
}
vec3 divideHex(vec3 hex, inout int age, float time) {
vec3 cell;
int dir = 0, type = 0;
float scale = 0.0;
for (int i = 0; i < 4; i++) {
scale = 1.0 + float(type) * nsin(time);
cell = hexToCell(hex * scale, 1.0);
dir = getHexDir(hex);
type = getHexType(hex);
hex = cell;
if (dir == 1 && type == 1) {
age = i;
break;
}
}
return cell;
}
void main(void) {
float time = globaltime * timescale;
vec2 center = vec2(sin(TWO_PI * time * 0.5), cos(TWO_PI * time * 0.5)) * nsin(time * 0.3) * 0.3;
vec2 tx = (gl_FragCoord.xy / resolution.xy - 0.5 + center) * vec2(aspect, 1.0) * 2.0;
float len = 1.0 - length(tx - center * 2.0) * 0.3;
float zoom = 15.0 + scroll * 20.0;
float angle = PI * scroll * len;
float value = 0.0;
int age = 0;
vec3 hex = coordToHex(tx, zoom, angle);
vec3 cell = divideHex(hex, age, time * 0.1);
float shift = float(age) / 3.0;
value = nsin(
hexToFloat(cell, nsin(time + shift)) * 0.1 * nsin(time * 0.5 + shift)
+ shift
+ time
) * len;
gl_FragColor = texture2D(gradient, vec2(0.0, value));
}
</script>
<script src="js/demo8.js"></script>
</body>
</html>
================================================
FILE: index9.html
================================================
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>WebGL Scroll Spiral | Demo 1 | Codrops</title>
<meta name="description" content="Some decorative background scroll effects for websites using WebGL and regl" />
<meta name="keywords" content="regl, webgl, background, website, decorative, scroll effect, spiral, distortion " />
<meta name="author" content="Codrops" />
<link rel="shortcut icon" href="favicon.ico">
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono:400,700" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="css/normalize.css" />
<link rel="stylesheet" type="text/css" href="css/demo.css" />
<script>document.documentElement.className = 'js';</script>
</head>
<body class="demo-9 loading">
<canvas id="webgl"></canvas>
<svg class="hidden">
<symbol id="icon-arrow" viewBox="0 0 24 24">
<title>arrow</title>
<polygon points="6.3,12.8 20.9,12.8 20.9,11.2 6.3,11.2 10.2,7.2 9,6 3.1,12 9,18 10.2,16.8 " />
</symbol>
<symbol id="icon-drop" viewBox="0 0 24 24">
<title>drop</title>
<path d="M12,21c-3.6,0-6.6-3-6.6-6.6C5.4,11,10.8,4,11.4,3.2C11.6,3.1,11.8,3,12,3s0.4,0.1,0.6,0.3c0.6,0.8,6.1,7.8,6.1,11.2C18.6,18.1,15.6,21,12,21zM12,4.8c-1.8,2.4-5.2,7.4-5.2,9.6c0,2.9,2.3,5.2,5.2,5.2s5.2-2.3,5.2-5.2C17.2,12.2,13.8,7.3,12,4.8z" />
<path d="M12,18.2c-0.4,0-0.7-0.3-0.7-0.7s0.3-0.7,0.7-0.7c1.3,0,2.4-1.1,2.4-2.4c0-0.4,0.3-0.7,0.7-0.7c0.4,0,0.7,0.3,0.7,0.7C15.8,16.5,14.1,18.2,12,18.2z" />
</symbol>
</svg>
<main>
<header class="content content--header">
<div class="content__top">
<h1 class="main-title">Scroll Spirals</h1>
<p class="main-tagline">Decorative Background Effects with WebGL</p>
<a class="github" href="https://github.com/codrops/ScrollSpiral/">GitHub</a>
<div class="codrops-links">
<a class="codrops-icon codrops-icon--prev" href="https://tympanus.net/Development/DeveloperDesignerPageLayout/" title="Previous Demo"><svg class="icon icon--arrow"><use xlink:href="#icon-arrow"></use></svg></a>
<a class="codrops-icon codrops-icon--drop" href="https://tympanus.net/codrops/?p=30761" title="Back to the article"><svg class="icon icon--drop"><use xlink:href="#icon-drop"></use></svg></a>
</div>
<nav class="demos">
<a class="demo" href="index.html">Demo 1</a>
<a class="demo" href="index2.html">Demo 2</a>
<a class="demo" href="index3.html">Demo 3</a>
<a class="demo" href="index4.html">Demo 4</a>
<a class="demo" href="index5.html">Demo 5</a>
<a class="demo" href="index6.html">Demo 6</a>
<a class="demo" href="index7.html">Demo 7</a>
<a class="demo" href="index8.html">Demo 8</a>
<a class="demo demo--current" href="index9.html">Demo 9</a>
</nav>
</div>
</header>
<section class="content content--main"></section>
<section class="content content--related">
<p class="content__text">This demo is powered by <a href="http://regl.party/">regl — declarative and stateless webgl</a></p>
<h3 class="content__text">If you enjoyed this demo you might also like:</h3>
<a class="media-item" href="https://tympanus.net/Development/AnimatedHeaderBackgrounds/">
<img class="media-item__img" src="img/related/AnimatedHeaderBackgrounds.png">
<h3 class="media-item__title">Animated Background Headers</h3>
</a>
<a class="media-item" href="https://tympanus.net/Tutorials/PrismEffectSlider/">
<img class="media-item__img" src="img/related/PrismEffectSlider.jpg">
<h3 class="media-item__title">Prism Effect Slider</h3>
</a>
</section>
</main>
<script src="js/regl.min.js"></script>
<script type="x-shader/x-fragment" id="fragmentShader">
#define TWO_PI 6.2831853072
#define PI 3.14159265359
precision highp float;
uniform float globaltime;
uniform vec2 resolution;
uniform float aspect;
uniform float scroll;
uniform float velocity;
const float timescale = 0.05;
const float displace = 0.09;
const float gridSize = 15.0;
const int layers = 2;
const float detail = 4.0;
const float wave = 2.0;
vec2 rotate(vec2 v, float angle) {
float c = cos(angle);
float s = sin(angle);
return v * mat2(c, -s, s, c);
}
vec3 coordToHex(vec2 coord, float scale, float angle) {
vec2 c = rotate(coord, angle);
float q = (1.0 / 3.0 * sqrt(3.0) * c.x - 1.0 / 3.0 * c.y) * scale;
float r = 2.0 / 3.0 * c.y * scale;
return vec3(q, r, -q - r);
}
vec3 hexToCell(vec3 hex, float m) {
return fract(hex / m) * 2.0 - 1.0;
}
float absMax(vec3 v) {
return max(max(abs(v.x), abs(v.y)), abs(v.z));
}
float nsin(float value) {
return sin(value * TWO_PI) * 0.5 + 0.5;
}
float hexToFloat(vec3 hex, float amt) {
return mix(absMax(hex), 1.0 - length(hex) / sqrt(3.0), amt);
}
float calc(vec3 hex, float time, float len) {
float value = 0.0;
for (int i = 0; i < layers; i++) {
vec3 cell = hexToCell(hex, 1.0 + float(i));
value += nsin(
hexToFloat(
cell,
nsin(len * wave + time + float(i) / float(layers))
) * detail + nsin(time * 0.5)
);
}
return value / float(layers);
}
void main(void) {
vec2 tx = (gl_FragCoord.xy / resolution.xy - 0.5) * vec2(aspect, 1.0) * 2.0;
float time = globaltime * timescale - scroll;
float invScroll = 1.0 - scroll;
float rgb[3];
float len = length(tx) * 0.9;
float zoom = nsin(time * 0.1) + len * velocity;
float angle = TWO_PI * nsin(time * 0.05) + PI * len * scroll * -2.0;
vec3 hex = coordToHex(tx, gridSize * zoom, angle);
for (int i = 0; i < 3; i++) {
float time2 = time + float(i) * displace * scroll;
rgb[i] = pow(calc(hex, time2, len), 5.0) * (0.2 + 0.8 * sin(PI * len * 0.5));
}
gl_FragColor = vec4(
rgb[0] * invScroll,
rgb[1] * invScroll,
rgb[2] * scroll,
1.0
);
}
</script>
<script src="js/demo9.js"></script>
</body>
</html>
================================================
FILE: js/demo1.js
================================================
!function() {
'use strict';
var canvas = document.querySelector('#webgl');
// Scroll variables
var scroll = 0.0, velocity = 0.0, lastScroll = 0.0;
// initialize REGL from a canvas element
var regl = createREGL({
canvas: canvas,
onDone: function(error, regl) {
if (error) { alert(error); }
}
});
// Create a REGL draw command
var draw = regl({
frag: document.querySelector('#fragmentShader').textContent,
vert: 'attribute vec2 position; void main() { gl_Position = vec4(3.0 * position, 0.0, 1.0); }',
attributes: { position: [-1, 0, 0, -1, 1, 1] },
count: 3,
uniforms: {
globaltime: regl.prop('globaltime'),
resolution: regl.prop('resolution'),
aspect: regl.prop('aspect'),
scroll: regl.prop('scroll'),
velocity: regl.prop('velocity')
}
});
// Hook a callback to execute each frame
regl.frame(function(ctx) {
// Resize a canvas element with the aspect ratio (100vw, 100vh)
var aspect = canvas.scrollWidth / canvas.scrollHeight;
canvas.width = 512 * aspect;
canvas.height = 512;
// Scroll amount (0.0 to 1.0)
scroll = window.pageYOffset / (document.documentElement.scrollHeight - window.innerHeight);
// Scroll velocity
// Inertia example:
// velocity = velocity * 0.99 + (scroll - lastScroll);
// lastScroll = scroll;
// Clear the draw buffer
regl.clear({ color: [0, 0, 0, 0] });
// Execute a REGL draw command
draw({
globaltime: ctx.time,
resolution: [ctx.viewportWidth, ctx.viewportHeight],
aspect: aspect,
scroll: scroll,
velocity: velocity
});
});
setTimeout(function() { document.body.classList.remove('loading');}, 1000);
}();
================================================
FILE: js/demo2.js
================================================
!function() {
'use strict';
var canvas = document.querySelector('#webgl');
// Scroll variables
var scroll = 0.0, velocity = 0.0, lastScroll = 0.0;
// Initialize REGL from a canvas element
var regl = createREGL({
canvas: canvas,
onDone: function(error, regl) {
if (error) { alert(error); }
}
});
// Loading a texture
var img = new Image();
img.src = 'img/img1.jpg';
img.onload = function() {
setTimeout(function() { document.body.classList.remove('loading');}, 1000);
// Create a REGL draw command
var draw = regl({
frag: document.querySelector('#fragmentShader').textContent,
vert: 'attribute vec2 position; void main() { gl_Position = vec4(3.0 * position, 0.0, 1.0); }',
attributes: { position: [-1, 0, 0, -1, 1, 1] },
count: 3,
uniforms: {
globaltime: regl.prop('globaltime'),
resolution: regl.prop('resolution'),
aspect: regl.prop('aspect'),
scroll: regl.prop('scroll'),
velocity: regl.prop('velocity'),
texture: regl.texture(img)
}
});
// Hook a callback to execute each frame
regl.frame(function(ctx) {
// Resize a canvas element with the aspect ratio (100vw, 100vh)
var aspect = canvas.scrollWidth / canvas.scrollHeight;
canvas.width = 1024 * aspect;
canvas.height = 1024;
// Scroll amount (0.0 to 1.0)
scroll = window.pageYOffset / (document.documentElement.scrollHeight - window.innerHeight);
// Scroll Velocity
// Inertia example:
// velocity = velocity * 0.99 + (scroll - lastScroll);
// lastScroll = scroll;
// Clear the draw buffer
regl.clear({ color: [0, 0, 0, 0] });
// Execute a REGL draw command
draw({
globaltime: ctx.time,
resolution: [ctx.viewportWidth, ctx.viewportHeight],
aspect: aspect,
scroll: scroll,
velocity: velocity
});
});
};
}();
================================================
FILE: js/demo3.js
================================================
!function() {
'use strict';
var canvas = document.querySelector('#webgl');
// Scroll variables
var scroll = 0.0, velocity = 0.0, lastScroll = 0.0;
// Initialize REGL from a canvas element
var regl = createREGL({
canvas: canvas,
onDone: function(error, regl) {
if (error) { alert(error); }
}
});
// Loading a texture
var img = new Image();
img.src = 'img/img2.jpg';
img.onload = function() {
setTimeout(function() { document.body.classList.remove('loading');}, 1000);
// Create a REGL draw command
var draw = regl({
frag: document.querySelector('#fragmentShader').textContent,
vert: 'attribute vec2 position; void main() { gl_Position = vec4(3.0 * position, 0.0, 1.0); }',
attributes: { position: [-1, 0, 0, -1, 1, 1] },
count: 3,
uniforms: {
globaltime: regl.prop('globaltime'),
resolution: regl.prop('resolution'),
aspect: regl.prop('aspect'),
scroll: regl.prop('scroll'),
velocity: regl.prop('velocity'),
texture: regl.texture(img)
}
});
// Hook a callback to execute each frame
regl.frame(function(ctx) {
// Resize a canvas element with the aspect ratio (100vw, 100vh)
var aspect = canvas.scrollWidth / canvas.scrollHeight;
canvas.width = 1024 * aspect;
canvas.height = 1024;
// Scroll amount (0.0 to 1.0)
scroll = window.pageYOffset / (document.documentElement.scrollHeight - window.innerHeight);
// Scroll Velocity
// Inertia example:
// velocity = velocity * 0.99 + (scroll - lastScroll);
// lastScroll = scroll;
// Clear the draw buffer
regl.clear({ color: [0, 0, 0, 0] });
// Execute a REGL draw command
draw({
globaltime: ctx.time,
resolution: [ctx.viewportWidth, ctx.viewportHeight],
aspect: aspect,
scroll: scroll,
velocity: velocity
});
});
};
}();
================================================
FILE: js/demo4.js
================================================
!function() {
'use strict';
var canvas = document.querySelector('#webgl');
// Scroll variables
var scroll = 0.0, velocity = 0.0, lastScroll = 0.0;
// Initialize REGL from a canvas element
var regl = createREGL({
canvas: canvas,
onDone: function(error, regl) {
if (error) { alert(error); }
}
});
// Loading a texture
var img = new Image();
img.src = 'img/img3.jpg';
img.onload = function() {
setTimeout(function() { document.body.classList.remove('loading');}, 1000);
// Create a REGL draw command
var draw = regl({
frag: document.querySelector('#fragmentShader').textContent,
vert: 'attribute vec2 position; void main() { gl_Position = vec4(3.0 * position, 0.0, 1.0); }',
attributes: { position: [-1, 0, 0, -1, 1, 1] },
count: 3,
uniforms: {
globaltime: regl.prop('globaltime'),
resolution: regl.prop('resolution'),
aspect: regl.prop('aspect'),
scroll: regl.prop('scroll'),
velocity: regl.prop('velocity'),
texture: regl.texture(img)
}
});
// Hook a callback to execute each frame
regl.frame(function(ctx) {
// Resize a canvas element with the aspect ratio (100vw, 100vh)
var aspect = canvas.scrollWidth / canvas.scrollHeight;
canvas.width = 1024 * aspect;
canvas.height = 1024;
// Scroll amount (0.0 to 1.0)
scroll = window.pageYOffset / (document.documentElement.scrollHeight - window.innerHeight);
// Scroll Velocity
// Inertia example:
// velocity = velocity * 0.99 + (scroll - lastScroll);
// lastScroll = scroll;
// Clear the draw buffer
regl.clear({ color: [0, 0, 0, 0] });
// Execute a REGL draw command
draw({
globaltime: ctx.time,
resolution: [ctx.viewportWidth, ctx.viewportHeight],
aspect: aspect,
scroll: scroll,
velocity: velocity
});
});
};
}();
================================================
FILE: js/demo5.js
================================================
!function() {
'use strict';
var canvas = document.querySelector('#webgl');
// Scroll variables
var scroll = 0.0, velocity = 0.0, lastScroll = 0.0;
// Initialize REGL from a canvas element
var regl = createREGL({
canvas: canvas,
onDone: function(error, regl) {
if (error) { alert(error); }
}
});
// Loading a texture
var img = new Image();
img.src = 'img/img4.jpg';
img.onload = function() {
setTimeout(function() { document.body.classList.remove('loading');}, 1000);
// Create a REGL draw command
var draw = regl({
frag: document.querySelector('#fragmentShader').textContent,
vert: 'attribute vec2 position; void main() { gl_Position = vec4(3.0 * position, 0.0, 1.0); }',
attributes: { position: [-1, 0, 0, -1, 1, 1] },
count: 3,
uniforms: {
globaltime: regl.prop('globaltime'),
resolution: regl.prop('resolution'),
aspect: regl.prop('aspect'),
scroll: regl.prop('scroll'),
velocity: regl.prop('velocity'),
texture: regl.texture(img)
}
});
// Hook a callback to execute each frame
regl.frame(function(ctx) {
// Resize a canvas element with the aspect ratio (100vw, 100vh)
var aspect = canvas.scrollWidth / canvas.scrollHeight;
canvas.width = 1024 * aspect;
canvas.height = 1024;
// Scroll amount (0.0 to 1.0)
scroll = window.pageYOffset / (document.documentElement.scrollHeight - window.innerHeight);
// Scroll Velocity
// Inertia example:
// velocity = velocity * 0.99 + (scroll - lastScroll);
// lastScroll = scroll;
// Clear the draw buffer
regl.clear({ color: [0, 0, 0, 0] });
// Execute a REGL draw command
draw({
globaltime: ctx.time,
resolution: [ctx.viewportWidth, ctx.viewportHeight],
aspect: aspect,
scroll: scroll,
velocity: velocity
});
});
};
}();
================================================
FILE: js/demo6.js
================================================
!function() {
'use strict';
var canvas = document.querySelector('#webgl');
// Scroll variables
var scroll = 0.0, velocity = 0.0, lastScroll = 0.0;
// initialize REGL from a canvas element
var regl = createREGL({
canvas: canvas,
onDone: function(error, regl) {
if (error) { alert(error); }
}
});
// Loading a texture
var img = new Image();
img.src = 'img/gradient_map1.png';
img.onload = function() {
setTimeout(function() { document.body.classList.remove('loading');}, 1000);
// Create a REGL draw command
var draw = regl({
frag: document.querySelector('#fragmentShader').textContent,
vert: 'attribute vec2 position; void main() { gl_Position = vec4(3.0 * position, 0.0, 1.0); }',
attributes: { position: [-1, 0, 0, -1, 1, 1] },
count: 3,
uniforms: {
globaltime: regl.prop('globaltime'),
resolution: regl.prop('resolution'),
aspect: regl.prop('aspect'),
scroll: regl.prop('scroll'),
velocity: regl.prop('velocity'),
gradient: regl.texture(img)
}
});
// Hook a callback to execute each frame
regl.frame(function(ctx) {
// Resize a canvas element with the aspect ratio (100vw, 100vh)
var aspect = canvas.scrollWidth / canvas.scrollHeight;
canvas.width = 768 * aspect;
canvas.height = 768;
// Scroll amount (0.0 to 1.0)
scroll = window.pageYOffset / (document.documentElement.scrollHeight - window.innerHeight);
// Scroll Velocity
// Inertia example:
// velocity = velocity * 0.99 + (scroll - lastScroll);
// lastScroll = scroll;
// Clear the draw buffer
regl.clear({ color: [0, 0, 0, 0] });
// Execute a REGL draw command
draw({
globaltime: ctx.time,
resolution: [ctx.viewportWidth, ctx.viewportHeight],
aspect: aspect,
scroll: scroll,
velocity: velocity
});
});
};
}();
================================================
FILE: js/demo7.js
================================================
!function() {
'use strict';
var canvas = document.querySelector('#webgl');
// Scroll variables
var scroll = 0.0, velocity = 0.0, lastScroll = 0.0;
// initialize REGL from a canvas element
var regl = createREGL({
canvas: canvas,
onDone: function(error, regl) {
if (error) { alert(error); }
}
});
// Loading a texture
var img = new Image();
img.src = 'img/gradient_map2.png';
img.onload = function() {
setTimeout(function() { document.body.classList.remove('loading');}, 1000);
// Create a REGL draw command
var draw = regl({
frag: document.querySelector('#fragmentShader').textContent,
vert: 'attribute vec2 position; void main() { gl_Position = vec4(3.0 * position, 0.0, 1.0); }',
attributes: { position: [-1, 0, 0, -1, 1, 1] },
count: 3,
uniforms: {
globaltime: regl.prop('globaltime'),
resolution: regl.prop('resolution'),
aspect: regl.prop('aspect'),
scroll: regl.prop('scroll'),
velocity: regl.prop('velocity'),
gradient: regl.texture(img)
}
});
// Hook a callback to execute each frame
regl.frame(function(ctx) {
// Resize a canvas element with the aspect ratio (100vw, 100vh)
var aspect = canvas.scrollWidth / canvas.scrollHeight;
canvas.width = 768 * aspect;
canvas.height = 768;
// Scroll amount (0.0 to 1.0)
scroll = window.pageYOffset / (document.documentElement.scrollHeight - window.innerHeight);
// Scroll Velocity
// Inertia example:
// velocity = velocity * 0.99 + (scroll - lastScroll);
// lastScroll = scroll;
// Clear the draw buffer
regl.clear({ color: [0, 0, 0, 0] });
// Execute a REGL draw command
draw({
globaltime: ctx.time,
resolution: [ctx.viewportWidth, ctx.viewportHeight],
aspect: aspect,
scroll: scroll,
velocity: velocity
});
});
};
}();
================================================
FILE: js/demo8.js
================================================
!function() {
'use strict';
var canvas = document.querySelector('#webgl');
// Scroll variables
var scroll = 0.0, velocity = 0.0, lastScroll = 0.0;
// initialize REGL from a canvas element
var regl = createREGL({
canvas: canvas,
onDone: function(error, regl) {
if (error) { alert(error); }
}
});
// Loading a texture
var img = new Image();
img.src = 'img/gradient_map3.png';
img.onload = function() {
setTimeout(function() { document.body.classList.remove('loading');}, 1000);
// Create a REGL draw command
var draw = regl({
frag: document.querySelector('#fragmentShader').textContent,
vert: 'attribute vec2 position; void main() { gl_Position = vec4(3.0 * position, 0.0, 1.0); }',
attributes: { position: [-1, 0, 0, -1, 1, 1] },
count: 3,
uniforms: {
globaltime: regl.prop('globaltime'),
resolution: regl.prop('resolution'),
aspect: regl.prop('aspect'),
scroll: regl.prop('scroll'),
velocity: regl.prop('velocity'),
gradient: regl.texture(img)
}
});
// Hook a callback to execute each frame
regl.frame(function(ctx) {
// Resize a canvas element with the aspect ratio (100vw, 100vh)
var aspect = canvas.scrollWidth / canvas.scrollHeight;
canvas.width = 768 * aspect;
canvas.height = 768;
// Scroll amount (0.0 to 1.0)
scroll = window.pageYOffset / (document.documentElement.scrollHeight - window.innerHeight);
// Scroll Velocity
// Inertia example:
// velocity = velocity * 0.99 + (scroll - lastScroll);
// lastScroll = scroll;
// Clear the draw buffer
regl.clear({ color: [0, 0, 0, 0] });
// Execute a REGL draw command
draw({
globaltime: ctx.time,
resolution: [ctx.viewportWidth, ctx.viewportHeight],
aspect: aspect,
scroll: scroll,
velocity: velocity
});
});
};
}();
================================================
FILE: js/demo9.js
================================================
!function() {
'use strict';
var canvas = document.querySelector('#webgl');
// Scroll variables
var scroll = 0.0, velocity = 0.0, lastScroll = 0.0;
// initialize REGL from a canvas element
var regl = createREGL({
canvas: canvas,
onDone: function(error, regl) {
if (error) { alert(error); }
}
});
// Create a REGL draw command
var draw = regl({
frag: document.querySelector('#fragmentShader').textContent,
vert: 'attribute vec2 position; void main() { gl_Position = vec4(3.0 * position, 0.0, 1.0); }',
attributes: { position: [-1, 0, 0, -1, 1, 1] },
count: 3,
uniforms: {
globaltime: regl.prop('globaltime'),
resolution: regl.prop('resolution'),
aspect: regl.prop('aspect'),
scroll: regl.prop('scroll'),
velocity: regl.prop('velocity')
}
});
// Hook a callback to execute each frame
regl.frame(function(ctx) {
// Resize a canvas element with the aspect ratio (100vw, 100vh)
var aspect = canvas.scrollWidth / canvas.scrollHeight;
canvas.width = 512 * aspect;
canvas.height = 512;
// Scroll amount (0.0 to 1.0)
scroll = window.pageYOffset / (document.documentElement.scrollHeight - window.innerHeight);
// Scroll Velocity
// Inertia example:
// velocity = velocity * 0.99 + (scroll - lastScroll);
// lastScroll = scroll;
// Clear the draw buffer
regl.clear({ color: [0, 0, 0, 0] });
// Execute a REGL draw command
draw({
globaltime: ctx.time,
resolution: [ctx.viewportWidth, ctx.viewportHeight],
aspect: aspect,
scroll: scroll,
velocity: velocity
});
});
setTimeout(function() { document.body.classList.remove('loading');}, 1000);
}();
gitextract_uisuplp9/
├── .gitignore
├── README.md
├── css/
│ ├── demo.css
│ └── normalize.css
├── index.html
├── index2.html
├── index3.html
├── index4.html
├── index5.html
├── index6.html
├── index7.html
├── index8.html
├── index9.html
├── js/
│ ├── demo1.js
│ ├── demo2.js
│ ├── demo3.js
│ ├── demo4.js
│ ├── demo5.js
│ ├── demo6.js
│ ├── demo7.js
│ ├── demo8.js
│ └── demo9.js
└── psd/
└── gradient_map.psd
Condensed preview — 23 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (85K chars).
[
{
"path": ".gitignore",
"chars": 314,
"preview": "*.DS_Store\n\n# Windows thumbnail cache files\nThumbs.db\nehthumbs.db\nehthumbs_vista.db\n\n# Folder config file\nDesktop.ini\n\n#"
},
{
"path": "README.md",
"chars": 1508,
"preview": "# WebGL Scroll Spiral\n\nSome decorative background scroll effects for websites using WebGL and regl. By Xoihazard.\n\n![Web"
},
{
"path": "css/demo.css",
"chars": 5733,
"preview": "*,\r\n*::after,\r\n*::before {\r\n\tbox-sizing: border-box;\r\n}\r\n\r\nbody {\r\n\tfont-family: 'Roboto Mono', monospace;\r\n\tcolor: #fff"
},
{
"path": "css/normalize.css",
"chars": 1825,
"preview": "article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block;}audio,canvas,video{"
},
{
"path": "index.html",
"chars": 5916,
"preview": "<!DOCTYPE html>\n<html lang=\"en\" class=\"no-js\">\n<head>\n\t<meta charset=\"UTF-8\" />\n\t<meta name=\"viewport\" content=\"width=de"
},
{
"path": "index2.html",
"chars": 4848,
"preview": "<!DOCTYPE html>\n<html lang=\"en\" class=\"no-js\">\n<head>\n\t<meta charset=\"UTF-8\" />\n\t<meta name=\"viewport\" content=\"width=de"
},
{
"path": "index3.html",
"chars": 4842,
"preview": "<!DOCTYPE html>\n<html lang=\"en\" class=\"no-js\">\n<head>\n\t<meta charset=\"UTF-8\" />\n\t<meta name=\"viewport\" content=\"width=de"
},
{
"path": "index4.html",
"chars": 4844,
"preview": "<!DOCTYPE html>\n<html lang=\"en\" class=\"no-js\">\n<head>\n\t<meta charset=\"UTF-8\" />\n\t<meta name=\"viewport\" content=\"width=de"
},
{
"path": "index5.html",
"chars": 4849,
"preview": "<!DOCTYPE html>\n<html lang=\"en\" class=\"no-js\">\n<head>\n\t<meta charset=\"UTF-8\" />\n\t<meta name=\"viewport\" content=\"width=de"
},
{
"path": "index6.html",
"chars": 6241,
"preview": "<!DOCTYPE html>\n<html lang=\"en\" class=\"no-js\">\n<head>\n\t<meta charset=\"UTF-8\" />\n\t<meta name=\"viewport\" content=\"width=de"
},
{
"path": "index7.html",
"chars": 6240,
"preview": "<!DOCTYPE html>\n<html lang=\"en\" class=\"no-js\">\n<head>\n\t<meta charset=\"UTF-8\" />\n\t<meta name=\"viewport\" content=\"width=de"
},
{
"path": "index8.html",
"chars": 6335,
"preview": "<!DOCTYPE html>\n<html lang=\"en\" class=\"no-js\">\n<head>\n\t<meta charset=\"UTF-8\" />\n\t<meta name=\"viewport\" content=\"width=de"
},
{
"path": "index9.html",
"chars": 5886,
"preview": "<!DOCTYPE html>\n<html lang=\"en\" class=\"no-js\">\n<head>\n\t<meta charset=\"UTF-8\" />\n\t<meta name=\"viewport\" content=\"width=de"
},
{
"path": "js/demo1.js",
"chars": 1638,
"preview": "!function() {\n\t'use strict';\n\n\tvar canvas = document.querySelector('#webgl');\n\n\t// Scroll variables\n\tvar scroll = 0.0, v"
},
{
"path": "js/demo2.js",
"chars": 1815,
"preview": "!function() {\n\t'use strict';\n\n\tvar canvas = document.querySelector('#webgl');\n\n\t// Scroll variables\n\tvar scroll = 0.0, v"
},
{
"path": "js/demo3.js",
"chars": 1815,
"preview": "!function() {\n\t'use strict';\n\n\tvar canvas = document.querySelector('#webgl');\n\n\t// Scroll variables\n\tvar scroll = 0.0, v"
},
{
"path": "js/demo4.js",
"chars": 1814,
"preview": "!function() {\n\t'use strict';\n\n\tvar canvas = document.querySelector('#webgl');\n\n\t// Scroll variables\n\tvar scroll = 0.0, v"
},
{
"path": "js/demo5.js",
"chars": 1815,
"preview": "!function() {\n\t'use strict';\n\n\tvar canvas = document.querySelector('#webgl');\n\n\t// Scroll variables\n\tvar scroll = 0.0, v"
},
{
"path": "js/demo6.js",
"chars": 1824,
"preview": "!function() {\n\t'use strict';\n\n\tvar canvas = document.querySelector('#webgl');\n\n\t// Scroll variables\n\tvar scroll = 0.0, v"
},
{
"path": "js/demo7.js",
"chars": 1824,
"preview": "!function() {\n\t'use strict';\n\n\tvar canvas = document.querySelector('#webgl');\n\n\t// Scroll variables\n\tvar scroll = 0.0, v"
},
{
"path": "js/demo8.js",
"chars": 1824,
"preview": "!function() {\n\t'use strict';\n\n\tvar canvas = document.querySelector('#webgl');\n\n\t// Scroll variables\n\tvar scroll = 0.0, v"
},
{
"path": "js/demo9.js",
"chars": 1638,
"preview": "!function() {\n\t'use strict';\n\n\tvar canvas = document.querySelector('#webgl');\n\n\t// Scroll variables\n\tvar scroll = 0.0, v"
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the codrops/ScrollSpiral GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 23 files (73.6 KB), approximately 26.8k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.