Downloading a dynamically generated SVG file from the browser - html

If I create an image using HTML SVG element, can I then offer this as an SVG file download to the user. For example I may want to load an SVG image, apply some basic transformations to it, add some text, then let the user download the result as a vector image.
Is that possible? I have been doing something similar with Canvas but have been struggling creating a vector image. I wasn't aware that SVG elements were so versatile when I cam across them this morning but if I can do the above it would be great.

Simple solution using a data URI:
var svg_root = document.getElementById('your_svg_root_element_here');
var svg_source = svg_root.outerHTML;
var svg_data_uri = 'data:image/svg+xml;base64,' + btoa(svg_source);
var link = document.getElementById('anchor_element');
link.setAttribute('href', svg_data_uri);
Although it worked, when clicking on the link, the browser stalled for a few seconds.
This seems to be the simplest solution and should be compatible with all modern browsers. However, it has some noticeable overhead. If someone else knows a different solution (maybe using blobs or something similar), please add here as another answer!

Related

How do I make my html gif unloop? [duplicate]

I have an animated gif in an img tag that I start by rewriting the src attribute. The gif was created, though, to loop and I only want it to play once. Is there a way, with Javascript or jQuery, to stop an animated gif from playing more than once?
I was having the same problem with an animated gif. The solution is rather simple.
Open the Animated gif in Photoshop.
Go to the Window tab and select timeline(if the timeline is not already open).
At the bottom of the timeline panel, you will find an option, which says "Forever".
Change that to "Once".
Go to File> Export> Export for Web and save it as a gif.
That should do it.
can you find out how long the gif takes to loop once?
if so then you can stop the image like this:
pseudocode:
wait until the end of the image (when it is about to loop)
create a canvas element that has a static version of the gif as currently displayed drawn on it
hide gif
display canvas element in a way that makes it look like the gif froze
javascript:
var c = $("canvas")[0];
var w = c.width;
var h = c.height;
var img = $("img")[0];
setTimeout(function () {
c.getContext('2d').drawImage(img, 0, 0, w, h);
$(img).hide();
$(c).show();
},10000);
jsfiddle
edit:
I forgot to add reference to the original answer that I took this from, sorry
Stopping GIF Animation Programmatically
that one doesn't address the time factor you need for only one loop
Also, it has been mentioned that this approach is problamatic in certain cases (It actually didn't work when I try it in firefox right now...). so here are a few alternatives:
mentioned by Mark: edit the gif itself to avoid looping. this is the best option if you can.
but I've run into cases where it was not an option (like automated generation of images by a third party)
instead of rendering the static image with canvas, keep a static image version and switch to stop looping . this probablyhas most of the problems as the canvas thing
Based on this answer, it's kinda expensive, but it works. Let's say a single loop takes 2 seconds. At a setTimeout after 2 seconds kick in a setInterval, that would reset image source every millisecond:
setTimeout(function() {
setInterval(function() {
$('#img1').attr('src',$('#img1').attr('src'))
},1)
}, 2000)
again, probably just a proof of concept, but here's demo: http://jsfiddle.net/MEaWP/2/
Actually it is possible to make a gif to stop after just one iteration or any specific number of iterations, see an example below (if it is not already stopped), or in jsfiddle.
To do that the gif must be created with number of iterations specified. This could be done using Screen to Gif, it allows to open a gif or a bunch of images and edit it frame by frame.
This solution also allows you to reset the animation by imgElem.src = imgElem.src; but this does not work in MS IE/Edge.
Jurijs Kovzels's answer works in some condition but not in all.
This is browser-dependent.
It works well with Firefox. But In Google Chrome and Safari, it does not work if the gif is on the same server. The example he provided works because the gif is on the external server.
To restart gifs stored on the internal server, using Google Chrome and Safari, you need extra steps to make it work.
const img = document.getElementById("gif");
img.style = "display: none;";
img.style = "display: block;";
setTimeout(() => {
img.src = img.src;
}, 0);
This is inspired by this answer.
Not sure if this is the best way to respond to everyone and have it appear after all the previous answers and comments, but it seems to work.
I don't have much control over the gif. People post whatever gif they want as the "thankyou.gif in their account directory and then the ThankYou code runs whatever they've put there when a comment is submitted to a form they've posted. So some may loop, some may not, some may be short, some may be long. The solution I've come to is to tell people to make them 5 seconds, because that's when I'm going to fade them out, and I don't care if they loop or not.
Thanks for all the ideas.
I know I am pretty late here but..here it is...
I don't know if you would go to this length but let me share a trick.
Open the GIF in Macromedia Flash 8(it has deprecated since then), Export the GIF as Animated GIF. You will have to choose the file location. After that you would receive a dialog box with settings. In that, add the number of times you want the animation to happen. Click OK. Problem solved.

Example of Click Map is not working for me

Sorry by this dummy question! :D
I´m trying to make a clickable map with html5 canvas element, I find this good example: http://www.rubydesigner.com/blog/click-map-using-html5-canvas
But when a download it (CTRL+S) from Chrome it doesnt work. It download the html page and files folder with the JS a images, I checked the path to the images, but still the map doesnt appear. What is the problem?
UPDATE
Initial assumption about CORS turns out to not be the case here.
The code seemed to work in Chrome and although CORS typically is the cause when downloading files and using canvas with local (file://) file references. As localhost is used here via XAMMP this won't be the cause and it turns out there are more than one bugs in the online code.
Specifically the way it calculates the coordinates for the mouse:
var datapos = ((e.offsetY-2) * 300 * 4) + ((e.offsetX-1) * 4);
This will result in a NaN value due to offsetX/Y which of course cannot be used for any index.
The more appropriate way is something like this, here also compensating for canvas offset:
var rect = map_wrapper.getBoundingClientRect();
var datapos = ((e.clientY - (rect.top |0)) * 300 * 4) +
((e.clientX - (rect.left|0)) * 4);
However, I have never came across a floating point position for an element which seem to be case here (rect.top shows a float value in my browser, another little surprise) and therefor I am forcing the value to integer here (normally not necessarily.. I didn't dig deep into this). As debugging the whole code is a bit out of the scope here I will leave it with that and to OP to locate other bugs.
Correcting the position will at least give a usable index for the pixel array which in turn will return a valid (not necessarily correct it turns out, which leave checking of image, tolerane in case gamma/color correction is applied....) value for the red component (still issues when testing but as said, it's a bit out of the scope to do a full debug and correction).
Hopefully this can lead you to where the other errors are. I did not go through the html etc.

PhantomJS / CasperJS Canvas selector

Using PhantomJS V 1.8.1
Thanks in advance.
I am trying to run some tests on a website that I am developing which is using backbone.js.
One of my tests involve checking to see if a Canvas is present and clicking on it. My problem is that whatever selector I use to get the Canvas Element I cannot get the selector to find it. I use the same CSS selector in Google Chrome when viewing the page and all is OK. At first I thought that the issue may have been due to the element not being present on the page but other elements which are inserted with the canvas are present so I am 99% sure that this is not the problem.
The selectors I have tried to use are:
document.querySelectorAll('#idOfCanvas');
document.querySelectorAll('canvas#idOfCanvas');
Also if I use .classClassName:nth(1) to select the tyre selector, it still fails to work (works in Google Chrome though as does the other examples provided)
The canvas has a class name which is picked up by the selector by I would rather not use a class selector.
Any help would be much appreciated.
Cheers :)
Also
Like I mentioned I am almost certain that the Canvas exists as the container div for it exists. Also I have four elements on the page with the same className (two of which are canvases) and four elements are being returned when I run
return document.querySelectorAll('.className').length = 4;
Assuming you have something like this:
<canvas id="idOfCanvas"></canvas>
This should work:
canvas = document.getElementById("idOfCanvas");
// or
canvas = document.querySelector("#idOfCanvas"); // Only get the first match, ID's should be unique, any way.;
// or
canvas = document.querySelectorAll("#idOfCanvas")[0];
// or
canvas = document.getElementsByTagName("canvas")[0]; // Get the first <canvas> element.
However, you'll have to make sure your canvas element is actually loaded when the script is executed. Have a look at this onload tutorial, for example.
Try this :
canvas = document.getElementById(#IdOfCanvas:nth-child(1));

Stop img tags from flickering when re-rendering with JavaScript

Our web app is built entirely in JS.
To make it snappy we cache resources (models) between page views and reload the resource when you view a page.
Our flow is like this:
The user is in ViewA
The user switches to ViewB
We use the cached resource to render ViewB
We start a fetch for resource
When the resource is fetched we render again
This has a nasty drawback of causing <img> tags to flicker, ever if they are the same.
The problem is that Backbone.js, which we use, doesn't tell us if anything changed when fetching a collection, just that it was fetched.
Here's a quick demo of what I mean: http://jsfiddle.net/p7DdG/
It only happens in webkit and with <img> tags, not with background images as you can see.
We think it's kinda ugly to use background-image instead of a proper img tag.
Is there any solution to this?
The problem is gone in Chrome 19, problem solved :)
Not knowing exactly how the URL of each image is being built I'm not certain this will work, but could you check the src attribute of each image tag against the one you are replacing it with before doing the replace?
e.g.
var newImageSrc = "http://www.google.com/intl/en_com/images/srpr/logo3w.png";
if (newImageSrc != $("img").attr("src")) {
$('img').replaceWith('<img src="'+newImageSrc +'">');
}
Alternatively - load the image offscreen, and attach an event handler to the onload event of the image, which moves the image to the current image's parent tag, and remove the old one.
e.g.
var oldImage = $("#oldImageId");
var newImageSrc = "http://www.google.com/intl/en_com/images/srpr/logo3w.png";
var newImage = new Image();
$(newImage).load(function (event) {
$(oldImage).parent().append(newImage);
$(oldImage).detach();
});
$(newImage).attr("src", newImageSrc);
I ran into the same problem and noticed that sometimes images do flicker and sometimes don't. Even in latest Chrome (v33 as of now).
For posterity, flickering happens with uncached images.
In my case, Cache-Control: public, max-age=31536000 totally eliminated it.

How to submit HTML and receive a bitmap?

I have an app that allows a user to use JQuery and Javascript to add images and position them in a div dynamically.
I would like to be able to submit the div with all the HTML to a WebService and receive back an image so we have a bitmap of the result of the end user's work.
I would prefer a solution in .Net as this is what I am most familiar with but am open to pretty much anything?
I would like to be able to submit the div with all the HTML to a WebService and receive back an image
Try http://browsershots.org!
Browsershots makes screenshots of your web design in different operating systems and browsers. It is a free open-source online web application providing developers a convenient way to test their website's browser compatibility in one place.
How about this. You load the html into a webbrowser control and then use the DrawToBitmap method. It doesn't show up on intellisense and this is probably not the best solution, but it works. Observe the DocumentCompleted event and add the following code:
private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
var bmp = new Bitmap(100, 100);
var rect = new Rectangle(webBrowser.Location.X, webBrowser.Location.Y, webBrowser.Width, webBrowser.Height);
webBrowser.DrawToBitmap(bmp, rect);
bmp.Save("test.jpg", ImageFormat.Jpeg);
}
You'll probably want to change the width and height of that bitmap object (do it in some smart way or something). Hope this helps.
EDIT: I see now that you are using a webservice for this, hence this solution probably won't work. I'll leave it here just for information's sake.
I was not able to figure out how to do this by submitting the html and receiving an image but I was able to create and ASHX handler that returns a png file based on this blog post
which was good enough for my scenario.
He uses CutyCapt to take a screen shot of an existing web page, write the image to a folder on the webserver and return it.