WEBVTT

00:00:08.833 --> 00:00:09.583
Hello, and

00:00:09.583 --> 00:00:14.650
welcome back to the second C2HO workshop
focusing on an introduction

00:00:14.683 --> 00:00:19.733
to machine
learning for creative computing with ML5.

00:00:19.816 --> 00:00:24.283
The ML5 library allows us to utilize
machine learning directly in our web

00:00:24.316 --> 00:00:27.316
browser using P5.js.

00:00:27.433 --> 00:00:31.733
The ML5 library also gives us access
to a bunch of pre-trained models,

00:00:31.766 --> 00:00:37.683
and today we will be playing around
with the sketch RNN model.

00:00:37.766 --> 00:00:39.983
Now the sketch again is a machine learning

00:00:39.983 --> 00:00:42.983
model developed by Google's Magenta team.

00:00:43.166 --> 00:00:46.533
The model is trained on
millions of doodles

00:00:46.616 --> 00:00:50.383
collected from the quick Draw game,
and it's

00:00:50.416 --> 00:00:55.316
designed to create sketches of objects
and different animals.

00:00:55.400 --> 00:00:59.566
And it uses a type of model
called a recurrent neural network,

00:00:59.600 --> 00:01:04.300
which is particularly good
at understanding sequences of data,

00:01:04.333 --> 00:01:12.866
which is exactly what a drawing is,
a sequence of strokes over time.

00:01:12.950 --> 00:01:14.500
To start, we will

00:01:14.533 --> 00:01:19.583
use our P5 editor,
which loads the ML5 library

00:01:19.633 --> 00:01:23.850
so we can see that here

00:01:23.933 --> 00:01:28.000
and we will add some extra things

00:01:28.033 --> 00:01:31.166
to our index.html HTML file.

00:01:31.250 --> 00:01:32.183
For this one,

00:01:32.183 --> 00:01:35.950
we're going to give it a header
and we're also going to give it a variable

00:01:35.983 --> 00:01:40.633
which will show the status
of the sketch art in.

00:01:40.716 --> 00:01:43.033
So inside our body here

00:01:43.033 --> 00:01:48.500
we will add a header

00:01:48.583 --> 00:01:50.733
each one

00:01:50.766 --> 00:01:58.933
and just write a sketch RNN

00:01:59.016 --> 00:02:00.183
and close it.

00:02:00.216 --> 00:02:02.316
So that's our header.

00:02:02.350 --> 00:02:09.800
And we also want a variable

00:02:09.883 --> 00:02:13.933
which we will call status

00:02:14.016 --> 00:02:20.216
to show the status of our model.

00:02:20.283 --> 00:02:24.916
And for now, sort of just to begin with,

00:02:25.000 --> 00:02:27.850
we're going to give it a sort of default

00:02:27.850 --> 00:02:32.600
text which is just loading,

00:02:32.683 --> 00:02:37.016
loading multiple,

00:02:37.083 --> 00:02:47.866
and then we close this one as well.

00:02:47.950 --> 00:02:52.350
So now we can run this script
and see if our headers

00:02:52.383 --> 00:02:58.833
and status message show up
and that should look something like this.

00:02:58.916 --> 00:03:01.583
So in our sketch.js

00:03:01.616 --> 00:03:07.266
file, we will first off,
we will set up or canvas.

00:03:07.333 --> 00:03:12.616
And since the size of the canvas,

00:03:12.650 --> 00:03:16.416
which is this gray square, we'll sort of

00:03:16.483 --> 00:03:19.133
vary depending on what kind of screen

00:03:19.133 --> 00:03:22.133
you're working on,
what size of screen you're working on.

00:03:22.316 --> 00:03:25.900
I like to just set them up as variables.

00:03:25.933 --> 00:03:28.750
So canvas height

00:03:28.783 --> 00:03:33.816
and canvas width.

00:03:33.883 --> 00:03:37.150
And then in our set top function,

00:03:37.183 --> 00:03:41.616
we're going to give them their values.

00:03:41.683 --> 00:03:46.533
So canvas

00:03:46.616 --> 00:03:48.466
height,

00:03:48.500 --> 00:03:50.600
we can set it for now off to these default

00:03:50.600 --> 00:04:00.833
values.

00:04:00.916 --> 00:04:01.750
And let's

00:04:01.783 --> 00:04:10.916
set up a canvas variable for this one,

00:04:11.000 --> 00:04:11.983
because we are

00:04:12.016 --> 00:04:15.233
going to
be, ah these should be the other way around.

00:04:15.316 --> 00:04:20.616
It doesn't really matter for now,
since they're the

00:04:20.683 --> 00:04:26.066
same value, but if you guys change it,

00:04:26.216 --> 00:04:29.783
should be the right way around like this.

00:04:29.850 --> 00:04:35.800
And we all want the canvas to be hidden.

00:04:35.883 --> 00:04:37.100
So let's use

00:04:37.116 --> 00:04:38.516
canvas.hide

00:04:38.550 --> 00:04:42.250
We want to hide the canvas
until the model is ready to start drawing.

00:04:42.283 --> 00:04:45.050
So we'll do canvas.hide.

00:04:45.066 --> 00:04:50.950
And now we can set up our sketch RNN
model.

00:04:51.033 --> 00:04:51.866
So we'll do that.

00:04:51.900 --> 00:04:54.900
We'll give it a name. Just model.

00:04:55.033 --> 00:05:02.000
We use ML5.sketchRNN

00:05:02.083 --> 00:05:03.850
Let's make this model

00:05:03.850 --> 00:05:06.850
variable globally accessible.

00:05:07.000 --> 00:05:08.800
Like this.

00:05:08.833 --> 00:05:12.766
So when loading the Pre-trained model,
we can choose between several

00:05:12.800 --> 00:05:17.100
different models
trained on various kinds of drawings.

00:05:17.183 --> 00:05:21.216
So from cats to dogs and to more obscure

00:05:21.250 --> 00:05:25.316
objects
such as rabbit turtles and yoga bicycles.

00:05:25.400 --> 00:05:29.900
And for now,
we're going to use my favorite,

00:05:29.983 --> 00:05:34.133
which is
80
00:05:34,216 --> 00:05:36,433
Crab Rabbit Face Pig,

00:05:36.466 --> 00:05:38.950
which is basically just an amalgamation
of drawings

00:05:38.950 --> 00:05:43.883
of crabs, rabbits, faces and pigs.

00:05:43.966 --> 00:05:45.950
The second argument

00:05:45.950 --> 00:05:49.816
that we are going to define

00:05:49.850 --> 00:05:54.733
now is a callback function,
which the model uses

00:05:54.766 --> 00:06:01.183
to give us information of what happens
when the loading is done.

00:06:01.216 --> 00:06:05.600
So basically
just going to call that model ready.

00:06:05.683 --> 00:06:08.316
And we can define that one immediately.

00:06:08.350 --> 00:06:10.933
So a function

00:06:10.966 --> 00:06:14.816
model ready.

00:06:14.900 --> 00:06:18.133
And what we want

00:06:18.166 --> 00:06:23.616
this function to do
is basically just show our cameras.

00:06:23.650 --> 00:06:29.066
So canvas.show

00:06:29.150 --> 00:06:33.833
and we want it to change this text

00:06:33.916 --> 00:06:37.116
from loading model
to something like model ready.

00:06:37.150 --> 00:06:42.050
So to do that, we are going to use the P5
select function.

