svgjs transform imported element - javascript

Using svg.js I am able to import a fragment from an existing svg file and add it to the dom. However I am not able to then manipulate that element using svg.js.
Here is my code.
$.get('img/sprite.svg', function (doc) {
var figure = $(doc).find('g#figure')[0];
var figureHTML = figure.outerHTML;
var added = draw.svg(figureHTML);
added.transform({rotate: 90});
});
Here is the link to the docs for importing
http://svgjs.dev/importing-exporting/
and the links for transforming
http://svgjs.dev/manipulating/transforms/
I can't get any transformations to work on the imported element.

Perhaps there is another way, but if one uses css selectors one can get a handle into the objects in question then the transformations work.
var elements = SVG.select('g#figure')
.transform({rotate: 90});
http://svgjs.dev/referencing/

Related

Interaction on namespaced SVG

I am trying to insert a SVG diagram on a Web page and add JavaScript interaction.
My issue: the SVG includes elements with namespaces, and when I insert it inline, only the non-namespaced elements are rendered. I have tried direct insertion in the html, innerHTML, and the SVGjs library, all give the same result.
Is there a way to render namespaced SVG on the page and interact with it?
For the record, the SVG files come from Visio and I don't have control on the namespaces. Also, I am using Reactjs if that can help.
Sample script (both methods work but strip out namespaced elements):
fetch (fileURL)
.then(response => response.text())
.then((image) => {
let startOfSvg = image.indexOf('<svg')
startOfSvg = startOfSvg >= 0 ? startOfSvg : 0
// innerHTML method
document.getElementById("map").innerHTML = image.slice(startOfSvg);
// svg.js library
const draw = SVG(image.slice(startOfSvg))
.addTo('#map')
.size('100%', 450);
}
There is a checkbox to export SVG without visio namespace. Other than that, you could take a look at my exporter (it can export pure svg as well, depending on the template you use): https://unmanagedvisio.com/products/svg-publish

Convert node elements to image

I'm looking for library or code snippet which will help me to convert HTML DOM node element to image/png file.
I tried to use html2canvas library but it does not render svg nodes, and in my current project i have a lot of them. Also i tried to use canvg library to convert all SVG elements on page to Canvas elements, but canvg always threw error on render step:
Uncaught (in promise) TypeError: Cannot read property 'ImageClass' of
undefined
Code snippet that is used to conver SVGs to Canvas:
export const svgToCanvas = () => {
const print = document.getElementsByClassName('print-page')[0]
const svgElements = print.getElementsByTagName('svg')
_.each(svgElements, e => {
let xml
const canvas = document.createElement('canvas')
canvas.className = 'screenShotTempCanvas'
xml = (new window.XMLSerializer()).serializeToString(e)
xml = xml.replace(/xmlns=http:\/\/www\.w3\.org\/2000\/svg/, '')
canvg(canvas, xml)
e.parentNode.insertBefore(canvas, e.nextSibling)
e.classList.add('tempHide')
e.style.display = 'none'
})
const temps = document.getElementsByClassName('.screenShotTempCanvas')
_.each(temps, e => {
e.remove()
})
const svgs = document.getElementsByClassName('tempHide')
_.each(svgs, e => {
if (e) {
e.style.display = 'block'
e.classList.remove('tempHide')
}
})
}
Error throws on this line in canvg code:
if (nodeEnv) {
if (!s || s === '') {
return;
}
ImageClass = opts['ImageClass']; //<= error throws here
CanvasClass = target.constructor;
svg.loadXml(target.getContext('2d'), s);
return;
}
I also tried to convert node to PDF format using jsPDF and html-pdf libraries, but in this case all styles are disappeared from node, and i need them not to be lost.
Can anyone provide me with appropriate approach how to convert HTML DOM node (which is rich on SVG elements) to image ?
This seems to be the result of seriously bad testing and documenting by canvg authors. The line the error is thrown at was introduced as part of a pull request that supposedly added support for executing canvg in a node environment. But it seems it was only tested to work if it was used as a dependency in node-svg2img.
If you look at that source, you will find the following (excerpt):
var canvg = require('canvg'),
Canvas = require('canvas');
function convert(svgContent) {
var canvas = new Canvas();
canvg(canvas, svgContent, { ignoreMouse: true, ignoreAnimation: true, ImageClass: Canvas.Image });
return canvas;
}
As you can see, canvg is called with an option ImageClass that has never been documented, and whose content is dependent on a module canvas that is never stated as a dependency for canvg. (And that is not a lightweight one, it is the complete <canvas> implementation.)
Now you never stated that you were doing all this in node, but I will assume you do, otherwise I would not understand why the line causing the error got called at all.
It seems a successfull call to document.createElement('canvas') does not indicate you have the canvas module installed. This note in the jsdom doc tells you what needs to be done.
From there, calling canvg in your code with
import Image from 'canvas';
canvg(canvas, xml, {ImageClass: Image});
should get you runing.

d3 importing external .SVG files and bind them to objects for functions

Exactly like this (https://bl.ocks.org/mbostock/2206590) but calling the data from an external .svg file drawn from Inkscape instead.
Here is my code so far (using Laravel):
<script>
// Extract the width and height that was computed by CSS.
var chartDiv = document.getElementById("vis");
var width = chartDiv.clientWidth;
var height = chartDiv.clientHeight;
// load the external svg from a file
d3.xml("{{ asset('assets/groundfloor.svg') }}", "image/svg+xml", function(xml) {
var importedNode = document.importNode(xml.documentElement, true);
d3.select("div#vis")
.each(function() {
this.appendChild(importedNode);
})
// inside of our d3.xml callback, call another function
// that styles individual paths inside of our imported svg
styleImportedSVG(); //calling the zoom feature from a function (it can be called here too)
});
Yes, I have looked it up everywhere on the web for the last few days browsing through multiple blocks and none have yet to make a sample on external .svg files and how to append the elements inside it and assigning it to objects.
EDIT: To be clear, I wanted to know the external .svg file variation of .data(importedNode.feature(us, us.objects.buildings).features) and if that's the only thing I need to change in order to bind the elements in my svg file to objects for d3 functions.

Sketch Plugin: How to programmatically make a layer exportable?

So, in Sketch, you can mark a layer/group as exportable.
And then the layer/group can be exported as .png/.svg/.pdf etc. I was trying to make a Sketch Plugin recently, where I need to mark a layer/group as exportable from code. A layer in code is represented using MSLayer and group is MSLayerGroup. The sketch documentation is not mature enough yet, so I used ClassDump to extract all the headers that has been used in the app. I have been looking for a method that might seem to do my job, but it has been days and am still out of luck. Can anybody please help me out in this regard?
Sketch supports slice and export to image. You can use - (void)saveArtboardOrSlice:(id)arg1 toFile:(id)arg2;
method of MSDocument.
This is almost how to do it.
var loopLayerChildren = [[layerToExport children] objectEnumerator],
rect = [MSSliceTrimming trimmedRectForSlice:layer],
useSliceLayer = false,
exportFilePath,
slice;
// Check for MSSliceLayer and overwrite the rect if present
while (layerChild = [loopLayerChildren nextObject]) {
if ([layerChild class] == 'MSSliceLayer') {
rect = [MSSliceTrimming trimmedRectForSlice:layerChild];
useSliceLayer = true;
}
}
slice = [MSExportRequest requestWithRect:rect scale:1];
if (!useSliceLayer) {
slice.shouldTrim = true;
}
// export to image file
[(this.document) saveArtboardOrSlice: slice toFile:exportFilePath];
Reference from #GeertWill's sketch-to-xcode-assets-catalog plugin.

How to get Layer Objects by IDs

Photoshop scripting API getting me struggled. It's not dev-friendly at all.
But still I believe, that there is a way to get layer object when I have layer id?
All I want to do is to duplicate selected layers to a new document. Layers might be nested within groups.
You're right, such a simple action shouldn't be so complicated.
Try this:
var curDoc = app.activeDocument;
var newDoc = app.documents.add(curDoc.width,curDoc.height,curDoc.resolution);//add a new doc with the same dimensions as the active one
app.activeDocument = curDoc;//set the original doc as active
try {
var curLayer = newDoc.activeLayer;//get a reference to the new document's current layer
curDoc.activeLayer.duplicate(newDoc,ElementPlacement.PLACEATBEGINNING);//dupliate the active layer from the original doc to the new/copy doc
} catch(e) { alert(e); }
If it helps, Photshop ships with a reference(which should be in PHOTOSHOP_INSTALL_FOLDER/Scripting/Documents) and/or the Object Model Viewer (visible under the Help menu in ExtendScriptToolkit).

Categories