(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@antv/g-lite')) :
typeof define === 'function' && define.amd ? define(['exports', '@antv/g-lite'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.G = global.G || {}, global.G.ImageLoader = {}), global.window.G));
}(this, (function (exports, gLite) { 'use strict';
function _inheritsLoose(subClass, superClass) {
subClass.prototype = Object.create(superClass.prototype);
subClass.prototype.constructor = subClass;
_setPrototypeOf(subClass, superClass);
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
/**
* Common utilities
* @module glMatrix
*/
var ARRAY_TYPE = typeof Float32Array !== 'undefined' ? Float32Array : Array;
if (!Math.hypot) Math.hypot = function () {
var y = 0,
i = arguments.length;
while (i--) {
y += arguments[i] * arguments[i];
}
return Math.sqrt(y);
};
/**
* 4x4 Matrix
Format: column-major, when typed out it looks like row-major
The matrices are being post multiplied.
* @module mat4
*/
/**
* Creates a new identity mat4
*
* @returns {mat4} a new 4x4 matrix
*/
function create() {
var out = new ARRAY_TYPE(16);
if (ARRAY_TYPE != Float32Array) {
out[1] = 0;
out[2] = 0;
out[3] = 0;
out[4] = 0;
out[6] = 0;
out[7] = 0;
out[8] = 0;
out[9] = 0;
out[11] = 0;
out[12] = 0;
out[13] = 0;
out[14] = 0;
}
out[0] = 1;
out[5] = 1;
out[10] = 1;
out[15] = 1;
return out;
}
/**
* Set a mat4 to the identity matrix
*
* @param {mat4} out the receiving matrix
* @returns {mat4} out
*/
function identity(out) {
out[0] = 1;
out[1] = 0;
out[2] = 0;
out[3] = 0;
out[4] = 0;
out[5] = 1;
out[6] = 0;
out[7] = 0;
out[8] = 0;
out[9] = 0;
out[10] = 1;
out[11] = 0;
out[12] = 0;
out[13] = 0;
out[14] = 0;
out[15] = 1;
return out;
}
/**
* Scales the mat4 by the dimensions in the given vec3 not using vectorization
*
* @param {mat4} out the receiving matrix
* @param {ReadonlyMat4} a the matrix to scale
* @param {ReadonlyVec3} v the vec3 to scale the matrix by
* @returns {mat4} out
**/
function scale(out, a, v) {
var x = v[0],
y = v[1],
z = v[2];
out[0] = a[0] * x;
out[1] = a[1] * x;
out[2] = a[2] * x;
out[3] = a[3] * x;
out[4] = a[4] * y;
out[5] = a[5] * y;
out[6] = a[6] * y;
out[7] = a[7] * y;
out[8] = a[8] * z;
out[9] = a[9] * z;
out[10] = a[10] * z;
out[11] = a[11] * z;
out[12] = a[12];
out[13] = a[13];
out[14] = a[14];
out[15] = a[15];
return out;
}
var toString = {}.toString;
var isType = function (value, type) { return toString.call(value) === '[object ' + type + ']'; };
var isString = (function (str) {
return isType(str, 'String');
});
var ImagePool = /*#__PURE__*/function () {
function ImagePool(canvasConfig) {
this.canvasConfig = void 0;
this.imageCache = {};
this.gradientCache = {};
this.patternCache = {};
this.canvasConfig = canvasConfig;
}
var _proto = ImagePool.prototype;
_proto.getImageSync = function getImageSync(src, callback) {
if (!this.imageCache[src]) {
this.getOrCreateImage(src).then(function () {
if (callback) {
callback();
}
});
} else {
if (callback) {
callback();
}
}
return this.imageCache[src];
};
_proto.getOrCreateImage = function getOrCreateImage(src) {
var _this = this;
if (this.imageCache[src]) {
return Promise.resolve(this.imageCache[src]);
}
// @see https://github.com/antvis/g/issues/938
var createImage = this.canvasConfig.createImage;
return new Promise(function (resolve, reject) {
var image;
if (createImage) {
image = createImage(src);
} else if (gLite.isBrowser) {
image = new window.Image();
}
if (image) {
image.onload = function () {
_this.imageCache[src] = image;
resolve(image);
};
image.onerror = function (ev) {
reject(ev);
};
image.crossOrigin = 'Anonymous';
image.src = src;
}
});
};
_proto.getOrCreatePatternSync = function getOrCreatePatternSync(pattern, context, $offscreenCanvas, dpr, callback) {
var patternKey = this.generatePatternKey(pattern);
if (patternKey && this.patternCache[patternKey]) {
return this.patternCache[patternKey];
}
var image = pattern.image,
repetition = pattern.repetition,
transform = pattern.transform;
var src;
var needScaleWithDPR = false;
// Image URL
if (isString(image)) {
src = this.getImageSync(image, callback);
} else if ($offscreenCanvas) {
src = $offscreenCanvas;
needScaleWithDPR = true;
} else {
src = image;
}
// @see https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/createPattern
var canvasPattern = src && context.createPattern(src, repetition);
if (canvasPattern) {
var mat;
// @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasPattern/setTransform
if (transform) {
mat = gLite.parsedTransformToMat4(gLite.parseTransform(transform));
} else {
mat = identity(create());
}
if (needScaleWithDPR) {
scale(mat, mat, [1 / dpr, 1 / dpr, 1]);
}
canvasPattern.setTransform({
a: mat[0],
b: mat[1],
c: mat[4],
d: mat[5],
e: mat[12],
f: mat[13]
});
}
if (patternKey && canvasPattern) {
this.patternCache[patternKey] = canvasPattern;
}
return canvasPattern;
};
_proto.getOrCreateGradient = function getOrCreateGradient(params, context) {
var key = this.generateGradientKey(params);
var type = params.type,
steps = params.steps,
width = params.width,
height = params.height,
angle = params.angle,
cx = params.cx,
cy = params.cy,
size = params.size;
if (this.gradientCache[key]) {
return this.gradientCache[key];
}
var gradient = null;
if (type === gLite.GradientType.LinearGradient) {
var _computeLinearGradien = gLite.computeLinearGradient(width, height, angle),
x1 = _computeLinearGradien.x1,
y1 = _computeLinearGradien.y1,
x2 = _computeLinearGradien.x2,
y2 = _computeLinearGradien.y2;
// @see https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/createLinearGradient
gradient = context.createLinearGradient(x1, y1, x2, y2);
} else if (type === gLite.GradientType.RadialGradient) {
var _computeRadialGradien = gLite.computeRadialGradient(width, height, cx, cy, size),
x = _computeRadialGradien.x,
y = _computeRadialGradien.y,
r = _computeRadialGradien.r;
// @see https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/createRadialGradient
gradient = context.createRadialGradient(x, y, 0, x, y, r);
}
if (gradient) {
steps.forEach(function (_ref) {
var offset = _ref.offset,
color = _ref.color;
if (offset.unit === gLite.UnitType.kPercentage) {
var _gradient;
(_gradient = gradient) === null || _gradient === void 0 ? void 0 : _gradient.addColorStop(offset.value / 100, color.toString());
}
});
this.gradientCache[key] = gradient;
}
return this.gradientCache[key];
};
_proto.generateGradientKey = function generateGradientKey(params) {
var type = params.type,
width = params.width,
height = params.height,
steps = params.steps,
angle = params.angle,
cx = params.cx,
cy = params.cy,
size = params.size;
return "gradient-" + type + "-" + ((angle === null || angle === void 0 ? void 0 : angle.toString()) || 0) + "-" + ((cx === null || cx === void 0 ? void 0 : cx.toString()) || 0) + "-" + ((cy === null || cy === void 0 ? void 0 : cy.toString()) || 0) + "-" + ((size === null || size === void 0 ? void 0 : size.toString()) || 0) + "-" + width + "-" + height + "-" + steps.map(function (_ref2) {
var offset = _ref2.offset,
color = _ref2.color;
return "" + offset + color;
}).join('-');
};
_proto.generatePatternKey = function generatePatternKey(pattern) {
var image = pattern.image,
repetition = pattern.repetition;
// only generate cache for Image
if (isString(image)) {
return "pattern-" + image + "-" + repetition;
} else if (image.nodeName === 'rect') {
return "pattern-" + image.entity + "-" + repetition;
}
};
return ImagePool;
}();
var LoadImagePlugin = /*#__PURE__*/function () {
function LoadImagePlugin() {}
var _proto = LoadImagePlugin.prototype;
_proto.apply = function apply(context) {
// @ts-ignore
var renderingService = context.renderingService,
renderingContext = context.renderingContext,
imagePool = context.imagePool;
var canvas = renderingContext.root.ownerDocument.defaultView;
var handleMounted = function handleMounted(e) {
var object = e.target;
var nodeName = object.nodeName,
attributes = object.attributes;
if (nodeName === gLite.Shape.IMAGE) {
var img = attributes.img;
if (isString(img)) {
imagePool.getImageSync(img, function () {
// set dirty rectangle flag
object.renderable.dirty = true;
renderingService.dirtify();
});
}
}
};
var handleAttributeChanged = function handleAttributeChanged(e) {
var object = e.target;
var attrName = e.attrName,
newValue = e.newValue;
if (object.nodeName === gLite.Shape.IMAGE) {
if (attrName === 'img') {
if (isString(newValue)) {
imagePool.getOrCreateImage(newValue).then(function () {
// set dirty rectangle flag
object.renderable.dirty = true;
renderingService.dirtify();
});
}
}
}
};
renderingService.hooks.init.tap(LoadImagePlugin.tag, function () {
canvas.addEventListener(gLite.ElementEvent.MOUNTED, handleMounted);
canvas.addEventListener(gLite.ElementEvent.ATTR_MODIFIED, handleAttributeChanged);
});
renderingService.hooks.destroy.tap(LoadImagePlugin.tag, function () {
canvas.removeEventListener(gLite.ElementEvent.MOUNTED, handleMounted);
canvas.removeEventListener(gLite.ElementEvent.ATTR_MODIFIED, handleAttributeChanged);
});
};
return LoadImagePlugin;
}();
LoadImagePlugin.tag = 'LoadImage';
var Plugin = /*#__PURE__*/function (_AbstractRendererPlug) {
_inheritsLoose(Plugin, _AbstractRendererPlug);
function Plugin() {
var _this;
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this = _AbstractRendererPlug.call.apply(_AbstractRendererPlug, [this].concat(args)) || this;
_this.name = 'image-loader';
return _this;
}
var _proto = Plugin.prototype;
_proto.init = function init() {
// @ts-ignore
this.context.imagePool = new ImagePool(this.context.config);
this.addRenderingPlugin(new LoadImagePlugin());
};
_proto.destroy = function destroy() {
this.removeAllRenderingPlugins();
};
return Plugin;
}(gLite.AbstractRendererPlugin);
exports.ImagePool = ImagePool;
exports.Plugin = Plugin;
Object.defineProperty(exports, '__esModule', { value: true });
})));