00:06:42.133 --> 00:06:44.033
We are going to be referring

00:06:44.050 --> 00:06:48.050
to our variable that we defined
in our indexed on each HTML file.

00:06:48.083 --> 00:06:51.083
So we gave it the ID status.

00:06:51.316 --> 00:06:54.166
So in this select function

00:06:54.166 --> 00:06:57.166
we write hash tag status

00:06:57.233 --> 00:07:01.450
and we are going to give it
what we want it to change to.

00:07:01.483 --> 00:07:04.383
This is our HTML file.

00:07:04.450 --> 00:07:12.266
We want to change it to model ready?

00:07:12.350 --> 00:07:17.883
Like this.

00:07:17.950 --> 00:07:22.750
So when we now run this code,
we should see that this model status

00:07:22.783 --> 00:07:27.266
changes to model ready
when the sketch is loaded.

00:07:27.350 --> 00:07:31.683
As long as everything is working
as expected,

00:07:31.750 --> 00:07:33.400
no model found.

00:07:33.433 --> 00:07:38.433
Let's check our spelling. Yep.

00:07:38.500 --> 00:07:41.300
I need to have the right
spelling for this model.

00:07:41.333 --> 00:07:45.050
There's an entire list of the different
models, and we'll have a look at that

00:07:45.133 --> 00:07:46.483
a little bit later.

00:07:46.516 --> 00:07:49.500
Right now,
we're just using Crab Rabbit face pig.

00:07:49.516 --> 00:07:50.450
So let's try again.

00:07:50.483 --> 00:07:53.666
Let's see if we can find it
this time. Yeah.

00:07:53.750 --> 00:07:56.050
So we see that
this status has changed to model.

00:07:56.050 --> 00:07:59.233
Ready? And our canvas shows up.

00:07:59.316 --> 00:08:01.833
So since we are loading
a pre-trained model,

00:08:01.833 --> 00:08:05.300
we don't need to add any data
or train the model ourselves.

00:08:05.383 --> 00:08:09.066
Instead, we will start
by creating a generate button,

00:08:09.100 --> 00:08:15.866
which will prompt the model to generate
pen strokes for us to draw on our canvas.

00:08:15.933 --> 00:08:19.966
So we'll
do that by in our set up function,

00:08:20.050 --> 00:08:24.083
we will define a button

00:08:24.166 --> 00:08:27.166
using the create

00:08:27.333 --> 00:08:31.550
button

00:08:31.633 --> 00:08:33.583
function from P5,

00:08:33.583 --> 00:08:37.616
and we'll just give it a name
what we want it to do.

00:08:37.683 --> 00:08:42.266
Good to have that inside our brackets.

00:08:42.333 --> 00:08:47.000
Like this.

00:08:47.083 --> 00:08:52.033
And then we will place it on our canvas.

00:08:52.116 --> 00:08:55.316
So we give it a position

00:08:55.383 --> 00:08:58.233
and it doesn't really matter

00:08:58.266 --> 00:09:01.150
that much where it is, place it
slightly, slightly

00:09:01.150 --> 00:09:05.216
down on our canvas.

00:09:05.283 --> 00:09:09.716
Let's have a look at what that looks like.

00:09:09.783 --> 00:09:10.050
Yeah.

00:09:10.066 --> 00:09:13.333
So now we have a generate button,
but it doesn't really

00:09:13.416 --> 00:09:17.400
do anything at the moment,
so we have to define the logic

00:09:17.433 --> 00:09:20.866
for how this button should work,
what it should do.

00:09:20.950 --> 00:09:23.400
So we do that by

00:09:23.433 --> 00:09:27.716
using the mouse pressed function.

00:09:27.783 --> 00:09:31.366
So when
the mouse is pressed on this button,

00:09:31.450 --> 00:09:35.183
we want it to start
generating our drawing.

00:09:35.266 --> 00:09:38.683
So let's define a function

00:09:38.766 --> 00:09:44.866
generate drawing.

00:09:44.950 --> 00:09:46.300
So let's just do that right

00:09:46.300 --> 00:09:49.300
below our set up function.

00:09:49.450 --> 00:09:52.066
We'll call it generate

00:09:52.100 --> 00:09:55.616
drawing.

00:09:55.700 --> 00:09:59.533
Let's fill this one in.

00:09:59.616 --> 00:10:04.683
So when the Generate button is pressed,
we want it to.

00:10:04.716 --> 00:10:09.250
First off, we want to clear
whatever was there before.

00:10:09.333 --> 00:10:15.666
So we can do that by calling background,
which will basically just

00:10:15.750 --> 00:10:18.266
re draw our background

00:10:18.300 --> 00:10:21.816
and give it the same value as is default.

00:10:21.900 --> 00:10:26.466
And then we want to reset our model.

00:10:26.500 --> 00:10:32.616
So if it's drawing and we press generate,
we want it to sort of just reset

00:10:32.700 --> 00:10:35.400
and start over.

00:10:35.433 --> 00:10:41.366
And we also want to define the location
of the first pin stroke.

00:10:41.400 --> 00:10:43.483
We want it to start

00:10:43.566 --> 00:10:45.516
in the middle of our canvas.

00:10:45.516 --> 00:10:50.033
So let's define a variable X
and a variable Y.

00:10:50.066 --> 00:10:56.000
So the middle of our canvas is our canvas,

00:10:56.083 --> 00:11:03.350
which is divided by two and our y location

00:11:03.416 --> 00:11:06.416
is the canvas height

00:11:06.666 --> 00:11:08.733
divided by two.

00:11:08.766 --> 00:11:12.433
This all centered,
it's in the middle or canvas.

00:11:12.516 --> 00:11:17.700
And then finally,
we want to use the sketch

00:11:17.733 --> 00:11:21.283
on end's own generate function

00:11:21.366 --> 00:11:29.616
to get our first sequence of pen strokes.

00:11:29.700 --> 00:11:31.233
So this function requires

00:11:31.233 --> 00:11:34.433
us to posit a function that we define,

00:11:34.466 --> 00:11:39.166
which should describe
how we should handle the results.

00:11:39.250 --> 00:11:41.616
So let's call this function.

00:11:41.650 --> 00:11:43.766


00:11:43.800 --> 00:11:46.133
Got stroke.

00:11:46.166 --> 00:11:49.166
And we can define that one just below.

00:11:49.266 --> 00:11:50.766
It's a function.

00:11:50.800 --> 00:11:56.866
Got stroke.

00:11:56.950 --> 00:11:59.933
And what we want this function to do
is that if

00:11:59.966 --> 00:12:04.850
there is an error
cause got stroke will return

00:12:04.916 --> 00:12:06.483
or our model generates

00:12:06.483 --> 00:12:10.916
function will return either
an error or a result.

00:12:10.950 --> 00:12:14.900
So we should give it these arguments.

00:12:14.966 --> 00:12:20.083
Let's just call our results
for stroke for this one.

00:12:20.166 --> 00:12:22.616
And then the first thing we want to do

00:12:22.616 --> 00:12:26.450
is say that if there is an error,

00:12:26.516 --> 00:12:30.800
we would like to log that error

00:12:30.866 --> 00:12:35.350
below on our console.

00:12:35.433 --> 00:12:37.466
So we just call console dot error.

00:12:37.466 --> 00:12:42.150
That simply makes it
so that when this message is logged,

00:12:42.183 --> 00:12:43.350
it will turn off in red.

00:12:43.350 --> 00:12:46.233
So it will catch our attention

