@salla.sa/twilight-components
Version:
Salla Web Component
1,696 lines (1,448 loc) • 68.9 kB
JavaScript
/*!
* Crafted with ❤ by Salla
*/
import { g as getDefaultExportFromCjs } from './_commonjsHelpers.js';
function _mergeNamespaces(n, m) {
m.forEach(function (e) {
e && typeof e !== 'string' && !Array.isArray(e) && Object.keys(e).forEach(function (k) {
if (k !== 'default' && !(k in n)) {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
});
return Object.freeze(n);
}
var filepondPluginImagePreview$3 = {exports: {}};
/*!
* FilePondPluginImagePreview 4.6.12
* Licensed under MIT, https://opensource.org/licenses/MIT/
* Please visit https://pqina.nl/filepond/ for details.
*/
var filepondPluginImagePreview$2 = filepondPluginImagePreview$3.exports;
var hasRequiredFilepondPluginImagePreview;
function requireFilepondPluginImagePreview () {
if (hasRequiredFilepondPluginImagePreview) return filepondPluginImagePreview$3.exports;
hasRequiredFilepondPluginImagePreview = 1;
(function (module, exports) {
/* eslint-disable */
(function(global, factory) {
(module.exports = factory())
;
})(filepondPluginImagePreview$2, function() {
// test if file is of type image and can be viewed in canvas
var isPreviewableImage = function isPreviewableImage(file) {
return /^image/.test(file.type);
};
function _slicedToArray(arr, i) {
return (
_arrayWithHoles(arr) ||
_iterableToArrayLimit(arr, i) ||
_nonIterableRest()
);
}
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterableToArrayLimit(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (
var _i = arr[Symbol.iterator](), _s;
!(_n = (_s = _i.next()).done);
_n = true
) {
_arr.push(_s.value);
if (_arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i['return'] != null) _i['return']();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
function _nonIterableRest() {
throw new TypeError('Invalid attempt to destructure non-iterable instance');
}
var vectorMultiply = function vectorMultiply(v, amount) {
return createVector(v.x * amount, v.y * amount);
};
var vectorAdd = function vectorAdd(a, b) {
return createVector(a.x + b.x, a.y + b.y);
};
var vectorNormalize = function vectorNormalize(v) {
var l = Math.sqrt(v.x * v.x + v.y * v.y);
if (l === 0) {
return {
x: 0,
y: 0
};
}
return createVector(v.x / l, v.y / l);
};
var vectorRotate = function vectorRotate(v, radians, origin) {
var cos = Math.cos(radians);
var sin = Math.sin(radians);
var t = createVector(v.x - origin.x, v.y - origin.y);
return createVector(
origin.x + cos * t.x - sin * t.y,
origin.y + sin * t.x + cos * t.y
);
};
var createVector = function createVector() {
var x =
arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
var y =
arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
return { x: x, y: y };
};
var getMarkupValue = function getMarkupValue(value, size) {
var scalar =
arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
var axis = arguments.length > 3 ? arguments[3] : undefined;
if (typeof value === 'string') {
return parseFloat(value) * scalar;
}
if (typeof value === 'number') {
return value * (axis ? size[axis] : Math.min(size.width, size.height));
}
return;
};
var getMarkupStyles = function getMarkupStyles(markup, size, scale) {
var lineStyle = markup.borderStyle || markup.lineStyle || 'solid';
var fill = markup.backgroundColor || markup.fontColor || 'transparent';
var stroke = markup.borderColor || markup.lineColor || 'transparent';
var strokeWidth = getMarkupValue(
markup.borderWidth || markup.lineWidth,
size,
scale
);
var lineCap = markup.lineCap || 'round';
var lineJoin = markup.lineJoin || 'round';
var dashes =
typeof lineStyle === 'string'
? ''
: lineStyle
.map(function(v) {
return getMarkupValue(v, size, scale);
})
.join(',');
var opacity = markup.opacity || 1;
return {
'stroke-linecap': lineCap,
'stroke-linejoin': lineJoin,
'stroke-width': strokeWidth || 0,
'stroke-dasharray': dashes,
stroke: stroke,
fill: fill,
opacity: opacity
};
};
var isDefined = function isDefined(value) {
return value != null;
};
var getMarkupRect = function getMarkupRect(rect, size) {
var scalar =
arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
var left =
getMarkupValue(rect.x, size, scalar, 'width') ||
getMarkupValue(rect.left, size, scalar, 'width');
var top =
getMarkupValue(rect.y, size, scalar, 'height') ||
getMarkupValue(rect.top, size, scalar, 'height');
var width = getMarkupValue(rect.width, size, scalar, 'width');
var height = getMarkupValue(rect.height, size, scalar, 'height');
var right = getMarkupValue(rect.right, size, scalar, 'width');
var bottom = getMarkupValue(rect.bottom, size, scalar, 'height');
if (!isDefined(top)) {
if (isDefined(height) && isDefined(bottom)) {
top = size.height - height - bottom;
} else {
top = bottom;
}
}
if (!isDefined(left)) {
if (isDefined(width) && isDefined(right)) {
left = size.width - width - right;
} else {
left = right;
}
}
if (!isDefined(width)) {
if (isDefined(left) && isDefined(right)) {
width = size.width - left - right;
} else {
width = 0;
}
}
if (!isDefined(height)) {
if (isDefined(top) && isDefined(bottom)) {
height = size.height - top - bottom;
} else {
height = 0;
}
}
return {
x: left || 0,
y: top || 0,
width: width || 0,
height: height || 0
};
};
var pointsToPathShape = function pointsToPathShape(points) {
return points
.map(function(point, index) {
return ''
.concat(index === 0 ? 'M' : 'L', ' ')
.concat(point.x, ' ')
.concat(point.y);
})
.join(' ');
};
var setAttributes = function setAttributes(element, attr) {
return Object.keys(attr).forEach(function(key) {
return element.setAttribute(key, attr[key]);
});
};
var ns = 'http://www.w3.org/2000/svg';
var svg = function svg(tag, attr) {
var element = document.createElementNS(ns, tag);
if (attr) {
setAttributes(element, attr);
}
return element;
};
var updateRect = function updateRect(element) {
return setAttributes(
element,
Object.assign({}, element.rect, element.styles)
);
};
var updateEllipse = function updateEllipse(element) {
var cx = element.rect.x + element.rect.width * 0.5;
var cy = element.rect.y + element.rect.height * 0.5;
var rx = element.rect.width * 0.5;
var ry = element.rect.height * 0.5;
return setAttributes(
element,
Object.assign(
{
cx: cx,
cy: cy,
rx: rx,
ry: ry
},
element.styles
)
);
};
var IMAGE_FIT_STYLE = {
contain: 'xMidYMid meet',
cover: 'xMidYMid slice'
};
var updateImage = function updateImage(element, markup) {
setAttributes(
element,
Object.assign({}, element.rect, element.styles, {
preserveAspectRatio: IMAGE_FIT_STYLE[markup.fit] || 'none'
})
);
};
var TEXT_ANCHOR = {
left: 'start',
center: 'middle',
right: 'end'
};
var updateText = function updateText(element, markup, size, scale) {
var fontSize = getMarkupValue(markup.fontSize, size, scale);
var fontFamily = markup.fontFamily || 'sans-serif';
var fontWeight = markup.fontWeight || 'normal';
var textAlign = TEXT_ANCHOR[markup.textAlign] || 'start';
setAttributes(
element,
Object.assign({}, element.rect, element.styles, {
'stroke-width': 0,
'font-weight': fontWeight,
'font-size': fontSize,
'font-family': fontFamily,
'text-anchor': textAlign
})
);
// update text
if (element.text !== markup.text) {
element.text = markup.text;
element.textContent = markup.text.length ? markup.text : ' ';
}
};
var updateLine = function updateLine(element, markup, size, scale) {
setAttributes(
element,
Object.assign({}, element.rect, element.styles, {
fill: 'none'
})
);
var line = element.childNodes[0];
var begin = element.childNodes[1];
var end = element.childNodes[2];
var origin = element.rect;
var target = {
x: element.rect.x + element.rect.width,
y: element.rect.y + element.rect.height
};
setAttributes(line, {
x1: origin.x,
y1: origin.y,
x2: target.x,
y2: target.y
});
if (!markup.lineDecoration) return;
begin.style.display = 'none';
end.style.display = 'none';
var v = vectorNormalize({
x: target.x - origin.x,
y: target.y - origin.y
});
var l = getMarkupValue(0.05, size, scale);
if (markup.lineDecoration.indexOf('arrow-begin') !== -1) {
var arrowBeginRotationPoint = vectorMultiply(v, l);
var arrowBeginCenter = vectorAdd(origin, arrowBeginRotationPoint);
var arrowBeginA = vectorRotate(origin, 2, arrowBeginCenter);
var arrowBeginB = vectorRotate(origin, -2, arrowBeginCenter);
setAttributes(begin, {
style: 'display:block;',
d: 'M'
.concat(arrowBeginA.x, ',')
.concat(arrowBeginA.y, ' L')
.concat(origin.x, ',')
.concat(origin.y, ' L')
.concat(arrowBeginB.x, ',')
.concat(arrowBeginB.y)
});
}
if (markup.lineDecoration.indexOf('arrow-end') !== -1) {
var arrowEndRotationPoint = vectorMultiply(v, -l);
var arrowEndCenter = vectorAdd(target, arrowEndRotationPoint);
var arrowEndA = vectorRotate(target, 2, arrowEndCenter);
var arrowEndB = vectorRotate(target, -2, arrowEndCenter);
setAttributes(end, {
style: 'display:block;',
d: 'M'
.concat(arrowEndA.x, ',')
.concat(arrowEndA.y, ' L')
.concat(target.x, ',')
.concat(target.y, ' L')
.concat(arrowEndB.x, ',')
.concat(arrowEndB.y)
});
}
};
var updatePath = function updatePath(element, markup, size, scale) {
setAttributes(
element,
Object.assign({}, element.styles, {
fill: 'none',
d: pointsToPathShape(
markup.points.map(function(point) {
return {
x: getMarkupValue(point.x, size, scale, 'width'),
y: getMarkupValue(point.y, size, scale, 'height')
};
})
)
})
);
};
var createShape = function createShape(node) {
return function(markup) {
return svg(node, { id: markup.id });
};
};
var createImage = function createImage(markup) {
var shape = svg('image', {
id: markup.id,
'stroke-linecap': 'round',
'stroke-linejoin': 'round',
opacity: '0'
});
shape.onload = function() {
shape.setAttribute('opacity', markup.opacity || 1);
};
shape.setAttributeNS(
'http://www.w3.org/1999/xlink',
'xlink:href',
markup.src
);
return shape;
};
var createLine = function createLine(markup) {
var shape = svg('g', {
id: markup.id,
'stroke-linecap': 'round',
'stroke-linejoin': 'round'
});
var line = svg('line');
shape.appendChild(line);
var begin = svg('path');
shape.appendChild(begin);
var end = svg('path');
shape.appendChild(end);
return shape;
};
var CREATE_TYPE_ROUTES = {
image: createImage,
rect: createShape('rect'),
ellipse: createShape('ellipse'),
text: createShape('text'),
path: createShape('path'),
line: createLine
};
var UPDATE_TYPE_ROUTES = {
rect: updateRect,
ellipse: updateEllipse,
image: updateImage,
text: updateText,
path: updatePath,
line: updateLine
};
var createMarkupByType = function createMarkupByType(type, markup) {
return CREATE_TYPE_ROUTES[type](markup);
};
var updateMarkupByType = function updateMarkupByType(
element,
type,
markup,
size,
scale
) {
if (type !== 'path') {
element.rect = getMarkupRect(markup, size, scale);
}
element.styles = getMarkupStyles(markup, size, scale);
UPDATE_TYPE_ROUTES[type](element, markup, size, scale);
};
var MARKUP_RECT = [
'x',
'y',
'left',
'top',
'right',
'bottom',
'width',
'height'
];
var toOptionalFraction = function toOptionalFraction(value) {
return typeof value === 'string' && /%/.test(value)
? parseFloat(value) / 100
: value;
};
// adds default markup properties, clones markup
var prepareMarkup = function prepareMarkup(markup) {
var _markup = _slicedToArray(markup, 2),
type = _markup[0],
props = _markup[1];
var rect = props.points
? {}
: MARKUP_RECT.reduce(function(prev, curr) {
prev[curr] = toOptionalFraction(props[curr]);
return prev;
}, {});
return [
type,
Object.assign(
{
zIndex: 0
},
props,
rect
)
];
};
var sortMarkupByZIndex = function sortMarkupByZIndex(a, b) {
if (a[1].zIndex > b[1].zIndex) {
return 1;
}
if (a[1].zIndex < b[1].zIndex) {
return -1;
}
return 0;
};
var createMarkupView = function createMarkupView(_) {
return _.utils.createView({
name: 'image-preview-markup',
tag: 'svg',
ignoreRect: true,
mixins: {
apis: ['width', 'height', 'crop', 'markup', 'resize', 'dirty']
},
write: function write(_ref) {
var root = _ref.root,
props = _ref.props;
if (!props.dirty) return;
var crop = props.crop,
resize = props.resize,
markup = props.markup;
var viewWidth = props.width;
var viewHeight = props.height;
var cropWidth = crop.width;
var cropHeight = crop.height;
if (resize) {
var _size = resize.size;
var outputWidth = _size && _size.width;
var outputHeight = _size && _size.height;
var outputFit = resize.mode;
var outputUpscale = resize.upscale;
if (outputWidth && !outputHeight) outputHeight = outputWidth;
if (outputHeight && !outputWidth) outputWidth = outputHeight;
var shouldUpscale =
cropWidth < outputWidth && cropHeight < outputHeight;
if (!shouldUpscale || (shouldUpscale && outputUpscale)) {
var scalarWidth = outputWidth / cropWidth;
var scalarHeight = outputHeight / cropHeight;
if (outputFit === 'force') {
cropWidth = outputWidth;
cropHeight = outputHeight;
} else {
var scalar;
if (outputFit === 'cover') {
scalar = Math.max(scalarWidth, scalarHeight);
} else if (outputFit === 'contain') {
scalar = Math.min(scalarWidth, scalarHeight);
}
cropWidth = cropWidth * scalar;
cropHeight = cropHeight * scalar;
}
}
}
var size = {
width: viewWidth,
height: viewHeight
};
root.element.setAttribute('width', size.width);
root.element.setAttribute('height', size.height);
var scale = Math.min(viewWidth / cropWidth, viewHeight / cropHeight);
// clear
root.element.innerHTML = '';
// get filter
var markupFilter = root.query('GET_IMAGE_PREVIEW_MARKUP_FILTER');
// draw new
markup
.filter(markupFilter)
.map(prepareMarkup)
.sort(sortMarkupByZIndex)
.forEach(function(markup) {
var _markup = _slicedToArray(markup, 2),
type = _markup[0],
settings = _markup[1];
// create
var element = createMarkupByType(type, settings);
// update
updateMarkupByType(element, type, settings, size, scale);
// add
root.element.appendChild(element);
});
}
});
};
var createVector$1 = function createVector(x, y) {
return { x: x, y: y };
};
var vectorDot = function vectorDot(a, b) {
return a.x * b.x + a.y * b.y;
};
var vectorSubtract = function vectorSubtract(a, b) {
return createVector$1(a.x - b.x, a.y - b.y);
};
var vectorDistanceSquared = function vectorDistanceSquared(a, b) {
return vectorDot(vectorSubtract(a, b), vectorSubtract(a, b));
};
var vectorDistance = function vectorDistance(a, b) {
return Math.sqrt(vectorDistanceSquared(a, b));
};
var getOffsetPointOnEdge = function getOffsetPointOnEdge(length, rotation) {
var a = length;
var A = 1.5707963267948966;
var B = rotation;
var C = 1.5707963267948966 - rotation;
var sinA = Math.sin(A);
var sinB = Math.sin(B);
var sinC = Math.sin(C);
var cosC = Math.cos(C);
var ratio = a / sinA;
var b = ratio * sinB;
var c = ratio * sinC;
return createVector$1(cosC * b, cosC * c);
};
var getRotatedRectSize = function getRotatedRectSize(rect, rotation) {
var w = rect.width;
var h = rect.height;
var hor = getOffsetPointOnEdge(w, rotation);
var ver = getOffsetPointOnEdge(h, rotation);
var tl = createVector$1(rect.x + Math.abs(hor.x), rect.y - Math.abs(hor.y));
var tr = createVector$1(
rect.x + rect.width + Math.abs(ver.y),
rect.y + Math.abs(ver.x)
);
var bl = createVector$1(
rect.x - Math.abs(ver.y),
rect.y + rect.height - Math.abs(ver.x)
);
return {
width: vectorDistance(tl, tr),
height: vectorDistance(tl, bl)
};
};
var calculateCanvasSize = function calculateCanvasSize(
image,
canvasAspectRatio
) {
var zoom =
arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
var imageAspectRatio = image.height / image.width;
// determine actual pixels on x and y axis
var canvasWidth = 1;
var canvasHeight = canvasAspectRatio;
var imgWidth = 1;
var imgHeight = imageAspectRatio;
if (imgHeight > canvasHeight) {
imgHeight = canvasHeight;
imgWidth = imgHeight / imageAspectRatio;
}
var scalar = Math.max(canvasWidth / imgWidth, canvasHeight / imgHeight);
var width = image.width / (zoom * scalar * imgWidth);
var height = width * canvasAspectRatio;
return {
width: width,
height: height
};
};
var getImageRectZoomFactor = function getImageRectZoomFactor(
imageRect,
cropRect,
rotation,
center
) {
// calculate available space round image center position
var cx = center.x > 0.5 ? 1 - center.x : center.x;
var cy = center.y > 0.5 ? 1 - center.y : center.y;
var imageWidth = cx * 2 * imageRect.width;
var imageHeight = cy * 2 * imageRect.height;
// calculate rotated crop rectangle size
var rotatedCropSize = getRotatedRectSize(cropRect, rotation);
// calculate scalar required to fit image
return Math.max(
rotatedCropSize.width / imageWidth,
rotatedCropSize.height / imageHeight
);
};
var getCenteredCropRect = function getCenteredCropRect(
container,
aspectRatio
) {
var width = container.width;
var height = width * aspectRatio;
if (height > container.height) {
height = container.height;
width = height / aspectRatio;
}
var x = (container.width - width) * 0.5;
var y = (container.height - height) * 0.5;
return {
x: x,
y: y,
width: width,
height: height
};
};
var getCurrentCropSize = function getCurrentCropSize(imageSize) {
var crop =
arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var zoom = crop.zoom,
rotation = crop.rotation,
center = crop.center,
aspectRatio = crop.aspectRatio;
if (!aspectRatio) aspectRatio = imageSize.height / imageSize.width;
var canvasSize = calculateCanvasSize(imageSize, aspectRatio, zoom);
var stage = {
width: canvasSize.width,
height: canvasSize.height};
var shouldLimit = typeof crop.scaleToFit === 'undefined' || crop.scaleToFit;
var stageZoomFactor = getImageRectZoomFactor(
imageSize,
getCenteredCropRect(stage, aspectRatio),
rotation,
shouldLimit ? center : { x: 0.5, y: 0.5 }
);
var scale = zoom * stageZoomFactor;
// start drawing
return {
widthFloat: canvasSize.width / scale,
heightFloat: canvasSize.height / scale,
width: Math.round(canvasSize.width / scale),
height: Math.round(canvasSize.height / scale)
};
};
var IMAGE_SCALE_SPRING_PROPS = {
type: 'spring',
stiffness: 0.5,
damping: 0.45,
mass: 10
};
// does horizontal and vertical flipping
var createBitmapView = function createBitmapView(_) {
return _.utils.createView({
name: 'image-bitmap',
ignoreRect: true,
mixins: { styles: ['scaleX', 'scaleY'] },
create: function create(_ref) {
var root = _ref.root,
props = _ref.props;
root.appendChild(props.image);
}
});
};
// shifts and rotates image
var createImageCanvasWrapper = function createImageCanvasWrapper(_) {
return _.utils.createView({
name: 'image-canvas-wrapper',
tag: 'div',
ignoreRect: true,
mixins: {
apis: ['crop', 'width', 'height'],
styles: [
'originX',
'originY',
'translateX',
'translateY',
'scaleX',
'scaleY',
'rotateZ'
],
animations: {
originX: IMAGE_SCALE_SPRING_PROPS,
originY: IMAGE_SCALE_SPRING_PROPS,
scaleX: IMAGE_SCALE_SPRING_PROPS,
scaleY: IMAGE_SCALE_SPRING_PROPS,
translateX: IMAGE_SCALE_SPRING_PROPS,
translateY: IMAGE_SCALE_SPRING_PROPS,
rotateZ: IMAGE_SCALE_SPRING_PROPS
}
},
create: function create(_ref2) {
var root = _ref2.root,
props = _ref2.props;
props.width = props.image.width;
props.height = props.image.height;
root.ref.bitmap = root.appendChildView(
root.createChildView(createBitmapView(_), { image: props.image })
);
},
write: function write(_ref3) {
var root = _ref3.root,
props = _ref3.props;
var flip = props.crop.flip;
var bitmap = root.ref.bitmap;
bitmap.scaleX = flip.horizontal ? -1 : 1;
bitmap.scaleY = flip.vertical ? -1 : 1;
}
});
};
// clips canvas to correct aspect ratio
var createClipView = function createClipView(_) {
return _.utils.createView({
name: 'image-clip',
tag: 'div',
ignoreRect: true,
mixins: {
apis: [
'crop',
'markup',
'resize',
'width',
'height',
'dirty',
'background'
],
styles: ['width', 'height', 'opacity'],
animations: {
opacity: { type: 'tween', duration: 250 }
}
},
didWriteView: function didWriteView(_ref4) {
var root = _ref4.root,
props = _ref4.props;
if (!props.background) return;
root.element.style.backgroundColor = props.background;
},
create: function create(_ref5) {
var root = _ref5.root,
props = _ref5.props;
root.ref.image = root.appendChildView(
root.createChildView(
createImageCanvasWrapper(_),
Object.assign({}, props)
)
);
root.ref.createMarkup = function() {
if (root.ref.markup) return;
root.ref.markup = root.appendChildView(
root.createChildView(createMarkupView(_), Object.assign({}, props))
);
};
root.ref.destroyMarkup = function() {
if (!root.ref.markup) return;
root.removeChildView(root.ref.markup);
root.ref.markup = null;
};
// set up transparency grid
var transparencyIndicator = root.query(
'GET_IMAGE_PREVIEW_TRANSPARENCY_INDICATOR'
);
if (transparencyIndicator === null) return;
// grid pattern
if (transparencyIndicator === 'grid') {
root.element.dataset.transparencyIndicator = transparencyIndicator;
}
// basic color
else {
root.element.dataset.transparencyIndicator = 'color';
}
},
write: function write(_ref6) {
var root = _ref6.root,
props = _ref6.props,
shouldOptimize = _ref6.shouldOptimize;
var crop = props.crop,
markup = props.markup,
resize = props.resize,
dirty = props.dirty,
width = props.width,
height = props.height;
root.ref.image.crop = crop;
var stage = {
width: width,
height: height,
center: {
x: width * 0.5,
y: height * 0.5
}
};
var image = {
width: root.ref.image.width,
height: root.ref.image.height
};
var origin = {
x: crop.center.x * image.width,
y: crop.center.y * image.height
};
var translation = {
x: stage.center.x - image.width * crop.center.x,
y: stage.center.y - image.height * crop.center.y
};
var rotation = Math.PI * 2 + (crop.rotation % (Math.PI * 2));
var cropAspectRatio = crop.aspectRatio || image.height / image.width;
var shouldLimit =
typeof crop.scaleToFit === 'undefined' || crop.scaleToFit;
var stageZoomFactor = getImageRectZoomFactor(
image,
getCenteredCropRect(stage, cropAspectRatio),
rotation,
shouldLimit ? crop.center : { x: 0.5, y: 0.5 }
);
var scale = crop.zoom * stageZoomFactor;
// update markup view
if (markup && markup.length) {
root.ref.createMarkup();
root.ref.markup.width = width;
root.ref.markup.height = height;
root.ref.markup.resize = resize;
root.ref.markup.dirty = dirty;
root.ref.markup.markup = markup;
root.ref.markup.crop = getCurrentCropSize(image, crop);
} else if (root.ref.markup) {
root.ref.destroyMarkup();
}
// update image view
var imageView = root.ref.image;
// don't update clip layout
if (shouldOptimize) {
imageView.originX = null;
imageView.originY = null;
imageView.translateX = null;
imageView.translateY = null;
imageView.rotateZ = null;
imageView.scaleX = null;
imageView.scaleY = null;
return;
}
imageView.originX = origin.x;
imageView.originY = origin.y;
imageView.translateX = translation.x;
imageView.translateY = translation.y;
imageView.rotateZ = rotation;
imageView.scaleX = scale;
imageView.scaleY = scale;
}
});
};
var createImageView = function createImageView(_) {
return _.utils.createView({
name: 'image-preview',
tag: 'div',
ignoreRect: true,
mixins: {
apis: ['image', 'crop', 'markup', 'resize', 'dirty', 'background'],
styles: ['translateY', 'scaleX', 'scaleY', 'opacity'],
animations: {
scaleX: IMAGE_SCALE_SPRING_PROPS,
scaleY: IMAGE_SCALE_SPRING_PROPS,
translateY: IMAGE_SCALE_SPRING_PROPS,
opacity: { type: 'tween', duration: 400 }
}
},
create: function create(_ref7) {
var root = _ref7.root,
props = _ref7.props;
root.ref.clip = root.appendChildView(
root.createChildView(createClipView(_), {
id: props.id,
image: props.image,
crop: props.crop,
markup: props.markup,
resize: props.resize,
dirty: props.dirty,
background: props.background
})
);
},
write: function write(_ref8) {
var root = _ref8.root,
props = _ref8.props,
shouldOptimize = _ref8.shouldOptimize;
var clip = root.ref.clip;
var image = props.image,
crop = props.crop,
markup = props.markup,
resize = props.resize,
dirty = props.dirty;
clip.crop = crop;
clip.markup = markup;
clip.resize = resize;
clip.dirty = dirty;
// don't update clip layout
clip.opacity = shouldOptimize ? 0 : 1;
// don't re-render if optimizing or hidden (width will be zero resulting in weird animations)
if (shouldOptimize || root.rect.element.hidden) return;
// calculate scaled preview image size
var imageAspectRatio = image.height / image.width;
var aspectRatio = crop.aspectRatio || imageAspectRatio;
// calculate container size
var containerWidth = root.rect.inner.width;
var containerHeight = root.rect.inner.height;
var fixedPreviewHeight = root.query('GET_IMAGE_PREVIEW_HEIGHT');
var minPreviewHeight = root.query('GET_IMAGE_PREVIEW_MIN_HEIGHT');
var maxPreviewHeight = root.query('GET_IMAGE_PREVIEW_MAX_HEIGHT');
var panelAspectRatio = root.query('GET_PANEL_ASPECT_RATIO');
var allowMultiple = root.query('GET_ALLOW_MULTIPLE');
if (panelAspectRatio && !allowMultiple) {
fixedPreviewHeight = containerWidth * panelAspectRatio;
aspectRatio = panelAspectRatio;
}
// determine clip width and height
var clipHeight =
fixedPreviewHeight !== null
? fixedPreviewHeight
: Math.max(
minPreviewHeight,
Math.min(containerWidth * aspectRatio, maxPreviewHeight)
);
var clipWidth = clipHeight / aspectRatio;
if (clipWidth > containerWidth) {
clipWidth = containerWidth;
clipHeight = clipWidth * aspectRatio;
}
if (clipHeight > containerHeight) {
clipHeight = containerHeight;
clipWidth = containerHeight / aspectRatio;
}
clip.width = clipWidth;
clip.height = clipHeight;
}
});
};
var SVG_MASK =
'<svg width="500" height="200" viewBox="0 0 500 200" preserveAspectRatio="none">\n <defs>\n <radialGradient id="gradient-__UID__" cx=".5" cy="1.25" r="1.15">\n <stop offset=\'50%\' stop-color=\'#000000\'/>\n <stop offset=\'56%\' stop-color=\'#0a0a0a\'/>\n <stop offset=\'63%\' stop-color=\'#262626\'/>\n <stop offset=\'69%\' stop-color=\'#4f4f4f\'/>\n <stop offset=\'75%\' stop-color=\'#808080\'/>\n <stop offset=\'81%\' stop-color=\'#b1b1b1\'/>\n <stop offset=\'88%\' stop-color=\'#dadada\'/>\n <stop offset=\'94%\' stop-color=\'#f6f6f6\'/>\n <stop offset=\'100%\' stop-color=\'#ffffff\'/>\n </radialGradient>\n <mask id="mask-__UID__">\n <rect x="0" y="0" width="500" height="200" fill="url(#gradient-__UID__)"></rect>\n </mask>\n </defs>\n <rect x="0" width="500" height="200" fill="currentColor" mask="url(#mask-__UID__)"></rect>\n</svg>';
var SVGMaskUniqueId = 0;
var createImageOverlayView = function createImageOverlayView(fpAPI) {
return fpAPI.utils.createView({
name: 'image-preview-overlay',
tag: 'div',
ignoreRect: true,
create: function create(_ref) {
var root = _ref.root,
props = _ref.props;
var mask = SVG_MASK;
if (document.querySelector('base')) {
var url = new URL(
window.location.href.replace(window.location.hash, '')
).href;
mask = mask.replace(/url\(\#/g, 'url(' + url + '#');
}
SVGMaskUniqueId++;
root.element.classList.add(
'filepond--image-preview-overlay-'.concat(props.status)
);
root.element.innerHTML = mask.replace(/__UID__/g, SVGMaskUniqueId);
},
mixins: {
styles: ['opacity'],
animations: {
opacity: { type: 'spring', mass: 25 }
}
}
});
};
/**
* Bitmap Worker
*/
var BitmapWorker = function BitmapWorker() {
self.onmessage = function(e) {
createImageBitmap(e.data.message.file).then(function(bitmap) {
self.postMessage({ id: e.data.id, message: bitmap }, [bitmap]);
});
};
};
/**
* ColorMatrix Worker
*/
var ColorMatrixWorker = function ColorMatrixWorker() {
self.onmessage = function(e) {
var imageData = e.data.message.imageData;
var matrix = e.data.message.colorMatrix;
var data = imageData.data;
var l = data.length;
var m11 = matrix[0];
var m12 = matrix[1];
var m13 = matrix[2];
var m14 = matrix[3];
var m15 = matrix[4];
var m21 = matrix[5];
var m22 = matrix[6];
var m23 = matrix[7];
var m24 = matrix[8];
var m25 = matrix[9];
var m31 = matrix[10];
var m32 = matrix[11];
var m33 = matrix[12];
var m34 = matrix[13];
var m35 = matrix[14];
var m41 = matrix[15];
var m42 = matrix[16];
var m43 = matrix[17];
var m44 = matrix[18];
var m45 = matrix[19];
var index = 0,
r = 0.0,
g = 0.0,
b = 0.0,
a = 0.0;
for (; index < l; index += 4) {
r = data[index] / 255;
g = data[index + 1] / 255;
b = data[index + 2] / 255;
a = data[index + 3] / 255;
data[index] = Math.max(
0,
Math.min((r * m11 + g * m12 + b * m13 + a * m14 + m15) * 255, 255)
);
data[index + 1] = Math.max(
0,
Math.min((r * m21 + g * m22 + b * m23 + a * m24 + m25) * 255, 255)
);
data[index + 2] = Math.max(
0,
Math.min((r * m31 + g * m32 + b * m33 + a * m34 + m35) * 255, 255)
);
data[index + 3] = Math.max(
0,
Math.min((r * m41 + g * m42 + b * m43 + a * m44 + m45) * 255, 255)
);
}
self.postMessage({ id: e.data.id, message: imageData }, [
imageData.data.buffer
]);
};
};
var getImageSize = function getImageSize(url, cb) {
var image = new Image();
image.onload = function() {
var width = image.naturalWidth;
var height = image.naturalHeight;
image = null;
cb(width, height);
};
image.src = url;
};
var transforms = {
1: function _() {
return [1, 0, 0, 1, 0, 0];
},
2: function _(width) {
return [-1, 0, 0, 1, width, 0];
},
3: function _(width, height) {
return [-1, 0, 0, -1, width, height];
},
4: function _(width, height) {
return [1, 0, 0, -1, 0, height];
},
5: function _() {
return [0, 1, 1, 0, 0, 0];
},
6: function _(width, height) {
return [0, 1, -1, 0, height, 0];
},
7: function _(width, height) {
return [0, -1, -1, 0, height, width];
},
8: function _(width) {
return [0, -1, 1, 0, 0, width];
}
};
var fixImageOrientation = function fixImageOrientation(
ctx,
width,
height,
orientation
) {
// no orientation supplied
if (orientation === -1) {
return;
}
ctx.transform.apply(ctx, transforms[orientation](width, height));
};
// draws the preview image to canvas
var createPreviewImage = function createPreviewImage(
data,
width,
height,
orientation
) {
// can't draw on half pixels
width = Math.round(width);
height = Math.round(height);
// draw image
var canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext('2d');
// if is rotated incorrectly swap width and height
if (orientation >= 5 && orientation <= 8) {
var _ref = [height, width];
width = _ref[0];
height = _ref[1];
}
// correct image orientation
fixImageOrientation(ctx, width, height, orientation);
// draw the image
ctx.drawImage(data, 0, 0, width, height);
return canvas;
};
var isBitmap = function isBitmap(file) {
return /^image/.test(file.type) && !/svg/.test(file.type);
};
var MAX_WIDTH = 10;
var MAX_HEIGHT = 10;
var calculateAverageColor = function calculateAverageColor(image) {
var scalar = Math.min(MAX_WIDTH / image.width, MAX_HEIGHT / image.height);
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var width = (canvas.width = Math.ceil(image.width * scalar));
var height = (canvas.height = Math.ceil(image.height * scalar));
ctx.drawImage(image, 0, 0, width, height);
var data = null;
try {
data = ctx.getImageData(0, 0, width, height).data;
} catch (e) {
return null;
}
var l = data.length;
var r = 0;
var g = 0;
var b = 0;
var i = 0;
for (; i < l; i += 4) {
r += data[i] * data[i];
g += data[i + 1] * data[i + 1];
b += data[i + 2] * data[i + 2];
}
r = averageColor(r, l);
g = averageColor(g, l);
b = averageColor(b, l);
return { r: r, g: g, b: b };
};
var averageColor = function averageColor(c, l) {
return Math.floor(Math.sqrt(c / (l / 4)));
};
var cloneCanvas = function cloneCanvas(origin, target) {
target = target || document.createElement('canvas');
target.width = origin.width;
target.height = origin.height;
var ctx = target.getContext('2d');
ctx.drawImage(origin, 0, 0);
return target;
};
var cloneImageData = function cloneImageData(imageData) {
var id;
try {
id = new ImageData(imageData.width, imageData.height);
} catch (e) {
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
id = ctx.createImageData(imageData.width, imageData.height);
}
id.data.set(new Uint8ClampedArray(imageData.data));
return id;
};
var loadImage = function loadImage(url) {
return new Promise(function(resolve, reject) {
var img = new Image();
img.crossOrigin = 'Anonymous';
img.onload = function() {
resolve(img);
};
img.onerror = function(e) {
reject(e);
};
img.src = url;
});
};
var createImageWrapperView = function createImageWrapperView(_) {
// create overlay view
var OverlayView = createImageOverlayView(_);
var ImageView = createImageView(_);
var createWorker = _.utils.createWorker;
var applyFilter = function applyFilter(root, filter, target) {
return new Promise(function(resolve) {
// will store image data for future filter updates
if (!root.ref.imageData) {
root.ref.imageData = target
.getContext('2d')
.getImageData(0, 0, target.width, target.height);
}
// get image data reference
var imageData = cloneImageData(root.ref.imageData);
if (!filter || filter.length !== 20) {
target.getContext('2d').putImageData(imageData, 0, 0);
return resolve();
}
var worker = createWorker(ColorMatrixWorker);
worker.post(
{
imageData: imageData,
colorMatrix: filter
},
function(response) {
// apply filtered colors
target.getContext('2d').putImageData(response, 0, 0);
// stop worker
worker.terminate();
// done!
resolve();
},
[imageData.data.buffer]
);
});
};
var removeImageView = function removeImageView(root, imageView) {
root.removeChildView(imageView);
imageView.image.width = 1;
imageView.image.height = 1;
imageView._destroy();
};
// remove an image
var shiftImage = function shiftImage(_ref) {
var root = _ref.root;
var imageView = root.ref.images.shift();
imageView.opacity = 0;
imageView.translateY = -15;
root.ref.imageViewBin.push(imageView);
return imageView;
};
// add new image
var pushImage = function pushImage(_ref2) {
var root = _ref2.root,
props = _ref2.props,
image = _ref2.image;
var id = props.id;
var item = root.query('GET_ITEM', { id: id });
if (!item) return;
var crop = item.getMetadata('crop') || {
center: {
x: 0.5,
y: 0.5
},
flip: {
horizontal: false,
vertical: false
},
zoom: 1,
rotation: 0,
aspectRatio: null
};
var background = root.query(
'GET_IMAGE_TRANSFORM_CANVAS_BACKGROUND_COLOR'
);
var markup;
var resize;
var dirty = false;
if (root.query('GET_IMAGE_PREVIEW_MARKUP_SHOW')) {
markup = item.getMetadata('markup') || [];
resize = item.getMetadata('resize');
dirty = true;
}
// append image presenter
var imageView = root.appendChildView(
root.createChildView(ImageView, {
id: id,
image: image,
crop: crop,
resize: resize,
markup: markup,
dirty: dirty,
background: background,
opacity: 0,
scaleX: 1.15,
scaleY: 1.15,
translateY: 15
}),
root.childViews.length
);
root.ref.images.push(imageView);
// reveal the preview image
imageView.opacity = 1;
imageView.scaleX = 1;
imageView.scaleY = 1;
imageView.translateY = 0;
// the preview is now ready to be drawn
setTimeout(function() {
root.dispatch('DID_IMAGE_PREVIEW_SHOW', { id: id });
}, 250);
};
var updateImage = function updateImage(_ref3) {
var root = _ref3.root,
props = _ref3.props;
var item = root.query('GET_ITEM', { id: props.id });
if (!item) return;
var imageView = root.ref.images[root.ref.images.length - 1];
imageView.crop = item.getMetadata('crop');
imageView.background = root.query(
'GET_IMAGE_TRANSFORM_CANVAS_BACKGROUND_COLOR'
);
if (root.query('GET_IMAGE_PREVIEW_MARKUP_SHOW')) {
imageView.dirty = true;
imageView.resize = item.getMetadata('resize');
imageView.markup = item.getMetadata('markup');
}
};
// replace image preview
var didUpdateItemMetadata = function didUpdateItemMetadata(_ref4) {
var root = _ref4.root,
props = _ref4.props,
action = _ref4.action;
// only filter and crop trigger redraw
if (!/crop|filter|markup|resize/.test(action.change.key)) return;
// no images to update, exit
if (!root.ref.images.length) return;
// no item found, exit
var item = root.query('GET_ITEM', { id: props.id });
if (!item) return;
// for now, update existing image when filtering
if (/filter/.test(action.change.key)) {
var imageView = root.ref.images[root.ref.images.length - 1];
applyFilter(root, action.change.value, imageView.image);
return;
}
if (/crop|markup|resize/.test(action.change.key)) {
var crop = item.getMetadata('crop');
var image = root.ref.images[root.ref.images.length - 1];
// if aspect ratio has changed, we need to create a new image
if (
crop &&
crop.aspectRatio &&
image.crop &&
image.crop.aspectRatio &&
Math.abs(crop.aspectRatio - image.crop.aspectRatio) > 0.00001
) {
var _imageView = shiftImage({ root: root });
pushImage({
root: root,
props: props,
image: cloneCanvas(_imageView.image)
});
}
// if not, we can update the current image
else {
updateImage({ root: root, props: props });
}
}
};
var canCreateImageBitmap = function canCreateImageBitmap(file) {
// Firefox versions before 58 will freeze when running createImageBitmap
// in a Web Worker so we detect those versions and return false for support
var userAgent = window.navigator.userAgent;
var isFirefox = userAgent.match(/Firefox\/([0-9]+)\./);
var firefoxVersion = isFirefox ? parseInt(isFirefox[1]) : null;
if (firefoxVersion !== null && firefoxVersion <= 58) return false;
return 'createImageBitmap' in window && isBitmap(file);
};
/**
* Write handler for when preview container has been created
*/
var didCreatePreviewContainer = function didCreatePreviewContainer(_ref5) {
var root = _ref5.root,
props = _ref5.props;
var id = props.id;
// we need to get the file data to determine the eventual image size
var item = root.query('GET_ITEM', id);
if (!item) return;
// get url to file (we'll revoke it later on when done)
var fileURL = URL.createObjectURL(item.file);
// determine image size of this item
getImageSize(fileURL, function(width, height) {
// we can now scale the panel to the final size
root.dispatch('DID_IMAGE_PREVIEW_CALCULATE_SIZE', {
id: id,
width: width,
height: height
});
});
};
var drawPreview = function drawPreview(_ref6) {
var root = _ref6.root,
props = _ref6.props;
var id = props.id;
// we need to get the file data to determine the eventual image size
var item = root.query('GET_ITEM', id);
if (!item) return;
// get url to file (we'll revoke it later on when done)
var fileURL = URL.createObjectURL(item.file);
// fallback
var loadPreviewFallback = function loadPreviewFallback() {
// let's scale the image in the main thread :(
loadImage(fileURL).then(previewImageLoaded);
};
// image is now ready
var previewImageLoaded = function previewImageLoaded(imageData) {
// the