先日、
「4Kモニタ用の壁紙を無料で無限生成できるウェブサービス」という記事を見かけました。
シンプルながらも独特な雰囲気な壁紙がちょっと気になったので、こちらのソースを覗いてみました。
思いの外に短いJavaScriptのコードだったので、
自サイトの壁紙としてやったら面白いかも、
と思った次第です。
オリジナルのコードでは各種パラメータを乱数で生成しているのですが、
色や模様がはっきりしない場合とか出たりするので、少し調整することにしました。
また、自サイトはもともと背景色を白でデザインしてあることもあり、
文字が読みにくくならないように壁紙全体を白っぽくなるようにしました。
それでも、記事本文のページでやってみるとややうるさくなる感じがあったので、
記事一覧のフロントページのみで壁紙を導入するようにしました。
なお、
壁紙自動生成は実験的な取り組みのつもりなので、
気に入らなくなったり、飽きてきたら元の単なる白一色に戻すかもしれません(^_^;)
参考までに、
オリジナルのコードの内で調整した部分を以下に載せます。
なお、canvas のサイズは予め設定されているものとします。
/**
* Generate a set of randomized values to create a wallpaper from.
*/
function generateValues( width ) {
const random = Math.random,
floor = Math.floor,
// line segments (either few, or fluent lines (200))
segments = ( random() < 0.5 ) ? 1 + floor( 9 * random() ) : 200,
// wavelength
wl = width / ( 5 + ( 10 * random() ) ),
// number of layers
layers = 3 + floor( 10 * random() ),
// lightness
//light = 15 + ( 45 * Math.random() );
light = 50; // 輝度は固定。
// calculate light increment based on available 'space' between 'light and either 0 or 100
let lightIncrement,
maxLightIncrement;
if( random() < 0.5 ){
maxLightIncrement = ( ( 100 - light ) / layers );
//lightIncrement = 0.33 * maxLightIncrement + random( 0.67 * maxLightIncrement );
lightIncrement = maxLightIncrement; // 常に最大。
} else {
maxLightIncrement = light / layers;
//lightIncrement = -( 0.33 * maxLightIncrement + random( 0.67 * maxLightIncrement ) );
lightIncrement = -maxLightIncrement; // 常に最大。
}
// other random values
return {
segments,
wl,
layers,
hueStart: 360 * random(),
hueIncrement: 20 - ( 40 * ( random() ) ),
ampl: ( 0.1 * wl ) + ( 0.9 * wl ) * random(),
offset: width * random(),
offsetIncrement: width/20 + (width/10) * random(),
//sat: 10 + ( 30 * random() ),
sat: 50, // 彩度は固定。
light,
lightIncrement
};
}
/**
* Draw the wallpaper onto the canvas, using values from the URL or a fresh set.
*/
function draw(canvas){
const ctx = canvas.getContext( '2d' ),
width = canvas.width,
height = canvas.height,
values = generateValues( width ),
{
segments,
layers,
hueStart,
hueIncrement,
wl,
ampl,
offset,
offsetIncrement,
sat,
light,
lightIncrement
} = values;
// background
ctx.fillStyle = 'hsl( ' + hueStart + ', ' + sat + '%, ' + light + '% )';
ctx.fillRect( 0, 0, width, height );
// draw the layers
for( let l=0; l<layers; l++ ){
let h = hueStart + ( (l+1) * hueIncrement ),
s = sat,
v = light + ( (l+1) * lightIncrement ),
layerOffset = offset + ( offsetIncrement * l ),
offsetY = ( (l+0.5) * ( height / layers ) ),
startY = offsetY + ( ampl * Math.sin( layerOffset / wl ) );
ctx.fillStyle = 'hsl( ' + h + ', ' + s + '%, ' + v + '% )';
ctx.beginPath();
ctx.moveTo( 0, startY );
for( let i=0; i<=segments; i++ ){
let x = i * width / segments;
ctx.lineTo( x , startY + ( ampl * Math.sin( ( layerOffset + x ) / wl ) ) );
}
ctx.lineTo( width, height );
ctx.lineTo( 0, height );
ctx.lineTo( 0, startY );
ctx.fill();
}
// 最終的に全体を白っぽくする。
ctx.fillStyle = 'rgba(255,255,255,.8)';
ctx.fillRect( 0, 0, width, height );
}
ということで、
試してみるにはこちらへ移動してください。
リロードやリサイズする毎に壁紙をランダムに更新します。
ちょっとパッとしない感じになったりするので(^_^;)、
別なやり方でやってみました -> こちら。