00:12:46.266 --> 00:12:48.966
a little, a little easier.

00:12:49.000 --> 00:12:52.000
So just console and then log this error.

00:12:52.050 --> 00:12:56.683
And if not, then we have our results.

00:12:56.766 --> 00:12:59.100
So what we're going to do now is

00:12:59.100 --> 00:13:02.316
we are going to define a stroke

00:13:02.350 --> 00:13:06.800
path variable,

00:13:06.866 --> 00:13:16.116
which we will be
using to draw our drawings.

00:13:16.183 --> 00:13:18.350
Now, since we will be using this,

00:13:18.383 --> 00:13:22.800
these X and Y initial locations
and our stroke path,

00:13:22.883 --> 00:13:26.266
different places throughout our program,
we want to define them globally.

00:13:26.300 --> 00:13:30.816
So let's do X and Y

00:13:30.883 --> 00:13:40.700
and our stroke path.

00:13:40.783 --> 00:13:42.783
So let's test this out.

00:13:42.800 --> 00:13:47.900
So there's a small spelling error
that got stroke is our function.

00:13:47.983 --> 00:13:52.083
Let's save it and run
it and let's see what happens.

00:13:52.116 --> 00:13:56.833
So everything is running smoothly for now.

00:13:56.983 --> 00:14:02.183
Model is ready when we press
generates still, nothing really happens

00:14:02.266 --> 00:14:07.033
because we're not doing anything
with this stroke path variable yet.

00:14:07.066 --> 00:14:11.516
So before we fill in our draw function,

00:14:11.600 --> 00:14:14.500
we should have a look at

00:14:14.533 --> 00:14:17.266
what is actually
being returned by the model.

00:14:17.300 --> 00:14:18.433
See what we can do with it.

00:14:18.433 --> 00:14:22.583
So let's use console.log

00:14:22.666 --> 00:14:25.083
and we want to have a look

00:14:25.116 --> 00:14:36.400
at this value as the returned results.

00:14:36.483 --> 00:14:38.166
So if we now press play,

00:14:38.166 --> 00:14:44.083
we will have a look at the results
we press generate.

00:14:44.166 --> 00:14:47.800
And now we can see that down here
in our console window

00:14:47.883 --> 00:14:50.783
this is being printed.

00:14:50.816 --> 00:14:55.083
And what we can see here
is that the sketch on end

00:14:55.116 --> 00:15:01.533
generates the change in position
and the state of this pen.

00:15:01.616 --> 00:15:04.616
Now the pen can be in one of three states,

00:15:04.650 --> 00:15:09.133
it can be up, down or end.

00:15:09.216 --> 00:15:10.766
And so what we want to do

00:15:10.766 --> 00:15:14.733
is to place our most recent results
in this variable stroke path,

00:15:14.766 --> 00:15:19.116
which is what we are doing in our results
function.

00:15:19.200 --> 00:15:22.950
So now that we'll be populating
our draw function,

00:15:23.033 --> 00:15:27.700
we should make this this pen variable.

00:15:27.766 --> 00:15:30.316
Just remove our background call here

00:15:30.350 --> 00:15:34.216
should make this pen
that variable available globally.

00:15:34.400 --> 00:15:38.100
So let's call it previous

00:15:38.183 --> 00:15:42.283
pen and let's give it

00:15:42.316 --> 00:15:46.716
just a
default value of down to begin with.

00:15:46.800 --> 00:15:52.033
So when the pen is down,
we are going to start drawing.

00:15:52.116 --> 00:15:56.783
So inside our draw function,
we are first going to check

00:15:56.816 --> 00:16:02.800
if there is something in our stroke
pass variable so we can just do if

00:16:02.883 --> 00:16:08.716
stroke pass.

00:16:08.800 --> 00:16:11.433
And so if stroke path is true,

00:16:11.466 --> 00:16:15.200
then sketchRNN
has something new for us to draw.

00:16:15.283 --> 00:16:20.316
So then we want to do another check
to see if our pen is down.

00:16:20.433 --> 00:16:26.083
So if previous pen

00:16:26.166 --> 00:16:29.050
is down,

00:16:29.083 --> 00:16:30.450
then we want to draw something.

00:16:30.450 --> 00:16:36.166
If our previous pen is up,
then there might be a change in position.

00:16:36.250 --> 00:16:39.400
So the pen might still be moving,
but we don't want to draw that line.

00:16:39.433 --> 00:16:43.100
We only want to draw while the pen is down

00:16:43.183 --> 00:16:46.183
to this.

00:16:46.233 --> 00:16:47.316
So if the previous

00:16:47.316 --> 00:16:53.016
pen is down, then
we want to actually draw to our canvas.

00:16:53.050 --> 00:16:59.400
So the way that we do this is we will set
some drawing variables from P5.

00:16:59.433 --> 00:17:04.900
So our stroke, which can contain the color
that we want to draw with.

00:17:04.933 --> 00:17:09.533
So let's give that as an RGB.

00:17:09.600 --> 00:17:16.366
So let's say we want it to be
like a greeny blue,

00:17:16.450 --> 00:17:20.950
so let's give it no red and

00:17:21.033 --> 00:17:26.200
equal amount of green and blue

00:17:26.283 --> 00:17:29.833
and then we want to

00:17:29.916 --> 00:17:34.116
set the stroke weight,
which is basically just the thickness

00:17:34.150 --> 00:17:37.533
of the line that we're drawing
and just set that to

00:17:37.566 --> 00:17:40.566
something like four.

00:17:40.633 --> 00:17:43.083
And then we want to actually
draw the line.

00:17:43.083 --> 00:17:46.400
So we use the P5 function line,

00:17:46.483 --> 00:17:51.650
which takes in four arguments, the

00:17:51.733 --> 00:17:53.650
X and Y positions of the beginning

00:17:53.650 --> 00:17:56.950
of the line and the X and Y positions
for the end of the line.

00:17:57.033 --> 00:17:59.950
So as we defined

00:17:59.950 --> 00:18:03.833
in our initial generate drawing

00:18:03.900 --> 00:18:06.933
function, here
we have an X and a Y position,

00:18:06.966 --> 00:18:11.533
which should be the first position of
of the pen.

00:18:11.616 --> 00:18:14.616
So let's start that X and Y

00:18:14.683 --> 00:18:18.600
and then we should end at X

00:18:18.633 --> 00:18:21.600
and then we're going to add the

00:18:21.633 --> 00:18:23.966
position

00:18:24.000 --> 00:18:27.833
given to us in this stroke
path from the model.

00:18:27.900 --> 00:18:31.450
So as we can see down here,
we have the difference in X and the

00:18:31.483 --> 00:18:33.250
difference in Y.

00:18:33.283 --> 00:18:36.000
So strokePath.dx is

00:18:36.000 --> 00:18:42.583
it is added to our x variable and

00:18:42.666 --> 00:18:47.783
we add to our y variable the same,

00:18:47.850 --> 00:18:52.483
but then we do dy.

00:18:52.566 --> 00:18:55.116
So this should be able to draw a line

00:18:55.116 --> 00:18:59.800
when we generate the drawing.

00:18:59.883 --> 00:19:20.366
So let's save the model and have a look.

00:19:20.450 --> 00:19:22.500
So let's reset things here.

00:19:22.500 --> 00:19:25.216
And we will also

00:19:25.250 --> 00:19:29.466
comment out this console.log.

