html2canvas
Version:
Screenshots with JavaScript
353 lines (300 loc) • 14.1 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.parseBackgroundImage = exports.parseBackground = exports.calculateBackgroundRepeatPath = exports.calculateBackgroundPosition = exports.calculateBackgroungPositioningArea = exports.calculateBackgroungPaintingArea = exports.calculateGradientBackgroundSize = exports.calculateBackgroundSize = exports.BACKGROUND_ORIGIN = exports.BACKGROUND_CLIP = exports.BACKGROUND_SIZE = exports.BACKGROUND_REPEAT = undefined;
var _Color = require('../Color');
var _Color2 = _interopRequireDefault(_Color);
var _Length = require('../Length');
var _Length2 = _interopRequireDefault(_Length);
var _Size = require('../drawing/Size');
var _Size2 = _interopRequireDefault(_Size);
var _Vector = require('../drawing/Vector');
var _Vector2 = _interopRequireDefault(_Vector);
var _Bounds = require('../Bounds');
var _padding = require('./padding');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var BACKGROUND_REPEAT = exports.BACKGROUND_REPEAT = {
REPEAT: 0,
NO_REPEAT: 1,
REPEAT_X: 2,
REPEAT_Y: 3
};
var BACKGROUND_SIZE = exports.BACKGROUND_SIZE = {
AUTO: 0,
CONTAIN: 1,
COVER: 2,
LENGTH: 3
};
var BACKGROUND_CLIP = exports.BACKGROUND_CLIP = {
BORDER_BOX: 0,
PADDING_BOX: 1,
CONTENT_BOX: 2
};
var BACKGROUND_ORIGIN = exports.BACKGROUND_ORIGIN = BACKGROUND_CLIP;
var AUTO = 'auto';
var BackgroundSize = function BackgroundSize(size) {
_classCallCheck(this, BackgroundSize);
switch (size) {
case 'contain':
this.size = BACKGROUND_SIZE.CONTAIN;
break;
case 'cover':
this.size = BACKGROUND_SIZE.COVER;
break;
case 'auto':
this.size = BACKGROUND_SIZE.AUTO;
break;
default:
this.value = new _Length2.default(size);
}
};
var calculateBackgroundSize = exports.calculateBackgroundSize = function calculateBackgroundSize(backgroundImage, image, bounds) {
var width = 0;
var height = 0;
var size = backgroundImage.size;
if (size[0].size === BACKGROUND_SIZE.CONTAIN || size[0].size === BACKGROUND_SIZE.COVER) {
var targetRatio = bounds.width / bounds.height;
var currentRatio = image.width / image.height;
return targetRatio < currentRatio !== (size[0].size === BACKGROUND_SIZE.COVER) ? new _Size2.default(bounds.width, bounds.width / currentRatio) : new _Size2.default(bounds.height * currentRatio, bounds.height);
}
if (size[0].value) {
width = size[0].value.getAbsoluteValue(bounds.width);
}
if (size[0].size === BACKGROUND_SIZE.AUTO && size[1].size === BACKGROUND_SIZE.AUTO) {
height = image.height;
} else if (size[1].size === BACKGROUND_SIZE.AUTO) {
height = width / image.width * image.height;
} else if (size[1].value) {
height = size[1].value.getAbsoluteValue(bounds.height);
}
if (size[0].size === BACKGROUND_SIZE.AUTO) {
width = height / image.height * image.width;
}
return new _Size2.default(width, height);
};
var calculateGradientBackgroundSize = exports.calculateGradientBackgroundSize = function calculateGradientBackgroundSize(backgroundImage, bounds) {
var size = backgroundImage.size;
var width = size[0].value ? size[0].value.getAbsoluteValue(bounds.width) : bounds.width;
var height = size[1].value ? size[1].value.getAbsoluteValue(bounds.height) : size[0].value ? width : bounds.height;
return new _Size2.default(width, height);
};
var AUTO_SIZE = new BackgroundSize(AUTO);
var calculateBackgroungPaintingArea = exports.calculateBackgroungPaintingArea = function calculateBackgroungPaintingArea(curves, clip) {
switch (clip) {
case BACKGROUND_CLIP.BORDER_BOX:
return (0, _Bounds.calculateBorderBoxPath)(curves);
case BACKGROUND_CLIP.PADDING_BOX:
default:
return (0, _Bounds.calculatePaddingBoxPath)(curves);
}
};
var calculateBackgroungPositioningArea = exports.calculateBackgroungPositioningArea = function calculateBackgroungPositioningArea(backgroundOrigin, bounds, padding, border) {
var paddingBox = (0, _Bounds.calculatePaddingBox)(bounds, border);
switch (backgroundOrigin) {
case BACKGROUND_ORIGIN.BORDER_BOX:
return bounds;
case BACKGROUND_ORIGIN.CONTENT_BOX:
var paddingLeft = padding[_padding.PADDING_SIDES.LEFT].getAbsoluteValue(bounds.width);
var paddingRight = padding[_padding.PADDING_SIDES.RIGHT].getAbsoluteValue(bounds.width);
var paddingTop = padding[_padding.PADDING_SIDES.TOP].getAbsoluteValue(bounds.width);
var paddingBottom = padding[_padding.PADDING_SIDES.BOTTOM].getAbsoluteValue(bounds.width);
return new _Bounds.Bounds(paddingBox.left + paddingLeft, paddingBox.top + paddingTop, paddingBox.width - paddingLeft - paddingRight, paddingBox.height - paddingTop - paddingBottom);
case BACKGROUND_ORIGIN.PADDING_BOX:
default:
return paddingBox;
}
};
var calculateBackgroundPosition = exports.calculateBackgroundPosition = function calculateBackgroundPosition(position, size, bounds) {
return new _Vector2.default(position[0].getAbsoluteValue(bounds.width - size.width), position[1].getAbsoluteValue(bounds.height - size.height));
};
var calculateBackgroundRepeatPath = exports.calculateBackgroundRepeatPath = function calculateBackgroundRepeatPath(background, position, size, backgroundPositioningArea, bounds) {
var repeat = background.repeat;
switch (repeat) {
case BACKGROUND_REPEAT.REPEAT_X:
return [new _Vector2.default(Math.round(bounds.left), Math.round(backgroundPositioningArea.top + position.y)), new _Vector2.default(Math.round(bounds.left + bounds.width), Math.round(backgroundPositioningArea.top + position.y)), new _Vector2.default(Math.round(bounds.left + bounds.width), Math.round(size.height + backgroundPositioningArea.top + position.y)), new _Vector2.default(Math.round(bounds.left), Math.round(size.height + backgroundPositioningArea.top + position.y))];
case BACKGROUND_REPEAT.REPEAT_Y:
return [new _Vector2.default(Math.round(backgroundPositioningArea.left + position.x), Math.round(bounds.top)), new _Vector2.default(Math.round(backgroundPositioningArea.left + position.x + size.width), Math.round(bounds.top)), new _Vector2.default(Math.round(backgroundPositioningArea.left + position.x + size.width), Math.round(bounds.height + bounds.top)), new _Vector2.default(Math.round(backgroundPositioningArea.left + position.x), Math.round(bounds.height + bounds.top))];
case BACKGROUND_REPEAT.NO_REPEAT:
return [new _Vector2.default(Math.round(backgroundPositioningArea.left + position.x), Math.round(backgroundPositioningArea.top + position.y)), new _Vector2.default(Math.round(backgroundPositioningArea.left + position.x + size.width), Math.round(backgroundPositioningArea.top + position.y)), new _Vector2.default(Math.round(backgroundPositioningArea.left + position.x + size.width), Math.round(backgroundPositioningArea.top + position.y + size.height)), new _Vector2.default(Math.round(backgroundPositioningArea.left + position.x), Math.round(backgroundPositioningArea.top + position.y + size.height))];
default:
return [new _Vector2.default(Math.round(bounds.left), Math.round(bounds.top)), new _Vector2.default(Math.round(bounds.left + bounds.width), Math.round(bounds.top)), new _Vector2.default(Math.round(bounds.left + bounds.width), Math.round(bounds.height + bounds.top)), new _Vector2.default(Math.round(bounds.left), Math.round(bounds.height + bounds.top))];
}
};
var parseBackground = exports.parseBackground = function parseBackground(style, resourceLoader) {
return {
backgroundColor: new _Color2.default(style.backgroundColor),
backgroundImage: parseBackgroundImages(style, resourceLoader),
backgroundClip: parseBackgroundClip(style.backgroundClip),
backgroundOrigin: parseBackgroundOrigin(style.backgroundOrigin)
};
};
var parseBackgroundClip = function parseBackgroundClip(backgroundClip) {
switch (backgroundClip) {
case 'padding-box':
return BACKGROUND_CLIP.PADDING_BOX;
case 'content-box':
return BACKGROUND_CLIP.CONTENT_BOX;
}
return BACKGROUND_CLIP.BORDER_BOX;
};
var parseBackgroundOrigin = function parseBackgroundOrigin(backgroundOrigin) {
switch (backgroundOrigin) {
case 'padding-box':
return BACKGROUND_ORIGIN.PADDING_BOX;
case 'content-box':
return BACKGROUND_ORIGIN.CONTENT_BOX;
}
return BACKGROUND_ORIGIN.BORDER_BOX;
};
var parseBackgroundRepeat = function parseBackgroundRepeat(backgroundRepeat) {
switch (backgroundRepeat.trim()) {
case 'no-repeat':
return BACKGROUND_REPEAT.NO_REPEAT;
case 'repeat-x':
case 'repeat no-repeat':
return BACKGROUND_REPEAT.REPEAT_X;
case 'repeat-y':
case 'no-repeat repeat':
return BACKGROUND_REPEAT.REPEAT_Y;
case 'repeat':
return BACKGROUND_REPEAT.REPEAT;
}
if (process.env.NODE_ENV !== 'production') {
console.error('Invalid background-repeat value "' + backgroundRepeat + '"');
}
return BACKGROUND_REPEAT.REPEAT;
};
var parseBackgroundImages = function parseBackgroundImages(style, resourceLoader) {
var sources = parseBackgroundImage(style.backgroundImage).map(function (backgroundImage) {
if (backgroundImage.method === 'url') {
var key = resourceLoader.loadImage(backgroundImage.args[0]);
backgroundImage.args = key ? [key] : [];
}
return backgroundImage;
});
var positions = style.backgroundPosition.split(',');
var repeats = style.backgroundRepeat.split(',');
var sizes = style.backgroundSize.split(',');
return sources.map(function (source, index) {
var size = (sizes[index] || AUTO).trim().split(' ').map(parseBackgroundSize);
var position = (positions[index] || AUTO).trim().split(' ').map(parseBackgoundPosition);
return {
source: source,
repeat: parseBackgroundRepeat(typeof repeats[index] === 'string' ? repeats[index] : repeats[0]),
size: size.length < 2 ? [size[0], AUTO_SIZE] : [size[0], size[1]],
position: position.length < 2 ? [position[0], position[0]] : [position[0], position[1]]
};
});
};
var parseBackgroundSize = function parseBackgroundSize(size) {
return size === 'auto' ? AUTO_SIZE : new BackgroundSize(size);
};
var parseBackgoundPosition = function parseBackgoundPosition(position) {
switch (position) {
case 'bottom':
case 'right':
return new _Length2.default('100%');
case 'left':
case 'top':
return new _Length2.default('0%');
case 'auto':
return new _Length2.default('0');
}
return new _Length2.default(position);
};
var parseBackgroundImage = exports.parseBackgroundImage = function parseBackgroundImage(image) {
var whitespace = /^\s$/;
var results = [];
var args = [];
var method = '';
var quote = null;
var definition = '';
var mode = 0;
var numParen = 0;
var appendResult = function appendResult() {
var prefix = '';
if (method) {
if (definition.substr(0, 1) === '"') {
definition = definition.substr(1, definition.length - 2);
}
if (definition) {
args.push(definition.trim());
}
var prefix_i = method.indexOf('-', 1) + 1;
if (method.substr(0, 1) === '-' && prefix_i > 0) {
prefix = method.substr(0, prefix_i).toLowerCase();
method = method.substr(prefix_i);
}
method = method.toLowerCase();
if (method !== 'none') {
results.push({
prefix: prefix,
method: method,
args: args
});
}
}
args = [];
method = definition = '';
};
image.split('').forEach(function (c) {
if (mode === 0 && whitespace.test(c)) {
return;
}
switch (c) {
case '"':
if (!quote) {
quote = c;
} else if (quote === c) {
quote = null;
}
break;
case '(':
if (quote) {
break;
} else if (mode === 0) {
mode = 1;
return;
} else {
numParen++;
}
break;
case ')':
if (quote) {
break;
} else if (mode === 1) {
if (numParen === 0) {
mode = 0;
appendResult();
return;
} else {
numParen--;
}
}
break;
case ',':
if (quote) {
break;
} else if (mode === 0) {
appendResult();
return;
} else if (mode === 1) {
if (numParen === 0 && !method.match(/^url$/i)) {
args.push(definition.trim());
definition = '';
return;
}
}
break;
}
if (mode === 0) {
method += c;
} else {
definition += c;
}
});
appendResult();
return results;
};