@nativescript-community/ui-svg
Version:
Adds support for SVGs in your NativeScript apps.
213 lines • 9.5 kB
JavaScript
import { Paint, PorterDuffXfermode } from '@nativescript-community/ui-canvas';
import { File, ImageAsset, Screen, Utils, knownFolders, path } from '@nativescript/core';
import { SVG as SVGBase, xfermodeFromString } from './canvas.common';
import { getSVGKImage } from './index.ios';
export { CanvasSVG } from './canvas.common';
let bgdImagePaint;
function getRenderer(src) {
if (!src) {
return null;
}
let imagePath;
if (src instanceof File) {
return SVGRenderer.alloc().initWithInputStream(NSInputStream.alloc().initWithFileAtPath(src.path));
}
else if (src instanceof ImageAsset) {
imagePath = src.ios;
}
else {
imagePath = src;
}
if (Utils.isFileOrResourcePath(imagePath)) {
if (imagePath.indexOf(Utils.RESOURCE_PREFIX) === 0) {
const resName = imagePath.substr(Utils.RESOURCE_PREFIX.length);
return SVGRenderer.alloc().initWithResourceNameInBundle(resName, NSBundle.mainBundle);
}
else if (imagePath.indexOf('~/') === 0) {
const strPath = path.join(knownFolders.currentApp().path, imagePath.replace('~/', ''));
return SVGRenderer.alloc().initWithContentsOfURL(NSURL.fileURLWithPath(strPath));
}
else if (imagePath.indexOf('/') === 0) {
return SVGRenderer.alloc().initWithContentsOfURL(NSURL.fileURLWithPath(imagePath));
// return com.caverock.androidsvg.SVG.getFromInputStream(stream);
}
}
return SVGRenderer.alloc().initWithString(imagePath);
}
export class SVG extends SVGBase {
makeScales(availableWidth, availableHeight) {
const width = this.getWidth(availableWidth, availableHeight);
const height = this.getHeight(availableWidth, availableHeight);
const svgSize = this._svgkimage.size;
// const svgSize = this._renderer.viewRect && this._renderer.viewRect.size;
const nativeWidth = svgSize ? svgSize.width : width;
const nativeHeight = svgSize ? svgSize.height : height;
const nativeAspectRatio = nativeWidth / nativeHeight;
const boundedAspectRatio = width / height;
let paintedWidth = width;
let paintedHeight = height;
const myGravity = this._stretch;
if (myGravity === 'aspectFit') {
if (nativeAspectRatio >= boundedAspectRatio) {
paintedHeight = paintedWidth / nativeAspectRatio;
}
else {
paintedWidth = paintedHeight * nativeAspectRatio;
}
const xOrigin = (width - paintedWidth) / 2.0;
const yOrigin = (height - paintedHeight) / 2.0;
return { px: xOrigin, py: yOrigin, sx: paintedWidth / nativeWidth, sy: paintedHeight / nativeHeight };
}
else if (myGravity === 'aspectFill') {
if (nativeAspectRatio <= boundedAspectRatio) {
paintedHeight = paintedWidth / nativeAspectRatio;
}
else {
paintedWidth = paintedHeight * nativeAspectRatio;
}
const xOrigin = (width - paintedWidth) / 2.0;
const yOrigin = (height - paintedHeight) / 2.0;
return { px: xOrigin, py: yOrigin, sx: paintedWidth / nativeWidth, sy: paintedHeight / nativeHeight };
}
else {
// flipped
return { px: 0, py: 0, sx: width / nativeWidth, sy: height / nativeHeight };
}
}
getWidth(availableWidth, availableHeight) {
if (this.width) {
return super.getWidth(availableWidth, availableHeight);
}
const svgSize = this._svgkimage.size;
// const svgSize = this._renderer.viewRect && this._renderer.viewRect.size;
if (svgSize) {
const nativeWidth = svgSize.width;
const nativeHeight = svgSize.height;
const width = Math.min(nativeWidth, availableWidth);
const height = this.height ? this.getHeight(availableWidth, availableHeight) : Math.min(nativeHeight, availableHeight);
let paintedWidth = width;
let paintedHeight = height;
const nativeAspectRatio = nativeWidth / nativeHeight;
const boundedAspectRatio = width / height;
if (this._stretch === 'aspectFit') {
if (nativeAspectRatio >= boundedAspectRatio) {
paintedHeight = paintedWidth / nativeAspectRatio;
}
else {
paintedWidth = paintedHeight * nativeAspectRatio;
}
return paintedWidth;
}
else if (this._stretch === 'aspectFill') {
if (nativeAspectRatio <= boundedAspectRatio) {
paintedHeight = paintedWidth / nativeAspectRatio;
}
else {
paintedWidth = paintedHeight * nativeAspectRatio;
}
return paintedWidth;
}
return paintedWidth;
}
return 0;
}
getHeight(availableWidth, availableHeight) {
if (this.height) {
return super.getHeight(availableWidth, availableHeight);
}
const svgSize = this._svgkimage.size;
// const svgSize = this._renderer.viewRect && this._renderer.viewRect.size;
if (svgSize) {
const nativeWidth = svgSize.width;
const nativeHeight = svgSize.height;
const height = Math.min(nativeHeight, availableHeight);
const width = this.width ? this.getWidth(availableWidth, availableHeight) : Math.min(nativeHeight, availableHeight);
let paintedWidth = width;
let paintedHeight = height;
const nativeAspectRatio = nativeWidth / nativeHeight;
const boundedAspectRatio = width / height;
if (this._stretch === 'aspectFit') {
if (nativeAspectRatio >= boundedAspectRatio) {
paintedHeight = paintedWidth / nativeAspectRatio;
}
else {
paintedWidth = paintedHeight * nativeAspectRatio;
}
return paintedHeight;
}
else if (this._stretch === 'aspectFill') {
if (nativeAspectRatio <= boundedAspectRatio) {
paintedHeight = paintedWidth / nativeAspectRatio;
}
else {
paintedWidth = paintedHeight * nativeAspectRatio;
}
return paintedHeight;
}
return paintedHeight;
}
return 0;
}
drawOnCanvas(canvas, parent) {
if (this._svgkimage) {
// const startTime = new Date().valueOf();
// const wasCached = !!this._cachedImage;
const availableWidth = Utils.layout.toDevicePixels(canvas.getWidth());
const availableHeight = Utils.layout.toDevicePixels(canvas.getHeight());
const scales = this.makeScales(availableWidth, availableHeight);
canvas.save();
if (this.blendingMode || this.cache) {
let newImage = this._cachedImage;
if (!this.cache || !this._cachedImage) {
const svgSize = this._svgkimage.size;
// const svgSize = this._renderer.viewRect && this._renderer.viewRect.size;
UIGraphicsBeginImageContextWithOptions(svgSize, false, Screen.mainScreen.scale);
const _context = UIGraphicsGetCurrentContext();
this._svgkimage.renderInContext(_context);
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
if (this.cache) {
this._cachedImage = newImage;
}
}
// const coreImage = CIImage.alloc().initWithCGImage(_newImage.CGImage);
// const filter = CIFilter.filterWithName('CIMultiplyBlendMode');
// filter.setValueForKey(coreImage, 'inputImage');
// const output = filter.outputImage;
// const context = CIContext.context();
// const CGImage = context.createCGImageFromRect(output, output.extent);
if (this.blendingMode) {
if (!bgdImagePaint) {
bgdImagePaint = new Paint();
}
bgdImagePaint.setXfermode(new PorterDuffXfermode(xfermodeFromString(this.blendingMode)));
}
canvas.translate(scales.px, scales.py);
canvas.scale(scales.sx, scales.sy, 0, 0);
canvas.drawBitmap(newImage, 0, 0, bgdImagePaint);
}
else {
canvas.translate(scales.px, scales.py);
canvas.scale(scales.sx, scales.sy, 0, 0);
this._svgkimage.renderInContext(canvas.ctx);
}
// console.log('drawSvg', wasCached, Date.now() - startTime, 'ms');
canvas.restore();
}
}
set src(value) {
this._src = value;
this._svgkimage = getSVGKImage(value);
// this._renderer = getRenderer(value);
}
get src() {
return this._src;
}
set stretch(value) {
this._stretch = value;
}
get stretch() {
return this._stretch;
}
}
//# sourceMappingURL=canvas.ios.js.map