Skip to content

Commit 78c2e5c

Browse files
committed
Fix demos and docs for Img
1 parent c549612 commit 78c2e5c

9 files changed

Lines changed: 39 additions & 45 deletions

File tree

bench/browser/image.bench.mjs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55
* sample an image.
66
*
77
* The fixture is generated rather than loaded from a file, so the suite has no
8-
* asset or network dependency. It still goes through `Img.load`, because that
9-
* is the only path that populates the `ImageData` the pixel functions read —
10-
* `Img.blank(...)` followed by `sync()` leaves it undefined until the image has
11-
* asynchronously reloaded itself.
8+
* asset or network dependency. It goes through `Img.load` to exercise the
9+
* realistic editable pipeline (pixel data now materializes lazily on first
10+
* read, and `Img.blank(...)` supports pixel reads directly).
1211
*/
1312

1413
import { SIZES } from "../lib/fixtures.mjs";

demo/guide.image_crop.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ window.demoDescription = "Demo in cropping images";
2525
animate: (time, ftime) => {
2626

2727
// As an example, this shows how we load the image and then check img.loaded here.
28-
// This is an alternative to Img.loadAsync() as shown in other examples in this guide
28+
// This is an alternative to the static Img.load() as shown in other examples in this guide
2929
if (img.loaded) {
3030

3131
// draw original image

demo/guide.image_edit.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ window.demoDescription = "Demo in editing images";
1010
let run = Pts.quickStart( "#pt", "#e2e6ef" );
1111
let lastP = new Pt();
1212
let imgform;
13-
let img = new Img(true, space.pixelScale);
13+
let img = new Img({ editable: true, pixelScale: space.pixelScale });
1414
img.load( "/assets/img_demo.jpg" ).then( res => imgform = new CanvasForm( res.ctx ) );
1515

1616
run( t => {

demo/guide.image_load2.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ window.demoDescription = "Demo in loading images";
1010
const run = Pts.quickStart( "#pt", "#e2e6ef" );
1111

1212
let duration = [Date.now(), 0];
13-
let img = await Img.loadAsync( "/assets/img_demo.jpg");
13+
let img = await Img.load( "/assets/img_demo.jpg");
1414
duration[1] = Date.now();
1515

1616
run( (time, ftime) => {

guide/Image-0900.html

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@
2222
<p>The standard API for working with images on canvas is rather laborious, and often takes the fun out of creative coding. In Pts, the <a href="#image-img"><code>Img</code></a> class simplifies the common use cases, from loading and displaying static images to generating dynamic textures, so that you can get started quickly. Let's take a look.</p>
2323
<h3>Loading and Displaying Images</h3>
2424
<p>We will start a minimalistic example: Load an image and display it on canvas. This can be done in 2 lines of code:</p>
25-
<pre><code>const img = Img.load( &quot;/assets/demo.jpg&quot; );
25+
<pre><code>const img = await Img.load( &quot;/assets/demo.jpg&quot; );
2626
space.add( time =&gt; form.image( space.pointer, img ) );
2727
</code></pre>
2828
<p><img src="./assets/bg.png" alt="js:image_load"></p>
2929
<h5>Image credit: &quot;C 50 Last Birds And Flowers&quot; by Kurt Schwitters</h5>
30-
<p>The above example uses the <em>static</em> function <a href="#image-img"><code>Img.load</code></a> to load an image, and then uses CanvasForm's <a href="#canvas-canvasform"><code>image</code></a> function to display it. The image will be displayed as soon as it's loaded.</p>
31-
<p>To wait for the image to be ready first, either use the static <a href="#image-img"><code>Img.loadAsync</code></a> function, or create a blank Img instance and then call the <em>instance</em> function <a href="#image-img"><code>load</code></a>. An example:</p>
30+
<p>The above example uses the <em>static</em> function <a href="#image-img"><code>Img.load</code></a>, which returns a Promise that resolves to the loaded image, and then uses CanvasForm's <a href="#canvas-canvasform"><code>image</code></a> function to display it. A load failure rejects the Promise.</p>
31+
<p>You can also create an Img instance yourself and call the <em>instance</em> function <a href="#image-img"><code>load</code></a>, which is handy when you want to configure the instance first. An example:</p>
3232
<pre><code>(async function() {
33-
let img = await Img.loadAsync( &quot;/assets/img_demo.jpg&quot; );
33+
let img = await new Img().load( &quot;/assets/img_demo.jpg&quot; );
3434
space.add( time =&gt; form.image( space.pointer, img ) );
3535
})();
3636
</code></pre>
@@ -40,11 +40,11 @@ <h5>In this example, we access the image's original width and height after it's
4040
<h3>Editing Images</h3>
4141
<p>When you create an Img instance with its <code>editable</code> parameter set to <code>true</code>, it will hold an internal canvas to support image manipulations. It will also match the pixel-density of your display. An example:</p>
4242
<pre><code>// Create an editable img with the current space's pixelScale
43-
let img = new Img( true, space.pixelScale );
43+
let img = new Img( { editable: true, pixelScale: space.pixelScale } );
4444
img.load( &quot;/assets/demo.jpg&quot; ).then( ... );
4545

46-
// Alternatively, Img.loadAsync static function
47-
let img2 = await Img.loadAsync( &quot;/assets/demo.jpg&quot;, true, space.pixelScale );
46+
// Alternatively, pass the options to the static load function
47+
let img2 = await Img.load( &quot;/assets/demo.jpg&quot;, { editable: true, pixelScale: space.pixelScale } );
4848
</code></pre>
4949
<p>You can do a lot with an editable image. Let's cover a couple common use cases.</p>
5050
<h3>Get Pixels and Crop Regions</h3>
@@ -61,7 +61,7 @@ <h5>Click to cut out a region in the image. Move pointer to shift its position.<
6161
<h3>Edit and Sync</h3>
6262
<p>Since an editable <a href="#image-img"><code>Img</code></a> stores an internal canvas, you can leverage <a href="#canvas-canvasform"><code>CanvasForm</code></a>'s many drawing functions to draw directly on it. It's that easy!</p>
6363
<p>After the image is loaded, you can access the canvas' rendering context through the property <code>img.ctx</code> and then create a new <a href="#canvas-canvasform"><code>CanvasForm</code></a> instance with it. For example:</p>
64-
<pre><code>const img = await Img.loadAsync( &quot;demo.jpg&quot; );
64+
<pre><code>const img = await Img.load( &quot;demo.jpg&quot;, true );
6565
const imgForm = new CanvasForm( img.ctx );
6666
...
6767
imgForm.fill(&quot;#f00&quot;).rect( rect );
@@ -76,7 +76,8 @@ <h5>Move pointer to draw patches on the image canvas.</h5>
7676
<pre><code>// draw internal image canvas
7777
form.image( img.canvas );
7878
</code></pre>
79-
<p>As we are only editing an internal canvas, the original image is unchanged until it's explicitly updated. Use <a href="#image-img"><code>sync</code></a> to update the original image when needed.</p>
79+
<p>As we are only editing an internal canvas, the original image is unchanged until it's explicitly updated. Use <a href="#image-img"><code>sync</code></a>, which returns a Promise, to update the original image when needed: <code>await img.sync()</code>.</p>
80+
<p>You can also work at the pixel level: <a href="#image-img"><code>setPixel</code></a> writes a color into the cached pixel data, <a href="#image-img"><code>updatePixels</code></a> applies those changes onto the canvas, and <a href="#image-img"><code>loadPixels</code></a> refreshes the cache after you've drawn on the canvas directly. When you're done with an Img, call <a href="#image-img"><code>dispose</code></a> to release its resources.</p>
8081
<h3>Patterns</h3>
8182
<p>In a similar way, you can treat an image (or an image canvas) as a pattern to fill an area. One difference is that we'll get a <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasPattern">CanvasPattern</a> instance for use in <code>form.fill(...)</code>, instead of an image for <code>form.image(...)</code>.</p>
8283
<pre><code>const pattern = await Img.loadPattern( &quot;tile.jpg&quot;, space );
@@ -103,19 +104,15 @@ <h3>Tips and Tricks</h3>
103104
<h3>Cheatsheet</h3>
104105
<p>Creating, loading, displaying</p>
105106
<pre><code>// Simplest way
106-
let img = Img.load( &quot;demo.jpg&quot;);
107+
let img = await Img.load( &quot;demo.jpg&quot;);
107108

108109
// Load an editable image that matches the screen's resolution
109-
// with an optional callback function when the image is loaded.
110-
let img = Img.load(&quot;demo.png&quot;, true, space.pixelScale, onLoad );
110+
let img = await Img.load(&quot;demo.png&quot;, { editable: true, pixelScale: space.pixelScale } );
111111

112-
// Equivalent but using async/await
113-
let img = new Img( true, space.pixelScale );
112+
// Equivalent, creating the instance first
113+
let img = new Img( { editable: true, pixelScale: space.pixelScale } );
114114
await img.load(&quot;demo.png&quot;)
115115

116-
// Or using the loadAsync static function
117-
let img = await Img.loadAsync( &quot;demo.png&quot; )
118-
119116
// Display an image automatically when it's loaded
120117
form.image( [0,0], img );
121118

guide/js/examples/image_crop.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
animate: (time, ftime) => {
2626

2727
// As an example, this shows how we load the image and then check img.loaded here.
28-
// This is an alternative to Img.loadAsync() as shown in other examples in this guide
28+
// This is an alternative to the static Img.load() as shown in other examples in this guide
2929
if (img.loaded) {
3030

3131
// draw original image

guide/js/examples/image_edit.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
let form = space.getForm();
1414
let lastP = new Pt();
1515
let imgform;
16-
let img = new Img(true, space.pixelScale);
16+
let img = new Img({ editable: true, pixelScale: space.pixelScale });
1717
img.load( "/assets/img_demo.jpg" ).then( res => imgform = new CanvasForm( res.ctx ) );
1818

1919
// animation

guide/js/examples/image_load.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
// Source code licensed under Apache License 2.0.
22
// Copyright © 2021 William Ngan. (https://github.com/williamngan/pts)
33

4-
(function(){
4+
(async function(){
55
// Pts.namespace( this ); // add Pts into scope if needed
66

77
var demoID = "image_load";
88

99
// create Space and Form
1010
let space = new CanvasSpace("#"+demoID).setup({ retina: true, bgcolor: "#e2e6ef", resize: true });
1111
let form = space.getForm();
12-
let img = Img.load( "/assets/img_demo.jpg");
12+
let img = await Img.load( "/assets/img_demo.jpg");
1313

1414
// animation
1515
space.add( (time, ftime) => {

guide/md/_0900_Image.md

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,21 @@ The standard API for working with images on canvas is rather laborious, and ofte
77
We will start a minimalistic example: Load an image and display it on canvas. This can be done in 2 lines of code:
88

99
```
10-
const img = Img.load( "/assets/demo.jpg" );
10+
const img = await Img.load( "/assets/demo.jpg" );
1111
space.add( time => form.image( space.pointer, img ) );
1212
```
1313

1414
![js:image_load](./assets/bg.png)
1515

1616
##### Image credit: "C 50 Last Birds And Flowers" by Kurt Schwitters
1717

18-
The above example uses the *static* function [`Img.load`](#image-img) to load an image, and then uses CanvasForm's [`image`](#canvas-canvasform) function to display it. The image will be displayed as soon as it's loaded.
18+
The above example uses the *static* function [`Img.load`](#image-img), which returns a Promise that resolves to the loaded image, and then uses CanvasForm's [`image`](#canvas-canvasform) function to display it. A load failure rejects the Promise.
1919

20-
To wait for the image to be ready first, either use the static [`Img.loadAsync`](#image-img) function, or create a blank Img instance and then call the *instance* function [`load`](#image-img). An example:
20+
You can also create an Img instance yourself and call the *instance* function [`load`](#image-img), which is handy when you want to configure the instance first. An example:
2121

2222
```
2323
(async function() {
24-
let img = await Img.loadAsync( "/assets/img_demo.jpg" );
24+
let img = await new Img().load( "/assets/img_demo.jpg" );
2525
space.add( time => form.image( space.pointer, img ) );
2626
})();
2727
```
@@ -38,11 +38,11 @@ When you create an Img instance with its `editable` parameter set to `true`, it
3838

3939
```
4040
// Create an editable img with the current space's pixelScale
41-
let img = new Img( true, space.pixelScale );
41+
let img = new Img( { editable: true, pixelScale: space.pixelScale } );
4242
img.load( "/assets/demo.jpg" ).then( ... );
4343
44-
// Alternatively, Img.loadAsync static function
45-
let img2 = await Img.loadAsync( "/assets/demo.jpg", true, space.pixelScale );
44+
// Alternatively, pass the options to the static load function
45+
let img2 = await Img.load( "/assets/demo.jpg", { editable: true, pixelScale: space.pixelScale } );
4646
```
4747

4848
You can do a lot with an editable image. Let's cover a couple common use cases.
@@ -76,7 +76,7 @@ Since an editable [`Img`](#image-img) stores an internal canvas, you can leverag
7676
After the image is loaded, you can access the canvas' rendering context through the property `img.ctx` and then create a new [`CanvasForm`](#canvas-canvasform) instance with it. For example:
7777

7878
```
79-
const img = await Img.loadAsync( "demo.jpg" );
79+
const img = await Img.load( "demo.jpg", true );
8080
const imgForm = new CanvasForm( img.ctx );
8181
...
8282
imgForm.fill("#f00").rect( rect );
@@ -101,7 +101,9 @@ To display the edited image, use CanvasForm's [`image`](https://ptsjs.org/docs/?
101101
form.image( img.canvas );
102102
```
103103

104-
As we are only editing an internal canvas, the original image is unchanged until it's explicitly updated. Use [`sync`](#image-img) to update the original image when needed.
104+
As we are only editing an internal canvas, the original image is unchanged until it's explicitly updated. Use [`sync`](#image-img), which returns a Promise, to update the original image when needed: `await img.sync()`.
105+
106+
You can also work at the pixel level: [`setPixel`](#image-img) writes a color into the cached pixel data, [`updatePixels`](#image-img) applies those changes onto the canvas, and [`loadPixels`](#image-img) refreshes the cache after you've drawn on the canvas directly. When you're done with an Img, call [`dispose`](#image-img) to release its resources.
105107

106108
### Patterns
107109

@@ -149,19 +151,15 @@ Creating, loading, displaying
149151

150152
```
151153
// Simplest way
152-
let img = Img.load( "demo.jpg");
154+
let img = await Img.load( "demo.jpg");
153155
154156
// Load an editable image that matches the screen's resolution
155-
// with an optional callback function when the image is loaded.
156-
let img = Img.load("demo.png", true, space.pixelScale, onLoad );
157+
let img = await Img.load("demo.png", { editable: true, pixelScale: space.pixelScale } );
157158
158-
// Equivalent but using async/await
159-
let img = new Img( true, space.pixelScale );
159+
// Equivalent, creating the instance first
160+
let img = new Img( { editable: true, pixelScale: space.pixelScale } );
160161
await img.load("demo.png")
161162
162-
// Or using the loadAsync static function
163-
let img = await Img.loadAsync( "demo.png" )
164-
165163
// Display an image automatically when it's loaded
166164
form.image( [0,0], img );
167165

0 commit comments

Comments
 (0)