mirror of
https://github.com/scrtwpns/mixbox.git
synced 2026-03-19 22:49:41 +01:00
add mixbox for javascript
This commit is contained in:
112
javascript/README.md
Normal file
112
javascript/README.md
Normal file
@@ -0,0 +1,112 @@
|
||||
# Mixbox for Javascript
|
||||
|
||||
```html
|
||||
<script src="https://scrtwpns.com/mixbox.js"></script>
|
||||
```
|
||||
```javascript
|
||||
import mixbox from 'https://scrtwpns.com/mixbox.esm.js'; // for ES6 module use this instead
|
||||
```
|
||||
|
||||
### Node
|
||||
```
|
||||
npm install mixbox
|
||||
```
|
||||
```javascript
|
||||
import mixbox from 'mixbox';
|
||||
```
|
||||
|
||||
## Usage
|
||||
```javascript
|
||||
var rgb1 = "rgb(0, 33, 133)"; // blue
|
||||
var rgb2 = "rgb(252, 211, 0)"; // yellow
|
||||
var t = 0.5; // mixing ratio
|
||||
|
||||
var mixed = mixbox.lerp(rgb1, rgb2, t);
|
||||
|
||||
console.log(mixed);
|
||||
```
|
||||
|
||||
## Mixing Multiple Colors
|
||||
```javascript
|
||||
var z1 = mixbox.rgbToLatent(rgb1);
|
||||
var z2 = mixbox.rgbToLatent(rgb2);
|
||||
var z3 = mixbox.rgbToLatent(rgb3);
|
||||
|
||||
var zMix = new Array(mixbox.LATENT_SIZE);
|
||||
|
||||
for (var i = 0; i < zMix.length; i++) { // mix:
|
||||
zMix[i] = (0.3*z1[i] + // 30% of rgb1
|
||||
0.6*z2[i] + // 60% of rgb2
|
||||
0.1*z3[i]); // 10% of rgb3
|
||||
}
|
||||
|
||||
var rgbMix = mixbox.latentToRgb(zMix);
|
||||
```
|
||||
|
||||
## Pigment Colors
|
||||
| Pigment | | RGB | Float RGB | Linear RGB |
|
||||
| --- | --- |:----:|:----:|:----:|
|
||||
| Cadmium Yellow | <img src="https://scrtwpns.com/mixbox/pigments/cadmium_yellow.png"/> | 254, 236, 0 | 0.996, 0.925, 0.0 | 0.991, 0.839, 0.0 |
|
||||
| Hansa Yellow | <img src="https://scrtwpns.com/mixbox/pigments/hansa_yellow.png"/> | 252, 211, 0 | 0.988, 0.827, 0.0 | 0.973, 0.651, 0.0 |
|
||||
| Cadmium Orange | <img src="https://scrtwpns.com/mixbox/pigments/cadmium_orange.png"/> | 255, 105, 0 | 1.0, 0.412, 0.0 | 1.0, 0.141, 0.0 |
|
||||
| Cadmium Red | <img src="https://scrtwpns.com/mixbox/pigments/cadmium_red.png"/> | 255, 39, 2 | 1.0, 0.153, 0.008 | 1.0, 0.02, 0.001 |
|
||||
| Quinacridone Magenta | <img src="https://scrtwpns.com/mixbox/pigments/quinacridone_magenta.png"/> | 128, 2, 46 | 0.502, 0.008, 0.18 | 0.216, 0.001, 0.027 |
|
||||
| Cobalt Violet | <img src="https://scrtwpns.com/mixbox/pigments/cobalt_violet.png"/> | 78, 0, 66 | 0.306, 0.0, 0.259 | 0.076, 0.0, 0.054 |
|
||||
| Ultramarine Blue | <img src="https://scrtwpns.com/mixbox/pigments/ultramarine_blue.png"/> | 25, 0, 89 | 0.098, 0.0, 0.349 | 0.01, 0.0, 0.1 |
|
||||
| Cobalt Blue | <img src="https://scrtwpns.com/mixbox/pigments/cobalt_blue.png"/> | 0, 33, 133 | 0.0, 0.129, 0.522 | 0.0, 0.015, 0.235 |
|
||||
| Phthalo Blue | <img src="https://scrtwpns.com/mixbox/pigments/phthalo_blue.png"/> | 13, 27, 68 | 0.051, 0.106, 0.267 | 0.004, 0.011, 0.058 |
|
||||
| Phthalo Green | <img src="https://scrtwpns.com/mixbox/pigments/phthalo_green.png"/> | 0, 60, 50 | 0.0, 0.235, 0.196 | 0.0, 0.045, 0.032 |
|
||||
| Permanent Green | <img src="https://scrtwpns.com/mixbox/pigments/permanent_green.png"/> | 7, 109, 22 | 0.027, 0.427, 0.086 | 0.002, 0.153, 0.008 |
|
||||
| Sap Green | <img src="https://scrtwpns.com/mixbox/pigments/sap_green.png"/> | 107, 148, 4 | 0.42, 0.58, 0.016 | 0.147, 0.296, 0.001 |
|
||||
| Burnt Sienna | <img src="https://scrtwpns.com/mixbox/pigments/burnt_sienna.png"/> | 123, 72, 0 | 0.482, 0.282, 0.0 | 0.198, 0.065, 0.0 |
|
||||
|
||||
## Mixbox in WebGL
|
||||
```javascript
|
||||
var shader = `
|
||||
precision highp float;
|
||||
|
||||
// uncomment the following line if you work in linear space
|
||||
// #define MIXBOX_COLORSPACE_LINEAR
|
||||
|
||||
uniform sampler2D mixbox_lut; // bind mixbox.lutTexture(gl) here
|
||||
|
||||
#include "mixbox.glsl"
|
||||
|
||||
void main(void) {
|
||||
vec3 rgb1 = vec3(0, 0.129, 0.522); // blue
|
||||
vec3 rgb2 = vec3(0.988, 0.827, 0); // yellow
|
||||
float t = 0.5; // mixing ratio
|
||||
|
||||
vec3 rgb = mixbox_lerp(rgb1, rgb2, t);
|
||||
|
||||
gl_FragColor = vec4(rgb, 1.0);
|
||||
}
|
||||
`;
|
||||
|
||||
shader = shader.replace('#include "mixbox.glsl"', mixbox.glsl());
|
||||
```
|
||||
|
||||
```javascript
|
||||
gl.useProgram(shaderProgram);
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
gl.bindTexture(gl.TEXTURE_2D, mixbox.lutTexture(gl));
|
||||
gl.uniform1i(gl.getUniformLocation(shaderProgram, "mixbox_lut"), 0);
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
| Gradients | Mountains | Palette Snakes |
|
||||
|:---:|:---:|:---:|
|
||||
| <a href="https://scrtwpns.com/mixbox/examples/gradients.html"><img src="https://scrtwpns.com/mixbox/examples/gradients.png"/></a> | <a href="https://scrtwpns.com/mixbox/examples/mountains.html"><img src="https://scrtwpns.com/mixbox/examples/mountains.png"/></a> | <a href="https://scrtwpns.com/mixbox/examples/palette.html"><img src="https://scrtwpns.com/mixbox/examples/palette.png"/></a> |
|
||||
| [source code](examples/gradients.js) | [source code](examples/mountains.js) | [source code](examples/palette.js) |
|
||||
|
||||
| Splash Art | Paint Mixer | Pigment Fluids |
|
||||
|:---:|:---:|:---:|
|
||||
| <a href="https://scrtwpns.com/mixbox/examples/splash.html"><img src="https://scrtwpns.com/mixbox/examples/splash.png"/></a> | <a href="https://scrtwpns.com/mixbox/examples/mixer.html"><img src="https://scrtwpns.com/mixbox/examples/mixer.png"/></a> | <a href="https://scrtwpns.com/mixbox/fluids"><img src="https://scrtwpns.com/mixbox/examples/fluids.png"/></a> |
|
||||
| [source code](examples/splash.html) | [source code](examples/mixer.js) | [source code](https://scrtwpns.com/mixbox/fluids/script.js) |
|
||||
|
||||
|
||||
## License
|
||||
Copyright (c) 2022, Secret Weapons. All rights reserved.<br>
|
||||
Mixbox is provided under the CC BY-NC 4.0 license for non-commercial use only.<br>
|
||||
If you want to obtain commercial license, please contact: mixbox@scrtwpns.com
|
||||
20
javascript/examples/canvas.html
Normal file
20
javascript/examples/canvas.html
Normal file
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="canvas" width="720" height="128"></canvas>
|
||||
<script src="https://scrtwpns.com/mixbox.js"></script>
|
||||
<script>
|
||||
var canvas = document.getElementById('canvas');
|
||||
var context = canvas.getContext("2d");
|
||||
var color1 = "rgb(0, 33, 133)"; // blue
|
||||
var color2 = "rgb(252, 211, 0)"; // yellow
|
||||
var n = canvas.width;
|
||||
for (var i = 0; i < n; i++) {
|
||||
context.fillStyle = mixbox.lerp(color1, color2, i / (n - 1));
|
||||
context.fillRect(i, 0, 1, canvas.height);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
30
javascript/examples/gradients.html
Normal file
30
javascript/examples/gradients.html
Normal file
@@ -0,0 +1,30 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Bootstrap -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
|
||||
<!-- P5js -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/p5@1.4.1/lib/p5.js"></script>
|
||||
<!-- Mixbox -->
|
||||
<script src="https://scrtwpns.com/mixbox.js"></script>
|
||||
<!-- Code -->
|
||||
<script src="gradients.js"></script>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row justify-content-center align-items-center text-center py-5 my-3">
|
||||
<div class="col-12"><main></main></div>
|
||||
</div>
|
||||
<div class="row justify-content-center align-items-center text-secondary text-center">
|
||||
<div class="col-12">
|
||||
<div class="d-inline" id="picker-A"></div>
|
||||
<div class="d-inline" id="picker-B"></div>
|
||||
<h3 class="pt-3">Pick colors</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
147
javascript/examples/gradients.js
Normal file
147
javascript/examples/gradients.js
Normal file
@@ -0,0 +1,147 @@
|
||||
let colorPicker_A;
|
||||
let colorPicker_B;
|
||||
let color_A;
|
||||
let color_B;
|
||||
|
||||
function setup() {
|
||||
createCanvas(650, 465);
|
||||
background(255);
|
||||
colorMode(RGB);
|
||||
|
||||
colorPicker_A = createColorPicker('#002185');
|
||||
colorPicker_A.parent('picker-A');
|
||||
color_A = colorPicker_A.color();
|
||||
|
||||
colorPicker_B = createColorPicker('#fcd200');
|
||||
colorPicker_B.parent('picker-B');
|
||||
color_B = colorPicker_B.color();
|
||||
|
||||
drawGradient("Mixbox", color_A, color_B, 50, 200, 65, 465);
|
||||
drawGradient("RGB", color_A, color_B, 250, 400, 65, 465);
|
||||
drawGradient("OkLab", color_A, color_B, 450, 600, 65, 465);
|
||||
|
||||
}
|
||||
|
||||
function draw() {
|
||||
|
||||
if(color_A.toString() != colorPicker_A.color().toString() || color_B.toString() != colorPicker_B.color().toString())
|
||||
{
|
||||
background(255);
|
||||
|
||||
color_A = colorPicker_A.color();
|
||||
color_B = colorPicker_B.color();
|
||||
|
||||
drawGradient("Mixbox", color_A, color_B, 50, 200, 65, 465);
|
||||
drawGradient("RGB", color_A, color_B, 250, 400, 65, 465);
|
||||
drawGradient("OkLab", color_A, color_B, 450, 600, 65, 465);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function drawGradient(method, color1, color2, x1, x2, y1, y2)
|
||||
{
|
||||
textSize(28);
|
||||
textStyle(BOLD);
|
||||
fill(79, 118, 123);
|
||||
text(method, x1 + (x2-x1)/2 - textWidth(method)/2, y1-30);
|
||||
let mixedColor;
|
||||
|
||||
for (let y = y1; y <= y2; y++)
|
||||
{
|
||||
let t = (y-y1)/(y2-y1);
|
||||
if(match(method, 'Mixbox'))
|
||||
{
|
||||
mixedColor = mixbox.lerp(color1, color2, t);
|
||||
}
|
||||
else if(match(method, 'RGB'))
|
||||
{
|
||||
mixedColor = lerpColor(color1, color2, t);
|
||||
}
|
||||
else if(match(method, 'OkLab'))
|
||||
{
|
||||
let c1 = [red(color1), green(color1), blue(color1)];
|
||||
let c2 = [red(color2), green(color2), blue(color2)];
|
||||
let tmp = linear_to_rgb (oklab_to_linear_srgb(linearMix(linear_srgb_to_oklab(rgb_to_linear(c1)),linear_srgb_to_oklab(rgb_to_linear(c2)),t)));
|
||||
mixedColor = color(tmp[0], tmp[1], tmp[2]);
|
||||
}
|
||||
strokeWeight(2);
|
||||
stroke(mixedColor);
|
||||
line(x1, y, x2, y);
|
||||
noStroke();
|
||||
}
|
||||
}
|
||||
|
||||
/* THE FOLLOWING CODE IS HANDLING THE CONVERSION TO OkLAB SPACE */
|
||||
/* https://bottosson.github.io/posts/oklab/ */
|
||||
|
||||
function linear_srgb_to_oklab(c)
|
||||
{
|
||||
let l = 0.4122214708 * c[0] + 0.5363325363 * c[1] + 0.0514459929 * c[2];
|
||||
let m = 0.2119034982 * c[0] + 0.6806995451 * c[1] + 0.1073969566 * c[2];
|
||||
let s = 0.0883024619 * c[0] + 0.2817188376 * c[1] + 0.6299787005 * c[2];
|
||||
|
||||
let l_ = Math.cbrt(l);
|
||||
let m_ = Math.cbrt(m);
|
||||
let s_ = Math.cbrt(s);
|
||||
|
||||
var lab = [ 0.2104542553*l_ + 0.7936177850*m_ - 0.0040720468*s_,
|
||||
1.9779984951*l_ - 2.4285922050*m_ + 0.4505937099*s_,
|
||||
0.0259040371*l_ + 0.7827717662*m_ - 0.8086757660*s_ ];
|
||||
|
||||
return lab;
|
||||
}
|
||||
|
||||
function oklab_to_linear_srgb(c)
|
||||
{
|
||||
let l_ = c[0] + 0.3963377774 * c[1] + 0.2158037573 * c[2];
|
||||
let m_ = c[0] - 0.1055613458 * c[1] - 0.0638541728 * c[2];
|
||||
let s_ = c[0] - 0.0894841775 * c[1] - 1.2914855480 * c[2];
|
||||
|
||||
let l = l_*l_*l_;
|
||||
let m = m_*m_*m_;
|
||||
let s = s_*s_*s_;
|
||||
|
||||
var lrgb = [ 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
|
||||
-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
|
||||
-0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s];
|
||||
return lrgb;
|
||||
}
|
||||
|
||||
function rgb_to_linear(rgb) // receiving Color object, returning array of 3 linear RGB values in range 0-1
|
||||
{
|
||||
var res = [0,0,0];
|
||||
var float_rgb = [rgb[0]/255, rgb[1]/255, rgb[2]/255];
|
||||
for (let i = 0; i < 3; ++i)
|
||||
{
|
||||
let c = float_rgb[i];
|
||||
if (c >= 0.04045)
|
||||
res[i] = pow((c + 0.055)/(1 + 0.055), 2.4);
|
||||
else
|
||||
res[i] = c / 12.92;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
function linear_to_rgb(lrgb) // receiving array of 3 linear RGB values, returning an array of gamma encoded RGB values in range 0-255
|
||||
{
|
||||
var res = [0,0,0];
|
||||
for (let i = 0; i < 3; ++i)
|
||||
{
|
||||
let c = lrgb[i];
|
||||
if (c >= 0.0031308)
|
||||
res[i] = 1.055 * pow(c, 1.0/2.4) - 0.055;
|
||||
else
|
||||
res[i] = 12.92 * c;
|
||||
}
|
||||
return [round(res[0]*255), round(res[1]*255), round(res[2]*255)];
|
||||
}
|
||||
|
||||
function linearMix (a, b, t)
|
||||
{
|
||||
var res = [0,0,0];
|
||||
for(let i=0; i<3; i++)
|
||||
{
|
||||
res[i] = a[i] * (1-t) + b[i]*t;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
26
javascript/examples/hello.html
Normal file
26
javascript/examples/hello.html
Normal file
@@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div id="blue" class="box">BLUE</div>
|
||||
<div id="mixed" class="box">MIXED</div>
|
||||
<div id="yellow" class="box">YELLOW</div>
|
||||
|
||||
<script src="https://scrtwpns.com/mixbox.js"></script>
|
||||
<script>
|
||||
var blue = "rgb(0, 33, 133)";
|
||||
var yellow = "rgb(252, 211, 0)";
|
||||
var t = 0.5;
|
||||
var mixed = mixbox.lerp(blue, yellow, t);
|
||||
|
||||
document.getElementById("blue").style.backgroundColor = blue;
|
||||
document.getElementById("mixed").style.backgroundColor = mixed;
|
||||
document.getElementById("yellow").style.backgroundColor = yellow;
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.box{width: 200px; height: 200px; padding: 10px; margin: 10px; color: white; font-weight: bold;}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
||||
17
javascript/examples/mixer.html
Normal file
17
javascript/examples/mixer.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<!-- P5js -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/p5@1.4.1/lib/p5.js"></script>
|
||||
<!-- Mixbox -->
|
||||
<script src="https://scrtwpns.com/mixbox.js"></script>
|
||||
<!-- Code -->
|
||||
<script src="mixer.js"></script>
|
||||
|
||||
<div align="center" style="margin-top: 50px;">
|
||||
<main> </main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
133
javascript/examples/mixer.js
Normal file
133
javascript/examples/mixer.js
Normal file
@@ -0,0 +1,133 @@
|
||||
let width = 650;
|
||||
let height = 650;
|
||||
let center_x = width/2;
|
||||
let center_y = height/2;
|
||||
let outer_radius = 300;
|
||||
let inner_radius = 100;
|
||||
let circle_radius = 45;
|
||||
var colors = [];
|
||||
var centers_outside = [];
|
||||
var centers_inside = [];
|
||||
var sliders_pos = [];
|
||||
var mix_t = [];
|
||||
let numPigments = 0;
|
||||
let step = 0;
|
||||
let dragged = -1;
|
||||
|
||||
function setup() {
|
||||
createCanvas(650, 650);
|
||||
background(255);
|
||||
colorMode(RGB);
|
||||
stroke(125);
|
||||
strokeWeight(3);
|
||||
|
||||
colors = [color( 255,236,4), color( 252,211,0), color( 255,105,0), color( 225,35,1), color( 191,0,18), color( 128,2,46), color( 78,1,66), color( 74,0,101), color( 16,31,61), color( 13, 27, 68), color( 25, 0, 89), color( 8,34,138), color( 12, 69,118), color( 6, 54, 51), color( 0,74,41), color( 84,50,36), color( 58,39,0), color( 13,9,1), color(249,250,249)];
|
||||
|
||||
numPigments = colors.length;
|
||||
step = TWO_PI / numPigments;
|
||||
|
||||
for(let i=0; i<numPigments; i++)
|
||||
{
|
||||
let x0 = center_x + sin(i * step) * inner_radius;
|
||||
let x1 = center_x + sin(i * step) * outer_radius;
|
||||
let y0 = center_y + cos(i * step) * inner_radius;
|
||||
let y1 = center_y + cos(i * step) * outer_radius;
|
||||
|
||||
centers_inside.push( createVector(x0, y0));
|
||||
centers_outside.push(createVector(x1, y1));
|
||||
mix_t.push(0);
|
||||
sliders_pos.push(createVector(x1,y1));
|
||||
|
||||
fill(colors[i]);
|
||||
line(x0, y0, x1, y1);
|
||||
ellipse(x1, y1, circle_radius, circle_radius);
|
||||
fill(200);
|
||||
ellipse(center_x, center_y, inner_radius*2, inner_radius*2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function draw() {
|
||||
|
||||
if(dragged > -1)
|
||||
{
|
||||
mix_t[dragged] = get_t(centers_outside[dragged].x, centers_outside[dragged].y, centers_inside[dragged].x, centers_inside[dragged].y, mouseX, mouseY);
|
||||
sliders_pos[dragged] = createVector(centers_outside[dragged].x - sin(dragged * step) * mix_t[dragged] * (outer_radius-inner_radius),
|
||||
centers_outside[dragged].y - cos(dragged * step) * mix_t[dragged] * (outer_radius-inner_radius));
|
||||
|
||||
background(255);
|
||||
let weights = 0;
|
||||
|
||||
for(let i=0; i<numPigments; i++)
|
||||
{
|
||||
line(centers_inside[i].x, centers_inside[i].y, centers_outside[i].x, centers_outside[i].y);
|
||||
fill(colors[i]);
|
||||
ellipse(sliders_pos[i].x, sliders_pos[i].y, circle_radius, circle_radius);
|
||||
|
||||
weights += mix_t[i];
|
||||
}
|
||||
|
||||
if(weights > 0.000001)
|
||||
{
|
||||
let latent_mix = [0,0,0,0,0,0,0];
|
||||
for(let j=0; j<numPigments; j++)
|
||||
{
|
||||
if(mix_t[j]>0.000001)
|
||||
{
|
||||
let latent = mixbox.rgbToLatent(colors[j]);
|
||||
let t = mix_t[j]/weights;
|
||||
for(let k=0; k<latent.length; k++)
|
||||
{
|
||||
latent_mix[k] += latent[k] * t;
|
||||
}
|
||||
}
|
||||
}
|
||||
let mixed_color = mixbox.latentToRgb(latent_mix);
|
||||
fill(mixed_color);
|
||||
ellipse(center_x, center_y, inner_radius*2, inner_radius*2);
|
||||
}
|
||||
else
|
||||
{
|
||||
fill(200);
|
||||
ellipse(center_x, center_y, inner_radius*2, inner_radius*2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function mousePressed()
|
||||
{
|
||||
for(let i=0; i<numPigments; i++)
|
||||
{
|
||||
if(mouseX > sliders_pos[i].x - circle_radius/2 &&
|
||||
mouseX < sliders_pos[i].x + circle_radius/2 &&
|
||||
mouseY > sliders_pos[i].y - circle_radius/2 &&
|
||||
mouseY < sliders_pos[i].y + circle_radius/2)
|
||||
{
|
||||
dragged = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function mouseReleased()
|
||||
{
|
||||
dragged = -1;
|
||||
}
|
||||
|
||||
function get_t (ax, ay, bx, by, qx, qy)
|
||||
{
|
||||
let u = createVector(bx-ax, by-ay);
|
||||
let v = createVector(qx-ax, qy-ay);
|
||||
|
||||
let d = (u.x*v.x + u.y*v.y) / u.mag();
|
||||
let t = d/u.mag();
|
||||
|
||||
return clamp(t, 0.0, 1.0);
|
||||
}
|
||||
|
||||
function clamp(x, lowerlimit, upperlimit) {
|
||||
if (x<lowerlimit) {return lowerlimit;}
|
||||
else if(x>upperlimit){return upperlimit;}
|
||||
else {return x;}
|
||||
}
|
||||
17
javascript/examples/mountains.html
Normal file
17
javascript/examples/mountains.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<!-- P5js -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/p5@1.4.1/lib/p5.js"></script>
|
||||
<!-- Mixbox -->
|
||||
<script src="https://scrtwpns.com/mixbox.js"></script>
|
||||
<!-- Code -->
|
||||
<script src="mountains.js"></script>
|
||||
|
||||
<div align="center" style="margin-top: 50px;">
|
||||
<main></main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
90
javascript/examples/mountains.js
Normal file
90
javascript/examples/mountains.js
Normal file
@@ -0,0 +1,90 @@
|
||||
let magenta, yellow, phthalo_blue, titanium_white, phthalo_medium;
|
||||
|
||||
function setup()
|
||||
{
|
||||
createCanvas(800, 650);
|
||||
background(80);
|
||||
colorMode(RGB);
|
||||
strokeWeight(2);
|
||||
|
||||
magenta = color(128,2,46);
|
||||
yellow = color(255,236,4);
|
||||
phthalo_blue = color(13,27,68);
|
||||
titanium_white = color(249,251,249);
|
||||
phthalo_medium = color(mixbox.lerp(phthalo_blue, titanium_white, 0.5));
|
||||
}
|
||||
|
||||
function draw()
|
||||
{
|
||||
for(let y=0; y<height; y++ )
|
||||
{
|
||||
let t = y*0.8/(height/2.3);
|
||||
let mix_col = mixbox.lerp(magenta, yellow,t);
|
||||
stroke(mix_col);
|
||||
line(0, y, width, y);
|
||||
noStroke();
|
||||
}
|
||||
|
||||
draw_mountain(460, 350, width/4, height);
|
||||
draw_mountain(430, 550, width/4*3, height);
|
||||
draw_mountain(370, 200, width/2-100, height);
|
||||
draw_mountain(250, 250, width/4*2.7, height);
|
||||
|
||||
draw_sun(width/2, height/4, 100);
|
||||
|
||||
updatePixels();
|
||||
noLoop();
|
||||
}
|
||||
|
||||
function draw_mountain (mount_height, mount_width, base_x, base_y)
|
||||
{
|
||||
let xoff1 = random(0, 300);
|
||||
let xoff2 = random(0, 300);
|
||||
let xoff3 = random(0, 300);
|
||||
let nScl1 = 0.009;
|
||||
let nScl2 = 0.009;
|
||||
let mountain_curr_width = 2;
|
||||
|
||||
for(let y=0; y<mount_height; y++)
|
||||
{
|
||||
let middle = noise(xoff1) * mountain_curr_width;
|
||||
let x1 = -mountain_curr_width - noise(xoff2)*mountain_curr_width/2;
|
||||
let x2 = mountain_curr_width + noise(xoff3)*mountain_curr_width/2;
|
||||
|
||||
for(let x=x1; x<middle; x++)
|
||||
{
|
||||
let t = (x -x1) / (middle - x1);
|
||||
let gradient_color = mixbox.lerp(phthalo_blue, phthalo_medium, t);
|
||||
gradient_color = mixbox.lerp(gradient_color, titanium_white, (1-y/mount_height)/1.5);
|
||||
set(base_x + x, (base_y-mount_height) + y, color(gradient_color));
|
||||
}
|
||||
for(let x=middle; x<x2; x++)
|
||||
{
|
||||
let t = pow((x-middle)/(x2-middle), 1.5);
|
||||
let gradient_color = mixbox.lerp(titanium_white, phthalo_medium, t);
|
||||
gradient_color = mixbox.lerp(gradient_color, titanium_white, (1-y/mount_height)/1.5);
|
||||
set(base_x + x, (base_y-mount_height) + y, color(gradient_color));
|
||||
}
|
||||
mountain_curr_width += mount_width/mount_height * (exp(y/mount_height * 1.5)-0.3);
|
||||
xoff1 += nScl1;
|
||||
xoff2 += nScl2;
|
||||
xoff3 += nScl2;
|
||||
}
|
||||
}
|
||||
|
||||
function draw_sun(center_x, center_y, radius)
|
||||
{
|
||||
for (let y = center_y-radius/2; y < center_y+radius/2; y++)
|
||||
{
|
||||
for (let x = center_x-radius/2; x < center_x+radius/2; x++)
|
||||
{
|
||||
let d = dist(x,y,center_x,center_y);
|
||||
if (d < radius/2)
|
||||
{
|
||||
let sun_color = mixbox.lerp(titanium_white, get(x,y), 0.5);
|
||||
sun_color = mixbox.lerp(get(x,y), sun_color, (y-(center_y-radius/2))/radius); // vertical fade
|
||||
set(x, y, color(sun_color));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
23
javascript/examples/p5js.html
Normal file
23
javascript/examples/p5js.html
Normal file
@@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="https://cdn.jsdelivr.net/npm/p5@1.4.1/lib/p5.js"></script>
|
||||
<script src="https://scrtwpns.com/mixbox.js"></script>
|
||||
<script>
|
||||
function setup() {
|
||||
createCanvas(400, 400);
|
||||
}
|
||||
|
||||
function draw() {
|
||||
var color1 = color(0, 33, 133); // blue
|
||||
var color2 = color(252, 211, 0); // yellow
|
||||
|
||||
var colorMix = mixbox.lerp(color1, color2, 0.5);
|
||||
|
||||
background(colorMix);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
17
javascript/examples/palette.html
Normal file
17
javascript/examples/palette.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<!-- P5js -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/p5@1.4.1/lib/p5.js"></script>
|
||||
<!-- Mixbox -->
|
||||
<script src="https://scrtwpns.com/mixbox.js"></script>
|
||||
<!-- Code -->
|
||||
<script src="palette.js"></script>
|
||||
|
||||
<div align="center" style="margin-top: 50px;">
|
||||
<main></main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
129
javascript/examples/palette.js
Normal file
129
javascript/examples/palette.js
Normal file
@@ -0,0 +1,129 @@
|
||||
var visited = []; // coordinates of the boxes the mouse has visited while pressed once
|
||||
var boxes = []; // all boxes that should be displayed and colored, item is an array [x, y, R, G, B]
|
||||
let boxSize = 40;
|
||||
let color1;
|
||||
let color2;
|
||||
let valid_start = false;
|
||||
let valid_end = false;
|
||||
|
||||
function setup() {
|
||||
|
||||
createCanvas(800, 680);
|
||||
background(80);
|
||||
colorMode(RGB);
|
||||
rectMode(CENTER);
|
||||
|
||||
boxes.push([ 60, 60,[ 13, 27, 68]]); // phthalo blue
|
||||
boxes.push([580, 180,[255, 236, 4]]); // bis yellow
|
||||
boxes.push([420, 60,[255, 236, 4]]); // bis yellow
|
||||
boxes.push([220, 300,[255, 208, 0]]); // hansa yellow
|
||||
boxes.push([420, 380,[ 25, 0, 89]]); // ultramarine blue
|
||||
boxes.push([500, 260,[ 25, 0, 89]]); // ultramarine blue
|
||||
boxes.push([700, 380,[225, 35, 1]]); // cadmium red
|
||||
boxes.push([580, 580,[128, 2, 46]]); // magenta
|
||||
boxes.push([100, 580,[249, 250, 249]]); // white
|
||||
boxes.push([260, 580,[249, 250, 249]]); // white
|
||||
drawBoxes();
|
||||
}
|
||||
|
||||
function draw()
|
||||
{
|
||||
// record visited boxes
|
||||
if(mouseIsPressed === true)
|
||||
{
|
||||
let x = snapToGrid(mouseX);
|
||||
let y = snapToGrid(mouseY);
|
||||
|
||||
let alreadyIn = false;
|
||||
for(let v=0; v<visited.length; v++)
|
||||
{
|
||||
if(visited[v][0]==x && visited[v][1]==y) {alreadyIn = true};
|
||||
}
|
||||
if(!alreadyIn) {visited.push([x,y]);}
|
||||
}
|
||||
|
||||
// draw overlay on visited boxes
|
||||
if (visited.length > 0)
|
||||
{
|
||||
stroke(230);
|
||||
noFill();
|
||||
setLineDash([5, 5]);
|
||||
for(let v=0; v<visited.length; v++)
|
||||
{
|
||||
rect(visited[v][0], visited[v][1], boxSize, boxSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function mousePressed()
|
||||
{
|
||||
// sample color from canvas
|
||||
[color1, valid_start] = sampleColor(snapToGrid(mouseX), snapToGrid(mouseY));
|
||||
}
|
||||
|
||||
function mouseReleased()
|
||||
{
|
||||
// sample color from canvas
|
||||
[color2, valid_end] = sampleColor(snapToGrid(mouseX), snapToGrid(mouseY));
|
||||
|
||||
// calculate color of visited boxes & push them into boxes
|
||||
if(mouseinside())
|
||||
{
|
||||
if(valid_start && valid_end)
|
||||
{
|
||||
let numVisited = visited.length;
|
||||
for(let v=0; v<numVisited; v++)
|
||||
{
|
||||
let t = numVisited>1 ? v * 1.0/(numVisited-1) : 1;
|
||||
let mixedColor = mixbox.lerp(color1, color2, t);
|
||||
boxes.push([visited[v][0], visited[v][1], mixedColor]);
|
||||
}
|
||||
}
|
||||
else{alert("You must start and end inside colored squares.");}
|
||||
}
|
||||
|
||||
|
||||
// clear visited array
|
||||
visited = [];
|
||||
|
||||
// redraw screen to erase the overlay, clear background, draw boxes
|
||||
background(80);
|
||||
drawBoxes();
|
||||
|
||||
}
|
||||
|
||||
function drawBoxes()
|
||||
{
|
||||
noStroke();
|
||||
for(let b=0; b<boxes.length; b++)
|
||||
{
|
||||
fill(color(boxes[b][2]));
|
||||
rect(boxes[b][0], boxes[b][1], boxSize, boxSize);
|
||||
}
|
||||
}
|
||||
|
||||
function sampleColor (x, y)
|
||||
{
|
||||
for(let b=0; b<boxes.length; b++)
|
||||
{
|
||||
if(boxes[b][0] == x && boxes[b][1] == y)
|
||||
{
|
||||
return [color(boxes[b][2]), true];
|
||||
}
|
||||
}
|
||||
|
||||
return [color(255), false];
|
||||
}
|
||||
|
||||
function snapToGrid (x){
|
||||
return boxSize/2 + floor(x/boxSize) * boxSize;
|
||||
}
|
||||
|
||||
function setLineDash(list) {
|
||||
drawingContext.setLineDash(list);
|
||||
}
|
||||
|
||||
function mouseinside(){
|
||||
if(mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {return true;}
|
||||
else {return false};
|
||||
}
|
||||
162
javascript/examples/splash.html
Normal file
162
javascript/examples/splash.html
Normal file
@@ -0,0 +1,162 @@
|
||||
<!--
|
||||
Inspired by Processing sketch by Okazz
|
||||
https://openprocessing.org/sketch/1533000
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body style="background-color: #dee0e3;">
|
||||
<!-- Mixbox -->
|
||||
<script src="https://scrtwpns.com/mixbox.js"></script>
|
||||
|
||||
<div id="cnvs" align="center" style="margin-top: 50px;"> </div>
|
||||
|
||||
<!-- Code -->
|
||||
<script>
|
||||
var width = 800;
|
||||
var height = 650;
|
||||
var numSplashes = 270;
|
||||
var frame = 0;
|
||||
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
document.getElementById("cnvs").appendChild(canvas);
|
||||
var ctx = canvas.getContext("2d");
|
||||
var pixels = new Uint8ClampedArray(width*height*4);
|
||||
var imageData = new ImageData(pixels,width,height);
|
||||
fillBackground(255,255,255, 240, 240, 230, 255);
|
||||
|
||||
// grid for perlin noise
|
||||
var grid = [];
|
||||
var nodes = 128;
|
||||
var noiseScale = 0.007;
|
||||
|
||||
for (let i=0; i<nodes*nodes; i++)
|
||||
{
|
||||
var unit = [];
|
||||
var angle = Math.random() * 2 * Math.PI;
|
||||
unit.push(Math.cos(angle));
|
||||
unit.push(Math.sin(angle));
|
||||
grid.push(unit);
|
||||
}
|
||||
|
||||
// color palette
|
||||
var colors = [ [249,250,249], [249,250,249], [255,236,4], [126,2,46], [255,236,4], [13,27,68], [255,236,4], [249,250,249], [249,250,249]];
|
||||
|
||||
function update()
|
||||
{
|
||||
frame++;
|
||||
if (frame < numSplashes)
|
||||
{
|
||||
window.requestAnimationFrame(update);
|
||||
}
|
||||
};
|
||||
|
||||
function splash()
|
||||
{
|
||||
var cx = randomGauss(0.5,0.15)*width;
|
||||
var cy = randomGauss(0.5,0.15)*height;
|
||||
var radius = width/2;
|
||||
for(var i=0; i<4; i++){radius = random(10,radius);}
|
||||
numStains = randomInt(3, radius);
|
||||
|
||||
for(var i=0; i<numStains; i++)
|
||||
{
|
||||
var angle = random(0.0, 6.28);
|
||||
var stain_x = cx + radius*Math.cos(angle);
|
||||
var stain_y = cy + radius*Math.sin(angle);
|
||||
var r = randomGauss(20, 15) * random(0,random(0,random(0,2)));
|
||||
circle(stain_x, stain_y, r);
|
||||
}
|
||||
}
|
||||
|
||||
function circle(cx,cy,radius)
|
||||
{
|
||||
var colorIndex = Math.round((perlin(cx*noiseScale, cy*noiseScale)+1.0)*0.5*8);
|
||||
var clr = colors[colorIndex];
|
||||
|
||||
var x0 = Math.round(clamp(cx-radius, 0, width));
|
||||
var x1 = Math.round(clamp(cx+radius, 0, width));
|
||||
var y0 = Math.round(clamp(cy-radius, 0, height));
|
||||
var y1 = Math.round(clamp(cy+radius, 0, height));
|
||||
|
||||
var alpha = random(0.01,0.7);
|
||||
|
||||
for(var y=y0; y<y1; y++)
|
||||
for(var x=x0; x<x1; x++)
|
||||
{
|
||||
var d = dist2D(cx, cy, x, y);
|
||||
if( d < radius)
|
||||
{
|
||||
var r = pixels[(x+y*width)*4+0];
|
||||
var g = pixels[(x+y*width)*4+1];
|
||||
var b = pixels[(x+y*width)*4+2];
|
||||
|
||||
var bgColor = [r,g,b];
|
||||
var mixedColor = mixbox.lerp(bgColor, clr, alpha * smoothStep(radius, radius*0.95, d));
|
||||
|
||||
pixels[(x+y*width)*4+0] = mixedColor[0];
|
||||
pixels[(x+y*width)*4+1] = mixedColor[1];
|
||||
pixels[(x+y*width)*4+2] = mixedColor[2];
|
||||
pixels[(x+y*width)*4+3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
ctx.putImageData(imageData,0,0);
|
||||
}
|
||||
|
||||
function fillBackground(r,g,b, r2, g2, b2, a)
|
||||
{
|
||||
for(var y=0;y<height;y++)
|
||||
for(var x=0;x<width;x++)
|
||||
{
|
||||
pixels[(x+y*width)*4+0] = (x>40 && x<(width-40) && y>40 && y<(height-40)) ? r2 : r;
|
||||
pixels[(x+y*width)*4+1] = (x>40 && x<(width-40) && y>40 && y<(height-40)) ? g2 : g;
|
||||
pixels[(x+y*width)*4+2] = (x>40 && x<(width-40) && y>40 && y<(height-40)) ? b2 : b;
|
||||
pixels[(x+y*width)*4+3] = a;
|
||||
}
|
||||
ctx.putImageData(imageData,0,0);
|
||||
}
|
||||
|
||||
function clamp(x, lowerlimit, upperlimit) { if (x<lowerlimit) {return lowerlimit;} else if(x>upperlimit){return upperlimit;} else {return x;}}
|
||||
function smoothStep(edge0, edge1, x) { x = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0); return x * x * (3 - 2 * x);}
|
||||
function dist2D(ax,ay,bx,by) { return Math.sqrt((ax-bx)*(ax-bx) + (ay-by)*(ay-by));}
|
||||
function box_muller(){ return Math.sqrt(-2 * Math.log(1 - Math.random())) * Math.cos(2 * Math.PI * Math.random());}
|
||||
function remap(x, from1, to1, from2, to2) { return from2 + (to2 - from2) * ((x-from1)/(to1-from1));}
|
||||
function random(min, max) {return remap(Math.random(), 0.0, 1.0, min, max);}
|
||||
function randomInt(min, max) {return Math.round(random(min, max));}
|
||||
function randomGauss(mean, variation){return box_muller()*variation + mean;}
|
||||
function randomGaussInt(mean, variation){return Math.round(box_muller()*variation + mean);}
|
||||
function perlin(_x,_y)
|
||||
{
|
||||
var x = _x;
|
||||
var y = _y;
|
||||
|
||||
var x0 = Math.floor(x);
|
||||
var x1 = x0+1;
|
||||
var y0 = Math.floor(y);
|
||||
var y1 = y0+1;
|
||||
|
||||
var dot_LT = dot([x-x0,y-y0], grid[(x0&127) + (y0&127)*nodes]);
|
||||
var dot_RT = dot([x-x1,y-y0], grid[(x1&127) + (y0&127)*nodes]);
|
||||
var dot_LB = dot([x-x0,y-y1], grid[(x0&127) + (y1&127)*nodes]);
|
||||
var dot_RB = dot([x-x1,y-y1], grid[(x1&127) + (y1&127)*nodes]);
|
||||
|
||||
var top = lerp_smooth(dot_LT, dot_RT, x-x0);
|
||||
var bottom = lerp_smooth(dot_LB, dot_RB, x-x0);
|
||||
var intensity = lerp_smooth (top, bottom, y-y0);
|
||||
|
||||
return intensity;
|
||||
}
|
||||
function dot(a,b) {return a[0] * b[0] + a[1] * b[1];}
|
||||
function lerp_smooth(a,b,t){var t_smooth = 6*t**5 - 15*t**4 + 10*t**3; return a*(1-t_smooth) + b*t_smooth;}
|
||||
|
||||
for(var s=0; s<numSplashes; s++){splash();}
|
||||
//update();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
16
javascript/examples/svg.html
Normal file
16
javascript/examples/svg.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<svg width="256" height="256">
|
||||
<rect id="rect" width="256" height="256">
|
||||
</svg>
|
||||
<script src="https://scrtwpns.com/mixbox.js"></script>
|
||||
<script>
|
||||
var color1 = "rgb(0, 33, 133)"; // blue
|
||||
var color2 = "rgb(252, 211, 0)"; // yellow
|
||||
document.getElementById('rect').setAttribute('fill', mixbox.lerp(color1, color2, 0.5));
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
44
javascript/examples/threejs.html
Normal file
44
javascript/examples/threejs.html
Normal file
@@ -0,0 +1,44 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.js"></script>
|
||||
<script src="https://scrtwpns.com/mixbox.js"></script>
|
||||
<script>
|
||||
var scene = new THREE.Scene();
|
||||
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
|
||||
scene.background = new THREE.Color(0xffffff);
|
||||
const renderer = new THREE.WebGLRenderer();
|
||||
renderer.setSize( window.innerWidth, window.innerHeight );
|
||||
document.body.appendChild( renderer.domElement );
|
||||
|
||||
const geometry = new THREE.BoxGeometry();
|
||||
var cubes = [];
|
||||
|
||||
var color1 = new THREE.Color(0x002185); // blue
|
||||
var color2 = new THREE.Color(0xfcd300); // yellow
|
||||
|
||||
for(var i = 0; i < 7; i++) {
|
||||
var colorMix = mixbox.lerp(color1, color2, i / 6.0).toString();
|
||||
const material = new THREE.MeshBasicMaterial( { color: colorMix } );
|
||||
const cube = new THREE.Mesh( geometry, material );
|
||||
cube.position.x = ((i / 6.0) * 2.0 - 1.0) * 4.5;
|
||||
cube.rotation.x = i / 3.0;
|
||||
scene.add(cube);
|
||||
cubes.push(cube);
|
||||
}
|
||||
|
||||
camera.position.z = 5;
|
||||
|
||||
function animate() {
|
||||
requestAnimationFrame( animate );
|
||||
for(var i=0;i<7;i++) {
|
||||
cubes[i].rotation.x += 0.01;
|
||||
cubes[i].rotation.y += 0.01;
|
||||
}
|
||||
renderer.render( scene, camera );
|
||||
}
|
||||
|
||||
animate();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
78
javascript/examples/webgl.html
Normal file
78
javascript/examples/webgl.html
Normal file
@@ -0,0 +1,78 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="canvas" width="512" height="512"></canvas>
|
||||
<script src="https://scrtwpns.com/mixbox.js"></script>
|
||||
<script>
|
||||
var canvas = document.getElementById("canvas");
|
||||
var gl = canvas.getContext("webgl");
|
||||
|
||||
var vertexShader = `
|
||||
attribute vec2 position;
|
||||
|
||||
void main(void) {
|
||||
gl_Position = vec4(position, 0.0, 1.0);
|
||||
}
|
||||
`;
|
||||
|
||||
var fragmentShader = `
|
||||
precision highp float;
|
||||
|
||||
uniform sampler2D mixbox_lut;
|
||||
|
||||
#include "mixbox.glsl"
|
||||
|
||||
void main(void) {
|
||||
vec3 rgb1 = vec3(0, 0.129, 0.522); // blue
|
||||
vec3 rgb2 = vec3(0.988, 0.827, 0); // yellow
|
||||
float t = gl_FragCoord.x / 512.0; // mixing ratio
|
||||
|
||||
vec3 rgb = mixbox_lerp(rgb1, rgb2, t);
|
||||
|
||||
gl_FragColor = vec4(rgb, 1.0);
|
||||
}
|
||||
`;
|
||||
|
||||
fragmentShader = fragmentShader.replace('#include "mixbox.glsl"', mixbox.glsl());
|
||||
|
||||
var shaderProgram = gl.createProgram();
|
||||
gl.attachShader(shaderProgram, compileShader(gl, gl.VERTEX_SHADER, vertexShader));
|
||||
gl.attachShader(shaderProgram, compileShader(gl, gl.FRAGMENT_SHADER, fragmentShader));
|
||||
gl.linkProgram(shaderProgram);
|
||||
|
||||
var vertexPosition = gl.getAttribLocation(shaderProgram, "position");
|
||||
|
||||
var positions = [1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0];
|
||||
|
||||
var positionBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
|
||||
|
||||
function render(now) {
|
||||
gl.useProgram(shaderProgram);
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
gl.bindTexture(gl.TEXTURE_2D, mixbox.lutTexture(gl));
|
||||
gl.uniform1i(gl.getUniformLocation(shaderProgram, "mixbox_lut"), 0);
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
|
||||
gl.vertexAttribPointer(vertexPosition, 2, gl.FLOAT, false, 0, 0)
|
||||
gl.enableVertexAttribArray(vertexPosition);
|
||||
|
||||
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
requestAnimationFrame(render);
|
||||
}
|
||||
|
||||
requestAnimationFrame(render);
|
||||
|
||||
function compileShader(gl, type, source) {
|
||||
var shader = gl.createShader(type);
|
||||
gl.shaderSource(shader, source);
|
||||
gl.compileShader(shader);
|
||||
return shader;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
996
javascript/mixbox.esm.js
Normal file
996
javascript/mixbox.esm.js
Normal file
File diff suppressed because one or more lines are too long
1000
javascript/mixbox.js
Normal file
1000
javascript/mixbox.js
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user