37 items tagged “svg”
2024
Mastodon discussion about sandboxing SVG data. I asked this on Mastodon and got some really useful replies:
How hard is it to process untrusted SVG data to strip out any potentially harmful tags or attributes (like stuff that might execute JavaScript)?
The winner for me turned out to be the humble <img src="">
tag. SVG images that are rendered in an image have all dynamic functionality - including embedded JavaScript - disabled by default, and that's something that's directly included in the spec:
2.2.6. Secure static mode
This processing mode is intended for circumstances where an SVG document is to be used as a non-animated image that is not allowed to resolve external references, and which is not intended to be used as an interactive document. This mode might be used where image support has traditionally been limited to non-animated raster images (such as JPEG and PNG.)
[...]
'image' references
An SVG embedded within an 'image' element must be processed in secure animated mode if the embedding document supports declarative animation, or in secure static mode otherwise.
The same processing modes are expected to be used for other cases where SVG is used in place of a raster image, such as an HTML 'img' element or in any CSS property that takes an
data type. This is consistent with HTML's requirement that image sources must reference "a non-interactive, optionally animated, image resource that is neither paged nor scripted" [HTML]
This also works for SVG data that's presented in a <img src="data:image/svg+xml;base64,...
attribute. I had Claude help spin me up this interactive demo:
Build me an artifact - just HTML, no JavaScript - which demonstrates embedding some SVG files using img src= base64 URIs
I want three SVGs - one of the sun, one of a pelican and one that includes some tricky javascript things which I hope the img src= tag will ignore
If you right click and "open in a new tab" on the JavaScript-embedding SVG that script will execute, showing an alert. You can click the image to see another alert showing location.href
and document.cookie
which should confirm that the base64 image is not treated as having the same origin as the page itself.
LLM Pictionary. Inspired by my SVG pelicans on a bicycle, Paul Calcraft built this brilliant system where different vision LLMs can play Pictionary with each other, taking it in turns to progressively draw SVGs while the other models see if they can guess what the image represents.
Pelicans on a bicycle. I decided to roll out my own LLM benchmark: how well can different models render an SVG of a pelican riding a bicycle?
I chose that because a) I like pelicans and b) I'm pretty sure there aren't any pelican on a bicycle SVG files floating around (yet) that might have already been sucked into the training data.
My prompt:
Generate an SVG of a pelican riding a bicycle
I've run it through 16 models so far - from OpenAI, Anthropic, Google Gemini and Meta (Llama running on Cerebras), all using my LLM CLI utility. Here's my (Claude assisted) Bash script: generate-svgs.sh
Here's Claude 3.5 Sonnet (2024-06-20) and Claude 3.5 Sonnet (2024-10-22):
Gemini 1.5 Flash 001 and Gemini 1.5 Flash 002:
GPT-4o mini and GPT-4o:
o1-mini and o1-preview:
Cerebras Llama 3.1 70B and Llama 3.1 8B:
And a special mention for Gemini 1.5 Flash 8B:
The rest of them are linked from the README.
fav.farm (via) Neat little site by Wes Bos: it serves SVG (or PNG for Safari) favicons of every Emoji, which can be added to any site like this:
<link rel="icon" href="https://fav.farm/🔥" />
The source code is on GitHub. It runs on Deno and Deno Deploy, and recently added per-Emoji hit counters powered by the Deno KV store, implemented in db.ts using this pattern:
export function incrementCount(emoji: string) {
const VIEW_KEY = [`favicon`, `${emoji}`];
return db.atomic().sum(
VIEW_KEY, 1n
).commit(); // Increment KV by 1
}
VTracer (via) VTracer is an open source library written in Rust for converting raster images (JPEG, PNG etc) to vector SVG.
This VTracer web app provides access to a WebAssembly compiled version of the library, with a UI that lets you open images, tweak the various options and download the resulting SVG.
I heard about this today on Twitter in a reply to my tweet demonstrating a much, much simpler Image to SVG tool I built with the help of Claude and the handy imagetracerjs library by András Jankovics.
SVG to JPG/PNG. The latest in my ongoing series of interactive HTML and JavaScript tools written almost entirely by LLMs. This one lets you paste in (or open-from-file, or drag-onto-page) some SVG and then use that to render a JPEG or PNG image of your desired width.
I built this using Claude 3.5 Sonnet, initially as an Artifact and later in a code editor since some of the features (loading an example image and downloading the result) cannot run in the sandboxed iframe Artifact environment.
Here's the full transcript of the Claude conversation I used to build the tool, plus a few commits I later made by hand to further customize it.
The code itself is mostly quite simple. The most interesting part is how it renders the SVG to an image, which (simplified) looks like this:
// First extract the viewbox to get width/height
const svgElement = new DOMParser().parseFromString(
svgInput, 'image/svg+xml'
).documentElement;
let viewBox = svgElement.getAttribute('viewBox');
[, , width, height] = viewBox.split(' ').map(Number);
// Figure out the width/height of the output image
const newWidth = parseInt(widthInput.value) || 800;
const aspectRatio = width / height;
const newHeight = Math.round(newWidth / aspectRatio);
// Create off-screen canvas
const canvas = document.createElement('canvas');
canvas.width = newWidth;
canvas.height = newHeight;
// Draw SVG on canvas
const svgBlob = new Blob([svgInput], {type: 'image/svg+xml;charset=utf-8'});
const svgUrl = URL.createObjectURL(svgBlob);
const img = new Image();
const ctx = canvas.getContext('2d');
img.onload = function() {
ctx.drawImage(img, 0, 0, newWidth, newHeight);
URL.revokeObjectURL(svgUrl);
// Convert that to a JPEG
const imageDataUrl = canvas.toDataURL("image/jpeg");
const convertedImg = document.createElement('img');
convertedImg.src = imageDataUrl;
imageContainer.appendChild(convertedImg);
};
img.src = svgUrl;
Here's the MDN explanation of that revokeObjectURL() method, which I hadn't seen before.
Call this method when you've finished using an object URL to let the browser know not to keep the reference to the file any longer.
tiny-world-map (via) I love this project. It’s a JavaScript file (694K uncompressed, 283KB compressed) which can be used with the Leaflet mapping library and provides a SVG base map of the world with country borders and labels for every world city with a population more than 48,000—10,000 cities total.
This means you can bundle an offline map of the world as part of any application that doesn’t need a higher level of detail. A lot of smaller island nations are missing entirely though, so this may not be right for every project.
It even includes a service worker to help implement offline mapping support, plus several variants of the map with less cities that are even smaller.
2023
SVG Tutorial: Learn SVG through 25 examples (via) Hunor Márton Borbély published this fantastic advent calendar of tutorials for learning SVG, from the basics up to advanced concepts like animation and interactivity.
excalidraw.com (via) Really nice browser-based editor for simple diagrams using a pleasing hand-sketched style, with the ability to export them as SVG or PNG.
2022
Draw SVG rope using JavaScript (via) Delightful interactive tutorial by Stanko Tadić showing how to render an illustration of a rope using SVG, starting with a path. The way the tutorial is presented is outstanding.
2021
Making GitHub’s new homepage fast and performant. A couple of really clever tricks in this article by Tobias Ahlin. The first is using IntersectionObserver in conjunction with the video preload=“none” attribute to lazily load a video when it scrolls into view. The second is an ingenious trick to create an efficiently encoded transparent JPEG image: embed the image in a SVG file twice, once as the image and once as a transparency mask.
2020
Pikchr. Interesting new project from SQLite creator D. Richard Hipp. Pikchr is a new mini language for describing visual diagrams, designed to be embedded in Markdown documentation. It’s already enabled for the SQLite forum. Implementation is a no-dependencies C library and output is SVG.
html-to-svg (via) This is absolutely ingenious: 50 lines of JavaScript which uses Puppeteer to get headless Chrome to grab a PDF screenshot of a page, then shells out to Inkscape to convert the PDF to SVG. Wraps the whole thing up in a Docker container and ships it to Cloud Run as a web service you can call by passing it a URL.
2017
Of SVG, Minification and Gzip. Delightfully nerdy exploration of tricks you can use to hand-optimize your SVG in order to maximize gzip compression. Premature optimization may be the root of all evil but this is still a great way to learn about how gzip actually works.
Using SVG as placeholders — More Image Loading Techniques. This is such a good idea: generate a tiny SVG placeholder for an image, and display that until the image itself has loaded. This article explores potential ways of generating those SVGs in some depth.
Carbon (via) Beautiful little tool that you can paste source code into to generate an image of that code with syntax highlighting applied, ready to be tweeted or shared anywhere that lets you share an image. Built in Node and next.js, with image generation handled client-side by the dom-to-image JavaScript library which loads HTML into a SVG foreignObject (sadly not yet supported by Safari) and uses that to populate a canvas and produce a PNG.
2010
Polymaps. Absurdly classy: “a JavaScript library for image- and vector-tiled maps using SVG”. It can pull in image tiles from sources such as OpenStreetMap, then overlay SVG paths specified using GeoJSON. The demos make use of GeoJSON tiles for US states and counties hosted on AppEngine. The library is developed by Stamen and SimpleGeo, and released under a BSD license. SVG support in the browser is required.
canto.js: An Improved HTML5 Canvas API (via) Improved is an understatement: canto adds jQuery-style method chaining, the ability to multiple coordinates to e.g. lineTo at once, relative coordinate methods (regular Canvas does everything in terms of absolute coordinates), the ability to use degrees instead of radians, a rounded corner shortcut, a more convenient .revert() method and a simple parser that can understand SVG path expressions! The only catch: it uses getters and setters so won’t work in IE.
Smokescreen demo: a Flash player in JavaScript. Chris Smoak’s Smokescreen, “a Flash player written in JavaScript”, is an incredible piece of work. It runs entirely in the browser, reads in SWF binaries, unzips them (in native JS), extracts images and embedded audio and turns them in to base64 encoded data:uris, then stitches the vector graphics back together as animated SVG. Open up the Chrome Web Inspector while the demo is running and you can see the SVG changing in real time. Smokescreen even implements its own ActionScript bytecode interpreter. It’s stated intention is to allow Flash banner ads to execute on the iPad and iPhone, but there are plenty of other interesting applications (such as news site infographics). The company behind it have announced plans to open source it in the near future. My one concern is performance—the library is 175 KB and over 8,000 lines of JavaScript which might cause problems on low powered mobile devices.
ZOMBO.com in HTML5. Uses SVG (scripted by JavaScript) and the audio element. Finally, Zombo.com comes to the iPad.
Firefox 4: the HTML5 parser—inline SVG, speed and more. A complete replacement for the oldest part of Gecko (the HTML parser dates back to 1998) headed up by HTML5 validator author Henri Sivonen, using the parsing algorithm defined in the HTML5 specification. Improvements include parsing taking place off the main UI thread and the ability to embed SVG and MathML directly inline in HTML pages.
"... the interchange format needed to be able to support future Flash Player features, which would not necessarily map to SVG features. As such, the decision was made to go with a new interchange format, FXG, instead of having a non-standard implementation of SVG. FXG does borrow from SVG whenever possible."
Internet Explorer Platform Preview Guide for Developers (via) Lots of SVG and CSS3 stuff, no mention of canvas here either though.
An Early Look At IE9 for Developers (via) Surprisingly, no mention of SVG or canvas and only a note in passing about HTML 5.
svg-edit. Click the “Try out SVG-edit 2.4” link—this is an impressive, full featured open source vector graphics editor that runs in the browser.
2009
How to Make a US County Thematic Map Using Free Tools. This is the trick I’ve been using to generate choropleths at the Guardian for the past year: figure out the preferred colours for a set of data in a Python script and then rewrite an SVG file to colour in the areas. I use ElementTree rather than BeautifulSoup but the technique is exactly the same. The best thing about SVG is that our graphics department can export them directly out of Illustrator, with named layers and paths automatically becoming SVG ID attributes. Bonus tip: sometimes you don’t have to rewrite the SVG XML at all, instead you can generate CSS to colour areas by ID selector and inject it in to the top of the file.
svgweb. Awesome. I’ve been having a lot of fun with SVG for dynamic graphics recently (maps in particular), and hoping someone builds an SVG renderer in Flash so I could serve up SVG files for IE. Brad Neuberg and team have done exactly that.
Fixing IE by porting Canvas to Flash. Implementing canvas using Flash is an obvious step, but personally I’m much more interested in an SVG renderer using Flash that finally brings non-animated SVGs to IE.
2008
Using SVG on the Web. I’ve been having a lot of fun playing with SVG recently. Here are some useful tips for including SVG images in HTML and XHTML documents.
It’s a purple world. Stuart Langridge made a purplish map of the US election results, using JSON data from Google and an SVG map of the US from Wikipedia.