Skip to content

Commit 8941fb1

Browse files
authored
Merge pull request #212 from adroitwhiz/subpixel-v3-cleanups
Clean up SVG renderer code
2 parents d455bd5 + e770e7a commit 8941fb1

File tree

3 files changed

+50
-48
lines changed

3 files changed

+50
-48
lines changed

README.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,17 @@ npm install
2121
```js
2222
import SvgRenderer from 'scratch-svg-renderer';
2323

24-
var svgRenderer = new SvgRenderer();
25-
svgRenderer.fromString(svgData, callback);
24+
const svgRenderer = new SvgRenderer();
25+
26+
const svgData = "<svg>...</svg>";
27+
const scale = 1;
28+
const quirksMode = false; // If true, emulate Scratch 2.0 SVG rendering "quirks"
29+
function doSomethingWith(canvas) {...};
30+
31+
svgRenderer.loadSVG(svgData, quirksMode, () => {
32+
svgRenderer.draw(scale);
33+
doSomethingWith(svgRenderer.canvas);
34+
});
2635
```
2736

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

5160
## Donate
52-
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!
61+
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!

src/playground/index.html

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,10 @@
7272
loadSVGString();
7373
}
7474

75-
function renderSVGString(str) {
76-
renderer.fromString(str);
77-
renderer._draw(parseFloat(scaleSlider.value), ()=>{});
75+
function renderSVGString() {
76+
if (renderer.loaded) {
77+
renderer.draw(parseFloat(scaleSlider.value));
78+
}
7879
renderedContent.value = renderer.toString(true);
7980
}
8081

@@ -103,11 +104,12 @@
103104
function loadSVGString() {
104105
readFileAsText(fileChooser.files[0]).then(str => {
105106
loadedSVGString = str;
107+
renderer.loadSVG(str, false);
106108
})
107109
}
108110

109111
function renderLoadedString() {
110-
renderSVGString(loadedSVGString);
112+
renderSVGString();
111113
referenceContent.value = loadedSVGString;
112114
shouldRenderReference.checked && updateReferenceImage();
113115
}

src/svg-renderer.js

Lines changed: 32 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,41 @@ class SvgRenderer {
1616
* @constructor
1717
*/
1818
constructor (canvas) {
19+
/**
20+
* The canvas that this SVG renderer will render to.
21+
* @type {HTMLCanvasElement}
22+
* @private
23+
*/
1924
this._canvas = canvas || document.createElement('canvas');
2025
this._context = this._canvas.getContext('2d');
26+
27+
/**
28+
* A measured SVG "viewbox"
29+
* @typedef {object} SvgRenderer#SvgMeasurements
30+
* @property {number} x - The left edge of the SVG viewbox.
31+
* @property {number} y - The top edge of the SVG viewbox.
32+
* @property {number} width - The width of the SVG viewbox.
33+
* @property {number} height - The height of the SVG viewbox.
34+
*/
35+
36+
/**
37+
* The measurement box of the currently loaded SVG.
38+
* @type {SvgRenderer#SvgMeasurements}
39+
* @private
40+
*/
2141
this._measurements = {x: 0, y: 0, width: 0, height: 0};
42+
43+
/**
44+
* The `<img>` element with the contents of the currently loaded SVG.
45+
* @type {?HTMLImageElement}
46+
* @private
47+
*/
2248
this._cachedImage = null;
49+
50+
/**
51+
* True if this renderer's current SVG is loaded and can be rendered to the canvas.
52+
* @type {boolean}
53+
*/
2354
this.loaded = false;
2455
}
2556

@@ -30,22 +61,6 @@ class SvgRenderer {
3061
return this._canvas;
3162
}
3263

33-
/**
34-
* Load an SVG from a string and draw it.
35-
* This will be parsed and transformed, and finally drawn.
36-
* When drawing is finished, the `onFinish` callback is called.
37-
* @param {string} svgString String of SVG data to draw in quirks-mode.
38-
* @param {number} [scale] - Optionally, also scale the image by this factor.
39-
* @param {Function} [onFinish] Optional callback for when drawing finished.
40-
* @deprecated Use the `loadSVG` method and public `draw` method instead.
41-
*/
42-
fromString (svgString, scale, onFinish) {
43-
this.loadSVG(svgString, false, () => {
44-
this.draw(scale);
45-
if (onFinish) onFinish();
46-
});
47-
}
48-
4964
/**
5065
* Load an SVG from a string and measure it.
5166
* @param {string} svgString String of SVG data to draw in quirks-mode.
@@ -438,25 +453,6 @@ class SvgRenderer {
438453
this._drawFromImage(scale);
439454
}
440455

441-
/**
442-
* Asynchronously draw the (possibly non-loaded) SVG to a canvas.
443-
* @param {number} [scale] - Optionally, also scale the image by this factor.
444-
* @param {Function} [onFinish] - An optional callback to call when the draw operation is complete.
445-
* @deprecated Use the `loadSVG` and public `draw` method instead.
446-
*/
447-
_draw (scale, onFinish) {
448-
// Convert the SVG text to an Image, and then draw it to the canvas.
449-
if (this._cachedImage === null) {
450-
this._createSVGImage(() => {
451-
this._drawFromImage(scale);
452-
onFinish();
453-
});
454-
} else {
455-
this._drawFromImage(scale);
456-
onFinish();
457-
}
458-
}
459-
460456
/**
461457
* Draw to the canvas from a loaded image element.
462458
* @param {number} [scale] - Optionally, also scale the image by this factor.
@@ -478,13 +474,8 @@ class SvgRenderer {
478474
this._cachedImage.naturalHeight <= 0
479475
) return;
480476
this._context.clearRect(0, 0, this._canvas.width, this._canvas.height);
481-
this._context.scale(ratio, ratio);
477+
this._context.setTransform(ratio, 0, 0, ratio, 0, 0);
482478
this._context.drawImage(this._cachedImage, 0, 0);
483-
// Reset the canvas transform after drawing.
484-
this._context.setTransform(1, 0, 0, 1, 0, 0);
485-
// Set the CSS style of the canvas to the actual measurements.
486-
this._canvas.style.width = bbox.width;
487-
this._canvas.style.height = bbox.height;
488479
}
489480
}
490481

0 commit comments

Comments
 (0)