00:19:29.550 --> 00:19:33.000
And the next thing that we need to do

00:19:33.083 --> 00:19:36.083
is to update our

00:19:36.116 --> 00:19:40.316
X and Y position
to be this new end of this line.

00:19:40.400 --> 00:19:45.566
So we set that X is equal to a

00:19:45.683 --> 00:19:50.366
strokePath.dx.

00:19:50.450 --> 00:19:53.116
Actually we should

00:19:53.150 --> 00:19:55.900
summarize it so we can do plus equals.

00:19:55.916 --> 00:20:01.800
So we increase the amount,
we increase X by strokPath.dx

00:20:01.883 --> 00:20:14.300
and let's do the same for y valuable.

00:20:14.383 --> 00:20:15.133
and we also need

00:20:15.133 --> 00:20:20.216
to update the position
or the state of our pen. So

00:20:20.283 --> 00:20:21.933
that's two

00:20:21.966 --> 00:20:26.933
previous pen was our variable

00:20:27.016 --> 00:20:31.033
and now we should get its state

00:20:31.116 --> 00:20:34.883
from our stroke.

00:20:34.966 --> 00:20:36.050
Let's see.

00:20:36.250 --> 00:20:38.750
Strokepath.pen

00:20:38.750 --> 00:20:42.600


00:20:42.683 --> 00:20:44.866
So we can also use this

00:20:44.900 --> 00:20:50.400
the state of the pen to figure out if
the model is still generating something.

00:20:50.483 --> 00:20:53.083
So let's add another if statement.

00:20:53.116 --> 00:20:56.800
So if strokePath.pen

00:20:56.833 --> 00:21:04.733
is not done yet,
so is not equal to end,

00:21:04.816 --> 00:21:07.750
then we want to keep going.

00:21:07.783 --> 00:21:12.233
So we want to empty out a stroke path.

00:21:12.266 --> 00:21:16.350
So we set that to null

00:21:16.433 --> 00:21:20.000
and we want to call the generate
function again.

00:21:20.033 --> 00:21:23.466
So model generate.

00:21:23.533 --> 00:21:26.350
And we want to,

00:21:26.383 --> 00:21:31.833
as usual, add this got stroke

00:21:31.916 --> 00:21:36.750
function
that we defined to handle these results.

00:21:36.833 --> 00:21:37.783
And otherwise,

00:21:37.783 --> 00:21:41.566
if the model has reached its end,

00:21:41.683 --> 00:21:45.200
the end of its drawing,
then we simply want to reset the model.

00:21:45.233 --> 00:21:51.433
So model.reset.

00:21:51.516 --> 00:21:52.233
So let's have a

00:21:52.233 --> 00:21:55.350
look at what this crab rabbit face

00:21:55.383 --> 00:21:59.916
pig model will generate by pressing play.

00:22:00.000 --> 00:22:05.866
Our model is loaded
and we can press the generate button

00:22:05.933 --> 00:22:09.883
and they would go a crab rabbit face.

00:22:09.966 --> 00:22:11.883
We can press, generate again

00:22:11.916 --> 00:22:16.150
and get a new drawing

00:22:16.233 --> 00:22:17.550
and keep going.

00:22:17.583 --> 00:22:21.333
I'm more of a crab this time.

00:22:21.416 --> 00:22:25.366
Instead of generating a single image,
let's change some things

00:22:25.400 --> 00:22:30.133
so that we can keep generating
new drawings to fill our canvas

00:22:30.200 --> 00:22:33.350
So by adding this call to background

00:22:33.383 --> 00:22:38.366
inside our generate drawing function,
we are clearing the previously

00:22:38.400 --> 00:22:42.816
generated image and we draw a new one
every time we press the generate button.

00:22:42.900 --> 00:22:46.083
So if we instead want to fill our canvas
with different drawings,

00:22:46.283 --> 00:22:50.916
we can remove this line of code
and make a small change to the location

00:22:51.000 --> 00:22:53.800
of the initial stroke of the model.

00:22:53.833 --> 00:22:57.083
So first we are going to

00:22:57.166 --> 00:23:00.866
comment out this background function call

00:23:00.933 --> 00:23:06.066
and then instead of setting the drawing
so that it always starts

00:23:06.100 --> 00:23:09.333
at the center of our canvas,
we are going to use

00:23:09.366 --> 00:23:14.033
the random function

00:23:14.116 --> 00:23:20.516
from P5.

00:23:20.583 --> 00:23:22.566
And what random does is that

00:23:22.566 --> 00:23:26.950
it gives us a number
in between two values.

00:23:26.983 --> 00:23:29.050
So we are just going to set these
two values.

00:23:29.050 --> 00:23:32.683
So from the top

00:23:32.766 --> 00:23:35.766
most corner of our canvas

00:23:36.016 --> 00:23:40.333
and for the x,
that will be some number between

00:23:40.416 --> 00:23:44.833
zero and the canvas

00:23:44.916 --> 00:23:50.483
width.

00:23:50.566 --> 00:23:53.566
And for Y we'll do the same.

00:23:53.733 --> 00:23:56.133
A random number between zero

00:23:56.166 --> 00:24:01.283
and our canvas height.

00:24:01.366 --> 00:24:01.883
And to make it

00:24:01.883 --> 00:24:04.933
a little more interesting,
let's make some of the variables

00:24:04.966 --> 00:24:09.366
that we use for the style of the pen
stroke random as well.

00:24:09.400 --> 00:24:13.266
So we can also set that for each
drawing by changing it

00:24:13.300 --> 00:24:16.300
inside this generate drawing function.

00:24:16.366 --> 00:24:18.916
So let's define some random colors.

00:24:18.916 --> 00:24:23.550
We'll do that by using our IGP. So

00:24:23.633 --> 00:24:28.583
let's set order to a random value

00:24:28.666 --> 00:24:32.116
between zero and to 55.

00:24:32.233 --> 00:24:36.450
For example,

00:24:36.533 --> 00:24:41.216
and let's do the same for

00:24:41.300 --> 00:24:46.250
green and blue, so we can just copy this.

00:24:46.333 --> 00:24:49.883
Oops,

00:24:49.966 --> 00:24:54.900
I go to r, g,

00:24:54.983 --> 00:24:57.816
and b

00:24:57.850 --> 00:25:02.316
I think for me personally, I'm
a big fan of the greens and blues,

00:25:02.350 --> 00:25:07.883
so I'm not going to allow too much red
just between zero and ten.

00:25:07.966 --> 00:25:13.466
Now the other value that we can change,
so these little affect or

00:25:13.550 --> 00:25:15.766
strokes,
which is the color and our stroke weight.

00:25:15.766 --> 00:25:17.783
So the other variable
is this stroke weight

00:25:17.800 --> 00:25:22.433
or sort of the the thickness of the lines.

00:25:22.516 --> 00:25:25.333
So let's call that just the weight

00:25:25.366 --> 00:25:28.633
W for short and give that

00:25:28.666 --> 00:25:32.633
also a random value between

00:25:32.716 --> 00:25:34.366
zero is probably too small.

00:25:34.366 --> 00:25:37.550
We don't want to allow it to be too small,
but for as a standard

00:25:37.583 --> 00:25:43.400
and then let's make it go
all the way up to 15 in a weight.

00:25:43.483 --> 00:25:45.250
And now we update that

00:25:45.283 --> 00:25:50.516
inside our draw function.

00:25:50.600 --> 00:25:54.383
So stroke

