From 146894583bfe0b221fed717b90baaf2562054ff0 Mon Sep 17 00:00:00 2001 From: Mike Lynch Date: Sat, 11 Jan 2025 17:18:43 +1100 Subject: [PATCH] First working version of wasm svg->png generator --- src/components/download.js | 21 +++++++++------ src/index.md | 52 +++++++++++++++++++++++++++++++++++--- 2 files changed, 61 insertions(+), 12 deletions(-) diff --git a/src/components/download.js b/src/components/download.js index d0ce83b..6c45b79 100644 --- a/src/components/download.js +++ b/src/components/download.js @@ -1,14 +1,16 @@ -// adapted from the DOM.download method as per this issue: -// https://github.com/observablehq/framework/issues/906 + const xmlns = "http://www.w3.org/2000/xmlns/"; const xlinkns = "http://www.w3.org/1999/xlink"; const svgns = "http://www.w3.org/2000/svg"; +// adapted from the DOM.download method as per this issue: + +// https://github.com/observablehq/framework/issues/906 + export function download(value, name = "untitled", label = "Save") { - console.log("in download"); const a = document.createElement("a"); const b = a.appendChild(document.createElement("button")); b.textContent = label; @@ -32,8 +34,6 @@ export function download(value, name = "untitled", label = "Save") { b.textContent = "Saving…"; try { const object = await (typeof value === "function" ? value() : value); - console.log("svg object:"); - console.log(object); b.textContent = "Download"; a.href = URL.createObjectURL(object); // eslint-disable-line require-atomic-updates console.log(`url = ${a.href}`); @@ -48,11 +48,16 @@ export function download(value, name = "untitled", label = "Save") { } -export function serialize_svg(svg) { +export function svg_to_string(svg) { svg = svg.cloneNode(true); svg.setAttributeNS(xmlns, "xmlns", svgns); svg.setAttributeNS(xmlns, "xmlns:xlink", xlinkns); const serializer = new window.XMLSerializer; - const string = serializer.serializeToString(svg); - return new Blob([string], {type: "image/svg+xml"}); + return serializer.serializeToString(svg); +} + + +export function svg_to_blob(svg) { + const str = svg_to_string(svg); + return new Blob([string], {type: "image/svg+xml"}) } diff --git a/src/index.md b/src/index.md index bec9ffc..6d72f4c 100644 --- a/src/index.md +++ b/src/index.md @@ -2,6 +2,8 @@ toc: false --- + +

poptimal

v1.1.0 | by mike lynch | @mikelynch@aus.social | source

@@ -14,9 +16,13 @@ toc: false import {RADIUS_OPTS, DotMaker} from './components/dots.js'; import {PALETTES, DotControls} from './components/controls.js'; -import {download, serialize_svg} from './components/download.js'; +import {download, svg_to_string, svg_to_blob} from './components/download.js'; import random from "npm:random"; +import * as resvg from 'npm:@resvg/resvg-wasm'; + +await resvg.initWasm(fetch('https://unpkg.com/@resvg/resvg-wasm/index_bg.wasm')); + const CELL = 10; const MAG = 2; const WIDTH = 20; @@ -154,14 +160,52 @@ display(svg.node()); ```js -display(download(() => serialize_svg(svg.node()), "poptimal.svg", "Save as SVG")); +display(download(() => svg_to_blob(svg.node()), "poptimal.svg", "Save as SVG")); ``` -

- +```js + +const png_img = document.createElement("img"); + +async function svg_to_png (svg) { + // The Wasm must be initialized first + + const svgstr = svg_to_string(svg.node()); + + const opts = { + background: 'rgba(238, 235, 230, .9)', + fitTo: { + mode: 'width', // If you need to change the size + value: 400, + } + }; + const resvgJS = new resvg.Resvg(svgstr, opts) + console.log(resvgJS); + const pngData = resvgJS.render(svgstr, opts) // Output PNG data, Uint8Array + console.log(`pngData = ${pngData}`); + const pngBuffer = pngData.asPng(); + const pngURL = URL.createObjectURL(new Blob([pngBuffer], { type: 'image/png' })) + console.log(`url = ${pngURL}`); + png_img.src = pngURL +} + +display(png_img); + +const made_png = view(Inputs.button("Make PNG")); + +``` + +```js +made_png; +console.log(made_png); +if( made_png > 0 ) { + console.log("Trying to make png"); + await svg_to_png(svg); +} +```