円や多角形をランダムに配置する背景をSVGで作る
公開:
更新:
以前に「サークルがランダムに配置される背景をSVGで作る」というものを書きましたが、それを発展させて多角形も混ぜられるようにしてみました。
今回はブラーとかはありません。
多角形の座標算出は、こちらの記事を参考にしました。
HTML5 Canvas で Polygon(多角形)描画 | TM Life
対応しているのは Internet Explorer 9+, Firefox 4+, Chrome, Safari 5.1+, Opera 11.6+です。
Random Geometric Pattern Background with SVG
一応、コメントつきのも載せておきます。
(function () {
/**
* window がロードされたら実効
*/
window.addEventListener('load', function () {
geometricPatternBG({
/**
* 図形の頂点の数。0-2は円、3は三角形、4は四角形...となる
* 負の数は不可
* 配列を指定すると、そこで指定された頂点数の図形をランダムに選択する
*/
apexes: [0, 3, 4],
/**
* 描画する図形の数
*/
count: 30,
/**
* 描画する図形の半径の最小値と最大値
* 多角形は指定された半径の円の内側に頂点が接するサイズとなる
*/
radius: {min: 20, max: 60},
/**
* RGB 値の最小値と最大値
* 大きいほど白に近くなる
*/
rgb: {min: 160, max: 240},
/**
* 図形の塗りつぶしの不透明度
* 色は上記のRGB値の範囲内でランダムに選択されたもの
*/
fillOpacity: 0.3,
/**
* ストローク(図形の縁)の太さ
*/
strokeWidth: 1,
/**
* ストロークの不透明度
* 色はfillと同じ色
*/
strokeOpacity: 0.5
});
}, false);
/**
* インラインSVGを作ってbodyに追加する
*/
function geometricPatternBG(userSettings) {
/**
* 初期設定
*/
var defaultSettings = {
apexes : 0,
count : 30,
radius : {min: 30, max: 100},
rgb : {min: 150, max: 250},
fillOpacity : 0.2,
strokeWidth : 1,
strokeOpacity: 0.3
};
/**
* ユーザー設定がなければ初期設定を使用する
*/
var options = userSettings || defaultSettings;
/**
* 表示領域の大きさ
* viewBox 属性や、図形の座標指定に使う
*/
var view = {
width : window.innerWidth,
height: window.innerHeight
};
/**
* 関数
*/
var fnc = {
/**
* SVGの要素を作る
*/
createSVG: function (tagName) {
return document.createElementNS('http://www.w3.org/2000/svg', tagName);
},
/**
* min-maxで指定された範囲内でランダムな数を返す
* 第3引数は整数にするかどうか
*/
getRandomNumber: function (min, max, integer) {
var num = Math.random() * (max - min);
if (integer) {
num = Math.floor(num);
}
return num + min;
},
/**
* min-maxの範囲内の数値のランダムなRGBカラーコードを返す
* rgb(255,255,255)のような文字列
*/
getRandomRGB: function (min, max) {
var channels = [];
for (var i = 0; i < 3; i++) {
channels.push(this.getRandomNumber(min, max, true));
}
return 'rgb(' + channels.join(',') + ')';
},
/**
* 属性と値をオブジェクトでまとめて指定する
*/
setAttributes: function (element, object) {
for (var z in object) {
if (object.hasOwnProperty(z)) {
element.setAttribute(z, object[z])
}
}
return element;
},
/**
* スタイルをオブジェクトでまとめて指定する
*/
setStyles: function (element, object) {
for (var n in object) {
if (object.hasOwnProperty(n)) {
element.style[n] = object[n];
}
}
return element;
}
};
/**
* 図形を作る
*/
var makeFigure = {
/**
* 円を作る
* 基準の座標(x, y)、半径、色を引数で指定する
*/
circle: function (coordinateX, coordinateY, radius, color) {
var circle = fnc.createSVG('circle');
circle = fnc.setAttributes(circle, {
'cx' : coordinateX,
'cy' : coordinateY,
'r' : radius,
'fill' : color,
'stroke' : color,
'fill-opacity' : options.fillOpacity,
'stroke-width' : options.strokeWidth,
'stroke-opacity': options.strokeOpacity
});
return circle;
},
/**
* 多角形を作る
* 頂点の数、基準の座標(x, y)、半径、色を引数で指定する
*/
polygon: function (apexes, coordinateX, coordinateY, radius, color) {
var polygon = fnc.createSVG('polygon');
// 中心角(rad)
var centralAngleRad = (Math.PI * 2) / apexes;
// 図形を回転させる角度
var rotateAngleRad = fnc.getRandomNumber(0, 180, true) * Math.PI / 180;
// 各頂点の座標を入れる配列
var apexCoordinates = [];
// 各頂点の座標を算出
for (var i = 0; i < apexes; i++) {
var x = Math.cos(centralAngleRad * i + rotateAngleRad) * radius + coordinateX;
var y = Math.sin(centralAngleRad * i + rotateAngleRad) * radius + coordinateY;
apexCoordinates.push(x + ',' + y);
}
polygon.setAttribute('points', apexCoordinates.join(' '));
polygon = fnc.setAttributes(polygon, {
'fill' : color,
'stroke' : color,
'fill-opacity' : options.fillOpacity,
'stroke-width' : options.strokeWidth,
'stroke-opacity': options.strokeOpacity
});
return polygon;
}
};
/**
* svg要素を作成
*/
var svg = fnc.createSVG('svg');
/**
* 指定された数だけ図形を作ってsvg要素の子要素に
*/
for (var i = 0, l = options.count; i < l; i++) {
// 頂点の数
var apx;
/**
* 頂点の数が配列なら、その配列からランダムに1つ選択
* そうでなければ設定で指定された数値を使う
*/
if (Array.isArray(options.apexes)) {
var rand = fnc.getRandomNumber(0, options.apexes.length, true);
apx = Math.floor(options.apexes[rand]);
} else {
apx = Math.floor(options.apexes);
}
// 図形の中心となるX座標
var baseX = fnc.getRandomNumber(0, view.width);
// 図形の中心となるY座標
var baseY = fnc.getRandomNumber(0, view.height);
// 図形の半径
var radius = fnc.getRandomNumber(options.radius.min, options.radius.max);
// 図形の塗りつぶしの色
var color = fnc.getRandomRGB(options.rgb.min, options.rgb.max);
// 図形用の変数
var figure;
/**
* 頂点数が0以上2以下なら円を作る
* 3以上ならその頂点数の多角形を作る
*/
if (apx > -1 && apx < 3) {
figure = makeFigure.circle(baseX, baseY, radius, color);
} else if (apx > 2) {
figure = makeFigure.polygon(apx, baseX, baseY, radius, color);
}
// svg要素の子要素に図形を追加
svg.appendChild(figure);
}
// svg要素にviewBox属性を指定
svg.setAttribute('viewBox', [0, 0, view.width, view.height].join(' '));
// svg要素に背景として使用するためのスタイル指定をする
svg = fnc.setStyles(svg, {
display : 'block',
position: 'fixed',
zIndex : -1,
width : '100%',
height : '100%'
});
// svg要素をbody要素に追加する
document.getElementsByTagName('body')[0].appendChild(svg);
}
})();
もっと改良できると思いますので、よかったら『jsdo.it』でフォークしてください。
それと、使うのは自由ですが何かあっても責任は負いません。