00:25:54.466 --> 00:26:02.733
should now be RGB instead

00:26:02.800 --> 00:26:08.516
RGB and our stroke weight

00:26:08.600 --> 00:26:15.516
should be w.

00:26:15.600 --> 00:26:20.983
And let's just reset everything
so that we can

00:26:21.066 --> 00:26:25.350
start fresh and see what happens.

00:26:25.433 --> 00:26:30.900
TSo we press play. Loading the model

00:26:30.983 --> 00:26:33.216
and we get an error.

00:26:33.250 --> 00:26:34.850
G is not defined.

00:26:34.883 --> 00:26:35.266
Let's see.

00:26:35.266 --> 00:26:38.950
I thought I did that.

00:26:39.033 --> 00:26:41.750
RBB.

00:26:41.783 --> 00:26:46.833
So RGB, save and run again,

00:26:46.900 --> 00:26:49.566
There we go.

00:26:49.600 --> 00:26:52.000
So now we are

00:26:52.033 --> 00:26:54.216
adding to our image

00:26:54.233 --> 00:27:00.683
every time we press generate.

00:27:00.766 --> 00:27:03.433
I think we should make our canvas
slightly bigger.

00:27:03.466 --> 00:27:05.466
At least I will.

00:27:05.500 --> 00:27:09.400
Let's make it 600 by 600

00:27:09.433 --> 00:27:13.500
pixels instead.

00:27:13.583 --> 00:27:16.333
And also I see that

00:27:16.366 --> 00:27:20.066
our background is not being drawn out.

00:27:20.100 --> 00:27:23.050
We don't want to overwrite it

00:27:23.083 --> 00:27:25.866
every time we hit the generate button.

00:27:25.900 --> 00:27:27.716
So let's

00:27:27.800 --> 00:27:35.666
set it here instead in our setup function,

00:27:35.750 --> 00:27:40.000
it's a background 220,

00:27:40.083 --> 00:27:43.566
which is just a grayscale value
for a background. Yes.

00:27:43.600 --> 00:27:48.133
So now we can see when the model is ready,
the canvas starts its better size.

00:27:48.166 --> 00:27:50.450
I think for

00:27:50.483 --> 00:27:52.183
for this screen.

00:27:52.216 --> 00:27:54.883
So this is our

00:27:54.916 --> 00:27:59.450
crab rabbit face pig model.

00:27:59.566 --> 00:28:03.000
And you can see
we're definitely getting some faces.

00:28:03.083 --> 00:28:06.066
That's maybe a rabbit,

00:28:06.100 --> 00:28:10.433
definitely a crab.

00:28:10.516 --> 00:28:10.750
Yeah.

00:28:10.750 --> 00:28:17.050
Now we can fill our screen
with all these strange images.

00:28:17.133 --> 00:28:21.650
Now, so far, we have just been using this
crab rabbit face pig model,

00:28:21.683 --> 00:28:26.550
but there are a bunch more versions
of the sketch on and model available.

00:28:26.633 --> 00:28:30.816
So there are actually over 100 available
through ML5.

00:28:30.900 --> 00:28:34.050
So let's create
a list of all the different models

00:28:34.083 --> 00:28:35.733
and then choose a new model.

00:28:35.733 --> 00:28:39.216
Every time we press the Generate button.

00:28:39.300 --> 00:28:42.466
Now again,
we are going to use the P5 random function

00:28:42.500 --> 00:28:45.933
so that we don't know
which model is being loaded.

00:28:46.016 --> 00:28:50.550
And this way you can kind of play a game
of Pictionary against the sketchRNN

00:28:50.633 --> 00:28:53.850
by trying to
guess what it is attempting to draw.

00:28:53.933 --> 00:28:59.066
So first off, let's load
this list of models.

00:28:59.150 --> 00:29:02.566
So on the ML5 reference
page for a sketch RNN

00:29:02.600 --> 00:29:08.233
we can find a link
to all these different models.

00:29:08.316 --> 00:29:13.500
And so let's just copy this entire list,

00:29:13.583 --> 00:29:18.600
and we're going to put it into our sketch.

00:29:18.683 --> 00:29:21.166
Let's call it

00:29:21.200 --> 00:29:26.983
simply a list of models

00:29:27.066 --> 00:29:30.066
and paste pasted in

00:29:30.133 --> 00:29:31.850
so you can maybe got the double up here

00:29:31.850 --> 00:29:43.533
that would go.

00:29:43.616 --> 00:29:44.366
So now let's

00:29:44.366 --> 00:29:47.366
change our generate drawing function

00:29:47.550 --> 00:29:50.866
to load a new random model.

00:29:50.900 --> 00:29:54.183
Every time we press, generate.

00:29:54.266 --> 00:29:56.500
So let's see.

00:29:56.516 --> 00:30:00.766
First off, we can add back this
call to background

00:30:00.800 --> 00:30:04.533
so that we are always showing a new

00:30:04.616 --> 00:30:07.616
fresh background for a new model.

00:30:07.666 --> 00:30:11.400
Actually,
let's change this random position back.

00:30:11.566 --> 00:30:14.566
Also back to our

00:30:14.783 --> 00:30:16.700
canvas size

00:30:16.733 --> 00:30:20.700
or half our canvas size
so that it's always in the middle.

00:30:20.783 --> 00:30:26.283
And then we are going to load
our new model here.

00:30:26.366 --> 00:30:28.916
So a good policy,

00:30:28.916 --> 00:30:32.733
I think, is to use this

00:30:32.816 --> 00:30:38.566
model status to update
that when we are loading in a new model.

00:30:38.600 --> 00:30:42.516
So let's use that one again,
which is hashtag.

00:30:42.600 --> 00:30:45.116
Um, let's see, hashtag not select

00:30:45.116 --> 00:30:49.833
hashtag status,

00:30:49.916 --> 00:30:52.783
dot HTML.

00:30:52.816 --> 00:30:58.683
And this time we want it to say

00:30:58.766 --> 00:31:05.666
new new model loaded,

00:31:05.750 --> 00:31:12.550
something like that.

00:31:12.616 --> 00:31:16.483
And then we are going to redefine model.

00:31:16.516 --> 00:31:26.666
So model now equals ML5.sketchRNN,

00:31:26.750 --> 00:31:29.416
and usually we would

00:31:29.450 --> 00:31:33.733
have our the name of the specific model
we want to use.

00:31:33.766 --> 00:31:36.583
But now since we want it to be random,

00:31:36.616 --> 00:31:44.250
we are going to pass our list of models

00:31:44.333 --> 00:31:47.366
and we are going to inside these square

00:31:47.400 --> 00:31:51.566
brackets,
we're going to put our random function.

00:31:51.650 --> 00:31:54.200
Now we want this to be an integer

00:31:54.200 --> 00:31:58.166
so we can make sure it is by wrapping

00:31:58.200 --> 00:32:02.766
this random function in an int function

00:32:02.850 --> 00:32:05.850
and then it goes random.

00:32:05.933 --> 00:32:08.716
That should be some value between zero

00:32:08.716 --> 00:32:13.150
and the the length of this list of models.

00:32:13.216 --> 00:32:15.883
So then we can use

00:32:15.916 --> 00:32:22.250
list of models.length

00:32:22.316 --> 00:32:27.183
like so.

00:32:27.266 --> 00:32:30.133
And we also want

00:32:30.166 --> 00:32:38.683
to pass our model ready function.

