Creating and scaling SVG for printer output - pdf

I have an app which creates a basic svg tile which is about 300 x 150px. I need to duplicate this tile, such that I can create a nice printout on two A4 pages, or a single A3 page. So, basically, I'm just doing page layout 101, in svg rather than Photoshop/whatever.
Can anyone give me any pointers on how to start this? At the moment, I'm doing it very naively:
set a large canvas, of about 1500 x 1500px
duplicate the tile 4 x 6 times in JavaScript
print from the browser
This is more-or-less passable, but doesn't look good. Would it help to set up a canvas with a physical size of an A4 page? If I do this, I then have the problem that the tile is a complex graphic which I have currently created using pixel units. Even if I do this, the browser will presumably ignore the canvas size anyway. Or should I convert to pdf first? If I do this, I still need to work out how to set up an svg 'page' that will convert well to pdf. And do any tools actually support the svg 1.2 page stuff?
Note that I can't use Inkscape, since my svg code is entirely JavaScript.

Don't use canvas for this!
The point of SVG is scalable graphics. You can just scale the SVG yourself in the browser and then print from there.
If you want to scale SVG then all you have to do is either apply a CSS scale:
http://jsfiddle.net/simonsarris/xYZyf/
Or an SVG scale:
http://jsfiddle.net/simonsarris/xYZyf/1/

Related

Unwanted lines appearing between semi-transparent elements in PDF output (generated with puppeteer)

I've been working on a node project with puppeteer.js for the last few months, but I have just started to use transparency in PDF files and have come across a real head scratcher...
What am I trying to achieve?
3 horizontally adjoined, semi transparent divs, rendered as part of a pdf via puppeteer.
What's the problem?
In html they display as expected. But in PDF a faint line appears between elements which I believe is to do with "stitching". I'm aware that this wont show in print, but I want to get rid of on screen. This is a mock up of some simple content which shows the behaviour I'm experiencing:
What have I tried?
Experimenting with Puppeteer params (antialiasing, flattening, color
flags like -webkit-print-color-adjust) - [Result: no change]
SVG elements with transparent background. [Result: lines still
appear]
A single div using a linear gradient with 3 block colors. [Result: Works when viewed in Acrobat, but has the weird effect in chrome where elements shift slightly to the right (pictured: top row - single div with linear gradient. Bottom row - black boxes used here as a guide for assessing alignment)].
SVG elements using a linear gradient. [Result: Same as above]
Flattening the pdf [Result: This does solve the problem, but degrades
the quality of the rest of the image, therefore not suitable]
I'm finding it difficult to find a solution as I'm not really sure where the behaviour is emanating from (the PDF, puppeteer, browser?). If anybody has any ideas, I'd be very grateful!
Thanks

matplotib: two overlaid transparent images look different when saved as svg or png

I'm trying to overlay two transparent images with matplotlib and save the result, but the result looks different depending on the file type. Specifically it's much more washed-out when saving to svg.
Here's an example. In this case, I could just add the two images before displaying them, but this is just a simple example. In reality what I'm trying to do is more complicated (images of different sizes with different colormaps), so they have to be plotted separately.
Example code:
f, ax = plt.subplots(figsize=(2,2))
ax.imshow(np.eye(3), alpha=.5)
ax.imshow(np.eye(3)[::-1], alpha=.5)
f.savefig('example.png')
f.savefig('example.svg')
The png file looks just like it does on the screen, but the svg file looks washed out. I would like to know how to save as svg, without the washed-out effect (i.e. it should look like it does on the screen).
As a bonus question, why does the png plot appear different depending on the order in which I plot the transparent images? The second image always looks stronger. Interestingly, in the svg, both are equally washed out.
Example saved as png:
Example saved as svg:
matplotlib version: 3.1.3
python version: 3.7.7
Thanks for any tips!
I'll post what I think is going on, but if someone can answer with more legit information I'll accept it.
I think that every time you call imshow with an alpha value, it blends the current image in the axis with the new image, using (new * alpha + current * (1-alpha)). The problem with this is that if you display 10 images each with alpha 0.5, then the first image is attenuated to nothing by the iterative blending, whereas the last image gets to be 50% of the final result. Nonetheless this is apparently the method used for rendering to the screen and saving to png.
In contrast, when saving to svg, it saves each image as a separate overlay with its own alpha. The svg container or renderer then uses some more intelligent method that considers all overlaid images at once. However, in my particular case, this leads to a more washed-out look because all the images are partially transparent.

Best approach to load a PDF in canvas

