sketch.p5.js (135 lines of code) (raw):
var sketchConfig = {
width: window.innerWidth,
height: window.innerHeight,
bgcolor: _rgb(66, 66, 66),
layers: []
//backImgSrc: 'http://localhost:8000/experiment_bg.png'
};
function showLoaderAt(pos) {
//console.log('+++++ showLoaderAt ', pos);
//setTimeout(function() {
d3.select('#loader-wrapper').style('opacity', 1);
d3.select('#loader-wrapper p').text('Rendering... ' + Math.floor(pos * 100) + '%');
d3.select('#loading-bar').style('width', Math.floor(pos * 100) + '%');
//}, 1);
}
function hideLoader() {
//console.log('+++++ hideLoader');
//setTimeout(function() {
d3.select('#loader-wrapper').style('opacity', 0);
d3.select('#loading-bar').style('width', '0%');
//}, 1);
}
function loadChangedValuesFrom(newConfig) {
Object.keys(newConfig).forEach(function(key) {
if (newConfig[key]) sketchConfig[key] = newConfig[key];
});
}
var canvas, ctx;
var pxDensity;
var lastPixelsTime, lastPointData;
var loadingResources = false;
var resourcesReceived = false;
var BLEND_TO_P5;
function preload() {
if (loadingResources || resourcesReceived) return;
// console.log('preload');
pxDensity = pixelDensity();
loadingResources = true;
loadSketchImages(this, function() {
resourcesReceived = true;
loadingResources = false;
if (window.__sendFirstBang) {
window.__sendFirstBang();
}
});
}
function setup() {
//console.log('setup');
var bgcolor = sketchConfig.bgcolor;
clear();
background(color(bgcolor.r, bgcolor.g, bgcolor.b));
d3.select('#rpd-jb-preview-target').selectAll('.sketch-canvas').remove();
canvas = createCanvas(sketchConfig.width, sketchConfig.height).parent('rpd-jb-preview-target');
canvas.canvas.className = 'sketch-canvas';
canvas.canvas.style.visibility = 'visible';
ctx = canvas.drawingContext;
noLoop();
updateSketchConfig(sketchConfig, true);
}
function draw() {
if (loadingResources) return;
//console.log('draw');
showLoaderAt(0, 'Rendering');
BLEND_TO_P5 = {
N: 'NORMAL',
B: 'BLEND',
A: 'ADD',
K: 'DARKEST',
L: 'LIGHTEST',
D: 'DIFFERENCE',
X: 'EXCLUSION',
M: 'MULTIPLY',
S: 'SCREEN',
R: 'REPLACE',
O: 'OVERLAY',
H: 'HARD_LIGHT',
F: 'SOFT_LIGHT',
G: 'DODGE',
U: 'BURN'
};
var p5 = this;
// ==========
// faster version, just ensures loading bar is shown, usually it stays at 0% until the end,
// since GPU is busy with drawing layers
// setTimeout(function() {
// clear();
// var layers = sketchConfig.layers;
// for (var i = 0; i < layers.length; i++) {
// if (layers[i] && layers[i] != 'dark') {
// showLoaderAt((i + 1) / layers.length, 'Rendering');
// console.time(layers[i].name || 'layer-' + i);
// layers[i].func(p5, layers[i].conf, ctx);
// console.timeEnd(layers[i].name || 'layer-' + i);
// }
// if (i == (layers.length - 1)) hideLoader();
// }
// hideLoader();
// }, 10);
// ==========
// a tiny bit slower version, ensures to show loading bar for every step by waiting 10msec
// between calls to free up GPU
var layersToRender = sketchConfig.layers.values;
var bgcolor = sketchConfig.layers.background || sketchConfig.bgcolor;
var drawLayer = Kefir.emitter();
var p5 = this;
clear();
background(color(bgcolor.r, bgcolor.g, bgcolor.b));
drawLayer.delay(10).onValue(function(v) {
showLoaderAt((v.index + 1) / layersToRender.length, 'Rendering');
var layer = v.layer;
//console.time(layer.name || 'layer-' + v.index);
applyRenderOptions(p5, v.renderOptions, v.index);
layer.func(p5, layer.conf, ctx, v.renderOptions);
resetRenderOptions(p5);
//console.timeEnd(layer.name || 'layer-' + v.index);
if (v.index == (layersToRender.length - 1)) {
hideLoader();
}
});
for (var i = 0; i < layersToRender.length; i++) {
drawLayer.emit({
index: i,
layer: layersToRender[i][0],
renderOptions: layersToRender[i][1]
});
}
// hideLoader();
}
function applyRenderOptions(p, options, index) {
var layerBlendMode = options.blendMode;
if (layerBlendMode) {
//console.log('apply blend mode', index, layerBlendMode, BLEND_TO_P5[layerBlendMode]);
p.blendMode(p[BLEND_TO_P5[layerBlendMode]]);
} else {
//console.log('apply blend mode', index, '', 'NORMAL');
p.blendMode(p.NORMAL);
}
//p.opacity(options.opacity);
ctx.globalAlpha = options.opacity;
}
function resetRenderOptions(p) {
//p.blendMode(p.NORMAL);
//p.opacity(1);
ctx.globalAlpha = 1;
}
var updateStream = Kefir.emitter();
updateStream.filter(function(value) {
//return value.config.srcPixels && value.config.srcPixels.pixels.length && value.config.logo && value.config.logo.product;
return value.config.layers.values && (value.config.layers.values.length > 0);
})
.throttle(1000, { leading: false })
.onValue(function(value) {
loadChangedValuesFrom(value.config);
if (!value.noRedraw) redraw();
});
function updateSketchConfig(newConfig, noRedraw) {
//var recalcPoints = (newConfig.chaos || newConfig.width || newConfig.height) ? true : false;
loadChangedValuesFrom(newConfig);
//var recalcPoints = (newConfig.irregularity || newConfig.maxPoints || newConfig.width || newConfig.height) ? true : false;
//loadChangedValuesFrom(newConfig);
// if (recalcPoints && lastBgImage) {
// pointData = collectPointData(sketchConfig, lastBgImage.pixels, lastBgImage.width, lastBgImage.height);
// }
//noiseSeed(random(1000));
//if (!noRedraw) redraw();
updateStream.emit({
config: newConfig,
noRedraw: noRedraw
});
}
function gradientLine(x1, y1, x2, y2, color1, color2) {
if (ctx) {
var grad = ctx.createLinearGradient(x1, y1, x2, y2);
grad.addColorStop(0, color1);
grad.addColorStop(1, color2);
ctx.strokeStyle = grad;
line(x1, y1, x2, y2);
}
}
function drawLoading() {
text('loading', 0, 0);
}