00:32:38.766 --> 00:32:41.283
Other than this,
we shouldn't have to change anything else

00:32:41.283 --> 00:32:44.750
in our draw function
that should function just as it has been.

00:32:44.833 --> 00:32:48.133
So let's clear everything and

00:32:48.216 --> 00:32:52.166
try to run it.

00:32:52.250 --> 00:32:53.083
Okay, so let's

00:32:53.083 --> 00:32:57.050
press play and see how this goes

00:32:57.133 --> 00:32:58.150
and press generate.

00:32:58.150 --> 00:33:01.850
We see that
a new model is loaded and ready

00:33:01.933 --> 00:33:05.133
and it has drawn something

00:33:05.200 --> 00:33:09.183
about maybe one of the items on this list.

00:33:09.250 --> 00:33:10.750
Let's try a new one.

00:33:10.783 --> 00:33:14.000
New model is loaded and ready.

00:33:14.083 --> 00:33:19.983
This time we can't really see it.

00:33:20.050 --> 00:33:22.433
So what I think we should do about that

00:33:22.433 --> 00:33:26.816
is that in our draw function, we should

00:33:26.900 --> 00:33:31.683
when the model has successfully predicted
something,

00:33:31.750 --> 00:33:35.083
we should reset not just the model,

00:33:35.116 --> 00:33:41.600
but the positions of X and Y.

00:33:41.683 --> 00:33:46.883
So let's set them back to canvas

00:33:46.966 --> 00:33:52.100
width divided by two

00:33:52.183 --> 00:34:03.050
income as height, divided by two.

00:34:03.133 --> 00:34:14.483
Let's reset again.

00:34:14.566 --> 00:34:16.183
So we're trying again.

00:34:16.216 --> 00:34:19.616
New model is loaded and ready

00:34:19.700 --> 00:34:21.666
and it draws something.

00:34:21.700 --> 00:34:23.733
Let's try again.

00:34:23.800 --> 00:34:25.033
Now we're consistently

00:34:25.033 --> 00:34:29.966
getting the first stroke starts
at the center.

00:34:30.050 --> 00:34:31.583
New model loaded can take

00:34:31.583 --> 00:34:35.633
a little bit of time
That's a good pineapple

00:34:35.716 --> 00:34:37.700
for it to load can take some time

00:34:37.700 --> 00:34:41.300
but now it's consistently drawing this.

00:34:41.333 --> 00:34:50.550
I have no idea what it is

00:34:50.633 --> 00:34:51.616
or so.

00:34:51.616 --> 00:34:55.400
Finally, let's let the sketchRNN
receive input

00:34:55.433 --> 00:35:00.866
from our pen strokes so that we can draw
collaboratively with the model.

00:35:00.950 --> 00:35:05.300
And to achieve this,
we can create a separate stroke path,

00:35:05.333 --> 00:35:10.283
which is user input, and we'll do that
inside our draw function.

00:35:10.366 --> 00:35:12.766
So first off, let's make

00:35:12.766 --> 00:35:16.733
a global variable underneath our list

00:35:16.816 --> 00:35:19.550
for our strokes,

00:35:19.583 --> 00:35:22.933
and we're going to use them to sort of
seed the models.

00:35:22.966 --> 00:35:25.850
So let's call them seed

00:35:25.883 --> 00:35:28.516
seed strokes

00:35:28.550 --> 00:35:34.266
and it can be empty to start

00:35:34.350 --> 00:35:37.533
And now inside our draw function,

00:35:37.616 --> 00:35:40.016
we are going to check

00:35:40.050 --> 00:35:43.200
if the mouse is pressed,
because if the mouse is pressed,

00:35:43.233 --> 00:35:46.866
we want to capture our strokes,
the use of strokes.

00:35:46.950 --> 00:35:52.066
So if I'm going to use the P5 variable

00:35:52.133 --> 00:35:57.166
mouse is pressed,
which is either true or false.

00:35:57.233 --> 00:35:59.783
So if the mouse is pressed,

00:35:59.816 --> 00:36:08.333
we want to create a stroke, which is ours,
so let's make it look different

00:36:08.366 --> 00:36:11.800
from the sketchRNN strokes,

00:36:11.883 --> 00:36:14.433
so let's make it black, for example.

00:36:14.466 --> 00:36:21.066
And our stroke weight

00:36:21.150 --> 00:36:22.950
can be

00:36:22.983 --> 00:36:24.716
random

00:36:24.750 --> 00:36:28.383
somewhere between four

00:36:28.466 --> 00:36:31.383
and nine.

00:36:31.416 --> 00:36:32.466
You can play around with this.

00:36:32.466 --> 00:36:37.333
It's really up to you what you want to do.

00:36:37.416 --> 00:36:40.416
And now we can create a line

00:36:40.616 --> 00:36:43.583
which again takes four variables.

00:36:43.616 --> 00:36:50.333
And now we're going to use our mouse
position as the positions to draw a line.

00:36:50.366 --> 00:36:54.466
So we're going to use some system
variables

00:36:54.533 --> 00:36:59.133
which are called mouse
X and Y and P, mouse X and Y.

00:36:59.166 --> 00:37:03.550
So we'll start from P, mouse x and Y,

00:37:03.633 --> 00:37:06.033
So p mouse x,

00:37:06.066 --> 00:37:08.633
which basically it's a system variable

00:37:08.633 --> 00:37:12.400
that has at any time

00:37:12.483 --> 00:37:17.583
contains the position on the canvas
where our mouse was at the previous frame.

00:37:17.616 --> 00:37:22.266
So its previous mouse X and previous
mouse Y

00:37:22.350 --> 00:37:26.266
p mouse y

00:37:26.333 --> 00:37:32.016
and we want the end to be mouse x

00:37:32.100 --> 00:37:36.066
and y

00:37:36.150 --> 00:37:41.866
not moved

00:37:41.933 --> 00:37:55.900
like so.

00:37:55.983 --> 00:37:56.916
Now since these are going

00:37:56.916 --> 00:37:59.883
to be input to our model,

00:37:59.916 --> 00:38:04.533
we need to create a stroke path

00:38:04.616 --> 00:38:08.116
with a d, x and a d, Y and a Penn State.

00:38:08.183 --> 00:38:10.316
So we're going to call that use a stroke.

00:38:10.316 --> 00:38:14.533
So let's say that user

00:38:14.616 --> 00:38:16.916
stroke

00:38:16.950 --> 00:38:19.766
and we're going to create an object

00:38:19.800 --> 00:38:22.650
with some attributes.

00:38:22.683 --> 00:38:25.900
So we want d X

00:38:25.983 --> 00:38:30.783
in the user strokes
to be equal to the difference

00:38:30.816 --> 00:38:40.833
between the current position
and the previous position.

00:38:40.916 --> 00:38:46.383
And then we want to add a d y,

00:38:46.466 --> 00:38:49.883
which I'm sure you can guess what
that value should be.

00:38:49.916 --> 00:38:55.116
So that's previous or current y

00:38:55.200 --> 00:38:58.416
minus previous Y,

00:38:58.500 --> 00:39:01.083
and then we need a pen state.

00:39:01.116 --> 00:39:05.733
So we'll define pen and we'll set that

00:39:05.816 --> 00:39:08.583
to down

00:39:08.616 --> 00:39:13.116
because we know that the mouse is pressed
if we're doing any of this.

00:39:13.200 --> 00:39:16.683
So that's our user stroke.

00:39:16.766 --> 00:39:21.016
And so the last thing we are going to do
is to add