Here, I have tried a various approach for loading a PDF to the canvas. First thing is I used the library PDF.JS to load the PDF in canvas. The problem I faced with PDF.JS is that when I try to zoom in to the PDF - [
I tried two approaches
Zooming in to the object and the canvas - which made browser crash in a certain point in scaling
Converting the image as a object and loading it to canvas using Fabric JS and zooming in to the object - which made the pixel to break while zooming in (scaling was not proper to a certain point while zooming in)]
So, suggest me some best way to upload a PDF in canvas with perfect scaling while zooming in without any crash to the browser when I upload some bigger size PDF.
Thanks In advance! :)
I don't know if you still need this, but I stumbled upon a tutorial a few days ago that exactly shows how to do your use case (if I understand it correctly and you're trying to zoom in). You can check it here:
tutorial

Adobe Animate CC Canvas (CreateJS) vector graphics becomes blurry on scale up

So I am new to this next-gen Flash application they call "Adobe Animate CC" and I am trying to create an interactive map scene... very basic. If you click on the USA it should zoom in. Click again it should zoom out.
The issue I am having is that even though my map was imported from an SVG file -- and from what I can tell when residing in the "Adobe Animate CC" workspace it retains its vector data -- when I apply the scale tween using CreateJS the edges of the graphic become very pixelated.
Here's the code I am using:
var _this = this;
_this.stop();
_this.america.addEventListener("click", zoomMap);
function zoomMap(event) {
createjs.Tween.get(exportRoot.world1).to({scaleX: 10, scaleY: 10, x: 4000, y: 1000}, 1000);
}
And here are some images of the pixelated result:
Even more disconcerting is that that blue-green circle is a native circle object inside a symbol. Not an svg. I would expect that at least that would stay crisp under transformation.
Is this unavoidable? Is the application caching bitmap versions of my vector files on export? Can I stop this? Can I force a re-render of the vector file during and after my tween? Is there any way around this? Does this application even really support vector graphics?
Animate might be exporting as images, but it shouldn't unless you tell it to. What does your library JavaScript look like? Are any images exported? Maybe search the source for .cache to see if Adobe is doing anything funny under the hood.
If the map is an SVG source: Unfortunately, only the only SVG support in EaselJS (which underlays the Animate export) is for svg as a "bitmap source". This means it is being treated as an image of a specific dimensions, and scaling it past "100%" will interpolate the details.
It might be possible to load it as a larger bitmap, and scale it down to start, but that will:
make it much larger in memory
still only let you scale so much
Another option is to import the SVG asset into Adobe Animate, which should convert it to a vector graphic. If it is vector in EaselJS, you can scale it as much as you want, because it uses Canvas vector APIs to draw, instead of an image source.
You mentioned that the green circle is native (I assume a shape in Animate?). Are you sure its not being exported as an image, instead of a shape? Are you caching anything?
Hope that helps!

How does Safari calculate size of svg objects?

How does Safari determine what size to output an svg in the following scenario;
SVG code
viewBox 0 0 800 800
height 100%
width 100%
css
svg width 100%
containing div width 60%
Safari outputs a much smaller svg than the 60% of screen, ok this is a bug. But what determines the size of this smaller svg, it has no connection to anything I can think of.
Just to give some background info. Safari needs both width and height in px for it to do what you want. % don-t work. But it does output the svg, and so it must make a decision somewhere about its size.
It's not a bug you're seeing. That's the correct behavior. The browser by default scales the SVG viewbox (careful with the terminology now, we're not talking about the browser viewport) to fill the CSS-determined dimensions of the SVG element. The fill behavior is determined by the SVG preserveAspectRatio attribute. By default it's set to meet, which keeps the whole SVG viewable, and the aspect ratio preserved. The alternative is slice which scales the viewbox up to cover the element, even when that means cropping. (slice behaves similarly to background-size:cover in CSS3.)
What you need to do is:
a) Don't declare explicit height or width in the SVG file. If your graphics editor is generating them, just go in by hand and delete them. According to the spec, if no width and height are specified, a value of 100% is assumed, so your pseudocode is redundant at best.
b) Make sure you're setting an explicit height for the svg element in CSS. I recommend developer or Canary builds of Chrome for troubleshooting responsive svg sizing, as there is a bug in Chrome 18 Dev Tools that has since been fixed. Once you've got it working in Chrome, it will almost certainly also work in Safari.
c) Figure out how you want to set preserveAspectRatio and manually edit the svg to put in the declaration.
If you're still having trouble, please post a jsfiddle. It's much easier for other people to comment on.