function _define_pattern(typeId, defaults, paint_fg, extra_init)
{
function size2(x) { return Array.isArray(x) ? x : [x, x]; }
function _PatternBase(settings) {
this.id = "";
this.settings = settings || this.defaults;
this.size = size2(this.settings.size);
this.extra_init(this.settings);
}
_PatternBase.prototype.typeId = typeId;
_PatternBase.prototype.defaults = defaults;
_PatternBase.prototype._svg_fg = paint_fg;
_PatternBase.prototype.extra_init = extra_init || function(){};
_PatternBase.prototype._new_settings = function(new_settings, id)
{
var s = {...this.settings, ...new_settings};
this.settings = s;
if (id == undefined) {
this.uid = DOM.uid("pattern-" + this.typeId);
this.id = this.uid.id;
}
else if (id.id) {
this.uid = id;
this.id = id.id;
}
else {
this.id = id.toString();
}
this.size = size2(s.size);
this.extra_init(this.settings);
}
_PatternBase.prototype.svg_fg = function()
{
var s = this.settings.size;
var f = this.settings.fill * s;
return this._svg_fg(s, f, this.settings)
};
_PatternBase.prototype.svg = function()
{
var s = this.size;
var f = this.settings.fill * s[0];
var offset = this.settings.offset;
return `
<pattern id="${this.id}"
x="${offset[0]}" y="${offset[1]}"
patternUnits="userSpaceOnUse" width="${s[0]}" height="${s[1]}"
patternTransform="rotate(${this.settings.rotate}) scale(${this.settings.scale})">
<rect width="${s[0]}" height="${s[1]}" fill="${this.settings.bg}"/>
${this._svg_fg(s, f, this.settings)}
</pattern>`;
};
_PatternBase.prototype.url = function()
{
return this.uid ? this.uid.toString() : `url(#${this.id})`
};
_PatternBase.prototype.with = function(new_settings)
{
var p = new _PatternBase(this.settings);
p._new_settings(new_settings || {}, new_settings && new_settings.id);
return p;
};
function make(new_settings)
{
new_settings = new_settings || {}
if (new_settings.settings)
{
new_settings = new_settings.settings;
}
var p = new _PatternBase();
p._new_settings(new_settings, new_settings.id);
return p;
}
return make;
}