00:39:21.083 --> 00:39:23.483
this user stroke that we just made

00:39:23.516 --> 00:39:30.633
to seed strokes.

00:39:30.716 --> 00:39:32.366
We can do that using push,

00:39:32.366 --> 00:39:40.450
which just adds this object to our list.

00:39:40.533 --> 00:39:47.616
So let's add user

00:39:47.700 --> 00:39:54.433
stroke

00:39:54.516 --> 00:39:58.366
and let's see

00:39:58.450 --> 00:40:00.150
another

00:40:00.183 --> 00:40:01.200
spelling error there.

00:40:01.200 --> 00:40:03.550
Mouse pressed.

00:40:03.583 --> 00:40:05.366
Let's try again.

00:40:05.400 --> 00:40:06.716
There we go.

00:40:06.750 --> 00:40:11.600
Now we want the model to start drawing
where we left off.

00:40:11.633 --> 00:40:15.683
So let's remove our generate button
and instead create a function

00:40:15.916 --> 00:40:19.783
which we will call start sketchRNN,
which will then be called

00:40:19.816 --> 00:40:24.766
when a release of the mouse is detected
inside our canvas.

00:40:24.850 --> 00:40:30.016
So let's remove
our generate drawing function

00:40:30.100 --> 00:40:32.816
and will replace it

00:40:32.850 --> 00:40:37.033
with our start

00:40:37.116 --> 00:40:42.916
sketchRNN function instead.

00:40:43.000 --> 00:40:45.750
And so we want to start where

00:40:45.783 --> 00:40:47.800
where the user left off.

00:40:47.833 --> 00:40:52.950
So we're going to change our X
and Y values that x should be current

00:40:52.983 --> 00:40:57.250
position of the mouse and Y

00:40:57.333 --> 00:41:00.700
should be also current position.

00:41:00.783 --> 00:41:04.250
The mouse in the Y dimension.

00:41:04.333 --> 00:41:06.433
And then we can call again

00:41:06.433 --> 00:41:10.216
model.generate.

00:41:10.300 --> 00:41:15.516
But this time
we not only want to send our function,

00:41:15.700 --> 00:41:20.416
our callback function got results,

00:41:20.500 --> 00:41:24.516
we also want to send it
some input to base.

00:41:24.550 --> 00:41:28.066
It's generation on, so we'll send it

00:41:28.150 --> 00:41:32.383
our seed strokes

00:41:32.466 --> 00:41:34.183
and now we can call this function

00:41:34.183 --> 00:41:40.183
from inside our model ready function
when the mouse is released.

00:41:40.266 --> 00:41:44.150
So we still want to show the chemist
when the model is ready.

00:41:44.233 --> 00:41:47.233
But then we also would like

00:41:47.283 --> 00:41:55.300
to use canvas dot mouse released

00:41:55.383 --> 00:41:58.083
and we send it what we want it to do

00:41:58.083 --> 00:42:02.050
and the mouse is released,
which is start function.

00:42:02.133 --> 00:42:06.850
Call our function start sketchRNN

00:42:06.933 --> 00:42:12.550


00:42:12.633 --> 00:42:13.200
So before

00:42:13.200 --> 00:42:17.783
we try out this new implementation,
we should remove this generate button

00:42:17.816 --> 00:42:23.983
since it's calling a function
which no longer exists.

00:42:24.066 --> 00:42:30.433
So let's just delete these three lines

00:42:30.500 --> 00:42:35.000
and we should also change
the stroke values

00:42:35.033 --> 00:42:38.433
so they are no longer random.

00:42:38.516 --> 00:42:41.800
This was all set in generate drawing.

00:42:41.883 --> 00:42:44.216
Let's change it.

00:42:44.250 --> 00:42:45.900
Let's give it a stroke weight

00:42:45.900 --> 00:42:47.333


00:42:47.366 --> 00:42:51.683
And just give it a color.

00:42:51.800 --> 00:42:55.000
This is sort of my default

00:42:55.083 --> 00:42:56.583
color that I always use.

00:42:56.583 --> 00:42:58.666
I don't really know why.

00:42:58.700 --> 00:43:03.883
Again, it's up to you guys
to play around with this.

00:43:03.950 --> 00:43:05.933
Okay, so now let's

00:43:05.966 --> 00:43:09.583
try and draw out

00:43:09.650 --> 00:43:16.000
we have an error
that got results is not defined.

00:43:16.083 --> 00:43:17.300
And that's true.

00:43:17.300 --> 00:43:18.650
It's not called got results.

00:43:18.650 --> 00:43:21.350
It's called got stroke.

00:43:21.383 --> 00:43:23.150
Sorry about that.

00:43:23.183 --> 00:43:28.800
Let's reset.

00:43:28.883 --> 00:43:32.183
So let's see if we can now draw something

00:43:32.266 --> 00:43:37.800
and the RNN continues our drawing.

00:43:37.883 --> 00:43:40.783
Something like this.

00:43:40.816 --> 00:43:42.166
Now, the sketchRNN

00:43:42.166 --> 00:43:46.733
model will use our previous
pen strokes as a starting point.

00:43:46.766 --> 00:43:49.816
And it will it will attempt to continue

00:43:49.850 --> 00:43:53.216
the drawing in a sensible way.

00:43:53.300 --> 00:43:57.200
So if we are loading the face model,
for example, sketch on end

00:43:57.233 --> 00:44:01.616
should try to create a face
based on whatever we draw.

00:44:01.700 --> 00:44:07.516
But sometimes, as you can see, the input
we supply can be, I don't know,

00:44:07.550 --> 00:44:13.066
confusing to the or an end to the model,
and we get sort of nonsense back.

00:44:13.133 --> 00:44:16.100
So I think a useful thing for us

00:44:16.133 --> 00:44:19.966
to implement here is a clear button

00:44:20.000 --> 00:44:24.350
so that we can clear the
canvas and reset the model.

00:44:24.433 --> 00:44:27.633
So first let's just clear screen

00:44:27.716 --> 00:44:36.900
and in setup
we are going to add a new button

00:44:36.983 --> 00:44:39.983
using create

00:44:40.100 --> 00:44:41.966
button

00:44:42.000 --> 00:44:45.000
and let's give it

00:44:45.166 --> 00:44:52.916
the name clear.

00:44:53.000 --> 00:44:55.216
We're going to place it

00:44:55.250 --> 00:44:57.916
around the same spot

00:44:57.916 --> 00:45:02.250
as we had our generate button

00:45:02.333 --> 00:45:05.633
and we need to define its logic.

00:45:05.783 --> 00:45:08.783
So what should happen when button

00:45:08.966 --> 00:45:16.383
has a mouse pressed event.

00:45:16.466 --> 00:45:20.466
So let's define a function clear

00:45:20.550 --> 00:45:31.466
drawing,

00:45:31.550 --> 00:45:34.433
so clear drawing.

00:45:34.466 --> 00:45:37.616
And what we want this function to do

00:45:37.650 --> 00:45:40.650
is to again call background.

00:45:40.766 --> 00:45:42.866
So we know that that

00:45:42.900 --> 00:45:44.783
resets

00:45:44.816 --> 00:45:46.350
our background and races.

00:45:46.350 --> 00:45:48.883
Everything that was on canvas.

00:45:48.916 --> 00:45:54.333
And we also want to clear
our seed strokes variable

00:45:54.416 --> 00:45:58.350
so that the model can get

