Skip to content

Commit

Permalink
Merge pull request #212 from adroitwhiz/subpixel-v3-cleanups
Browse files Browse the repository at this point in the history
Clean up SVG renderer code
  • Loading branch information
fsih authored Feb 19, 2021
2 parents d455bd5 + e770e7a commit 8941fb1
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 48 deletions.
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,17 @@ npm install
```js
import SvgRenderer from 'scratch-svg-renderer';

var svgRenderer = new SvgRenderer();
svgRenderer.fromString(svgData, callback);
const svgRenderer = new SvgRenderer();

const svgData = "<svg>...</svg>";
const scale = 1;
const quirksMode = false; // If true, emulate Scratch 2.0 SVG rendering "quirks"
function doSomethingWith(canvas) {...};

svgRenderer.loadSVG(svgData, quirksMode, () => {
svgRenderer.draw(scale);
doSomethingWith(svgRenderer.canvas);
});
```

## How to run locally as part of scratch-gui
Expand All @@ -49,4 +58,4 @@ To run scratch-svg-renderer locally as part of scratch-gui, for development:
6. In scratch-gui, follow its instructions to run it or build its code

## Donate
We provide [Scratch](https://scratch.mit.edu) free of charge, and want to keep it that way! Please consider making a [donation](https://secure.donationpay.org/scratchfoundation/) to support our continued engineering, design, community, and resource development efforts. Donations of any size are appreciated. Thank you!
We provide [Scratch](https://scratch.mit.edu) free of charge, and want to keep it that way! Please consider making a [donation](https://secure.donationpay.org/scratchfoundation/) to support our continued engineering, design, community, and resource development efforts. Donations of any size are appreciated. Thank you!
10 changes: 6 additions & 4 deletions src/playground/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,10 @@
loadSVGString();
}

function renderSVGString(str) {
renderer.fromString(str);
renderer._draw(parseFloat(scaleSlider.value), ()=>{});
function renderSVGString() {
if (renderer.loaded) {
renderer.draw(parseFloat(scaleSlider.value));
}
renderedContent.value = renderer.toString(true);
}

Expand Down Expand Up @@ -103,11 +104,12 @@
function loadSVGString() {
readFileAsText(fileChooser.files[0]).then(str => {
loadedSVGString = str;
renderer.loadSVG(str, false);
})
}

function renderLoadedString() {
renderSVGString(loadedSVGString);
renderSVGString();
referenceContent.value = loadedSVGString;
shouldRenderReference.checked && updateReferenceImage();
}
Expand Down
73 changes: 32 additions & 41 deletions src/svg-renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,41 @@ class SvgRenderer {
* @constructor
*/
constructor (canvas) {
/**
* The canvas that this SVG renderer will render to.
* @type {HTMLCanvasElement}
* @private
*/
this._canvas = canvas || document.createElement('canvas');
this._context = this._canvas.getContext('2d');

/**
* A measured SVG "viewbox"
* @typedef {object} SvgRenderer#SvgMeasurements
* @property {number} x - The left edge of the SVG viewbox.
* @property {number} y - The top edge of the SVG viewbox.
* @property {number} width - The width of the SVG viewbox.
* @property {number} height - The height of the SVG viewbox.
*/

/**
* The measurement box of the currently loaded SVG.
* @type {SvgRenderer#SvgMeasurements}
* @private
*/
this._measurements = {x: 0, y: 0, width: 0, height: 0};

/**
* The `<img>` element with the contents of the currently loaded SVG.
* @type {?HTMLImageElement}
* @private
*/
this._cachedImage = null;

/**
* True if this renderer's current SVG is loaded and can be rendered to the canvas.
* @type {boolean}
*/
this.loaded = false;
}

Expand All @@ -30,22 +61,6 @@ class SvgRenderer {
return this._canvas;
}

/**
* Load an SVG from a string and draw it.
* This will be parsed and transformed, and finally drawn.
* When drawing is finished, the `onFinish` callback is called.
* @param {string} svgString String of SVG data to draw in quirks-mode.
* @param {number} [scale] - Optionally, also scale the image by this factor.
* @param {Function} [onFinish] Optional callback for when drawing finished.
* @deprecated Use the `loadSVG` method and public `draw` method instead.
*/
fromString (svgString, scale, onFinish) {
this.loadSVG(svgString, false, () => {
this.draw(scale);
if (onFinish) onFinish();
});
}

/**
* Load an SVG from a string and measure it.
* @param {string} svgString String of SVG data to draw in quirks-mode.
Expand Down Expand Up @@ -438,25 +453,6 @@ class SvgRenderer {
this._drawFromImage(scale);
}

/**
* Asynchronously draw the (possibly non-loaded) SVG to a canvas.
* @param {number} [scale] - Optionally, also scale the image by this factor.
* @param {Function} [onFinish] - An optional callback to call when the draw operation is complete.
* @deprecated Use the `loadSVG` and public `draw` method instead.
*/
_draw (scale, onFinish) {
// Convert the SVG text to an Image, and then draw it to the canvas.
if (this._cachedImage === null) {
this._createSVGImage(() => {
this._drawFromImage(scale);
onFinish();
});
} else {
this._drawFromImage(scale);
onFinish();
}
}

/**
* Draw to the canvas from a loaded image element.
* @param {number} [scale] - Optionally, also scale the image by this factor.
Expand All @@ -478,13 +474,8 @@ class SvgRenderer {
this._cachedImage.naturalHeight <= 0
) return;
this._context.clearRect(0, 0, this._canvas.width, this._canvas.height);
this._context.scale(ratio, ratio);
this._context.setTransform(ratio, 0, 0, ratio, 0, 0);
this._context.drawImage(this._cachedImage, 0, 0);
// Reset the canvas transform after drawing.
this._context.setTransform(1, 0, 0, 1, 0, 0);
// Set the CSS style of the canvas to the actual measurements.
this._canvas.style.width = bbox.width;
this._canvas.style.height = bbox.height;
}
}

Expand Down

0 comments on commit 8941fb1

Please sign in to comment.