00:45:58.433 --> 00:46:00.916
a fresh

00:46:00.950 --> 00:46:02.716
stroke from us.

00:46:02.750 --> 00:46:06.183
Let's see.

00:46:06.266 --> 00:46:10.116
There we go.

00:46:10.200 --> 00:46:14.650
And we also want to reset
the model for good measure.

00:46:14.716 --> 00:46:20.900
So model dot reset.

00:46:20.983 --> 00:46:23.883
So let's see what that does.

00:46:23.916 --> 00:46:26.566
So we now have our clear button

00:46:26.600 --> 00:46:30.066
we can draw and the model will continue

00:46:30.100 --> 00:46:34.666
our drawing

00:46:34.750 --> 00:46:35.150
and draw

00:46:35.150 --> 00:46:38.533
some small faces, it seems,
and then we can clear it.

00:46:38.566 --> 00:46:40.150
And then the model is

00:46:40.183 --> 00:46:45.133
the canvas is cleared
and the model is ready for some new input.

00:46:45.216 --> 00:46:50.183
So the last thing that we are going to do
is to add a dropdown menu

00:46:50.216 --> 00:46:55.550
so that we can select different models
based on what we are drawing.

00:46:55.616 --> 00:47:01.350
So first let's add our global variable
to indicate our dropdown menu.

00:47:01.383 --> 00:47:07.416
Let's just call it dropdown

00:47:07.500 --> 00:47:10.016
and then we can initialize it

00:47:10.050 --> 00:47:13.566
inside or set up function

00:47:13.650 --> 00:47:16.900
to contain
all the different models from our list.

00:47:17.066 --> 00:47:21.666
So dropdown

00:47:21.750 --> 00:47:26.266
to initialize it, we use create

00:47:26.350 --> 00:47:32.866
not button, but create select.

00:47:32.950 --> 00:47:35.300
We need to place it somewhere.

00:47:35.316 --> 00:47:40.066
So let's just

00:47:40.150 --> 00:47:41.400
dropdown dot position.

00:47:41.400 --> 00:47:43.866
Let's just place it

00:47:43.900 --> 00:47:57.550
slightly lower than our clear button

00:47:57.633 --> 00:47:58.766
and then we're going to use

00:47:58.766 --> 00:48:02.616
a for loop to populate this dropdown

00:48:02.650 --> 00:48:07.716
menu with all of these different models
from our list of models.

00:48:07.800 --> 00:48:11.233
So the way we do that is we say for

00:48:11.316 --> 00:48:15.100
and we need a temporary constant,

00:48:15.183 --> 00:48:22.483
call it just the value of our

00:48:22.566 --> 00:48:28.866
list of models.

00:48:28.950 --> 00:48:30.150
And inside this

00:48:30.150 --> 00:48:33.950
for loop we are
then just going to call dropdown

00:48:34.016 --> 00:48:37.750
dot option

00:48:37.833 --> 00:48:41.766
and give it our value.

00:48:41.916 --> 00:48:46.350
So for each value in our list of models,
we're going to make it an option

00:48:46.383 --> 00:48:50.900
in our dropdown menu.

00:48:50.983 --> 00:48:55.266
So we also want to add a function
to handle

00:48:55.300 --> 00:49:00.350
what'll happen when we select a new value
from our dropdown menu

00:49:00.433 --> 00:49:08.933
so we can do that
using dropdown dot changed,

00:49:09.016 --> 00:49:13.216
which is a P5

00:49:13.300 --> 00:49:18.050
solution for making these sort of compact

00:49:18.133 --> 00:49:19.900
function calls.

00:49:19.933 --> 00:49:23.166
So what we're going to do is do dropdown

00:49:23.200 --> 00:49:27.166
dot changed and then

00:49:27.250 --> 00:49:31.183
we put these double parentheses

00:49:31.266 --> 00:49:36.733
and a little arrow
to point to our function

00:49:36.783 --> 00:49:40.783
and we're just going to bake
this entire function into this

00:49:40.866 --> 00:49:43.800
small sort of line of code.

00:49:43.833 --> 00:49:46.833
So what we want to do
is we want to reset the model

00:49:46.833 --> 00:49:50.083
when the dropdown menu changes

00:49:50.166 --> 00:49:53.900
because we are going to be changing
to a different one.

00:49:53.983 --> 00:49:59.450
And so let's make
a variable model selected

00:49:59.533 --> 00:50:04.250
and then we need to access
the current value of the dropdown menu.

00:50:04.333 --> 00:50:07.783
So dropdown dot

00:50:07.866 --> 00:50:09.816
value.

00:50:09.850 --> 00:50:12.250
This always refers to the current

00:50:12.250 --> 00:50:15.500
value of the dropdown menu

00:50:15.583 --> 00:50:19.033
and then we will initialize a new model.

00:50:19.066 --> 00:50:22.433
So we will say that model is now equal to

00:50:22.516 --> 00:50:28.883
ml5.sketchRNN

00:50:28.966 --> 00:50:33.133
this and

00:50:33.216 --> 00:50:40.250
we will be using the model selected

00:50:40.333 --> 00:50:43.083
and of course

00:50:43.116 --> 00:50:45.333
we want to send in our callback
function model

00:50:45.333 --> 00:50:48.333
ready for good measure.

00:50:48.516 --> 00:50:49.116
There we go.

00:50:49.116 --> 00:50:52.466
And then outside this changed

00:50:52.533 --> 00:50:56.183
dropdown dot changed function description.

00:50:56.266 --> 00:51:01.200
If you remember to close this off

00:51:01.283 --> 00:51:04.250
one last thing we want to do

00:51:04.283 --> 00:51:08.216
is at the end of our

00:51:08.300 --> 00:51:10.550
setup function,

00:51:10.583 --> 00:51:12.616
let's actually move this

00:51:12.650 --> 00:51:16.516
initial line
which sets up our model for the first time

00:51:16.550 --> 00:51:21.933
and it sets up this crab rabbit face
pig model.

00:51:22.016 --> 00:51:26.600
And instead
we want the initial choice of the default

00:51:26.633 --> 00:51:30.900
when we start running our program to

00:51:30.983 --> 00:51:32.683
be set to

00:51:32.683 --> 00:51:36.766
whatever the dropdown menu
has as its current value.

00:51:36.800 --> 00:51:39.800
Instead.

00:51:40.016 --> 00:51:44.166
So the first element
should be alarm clock.

00:51:44.233 --> 00:51:47.783
So we want alarm clock
to be sort of the default model

00:51:47.816 --> 00:51:59.466
that loads when we start our program.

00:51:59.533 --> 00:52:01.883
So there's our alarm clock

00:52:01.916 --> 00:52:04.700
kind of let's try out another one.

00:52:04.733 --> 00:52:08.166
For example, book,

00:52:08.233 --> 00:52:10.583
we can clear it

00:52:10.616 --> 00:52:13.616
and I'll do this

00:52:13.850 --> 00:52:17.616
not a not a great addition, but

00:52:17.683 --> 00:52:21.083
let's try another one.

00:52:21.166 --> 00:52:27.983
Angel, for example.

00:52:28.066 --> 00:52:30.100
Yeah, pretty good.

00:52:30.133 --> 00:52:32.200
And so that's it for now.

00:52:32.233 --> 00:52:37.333
You can take this further, if you like,
by checking out the links on our website

00:52:37.366 --> 00:52:40.850
under the header, going further
and thanks so much for joining.

