COLTON OGDEN: All right, everybody.
Come one, come all
this is CS50 on Twitch.
My name is Colton Ogden and I'm
today joined by CS50's Dan Coffey.
DAN COFFEY: Hello.
COLTON OGDEN: Dan, why don't you
tell us a little bit about yourself?
DAN COFFEY: Sure.
[INTERPOSING VOICES]
DAN COFFEY: Hello.
So I have a long history with CS50.
As you may or may not know.
I took CS50 back in 2010, which is eight
years ago, unbelievably at this point.
I took it.
It was a much different
course at the time.
There's a lot more resources now and
some really exciting things going on.
And it's really just been a pleasure
to be a part of it and watch it grow.
And Colton, you were actually hired
around the same time I was hired.
COLTON OGDEN: Yeah.
DAN COFFEY: I joined in 2012 and
I think you joined the same year?
COLTON OGDEN: Yeah.
I joined in 2012 remotely
and then came here in 2013.
And for the last eight years you've
been-- or not last full eight years,
but for most of time, you've
actually been on the production team.
DAN COFFEY: I have, yep.
I'm where my CS50
production sweatshirt and--
COLTON OGDEN: Represent.
DAN COFFEY: Yeah.
So my primary role in CS50
is not as a developer,
so I hope you'll forgive any stumbling
or extra documentation reading today.
As I took the course, coding
is a hobby and passion of mine,
but I would say my skill set is more
aligned with the video production
of the course.
So if you enjoy how CS50
looks, I have a hand in that.
And we built the studio
together here, so it's
kind of fun to be on
the other side instead
of being the guy who
sits off on the side
and turns your mic on
and fixes problems,
to actually be in the spotlight.
COLTON OGDEN: Yeah.
Special thanks and shout out to Dan
for building the streaming setup
and also for being--
if you've been paying attention, he's
typically this character off stream
as well.
A little Easter egg, CS50 has a
long history with this Muppet too.
DAN COFFEY: Yeah.
And I see we've got people joining
in the chat, so hello, Bhavik Knight.
Hello, Nuwanda and Galyash, Gulyash.
COLTON OGDEN: Yeah,
Gulyash74, Bhavik Knight.
I missed yesterday's, started early.
Oh yeah, yesterday's did start early.
We normally-- we've
been doing 3:00, 4:00 PM
streams, but we're trying to go a
little bit more towards 1:00 PM,
just to hit people abroad.
Bella Kirs is in.
Hello, Bella.
Good to see you.
And Nuwanda3333 which
is Asli, is in here.
Colton, Dan, and everybody,
and Gulya says hello.
So awesome, we have a full
crowd of people in here already.
So yeah.
So you're here on the
production team, but you
have sort of a passion, a hobby
dealing with programming and CS.
DAN COFFEY: Yeah.
COLTON OGDEN: So what
is the project we're
going to be taking a look at today?
DAN COFFEY: Yeah, so today, if you
want to switch to our laptop view here,
I've got cued up--
I'm just going to hit
Play on our video player.
The drawing app that David
is using on screen here,
it's called draw.cs50.io if
you want to play along at home.
And so the idea was we
had this problem where
we wanted no Chrome on the screen.
We wanted everything to be hidden,
and so nice and clean and easy to use.
And the way that David wanted
to be able to draw and erase
was to put one finger on the screen
and move to draw, two fingers to erase.
There's some additional
functionality, which
we're not going to
implement today, which
is three fingers is for large
erase and then five fingers
pans the image around.
And there's some interesting features.
Let's actually jump
over to the app itself.
So it is live at a
draw.cs50.io if you care to--
COLTON OGDEN: So anybody can go--
DAN COFFEY: Anybody can try this out.
I'm going to click and
draw and it's that easy.
There's a secret menu.
If you click and swipe up from the
bottom, there's a hidden menu here.
We can change our color.
We can increase our stroke size.
COLTON OGDEN: So if I were to go
to draw.cs50.io on my computer,
which I have here, which isn't on the
screen, but if I try to draw something,
will you see it there
on your end as well?
DAN COFFEY: No.
So that's one of the cool
features though if we go /twitch,
and anybody in Twitch land that wants
to join us, if you just go to /twitch.
COLTON OGDEN: OK.
I'm on /twitch now.
DAN COFFEY: And now
if I click and draw--
COLTON OGDEN: OK, I'm going
to draw a three on the right.
And it showed.
I see it showed up.
The chat is kind of
blocking it, but you can
see behind there the three is there.
Yay.
DAN COFFEY: And we've got
the same functionality
if anybody watching the stream
wants to click and draw too.
We'll see if this breaks itself.
So this is very much a work in progress.
I'll say that because there's--
so the erase condition I
haven't quite figured out yet.
And also there's no delete feature yet.
COLTON OGDEN: Always more
features to be implemented.
DAN COFFEY: Yeah.
We can clear the screen.
But this is a work in progress.
COLTON OGDEN: Cool.
DAN COFFEY: It's been a
really fun project to work on.
And the way that the version that
you're seeing on screen right now works
is by using a technology
called web sockets,
so it's like a real-time
connection between our browsers.
And anybody else who
connects to it can also draw.
Oh, we've got a taker.
COLTON OGDEN: We've got some people.
DAN COFFEY: Who's drawing?
It's Bhavik Knight.
COLTON OGDEN: I'm guessing
it's going to be Bhavik.
Now there it is.
That's awesome.
It's so cool to see people
interacting with it in real time.
DAN COFFEY: We've got
a couple of people.
COLTON OGDEN: Oh, yeah.
It looks like a heart.
DAN COFFEY: So I'm really hoping
that this doesn't break because it's
quite possible that it will.
COLTON OGDEN: Or hopefully
not devolve into--
DAN COFFEY: And if we
cheat and just look
at the inspector here,
the developer tools,
you can see all of the debug
information that's still here
even though this code's in production.
Sh.
It's really just because
it's a work in progress.
And it is a public repository, but
you're welcome to take a peek at it.
It's not the cleanest code, again.
My--
COLTON OGDEN: What's the URL and
I'll plug it in the twitch chat?
DAN COFFEY: Sure.
It's github.com--
COLTON OGDEN: CS50?
DAN COFFEY: CS50.
COLTON OGDEN: Draw50?
DAN COFFEY: Draw50.
And the version that's here
is currently the master branch
if you're looking for it.
COLTON OGDEN: That's so cool.
And we got-- so let's do some comments.
I was wondering where
I heard that name, then
I recall I watched this Turkish series.
[INAUDIBLE]
Oh, he's talked about Asli's name.
OK, got it.
OK.
Bella Kirs says, cool.
Awesome.
Yeah and then we have Just
Another Silly Bot says hi.
DAN COFFEY: Hello.
COLTON OGDEN: Hello.
Good to have you with us today.
So awesome.
So how is-- what's the,
I guess, the couple
of sentences that describe how
or what Draw50 has implemented
and they're using.
DAN COFFEY: Sure.
I'm going to go back to this
version just so we don't get
any distracting drawing on the screen.
If you just go to
draw.cs50.io, it's simply
there's no web sockets happening, so
you're having your own drawing board.
And this is analogous to what David uses
on the screen if we look at the lecture
here.
So we can draw by clicking.
And this is actually built
for using a touch screen.
I don't have one in front of me.
I just have a Mac in front of me, but
if you use one finger, it'll draw.
If you use two fingers, it'll erase.
And you can simulate
this by pressing Shift.
So now we can erase.
If you hold Shift and Command--
let me draw a little bit
more on the screen first.
You can do large erase--
or sorry, that's pan.
So you can move things around.
And then if you will just
Command, you can do large erase
for clearing big portions of the screen.
COLTON OGDEN: Command is
probably Control on Windows?
Do we know?
Some folks are using--
DAN COFFEY: Or Alt. Yeah.
COLTON OGDEN: OK, yeah.
Alt or Control probably on Windows.
Goal1 says that's really nice.
DAN COFFEY: Yeah.
It's kind of cool because as computer
scientists or coders ourselves,
it's really fun.
Like, this is why I love it.
Being able to solve your
own problems because we
were using this-- we had
a former student, Bjorn,
who developed the first
version of this app for us
and it ran on Windows directly on
a Microsoft Surface, the original.
And it just-- it's really
hard to add new features
and we had to work with Bjorn to
get him to make tweaks for us.
And that was wonderful,
but it's so nice just
using JavaScript to be able to very
quickly implement something new
and try something new.
And that's one of my
favorite parts about playing
with code is that, literally,
David was-- this was, I think,
a week before lecture.
And I got to give credit to Rongxin
Liu, who co-developed this with me.
He actually made the
first version of it.
And so you know it's just really fun
to open it up and a week before lecture
say, hey, how do we build an app that
gets rid of all the stuff on the screen
and has these features where
I can just use my fingers
and get the distraction away of all
the stuff that sits on the screen?
And here we are.
COLTON OGDEN: And it's networked, too,
which is nice, as we've just seen.
DAN COFFEY: Yeah, so that's
the current thinking.
So I teach an intro to digital
media class here at Harvard.
And so I plan to use this in
the spring in my course, which
is called Exploring Digital Media.
And it will be online if you care
to join us this coming spring.
And that's exploring digital
dot media as a domain.
COLTON OGDEN: Does it have
a website at the moment?
DAN COFFEY: It does.
Don't plug it yet because it's
last year's syllabus still,
but we'll definitely put out
the URL once it's ready to go.
I'm hoping to actually update
the syllabus this week.
I have it updated.
It's not updated in the markdown,
so I haven't committed it yet.
COLTON OGDEN: Awesome.
DAN COFFEY: So I thought
today what we would
do is kind of implement a simple version
of draw.cs50.io where we basically
have a canvas element that
we're going to draw on.
We'll break down getting
mouse input and coordinates
and go through the process of drawing,
erasing, maybe changing colors.
If there's any feature
requests out there
that we want to implement together,
certainly put it in the chat.
COLTON OGDEN: And questions, as always.
DAN COFFEY: And questions, yeah.
And I'm the kind of coder who
I don't do this full time,
so I'm going to be reading
lots of documentation.
I'll take you down that journey with me.
COLTON OGDEN: It's an important
part of being a programmer.
DAN COFFEY: Yeah.
So should we just get started?
COLTON OGDEN: Mm-hmm.
DAN COFFEY: All right.
Let's go ahead and close this.
So I'm going to simply start
by opening my code editor.
I'm going to use Sublime
Text and make a new file.
Let's go ahead get
ourselves organized here.
COLTON OGDEN: From the
very beginning, too.
It's just how we do.
DAN COFFEY: So on my desktop,
let's just make a new folder
and call this Draw50Live,
put all our files in there.
I like to use this view.
And let's save this file as index.html,
put it into my Draw50Live folder.
And here we go.
We've got the startings of our web page.
COLTON OGDEN: Beautiful.
DAN COFFEY: All right.
I think it's doc type html.
Or is it all caps?
COLTON OGDEN: I think
you can do either one.
DAN COFFEY: OK.
We'll leave it like that.
We open our html element.
We'll go ahead and preemptively close
it, do the same thing with our head.
Close our head.
Whoops.
We'll put our body element in here, too.
COLTON OGDEN: Everyone's getting a day
one HTML tutorial for free as well.
DAN COFFEY: Yeah, welcome to HTML.
It's technically HTML5, but HTML 1.0 for
those of us starting from scratch here.
Body element, body element, great.
So here is our rough HTML page.
It's got nothing in it at the moment.
And let's go ahead and
look at our first--
so there's two technologies
which we're going to use on this.
And so Paper.js, let's go
ahead Google that together.
Paperjs.org is the URL.
And if we go to this, it does
a lot of really cool things
with canvas elements
and different things.
And we can just look through a couple of
these maybe because they're really fun.
Let's see Tutorial, Examples.
COLTON OGDEN: Just sort
of, like, vector-based--
DAN COFFEY: Yeah.
Like, ways to visualize things.
It takes images.
You can--
COLTON OGDEN: Oh, that's cool.
DAN COFFEY: This detects
edge detection, collisions.
COLTON OGDEN: Oh, nice.
That is really cool.
DAN COFFEY: And it's
really well documented.
So if you're looking
for a drawing library,
it's a really great place to
start because the documentation is
really good.
And there's a lot of good examples
that you can just click on.
COLTON OGDEN: Neon Rainbow is--
DAN COFFEY: You want
to see Neon Rainbow?
COLTON OGDEN: Right there.
Yeah.
DAN COFFEY: Not yet but-- yeah.
COLTON OGDEN: There we--
DAN COFFEY: This is pretty cool.
COLTON OGDEN: Wow, yeah.
That is pretty cool.
DAN COFFEY: And this is all JavaScript,
all canvas, and it follows the mouse.
And like it says here,
if you click on Source,
you can even see the source code for
this, and you can modify it and run it.
So it's a really easy way to
kind of get up and running.
COLTON OGDEN: Bhavik Knight says,
started CS50 W, the web course,
just yesterday.
Wink.
DAN COFFEY: Oh, nice.
COLTON OGDEN: So he's very familiar
with what we've talked about so far.
DAN COFFEY: Brian is probably
keeping him pretty busy.
COLTON OGDEN: Yeah, probably.
DAN COFFEY: All right.
So this is what we're use to actually
create our canvas element for drawing.
But we need a way to
track the mouse and keep
track of where the
coordinates on the screen
are that we're going
to actually draw with.
And so for that we're
going to use a library
called Hammer js, which is
just a popular touch library.
Again, really well supported.
If we go here, this is where
you can download the code.
COLTON OGDEN: So the other library
does do single mouse detection?
Because I noticed the [INAUDIBLE]
thing would follow your mouse.
DAN COFFEY: Probably.
COLTON OGDEN: And this
one's for multi-touch?
DAN COFFEY: Yeah.
COLTON OGDEN: Multiple fingers?
DAN COFFEY: Let's actually look
because that's a really good question.
COLTON OGDEN: Oh, it looks
like view.center, view.bounds.
DAN COFFEY: Yeah.
So we could probably implement
this entirely with just Paper js.
I was using Hammer js because Hammer
js is really for touch interaction,
and when I developed this
with Rongxin for draw.cs50,
we were planning on
using a touch screen.
We were planning on
using five to 10 fingers
and you can't do that
with just Paper js alone.
But I'm sure we could
probably do it with Hammer js.
COLTON OGDEN: Probably,
like, a simple version.
DAN COFFEY: Yeah.
COLTON OGDEN: Well, we can
see what the Hammer js does.
DAN COFFEY: Yeah.
We'll use Hammer js just to
mingle two libraries together
because it's always--
can be fun to figure out.
And I'm also just more
familiar with the elements in--
COLTON OGDEN: Sure, yeah.
DAN COFFEY: --Hammer
js a little bit more.
So as you can see, if I click back
here to the Hammer js GitHub page--
it's for click and drag
stuff, but the Docs
is really where we want
to look at because this
is going to get us started.
COLTON OGDEN: A good
library has good docs.
DAN COFFEY: Yes.
Yes.
All right.
So we've got a Paper js as
well and we'll go to their--
tutorials is if you want to just
get started with a simple example,
but we're going to look at
the reference page as well.
All right.
So I guess the first thing we should do
is set up our canvas and our HTML page.
COLTON OGDEN: OK.
DAN COFFEY: So let's
go ahead and do that.
We're just going to make
a div with an ID of Touch.
Or maybe we should call it Draw.
COLTON OGDEN: Sure, yeah.
DAN COFFEY: Since we'll be drawing.
And then we'll go ahead
and close that div.
And so now since we have
a unique ID for this div,
we can set up our libraries
to interact with it.
And let's also go ahead and
make our own CSS file now.
So we'll just call this style--
whoops-- save this as Style CSS.
Sorry.
This is going to be a painful tutorial
on bad typing as well, so get excited.
COLTON OGDEN: No, you're doing great.
DAN COFFEY: All right,
so each HTML and body,
I'm going to modify
both at the same time,
so I can do that with just the comma.
And I'm going to cheat and look at
what I did before because CSS is also
not my strong suit.
COLTON OGDEN: CSS isn't my strong--
I end up always needing to Google if I
need to figure something out with CSS.
DAN COFFEY: So I'm going to make
the height and width 100% so
that it fills the web page completely.
I'm going to make sure that
there's no margin attached.
COLTON OGDEN: Shayaaan12
says, do you plan
on doing a live session on some
data structures any time soon?
Nothing concrete, but I'll
definitely take a look
at what we can do in
that regard and maybe ask
some people that are super
intimate with data structures
or have some ideas in mind
for what they want to do.
And I'll consider maybe
doing some myself.
Good question.
Thank you for the suggestion.
DAN COFFEY: All right.
And so we're going to
make our ID of touch.
We're going to give of that a few
parameters, just fill that to the-- so
it fills the entire heightened
width of the screen,
we're going to make the height 100%.
COLTON OGDEN: So want to make
that Draw, though, right?
Because I think Touch,
was it, previously?
DAN COFFEY: You're right, yep.
If we look back here,
I did make the ID draw.
COLTON OGDEN: And so the pound
sign is like looking for an ID.
DAN COFFEY: Yeah, that's an ID.
If this was a class, we
would use a period instead.
But since we're using an ID,
we're going to use the pound.
And we'll make the width 100%.
All right, looking good.
So if we just now open
this web page so we
can start to look at what we're
doing, simply double click on that.
And here it is.
Beautiful.
We'll open our developer tools which is
View Developer Tools or Option Command
I if you're using a keyboard shortcut.
And Bhavik, yes, you're right.
Hash is for IDs and dot is for classes.
COLTON OGDEN: MKloppenburg,
we just started
so we haven't dived too
deep into anything yet.
But basically, Paper
js and Hammer js are
a couple libraries are going to be using
and we're making the digital blackboard
app that David uses in lecture.
DAN COFFEY: Yeah, simple version.
COLTON OGDEN: Draw50.
And the link for the source
code, I can pass it to here.
DAN COFFEY: All right.
And so we can see here we've got
our web page being started up here.
And so let's go ahead
and bring in our library.
So we need Paper js.
I'm just going is jQuery just
to wrap all of my JavaScript.
COLTON OGDEN: Another JavaScript library
that gives us a lot of useful features.
DAN COFFEY: And I'm just
going to Google jQuery CDN
because I like to, instead of having
to download the code and install it,
I'm just going to go ahead
and get the CDN link for it.
And we want--
I want just a URL that I can copy paste.
COLTON OGDEN: Oh, the CDN URL?
DAN COFFEY: Yeah.
This'll probably do it.
COLTON OGDEN: They usually have a--
DAN COFFEY: There it is.
That's what I want.
So we're just going to get the
Core jQuery, so I copy that.
Go ahead and put this into my head here.
This is where all the JavaScript goes.
OK, so we've got to make
a script, type=javascript.
And it's source, right?
COLTON OGDEN: Yeah.
DAN COFFEY: Go ahead and close that tag.
So that should get us our
CDN link to the jQuery Core.
We're going to do the same thing.
COLTON OGDEN: Let me
verify that it's source.
You can keep going.
DAN COFFEY: OK.
COLTON OGDEN: Actually,
I don't do a lot of--
DAN COFFEY: I'm pretty sure it's source.
COLTON OGDEN: I'm
pretty sure it is, but--
DAN COFFEY: All right.
We also-- let's get a Paper js CDN.
Same thing, there's Paper js
Core, just take the latest.
I'm going to go ahead
and drop that in here.
All right, looking good.
And then Hammer js.
All right.
I forgot to copy this element,
so let's go ahead and do that.
Come back here, grab the
link, and paste this in.
And so bam.
Now we should, if we
reload, we'll just make sure
that they're all loading as expected.
If we look at our Network tab, you can--
there's Core js.
Did I not save?
Save.
COLTON OGDEN: I don't think you
refreshed the page, did you?
Or did you refresh the page?
DAN COFFEY: Maybe I didn't.
All right.
COLTON OGDEN: Hey,
Colton, please prepare
us a session on Java
parallel programming, thread,
semaphores, and monitors.
Thank you.
Yeah, I'll definitely
take a look at that.
DAN COFFEY: All right.
We're going to go on for a moment.
COLTON OGDEN: I don't
do a lot of it myself,
so I wouldn't be able to
probably do it on my own.
I'd probably have to
find somebody, but if I
know anybody that programs in
Java, I'll definitely ask them.
Are they basically libraries, Paper
and Hammer, says Bhavik Knight?
DAN COFFEY: Yes, they are.
Exactly.
So code you don't have
to write that takes
care of a lot of the low-level details
that you don't have to know about
and it just makes it easy to use.
And again, we chose these two libraries
because they're very great, very
well documented and easy to use.
Just make sure I have jQuery in here.
There it is.
All right.
And so we'll just kind of build a
big, monolithic application for now.
Is the functionality to
do onload with jQuery?
COLTON OGDEN: I think it's
document.onload, something like that.
DAN COFFEY: Let's just
do a quick search for it.
COLTON OGDEN: Oh, document.ready.
DAN COFFEY: OK.
COLTON OGDEN: Then it takes an
anonymous function, I believe.
DAN COFFEY: Great.
And I've got to actually put
this into a script header, too.
COLTON OGDEN: Correct.
DAN COFFEY: So script type=text--
no, just JavaScript, right?
COLTON OGDEN: Yeah, I think so.
I don't even think you need
the type=javascript, actually.
DAN COFFEY: I'm old school, Colton.
Like I said, I took CS50 in 2010.
We were using local servers at the time.
There was no IDE.
All right.
So let's just do a little console.log
to make sure this is working.
Hi there.
OK, I think it's text JavaScript.
That'll just give me the highlighting
in my syntax highlighting so that it's
easier to kind of read the code.
All right.
So we'll do a quick
reload on our HTML page.
Reload.
All right.
COLTON OGDEN: So what I
think you have to do, too,
I think this has to be an anonymous
function inside the parentheses there.
So you'd have something like,
let's see, document.ready
and then it's be function.
DAN COFFEY: OK.
So I can take it as
this extra curly brace.
This should get us where we want to be.
Thank you, Colton.
The struggles.
All right, we reload that.
COLTON OGDEN: Is it still not working?
DAN COFFEY: So close.
So close, but so far.
I feel like this is a
really immature move,
so I'm going to just got to
my cheat sheet for a second.
Let's figure this out real quick
and stop wasting everybody's time.
It's always the silly things
to trip you up, right?
COLTON OGDEN: Yeah.
You entered it correctly.
DAN COFFEY: So what am I doing wrong?
Let's debug this together.
COLTON OGDEN: Is it
because it's in the head?
Does it have to go in the body?
DAN COFFEY: I don't think so because
we have document.ready, right?
COLTON OGDEN: Yeah, you would think so.
DAN COFFEY: Let's just take a look at
the documentation for document.ready.
jQuery document ready.
COLTON OGDEN: No, it definitely
says that you did it correctly.
DAN COFFEY: All right.
We've got out file, console.log
ready, so that is all looking good.
Our script tag, we can just
move this to the body and see,
do a little check here.
I don't think this is it, though.
I don't think this is the problem.
COLTON OGDEN: Yeah, I'm not sure.
Did you maybe shift--
reload your index in HTML.
I mean, it's a silly thing, but
I don't know if it's cached.
DAN COFFEY: I did, I did.
All right.
Stand by, everybody.
Fix this, too.
COLTON OGDEN: Part of
the fun of live coding.
DAN COFFEY: Yeah.
And not preparing a real
example [INAUDIBLE]..
COLTON OGDEN: Ghassen says,
please take a look at the resume.
I know the unique way to communicate
with you is Facebook CS50 live session.
Sorry for that.
Yeah, no problem.
Again, Ghassen, I don't have a ton
of time, but when I do find time
I'll definitely take a look at it.
Forsunlight says, no problem.
Forsunlight, check elements.
Bhavik Knight-- oh, so this how
you debug js in the console.
I kind of had a very hard time
with the jQuery in the mashup pset.
Yeah, no.
Console's a fantastic weighted to
debug variables and stuff like that.
DAN COFFEY: We'll do a
bunch of that today, too.
COLTON OGDEN: Yeah.
Debugging is part of the fun you know.
Just Another Silly Bot
says, yeah, don't worry.
We're here not for a speed run.
Yeah.
DAN COFFEY: Excellent.
COLTON OGDEN: Well, next time we
can maybe do a speed run next time.
[INAUDIBLE] says, it's OK.
DAN COFFEY: Just watch the playback at
2x when you watch this after the fact.
COLTON OGDEN: Bhavik Knight says,
glad that I'm not the only one.
Yeah, no.
It's--
DAN COFFEY: No.
Welcome to the club, guys.
COLTON OGDEN: Little things happen.
It's all too common.
DAN COFFEY: All right.
I did this before.
COLTON OGDEN: Yeah, that's,
like, the shorthand version
of it, the dollar sign.
In jQuery, this is
dollar sign and then they
allow you as a shorthand to say
dollar sign and then, I think,
just empty one or whatever
with the function.
DAN COFFEY: Oh, I think
it's because I didn't--
oh, those are self closing.
Are script tags not self closing?
Maybe that's what it is.
COLTON OGDEN: Oh, yeah
because we do have the--
but I thought you said you
saw jQuery in the console.
DAN COFFEY: I did.
I saw the first one.
COLTON OGDEN: You saw
the library load, right.
DAN COFFEY: Dollar sign is not defined.
Network, OK.
So it was that these weren't closed.
That was part of it.
COLTON OGDEN: Is Core
different from jQuery.min.js?
DAN COFFEY: Yeah, so
min is minified version,
so it's just a lighter
weight version of the code.
COLTON OGDEN: But Core is
still-- it has all the stuff.
DAN COFFEY: Core is all the
basic functionality of it.
So now we're seeing all of our
libraries come in, which is good.
And so the issue was I didn't have this
closing script tags after everything.
It's one of those silly things.
I thought, just like an image,
you can put a trailing slash
like that to close the element.
You can't.
So you have to have an actual
closing script tag, even
though there's nothing in the middle.
Kind of silly, but
definitely tripped me up.
And so now--
COLTON OGDEN: Now it's
saying that-- in the console,
it says that dollar sign is not defined.
DAN COFFEY: Yeah.
So for some reason,
we're not getting jQuery.
Let's see.
If we do this--
so we are getting it.
So here's the function.
If I do the dollar sign, it's
the shorthand for jQuery.
COLTON OGDEN: Yeah.
DAN COFFEY: So we should be able to--
it must be because jQuery has--
COLTON OGDEN: Oh, you're not doing
document.ready anymore, I don't think.
DAN COFFEY: I shorten it to what I
did in production, which is this.
But we can go back to see if that's it.
Document dot ready,
function, open brace.
So this is back to where we were.
Let's see if this fixes it.
COLTON OGDEN: Still doesn't fix it.
DAN COFFEY: Oh, boy.
It's going to be quite a stream here.
COLTON OGDEN: Yeah, it's fun stuff.
It's all right.
I had a couple streams
where I tripped up on--
I had two variables that
were similarly named
and I spent, like, 10 minutes trying to
figure out why my code wasn't working.
It was a fun stuff.
Zodiac, hello.
Thanks for joining us today.
Ghassen says, hope you
make a open street map
demo of an app that anchors a route
into a map and identify all the city
points between the two cities,
that's little car pooling car.
Oh, like an Uber-type thing?
Yeah, that would be a bit of
a somewhat complicated stream,
but we could definitely maybe mock up
an Uber-type demo one of these days.
Forsunlight says, use Firefox.
DAN COFFEY: All right.
I'm going to go to jQuery's website
directly to get the actual link.
So let's see.
COLTON OGDEN: I had
never seen Core before.
I thought you needed the jQuery
min, but I might be wrong.
DAN COFFEY: I don't think so.
COLTON OGDEN: jQuery Core.
DAN COFFEY: Is this actually
downloaded or can I get the--
COLTON OGDEN: I don't
know what jQuery Core is.
I've never-- it's been a
while since I've used jQuery.
I know about jQuery 2, jQuery 1.
I usually get in the min build.
DAN COFFEY: I'm not familiar with Core.
All right.
We'll go to-- W3 schools
is a great resource
as an example for getting started.
So we can-- let's try just taking
this version of jQuery 3.3.1
and see if this will fix it.
So now-- whoops.
Oh, that's the not a CDN link.
Here's a link from Google.
So you can see the example
of using it in the head tag.
It's got a closing script tag, so we'll
go ahead and just replace this line--
COLTON OGDEN: Cool.
DAN COFFEY: --and see
if this helps us out.
Cross our fingers.
Hi there.
COLTON OGDEN: So it
was the Core version.
DAN COFFEY: Something with the Core.
COLTON OGDEN: Yeah, that's weird.
Not sure what that is.
DAN COFFEY: I might have missed--
COLTON OGDEN: That was the
first time time I'd seen Core.
Personally I don't know, but this
Saturday, Chrome gave so much trouble.
Firefox worked fine.
Oh, yeah.
I mean browsers definitely do
have interoperability issues.
Chrome tends to be the most stable
and Firefox is also really stable.
I'm not sure.
I think it depends on
what you're trying to do.
DAN COFFEY: Yeah, and I think
it's also your preference.
Like, I've used Chrome for developing
pretty much since it came out
and so I'm used to the keyboard
shortcuts to open up the console.
I know where everything is.
So it's also just my
preference to use it.
But I hear great things about Firefox.
So definitely.
COLTON OGDEN: I used Firefox
before I even knew what Chrome was.
I used to use Firefox all the time.
Forsunlight says, yay.
DAN COFFEY: We're getting some yays.
Thank you, guys, for
your emotional support.
We're going to get there, I promise.
Let me shrink this
font just a little bit.
OK.
COLTON OGDEN: I guarantee you will never
forget that Core is not the way to go.
DAN COFFEY: Yeah.
Yeah.
All right.
So let's review where we're at.
We've got our basic web page up.
If we look at the elements of
our page, we have our draw div.
And the sizing on this,
if we look over here,
this is how you can see
the current sizing applied.
And so it's the size of our page.
And let's go ahead and just
take a look at the color of it.
So I like to kind of poke at things as
I go to make sure I'm touching things
the right way.
So we could put a style tag in here, but
since we have this ourstyle.css handy
to go--
COLTON OGDEN: Yeah, typically want to
keep your CSS out of your HTML page.
DAN COFFEY: So we'll just do
a little background color.
And let's go ahead
and just make it black
because if we're going to
do a blackboard-type thing,
let's go ahead make
our background black.
If I refresh now--
COLTON OGDEN: Did you give it the style?
What was the selector that you did?
Oh, because it needs to be draw.
DAN COFFEY: Remember we talked
about this and I never changed it?
Silly me.
COLTON OGDEN: Do we
need to hard refresh?
DAN COFFEY: Yeah.
COLTON OGDEN: Shift
refresh or whatever it is?
DAN COFFEY: Yep.
Command Shift R. All right.
Let's take a look.
COLTON OGDEN: Oh, did you
link your CSS in your HTML?
DAN COFFEY: No.
No, I did not.
So I have a nice style.css
page, but there is no default
that the browser looks for, so I
need to link in our style sheet.
So we'll go ahead and
do that up top here.
Is it style sheet?
COLTON OGDEN: I think it's link
rel=stylesheet and then source.
DAN COFFEY: And since it's
in the same directory,
I can simply just say
style.css with no path to it.
COLTON OGDEN: Yeah, rel stylesheet
type=text/css and then href=style.css.
DAN COFFEY: OK.
COLTON OGDEN: All these
different attributes
and things you've got to memorize.
DAN COFFEY: It's so silly, right?
And I believe you can
self close the link tag.
COLTON OGDEN: You don't
even need the slash for it.
DAN COFFEY: OK, great.
COLTON OGDEN: It looks like.
DAN COFFEY: Reload the page.
Bam.
COLTON OGDEN: Boom.
DAN COFFEY: All right.
And now you can see
over here in our style.
And if you're ever playing with
CSS, this tool is the greatest.
So if you want to just change the width
to 50%, you just change it-- whoops,
50%--
and it happens immediately.
I am terrible at CSS,
but this is the way
that I stumble through it because I'll
come in here, play with the parameters,
and we'll do this as we build the menu.
And then you finally
get it how you like it,
and then you look at
these parameters and you--
actually, should we hide the chat
maybe so that this isn't covered up?
COLTON OGDEN: Oh, sure.
Yeah, let's take the chat
off for just a second.
DAN COFFEY: So I change
this parameter here to 50%
and immediately it reflects on the page.
And I'm not actually
editing my source code,
so if I want to change that in reality,
I need to go back to my text editor
and change it there.
But really handy for
debugging any CSS issues.
COLTON OGDEN: Yeah, you don't want to
have to keep editing your text then
refresh the page over and over again.
DAN COFFEY: Yeah.
And Bhavik asked us
to move the chat box,
so I think we did that just in time.
COLTON OGDEN: Here, I'll bring it back
up and then I'll go to the editor.
I'll make it a little bit smaller just
so we can see just a little better.
Let's make it a little bit smaller.
Hopefully it won't be too small on
stream when it starts populating again.
But definitely let us know.
DAN COFFEY: I can move the
text editor around, too.
All right, great.
Let's see.
What should we do next?
I did make a little order of
operations here so that we
didn't get too far off the rails.
COLTON OGDEN: Sort of like a--
DAN COFFEY: So we covered Paper
js, we looked at Hammer js.
We got jQuery set up,
our canvas is set up.
Our background is now colored.
So let's go ahead and
take a look at Hammer js.
And so I think what
we'd like to do-- maybe
we could start by just
seeing the coordinates
of the mouse in the console.
[INTERPOSING VOICES]
COLTON OGDEN: Oh, sure.
Yeah.
DAN COFFEY: Maybe that's
a good way to get started
COLTON OGDEN: Ghassen says, hey,
Colton, you look like those VIP raving
in Dubai.
What did he call face mash or Facebook?
Let's have a beer.
I have all the code needed.
The Winklevoss brothers
are proud of you--
Eduardo, Saverin.
Have you seen the movie
The Social Network?
I haven't seen The Social Network,
so I'm not sure if you're--
DAN COFFEY: You haven't
seen The Social Network?
COLTON OGDEN: I haven't.
Is he quoting from The Social Network?
DAN COFFEY: Oh, man.
It's a great movie.
COLTON OGDEN: I've heard it's good.
I'm not sure if what he said in the
message there is a quote from it
or not.
I hope it's a compliment,
so thank you if it is.
I haven't seen The
Social Network, though,
so I'm not entirely sure
I understand the message.
And then Bhavik said, can you
move the chat box, which we did.
OK.
DAN COFFEY: All right.
So here we are at the
Hammer js documentation.
I'm just going to click
on Getting Started.
And so usually when you
come to a library like this,
there's simple documentation
for how to get started.
So let's go ahead and
just get the Hammer Time--
the Hammer elements set up.
COLTON OGDEN: I love
how it's Hammer Time.
HammerTime.get.
DAN COFFEY: And they give
you this line of code,
which is helpful, especially
with touch interaction,
that I'm just going to copy paste
into my page, just in the head
so that the screen sizes
appropriately as expected.
COLTON OGDEN: OK, nice.
DAN COFFEY: All right.
So we have a bunch of examples here.
And the thing I really
like about Hammer js
is that there's a couple
of ways to use it.
You can use it by setting
up different actions,
so a pan is like a click and a drag.
A swipe is a bit more
quick of a flick, and you
can set the parameters for how
quick you want things to happen.
You can set up something
like a quadruple tap,
which means that somebody has to tap
four times to trigger the action.
COLTON OGDEN: So you're
naming it yourself.
You're basically saying, I want
something called a quadruple tap
to fire off if someone
taps four times in a row.
DAN COFFEY: Yeah, and they've
got some basic ones, too.
You can just have something called pan.
Pan is something that is just a
click and a drag kind of thing
or a tap in a drag because, again,
Hammer js is made for human interaction
with fingers and digits, and
it works with a mouse, too.
COLTON OGDEN: So it's like an
event manager type library.
DAN COFFEY: Exactly.
And so when we built Draw50,
there's another feature of Hammer js
that I like.
It just gives you more control.
And I'm going to go to the
actual API area for this
and it's hidden down here somewhere.
I'm just going to
scroll until I find it.
COLTON OGDEN: Ghassen says,
yes, it's a compliment.
DAN COFFEY: Right here.
COLTON OGDEN: I love you,
CS50, especially you.
Thanks, Ghassen, Much appreciated.
DAN COFFEY: All right.
So this, guys, can make you
feel like a real hacker here.
So a secret event is being
triggered by Hammer every time
that an event is admitted.
And so this is the function
that I use to actually create
the actions with the Draw50.
We can go ahead and do that here
because it gives you a couple of things.
So I'm going to copy
paste this in for now.
And I'm getting ahead of myself.
So we're going to just put
this here with a comment
so that we handle touch input.
We'll paste that in for the moment.
COLTON OGDEN: Got to love the way
that tabs are auto formatted on Paste.
DAN COFFEY: Yeah.
All right.
And then let's get our
Hammer manager set up.
It didn't jump for me.
Hammer Defaults.
I think we can just do this.
So our hammer element
is going to be this.
And my element, we can just do--
COLTON OGDEN: And that's going to be
the draw div that we specified earlier,
right?
DAN COFFEY: Yep.
And so we can even shorten this.
And I have to remember
the ID is Draw, not Touch,
which is the mistake we made earlier.
COLTON OGDEN: So you're
grabbing an element
with document.getelementbyID, which
grabs it from the HTML page, right?
DAN COFFEY: Mm-hmm.
And it stores it in this variable, but
we can shortcut this even, and just
take this and paste it in here.
COLTON OGDEN: Oh, right.
OK, nice.
DAN COFFEY: And so now that element
is going to turn it into a--
COLTON OGDEN: So fancy.
DAN COFFEY: Yeah.
OK, so then--
COLTON OGDEN: I got DJM
in the stream, everybody.
Thanks to Dan and Colton
for today's stream.
Thanks, David.
Appreciate it.
Thanks for tuning in.
DAN COFFEY: All.
Right so here we go.
If everything that we've
set up is correct so far,
what's going to happen is
when our page initializes
and once that page is loaded, it's
going to initiate the Hammer--
what, it's object, element?
COLTON OGDEN: Yeah,
this would be an object.
DAN COFFEY: And so then
there's a listener,
which is HammerTime.on, which
will automatically fire.
And what it's going to do
anytime there's any input,
it's going to console.log the pointers.
So let's go ahead and see if this works.
So if we go back here, I'm
going to reload the page
and give myself just a little bit
more space here and shrink this.
And so if we want to look at the output
of the JavaScript console, we go here.
Oh, Hammer is not defined.
COLTON OGDEN: Hammer is not defined.
DAN COFFEY: So let's go debug.
All right.
New Hammer.
We have the Hammer library here.
And let's go back to the documentation.
I don't need jQuery anymore.
We don't need these
CDN links up anymore.
Hammer js.
OK, let's go back to
the Getting Started.
Always a good place to start.
COLTON OGDEN: Yep.
DAN COFFEY: All.
Right so we have--
new Hammer is going to be
what we're looking for.
There it is.
COLTON OGDEN: Yeah, which are doing.
DAN COFFEY: There's
something else silly.
COLTON OGDEN: So it's not recognizing
that you imported the hammer library
for some reason.
DAN COFFEY: Yeah.
Hammer is not defined.
Hammer is not a defined.
Reference error.
Hammer is not defined.
jQuery is deferred exception.
OK.
Hammer not defined.
COLTON OGDEN: Let me help
you trying and debug that.
DAN COFFEY: Great.
All the silly things.
COLTON OGDEN: A lot of people
use it with node setup,
but you don't have it set in
for a node setting, right?
DAN COFFEY: I don't.
We're just using static.
COLTON OGDEN: Like, even
for the deployed app?
DAN COFFEY: Oh, we are using
node for the deployed app,
but that's just for
the web socket portion.
And it uses a database as well.
OK.
Let's figure out what's going on here.
So we have our closing.
COLTON OGDEN: Yeah, a
ton of people use it,
so all their arrows are saying--
because their what's called a gulp file
doesn't have a reference to
it, but that's in a node setup.
So we're actually using
it as a script that we
have locally on our file system.
So it's not quite the same.
So it's got to figure out why that is
DAN COFFEY: And we're getting 200,
if we look at just trying to debug.
We get a 200 from the CDN
js at CloudFlare that we--
so it is bringing it in.
So we must be doing something
wrong with the loading order.
So if we look at the--
right here is Hammer.js, so
you can see that it's loading.
So let's now-- you would think
that with document.ready it
would wait for the page to be
ready, but I wonder if we're just
doing this in the wrong order.
COLTON OGDEN: Yeah, because
you're loading jQuery first.
You should let all the scripts
and have done all that by the time
it actually executes
your document.ready.
DAN COFFEY: So that's why I'm confusing.
Oh, it's because I'm calling
Hammer Time and our variable is MC,
because I'm copying from two
different places in the documentation.
COLTON OGDEN: Right.
That'll do it.
DAN COFFEY: So that is
probably our problem.
Let's reload here.
COLTON OGDEN: Oh it still
say Hammer is not defined.
Index at line 15.
Oh, well, you are instantiating it.
It's on your-- so that's
another bug that you caught
by looking through your search code.
DAN COFFEY: We got ahead
of ourselves by one.
COLTON OGDEN: So we jumped that.
But we still to figure out the new
Hammer, the instantiation of that.
So Hammer not defined show script.
DAN COFFEY: For the moment,
I'm going to cheat and just
move this in to right above
and see if this will--
COLTON OGDEN: I don't
think you can-- you can't
include a script in a block of code.
DAN COFFEY: This is
definitely an amateur error.
I know that.
So just a matter of figuring
out how to get around it.
COLTON OGDEN: Everybody uses Hammer js
in the node setup, which is hilarious.
DAN COFFEY: New Hammer.
COLTON OGDEN: And we're definitely
using the most recent version of it
and a version that supports the Hammer.
DAN COFFEY: Let me just try Google.
Hammer js.
COLTON OGDEN: A lot of
people are reporting issues
with jQuery and Hammer.
DAN COFFEY: Well, we do use it in
the production version of Draw50.
[INAUDIBLE] definitions after your app.
Hammer js-- so we're going
to try getting it from Google
because they use the Ajax.
COLTON OGDEN: Forsunlight
says, it takes two parameters.
Is that the case?
Is that true?
Does it take two parameters?
DAN COFFEY: There's an options
parameter which you can pass in second,
but I think the issue is that
it's not even recognizing Hammer.
COLTON OGDEN: And then Hammer should--
DAN COFFEY: The Hammer symbol's
not being defined, yeah.
More debugging.
COLTON OGDEN: It's funny.
Usage-- it's easy to use.
Just include the library
and create a new instance.
DAN COFFEY: OK.
So I think it's got
something to do with how
we're importing our libraries
because the error is now gone.
All I simply did was switch to
the Google APIs instead of CDN js
off CloudFlare.
I'm almost positive this
is a user error on my part
and debugging it live is
stressful, so I'm just
going to go and switch to
the thing that works for now.
COLTON OGDEN: OK, so you basically did
a from CDN js to the Google version
and that worked?
DAN COFFEY: Yeah.
And I'm wondering if
Paper js is going to be
the same thing, so
I'm going preemptively
just see if I can switch now to--
I'm guessing that it loads
it dynamically with Ajax
from this link or something with that.
Let's see.
Is this Paper js on here?
Do you host it, Google?
All right.
Well, we'll cover that
when we cross that bridge.
For now, we're just working
on getting our touch stuff.
So what we posited was that now
that we have everything hooked up,
if we click for Hammer input
on this canvas element,
I'm hoping that in the console
we see the coordinates.
COLTON OGDEN: There we
go [INAUDIBLE] yeah.
DAN COFFEY: We see pointer event.
And so if we look, what
we're actually seeing
is this thing here that we're
logging called ev.pointers.
And so if we just look at
the Hammer js documentation,
this is what we're going to see.
So once we expand this, we'll
probably see all of this information
that you get from every single event.
And so that's firing like
thousands of times a second.
And so let's just go ahead and
look at that in the console
and see what we have in here.
Pointer event.
Oh, boy.
Live coding.
Let's look at EO.
COLTON OGDEN: Oh, because you're logging
the actual pointers event attribute.
DAN COFFEY: Yeah.
Let me reload this.
Look and drag.
There we go.
This is what I was looking for.
So now, if we just open up one of
these, just like the documentation says,
we have all of these parameters.
COLTON OGDEN: And previously you were
just doing the array of pointers.
DAN COFFEY: Yep.
COLTON OGDEN: Is that multiple fingers?
DAN COFFEY: Yep, exactly.
It's how many fingers
are touching the screen.
And so this is array of 0 at the moment.
So handy if you're trying to do
finger detection for how many pointers
you're using.
All right, but what's going to
be really helpful to us here
is I believe it's called center.
There it is.
And so what we get on our
screen is an x and y value.
And I believe that the top left
point is 0, 0 and the numbers grow
as you come down across the screen.
So this is going to be
really handy when we'd
want to tell Paper js, hey,
we want to draw at this point.
COLTON OGDEN: I guess Forsunlight
says, Dan, act like we're not here.
That's part of the fun, though.
DAN COFFEY: This is what
happens when you're not here.
There's just probably
a lot more cursing.
COLTON OGDEN: Bilateral inner--
Kid-friendly version.
Bhavik Knight, it's the
great debugging experience.
DAN COFFEY: Yes.
Debugging is always fun.
But I'm glad that we're
getting back on track here.
It's always getting yourself
set up is the hardest part,
and then the intellectually
stimulating part of coding
is actually doing the work
once everything is working.
So now we're getting to that
part, so that's really exciting.
All right.
So let's get Paper js set up now.
So we'll go over to
Paper js's documentation.
We're going to click on their
Getting Started or maybe Tutorials,
Working With Paper js because there's
some instantiation that we have to do.
So this is showing you
how to get started.
Import Paper js.
And so if I remember right,
Paper js has this thing
that they use called
Paper Script and that
takes away some of the overhead of
actually writing some JavaScript
overhead.
I believe when I did this for production
I actually wrote it all in JavaScript
and it didn't use their
Paper Script portion at all.
So let's go ahead and continue that way.
I'm going to cheat and look
at my code for a second.
It'll just be easier to get started.
So I instantiate Paper js with--
stand by.
The actual production code
is also a monolithic app.
So we have just a lot
of code to look through.
COLTON OGDEN: It's growing to
be quite a large [INAUDIBLE]..
DAN COFFEY: Well, it started
off as a really basic app
and we just kept adding features.
And then it was like, oh, it'd be cool
if you could draw with two people,
and so you just keep building
and building and building.
And instead of stopping and refactoring
the code, I just kept going.
And that's where you end up.
So this is a good lesson as
do as I say, not as I do.
And stop and take a break
and refactor your code.
All right.
So let's go ahead and let's see.
What's easier?
Examples, this is all the
Paper Script stuff, though.
If we look at this, there's no
importing or initializing Paper js.
I know what we can do
let's go to draw.cs50.io
and look at the source code.
So we'll go to Elements and
I believe I can search here.
COLTON OGDEN: So in this I notice
you used a canvas instead of a div.
Do we want to use a
canvas in our demo today
or are we just going to use a div?
Because I think it works just fine
either way, but I'm assuming--
well, canvas I know for sure
has more features than a div,
but maybe it injects a canvas
into the div if it doesn't exist?
DAN COFFEY: Possibly, yeah.
I'm actually not sure.
We'd have to look up the
documentation to be sure.
We will make it a canvas element
because Paper is the thing that's
going to care about that.
Hammer js only cares that we have an
element and that it can track on there.
COLTON OGDEN: Yeah, that's true.
That's true.
DAN COFFEY: All right.
Paper--
COLTON OGDEN: I think I got
an emojis list there, too.
That's great.
I like how Chrome actually
renders them as emojis, too.
DAN COFFEY: Yeah.
COLTON OGDEN: I noticed
that it parsed the--
DAN COFFEY: It's a fun
hidden feature that's
currently disabled, where it makes the
emojis kind of fly across the screen.
COLTON OGDEN: Oh, that is pretty--
DAN COFFEY: I tried to get
David to use it in a lecture
and he shut me down right before we
got started, so I had to disable it.
COLTON OGDEN: It feels apt,
especially because we covered emojis
in the first lecture this year.
DAN COFFEY: Yeah.
All right.
So I'm just looking for the piece of
initializing Hammer js as JavaScript,
failing terribly.
COLTON OGDEN: It's all right.
It's part of the experience.
DAN COFFEY: Let's do--
Oh, Using JavaScript Directly,
this seems like the place
that we should actually start.
All right, so set up a
scope, window on load.
COLTON OGDEN: So window on load is--
[INTERPOSING VOICES]
DAN COFFEY: This is what I
was looking for, Paper setup.
COLTON OGDEN: So we've got to
get the actual canvas element.
So you probably want to change--
we're guessing you want to change
that div to be a canvas instead.
DAN COFFEY: Yep.
Let's go ahead and do that right now.
So instead of div, we're
going to make this canvas.
COLTON OGDEN: And you want to
change the closing tag as well.
DAN COFFEY: Thank you.
Save me another headache.
Canvas.
All right, so let's go ahead and do--
up in our initialization here,
paper.setup and our canvas
is going to be the same element.
I think that will work because is
that the same document.getelementbyid.
COLTON OGDEN: Yep.
DAN COFFEY: All right,
so let's-- whoops--
not save that, save this version.
Now go and reload this.
Paper is not defined.
So we're having the same
problem we had before.
So it's definitely something with
how we're loading the libraries in.
COLTON OGDEN: Yeah, which is weird.
I'm not sure why--
text JavaScript.
DAN COFFEY: Yeah.
Maybe what we could do--
you know what we're going to do, Colton?
We're going to move this to the
bottom of our body because, remember,
the page finishes loading
and then this is called.
And for some reason, I'm not sure why,
but it seems to not be loading this.
COLTON OGDEN: OK.
Let's try it.
[INTERPOSING VOICES]
DAN COFFEY: So let's do that.
I'm going to move the script tag
COLTON OGDEN: How can I
convince my employer in the US
to hire me whereas I'm in North Africa?
Could trust be built
online, says Ghassen119.
That's not something I have
experience and expertise on,
but I would imagine that
yes, that's probably
your best bet would be to build a
resume and reach out to companies,
build a portfolio of projects.
Find an employer somewhere in the US in
a tech-related field and then sort of
establish that rapport.
But it's not an easy silver
bullet question to answer.
So again, that's something that
you'll have to undertake and just keep
working hard at it.
Bhavik Knight, what's up
at the this var and let?
I recall David using a let.
Let is a keyword introduced
in JavaScript ES6.
And it basically is kind of the same
thing as var, but a little bit more--
it has different scoping rules and I
don't recall what they are offhand.
Let versus var.
DAN COFFEY: Let keeps it
within the parentheses
and var makes it
accessible almost globally.
COLTON OGDEN: Is that how it is?
It's like Lua then?
DAN COFFEY: I believe so.
COLTON OGDEN: OK.
In that case, then, let is like
a proper scope of a variable, how
it would work in C where your variable's
sort of delimited within wherever it's
parentheses-- wherever its current
scope is, it's only accessible there,
whereas var is a more global variable.
I would have to do a little
bit more research to, I think,
elaborate on that because the semantics
of that I'm not 100% sure about.
Yeah, block scope for let and then
var is the entire enclosing function.
Oh, yeah.
OK.
So if you were to declare
a new variable within an if
statement in a loop in
a function, for example,
and it had the same
name as a variable you
declared above that, like if you have
a function that you declare x and then
an if statement that declares its own
x, those would be the same variable.
But if you use let, then they'll
both be different variables.
And you can get more information
on that if you look at the Mozilla
documentation, developer.Mozilla.org.
They have a page on the
semantics between let--
the differences between let and var,
and you can look at that a little bit.
But for our use case, unless we
do some fairly complicated coding,
they're more or less the same.
Let is more widely adopted now
as part of ES6 and, I think,
has less opportunity to
introduce subtle bugs.
DAN COFFEY: All right.
Here's what we're going to do, Colton.
We're just going to
download this ourselves.
COLTON OGDEN: We used the [INAUDIBLE].
DAN COFFEY: I'm not sure that
this will actually fix it.
COLTON OGDEN: PaperCore.min
probably, or paperfold.min.
DAN COFFEY: So we're going to just
move this into the js folder, delete
everything else, samples.
And just copy this file name.
Again, I'm sorry that we're
having trouble debugging this
because this is really
amateur hour happening here.
COLTON OGDEN: It's js slash, right?
DAN COFFEY: Yes.
Thank you.
Reload console.
OK.
COLTON OGDEN: You didn't
get the error, so OK.
Yeah, I'm honestly not 100% sure what
the error issue is with the loading it
through script tags, either.
I'd have to look at that.
DAN COFFEY: All right.
So now let's go ahead and
just recap where we are.
So we've got our Hammer
library installed,
which will handle our
touch events and we've
seen that we can get the
coordinates from that.
We have our canvas setup and now
Paper js is initializing that.
So the things that we're going
to want to do next, let's
just go ahead with some
pseudocode in for ourselves
to figure out what we want to do.
And so we want to handle--
there's kind of three parts to drawing.
And let's actually look at
the Draw50 app for this.
COLTON OGDEN: Bhavik,
let kind of seems fine.
Global variables are
generally not good practice.
I think, to elaborate
on it, I don't think--
based on the documentation I read,
it's not that they become global,
it's that they have
different scoping rules
such that you could easily
overwrite the variable,
depending on if you use
it in a nested context.
But yeah, basically, let
avoids you overwriting
variables sort of haphazardly.
And then MKloppenburg put
a let var, and then const
being the other keyword which is even
more of a consideration for making sure
your code is safer, so
that you can't overwrite
variables that should stay consistent
throughout the entire application.
We cover consts in CS50
as well, I do believe.
Right?
DAN COFFEY: Yeah.
COLTON OGDEN: Yeah.
DAN COFFEY: All right.
So there's three parts to drawing.
When you first click-- so
I just clicked my mouse
and you can't see
anything yet, but. we've
got an event that fired from Hammer
that says, event has started.
And then I'm going to actually drag.
It's firing a whole bunch of times every
second, detecting as I move the mouse.
And when I let go, another
event is fired that is the end.
And what you might notice, if
I kind of make some lines here,
you can see how it's
kind of jagged and places
and when I let go it
actually smooths itself.
And this is the real reason that I
chose Paper js to actually implement
this is because we wanted to kind of
clean up David's handwriting in lecture
so that it automatically smooths.
And I was looking at all these
algorithms that would do this for me,
and then I found that Paper js
has this dot simplify method.
And I was like, problem solved.
COLTON OGDEN: Some things
aren't fixable, though.
DAN COFFEY: Yeah.
I like importing JavaScript.
OK.
So we want to handle start draw.
We want to handle we'll call it
middle draw, and then handle end draw.
COLTON OGDEN: So when they first
click down, while they're drawing,
and then when they let go, basically?
DAN COFFEY: Yeah, exactly.
And so let's do this.
We need to have event handlers
that are listening for when--
the listener for when those events fire.
And we can go ahead and use
this hammer dot event on,
but we need to call
functions that will define
to handle depending on if
it's the first, middle,
or last part of drawing,
functions to handle this.
And so let's look at the structure of
Paper js for a second and how it works.
So if we go back to the documentation
and we go to their reference,
so they're kind of global--
once you import Paper, there's this
global project that you're working on,
and each project has layers on it.
And so let's see.
Project-- what I'm really looking for
is-- let's look over here on the right.
So there's layers of project.
Projects have items, items have layers,
layers have groups, shapes, rasters.
And so what we're going to be
doing is all working at one layer,
so you can have multiple layers
if you want to do layering.
And when I built the emoji thing so
all the emojis move in the background,
I put them on a separate
layer so that as you
drew it didn't actually mess
with all the emojis that--
COLTON OGDEN: So it's really more like
a background, separate background layer?
DAN COFFEY: Yeah, exactly.
If you think of it like
Photoshop, if you've
got a layer on top of
another layer, kind of a clue
it's what you're looking at,
and that's kind of how it works.
And so within our layer
what we're going to do
is we're going to add a bunch
of these path items to it.
And so a path will actually be the line.
And so on each layer, if we look
for children-- so layers have
children and children can
be any shape or object.
that we're going to
be adding paths to it.
And so the way that we
keep track of all the lines
by adding these path items
as children to the layer,
and that's going to build
our actual drawing for us.
COLTON OGDEN: OK.
DAN COFFEY: All right.
So let's go ahead and
make our function here.
And so we'll just do a const and we'll
call this function and start draw.
COLTON OGDEN: OK.
DAN COFFEY: And I believe,
if I get the syntax right--
COLTON OGDEN: Setting,
it's equals first.
DAN COFFEY: OK.
I'm not used to using ES6.
I decided I would step
up and do it here,
but I don't have the page in
front of me for the exact syntax.
I'm sorry.
So it's equals and the
that's this, right?
COLTON OGDEN: Yeah, then the--
[INTERPOSING VOICES]
DAN COFFEY: Arrow notation?
COLTON OGDEN: Yeah, exactly.
DAN COFFEY: And then this, right?
So there.
Nice, clean ES6.
And so start draw is going to
simply take an event for now.
And so the event, if we look back,
what is this event going to look like?
COLTON OGDEN: For people
who are unfamiliar,
this is called arrow functions.
It's basically the same thing that
Dan did up on line 13 with function,
but instead of needing
the function keyword,
you can just say equals and then
the parentheses with the arguments
and then an arrow, and then the
block of your function body.
DAN COFFEY: Yes.
All right.
So what we want to do is
actually in this listener,
we're going to decide
which function to call.
So let's go ahead and just copy
paste for a second, make middle draw
and then also end draw.
And I can't remember.
We might end up passing
additional parameters,
but we're just going to start with this.
And so now we need to call, depending
on this event, the correct thing,
if it's the start or end.
How do we know if it's the start or end?
What is your guess, Colton?
COLTON OGDEN: I'm guessing
there's probably a hammer.touch
or on touch start or something
like that, some event.
DAN COFFEY: You've got it.
So if we look through here,
and so there is a parameter
called I think it is first.
So it is first.
We'll make it true.
COLTON OGDEN: They make it easy.
DAN COFFEY: Yeah.
So it's like, again, I love
this library for this reason.
So every single event is
going to have an is first.
And literally, if it's the
first time you click the mouse,
this parameter will be true.
And if it's the last,
is final will be true.
So we can just have an if
condition here, so if ev.isfirst,
then what we're going to do is call our
start draw function and pass the ev.
COLTON OGDEN: Nice.
DAN COFFEY: All right.
So nice and simple.
COLTON OGDEN: Bhavik Knight
says, this is so much cleaner,
referring to the equal,
the arrow function.
DAN COFFEY: Yeah, yeah.
ES6, I know.
I just-- as you're a dinosaur and
you've done it the old way for so long,
it's hard to adapt sometimes, especially
when you don't do it every day.
So else if ev.isfinal, we'll go
ahead and put that condition in now.
Do that.
And then the last case is going to be--
I'm going to put just a note in here.
This is really for middle
because if it's not the first
and it's not the last, it's
going to be the middle.
COLTON OGDEN: Right.
DAN COFFEY: And so this is going
to be last and we'll just--
it's good practice to keep comments
in here, so this will be start.
Start, last, middle.
Makes sense.
So if it's the final, we're going
to call final draw, pass the event.
And middle, same thing--
middle draw, pass the event.
COLTON OGDEN: Nice.
DAN COFFEY: All right.
Making sense so far.
COLTON OGDEN: Super clean.
DAN COFFEY: Great.
So in start draw, let's
go ahead and I like
to test as I go, especially
building such a long app.
So we're going to do a console.log
and we'll just say start draw.
And let's go ahead and actually log
a second thing at the same time,
and we'll just--
if we look back at the
documentation and we look at we
want the coordinates
right to start drawing at.
So if we look for-- what
was it called, center?
COLTON OGDEN: Yeah.
DAN COFFEY: Center of the mouse click?
This center has an x
value and a y value.
So we'll go ahead and just log that.
So this would be
ev.center.x and ev.center.y.
And so if this line works,
we should see start draw
and the start draw coordinates.
Let's make sure that works
before we copy paste.
COLTON OGDEN: Did you save it?
DAN COFFEY: Yes.
COLTON OGDEN: OK.
DAN COFFEY: All right.
This is-- let's close the
extra tabs we have open here.
COLTON OGDEN: Paper is not defined.
DAN COFFEY: Why are we
having this error again?
COLTON OGDEN: Where
did you reference it?
DAN COFFEY: I thought
we solved this problem.
COLTON OGDEN: Yeah, I
thought we did, too.
Go back to your--
what line was it saying it was?
DAN COFFEY: So we're
having an error on line--
COLTON OGDEN: 16?
DAN COFFEY: --16.
COLTON OGDEN: Paper.setup.
Do you have to get a
reference to Paper first,
just, like, var paper equals something?
DAN COFFEY: I don't think so.
Let's see.
Hold on.
We'll go back to--
what was it, about?
Remember the page we
were looking at that
was, like, if you're using JavaScript?
COLTON OGDEN: Yeah, Using
JavaScript Directly.
DAN COFFEY: Not Example, Tutorials.
[INAUDIBLE]
COLTON OGDEN: You do have the
script at the bottom of your body,
so I'm not sure if you want to
bring that back up to your scripting
because you have the local source file.
So if you go to the bottom, you put it
at the bottom underneath your canvas.
DAN COFFEY: Oh, you're
saying put it at the top.
COLTON OGDEN: Yeah.
Since now you have it as a local file.
DAN COFFEY: Yeah.
All right.
We'll just put it in.
COLTON OGDEN: Like, right about there.
See if that works.
DAN COFFEY: Sure.
COLTON OGDEN: And then Shift--
Command Shift R, whatever it is.
DAN COFFEY: Hard reloading
here, that's not working.
Let me put it at the top of
the body so it loads first.
Again, I know this is a dumb
mistake and I should easily
be able to figure this out, but alas.
COLTON OGDEN: Other people
are having the issue.
It looks like it's an
issue on the actual--
oh, because it's another NPN.
DAN COFFEY: It's a react, right?
Yeah.
I thought we were past all this trouble.
COLTON OGDEN: Yeah, I
thought I fixed that, too.
Yeah, it's really strange.
DAN COFFEY: Because if we look at
our network, are we getting-- wait.
We're not getting it.
Paper full.
Oh, yeah, there it is.
So it is loading.
COLTON OGDEN: Most of these
people, the vast majority of people
seem to use it with a node project.
DAN COFFEY: Yeah.
Yeah, it's really popular for that.
Man.
COLTON OGDEN: Live debugging.
This is fun.
DAN COFFEY: Yep.
I'm so embarrassed because
it's such a basic thing.
COLTON OGDEN: Yeah, that's OK.
Like I said, I couldn't
figure out that I was missing
a variable for, like, 10 minutes.
George1784 says, hello.
Hello, George.
DAN COFFEY: Hello, George.
COLTON OGDEN: Thanks for joining us.
We are currently debugging why Paper
js is not importing into the project.
But if you're unfamiliar
what we're doing,
we're basically walking through
a from-scratch implementation
of the drawing app that David
uses in Sanders Theater.
DAN COFFEY: Is it this?
No.
No, it is loading.
This shouldn't matter.
Was that simply it?
I didn't put the correct type in?
COLTON OGDEN: I wouldn't
think so, but try it, see.
What happens if you click?
Oh, really?
[INAUDIBLE] final draw is not defined.
DAN COFFEY: OK.
So a bunch of stuff happened here.
The good thing is we see--
let's walk through the
code and what happened.
So that seemed to fix it.
It was simply that I didn't have the
type correct for the JavaScript file.
COLTON OGDEN: What was it before?
DAN COFFEY: It was just JavaScript.
So it's text/JavaScript.
It's very important.
COLTON OGDEN: Causes some weird issue.
JefferyHus says hey.
Hey, Jeffery.
Thanks for joining us.
Hezekiahma is that how
you pronounce that?
Let me read one closer.
Hezekiahma or Hezekiahma says hello.
Thank you for joining us.
DAN COFFEY: Welcome, welcome.
COLTON OGDEN: First time
I've seen you in a chat.
DAN COFFEY: All right, great.
Colton, I think we are past
the painful installing process.
And this is why people
use Gulp and other--
I don't know if project
managers is the right term,
but ways to kind of install
these things for you
so you simply work on the
interesting part of the problem
and don't have these kind of
headaches that we're having now.
COLTON OGDEN: I think going through
it is a formative process, though.
DAN COFFEY: It is.
COLTON OGDEN: I think we are
unlikely to make this mistake again,
or at least we'll be conscious
of it when it happens.
DAN COFFEY: Yeah.
All right, so I'm going to fix
the problem that we have here just
by replacing final draw with end draw.
COLTON OGDEN: Oh, because it's end draw.
Yeah, got it.
DAN COFFEY: So what's happening
is as we fire the first input,
the is first parameter is true.
So that calls start draw, so
what we should see in the console
is start draw exclamation,
exclamation, and then
the x and y-coordinates of the
mouse, which is what we see here.
COLTON OGDEN: I think you're still
printing the pointers thing somewhere,
too--
DAN COFFEY: Yeah.
COLTON OGDEN: Which is kind
of clogging up the-- yeah.
DAN COFFEY: Yep.
So we can go ahead and
comment that out like so.
COLTON OGDEN: [INAUDIBLE]
20, it looks like.
DAN COFFEY: That's this right here,
and just comment that right out.
Reload, reload this page.
And now there we go.
So start draw, even
though I click and drag,
so I can see the coordinates
x and y, that things
are happening on screen on me.
COLTON OGDEN: So we've clicked
four times there just to show that,
and that's giving you the x,y coordinate
of where your mouse was in the canvas.
DAN COFFEY: Yeah.
All right.
So now let's move on to the middle draw.
We'll do the same thing
just to give people
a sense of what's actually
happening while we draw.
COLTON OGDEN: Sure.
DAN COFFEY: This is middle, middle draw.
And then we'll do end draw.
Reload, and so we're going
a lot more output here
because middle draw is
going to be the dominant.
COLTON OGDEN: Most of it's
going to be middle draw, yeah.
Tons of the middle draw, and
then when you finally let go,
it does say end draw.
So that's really cool.
DAN COFFEY: Yeah.
So we know that in the
right order now, and then
the next step is to hook up Paper js
to actually draw our line, finally.
We were talking about this
drawing app and that's actually--
COLTON OGDEN: I'm guessing we'll
feed those x,y values probably
into the Paper js.
DAN COFFEY: And let's go ahead
and look at the documentation.
We know we want to create a path.
The path is a line.
So we'll just go to the
reference and let's look at path.
COLTON OGDEN: Bhavik says,
cool things happening.
DAN COFFEY: I'm glad, Bhavik.
Thanks for sticking with us.
All right.
So if I recall correctly, it's
pretty easy to create a path.
And so you can simply--
there's a bunch of
parameters in a path as well.
And so you can see all kinds of
different shapes that you can make.
We're going to create a line.
And so paths have segments.
There's a bunch of easily
accessible properties
here that you can quickly grab and use.
There's a bunch of methods
attached to it as well.
So if you want to add
a segment, which is
what we're going to end
up doing in middle draw,
so first we're going to add
a segment in the start draw,
but also middle draw is going to keep
just adding segments along the way.
COLTON OGDEN: Right.
DAN COFFEY: And then at
the end we'll be done.
And so there's a whole bunch
of things that you can do.
You can split lines, you
can do all kinds of things.
Let's see.
Is simplify in here?
COLTON OGDEN: Thejasong says, hello.
Hello, again.
If I'm not mistaken, you
are from Greece, correct?
DAN COFFEY: Hello, welcome.
So we'll ultimately use simplify
at the end to kind of smooth for us
and we can play with the tolerance
here that we want to actually apply.
But that's going to apply
the smoothing for us,
and it's super simple
and really nice to use.
All right, a bunch of other methods that
we're probably not going to use today,
but we're going to start with add.
So what we need to do in start
draw is create a new path.
And so let's just see if they
have an example for that.
So our path equals new path, so we'll go
ahead and start with their boiler code
here, boilerplate code.
Copy, paste.
COLTON OGDEN: I'm glad I got that right.
Thejasong is indeed from Greece.
DAN COFFEY: Oh, welcome.
What, good evening over there?
COLTON OGDEN: Yeah, I think
it's, like, 8:00 PM or 9:00
PM over there, something like that.
DAN COFFEY: All right.
So we have our new path
being instantiated.
And so stroke color is one
of the parameters we can add.
Our background is black, so let's
go ahead and just make this white.
Reload and then we know that we
kind of want keep doing this,
but the problem is we can't just say
path.strokecolor because path won't
be defined when we get to middle draw.
And so what we want to do
is go back to our layer.
And so I think it's paper--
let's see.
The easiest way to do this,
I think, is to come here
to the console, our friendly console.
And Paper we know is
the global object dot,
and then you can kind
of look at auto fills.
I think it's paper.project.layer.
And there's also a
shortcut for active layer,
so I can just choose that
because we have a default layer.
And .children, which is empty because
we don't have anything in there.
But if we just look at
active layer, you can see--
it's null at the moment,
so we have to add a layer,
add something so that it exists.
So that's what this should do.
COLTON OGDEN: It's like in
Photoshop, clicking Add New Layer.
DAN COFFEY: Yeah.
COLTON OGDEN: And then we
can start drawing on it.
DAN COFFEY: Empty, right?
Yeah.
All right.
So we're going to add--
we don't need to have a stroke color.
The stroke color is going to be defined
when we instantiate the path itself.
But we want to do--
so it's paper.
What did I say it was?
Paper.projects, I'm
going to copy paste this.
Paper.projects.activelayer dot--
there's another handy shortcut.
I think its last, so last
child, if we click on that.
Where did that go?
So it's the last item.
So basically, all these lines
are just stored in an array.
So you could do paper dot canvas
dot blah blah blah dot length,
dot children dot length minus
1, but they make a nice shortcut
for it called last child.
So we can just do activelayer.lastchild,
and then to the last child
you just want to add a new point.
And we can add a point just by passing
an object, I believe, with x value,
which we know is ev.center.x and
ev.center.y to pass in the y value.
COLTON OGDEN: You want to
make it y colon, right?
DAN COFFEY: Yes.
We might not even need to do this.
I'm doing this on the fly here.
You might just actually
pass the two values.
But let's go ahead and see if
this gets us where we want to go.
COLTON OGDEN: Oh, ev.center?
DAN COFFEY: / and we'll skip the
end draw for now because it'll just
be our kind of cleanup step.
So let's see.
COLTON OGDEN: Bhavik Knight says, of
course, I'm going to stick to the end.
I'm pretty much uncomfortable with js.
This will be a great learning
curve for me as well.
DAN COFFEY: Excellent.
I'm glad to hear it.
COLTON OGDEN: And
Forsunlight says, same here.
I'd like to enhance my
event understanding.
DAN COFFEY: OK, I'm
going to reload this.
I'm going to clear my log here.
No errors, that's a good sign to start.
Click and drag.
Oh, errors all the way.
Last child--
[INTERPOSING VOICES]
COLTON OGDEN: You said we
have to add the layer, right?
Did we do that yet?
DAN COFFEY: Let's see.
I don't think we did.
COLTON OGDEN: Do we have to add a layer?
Or does it do--
DAN COFFEY: So my understanding,
I thought, from memory,
that it adds it for you
when you declare it.
COLTON OGDEN: Right.
DAN COFFEY: But it might not.
So let's look at--
I like to do this, too.
So Paper js add path, let's just
see if they have an example for us.
Or there's a tutorial,
Working With Paths.
So you get the anatomy,
so you create the path.
And this is happening live,
so this is their code.
COLTON OGDEN: Oh, you have to add
a new point it looks like, right?
DAN COFFEY: Yes.
COLTON OGDEN: Instead
of just the object?
Or can you just also add an object?
DAN COFFEY: I think that
you can just add the object.
COLTON OGDEN: Maybe you could do both.
DAN COFFEY: I think it's smart enough.
COLTON OGDEN: Magedrifaat says,
does the path default to a line?
DAN COFFEY: So a path object
is a line in Paper js.
It's just like if we
look at the example,
here's a path item which
has all these things.
So you can bend lines, you can
adjust these handle in, handle outs,
and whatever.
We're just simply going to
be taking points and making
a line by connecting them all.
So what we're going to do is just
add a bunch of points along the way
and plot a line through them.
That's what a path actually is.
OK.
So you know what?
Let's look at a simple example.
Here's a line.
COLTON OGDEN: Then other examples
are super simple [INAUDIBLE]..
DAN COFFEY: That's OK.
But we can see how they add it.
So here's the actual path
with the path options.
They don't add it anywhere.
But I bet you this is one of those
things with using pure JavaScript
vs. using their Paper Script.
COLTON OGDEN: Yeah.
DAN COFFEY: So let's go ahead and--
COLTON OGDEN: You think
it's in Tutorials?
DAN COFFEY: Tutorials.
COLTON OGDEN: Yeah, and then
Using JavaScript Directly.
DAN COFFEY: Yeah.
So it looks like it has it.
COLTON OGDEN: Oh, and do paper.path.
DAN COFFEY: OK.
Oh, paper.path.
Did I just do .path?
COLTON OGDEN: I'm not sure.
Oh, yeah.
You did do just path.
But is that a--
DAN COFFEY: It's new paper.path.
That's what we're
missing because we're--
this should fix it.
And so that should work.
Everybody cross your fingers
out there, virtually.
Here we go.
Whew.
Look at that.
COLTON OGDEN: Oh, nice.
That's beautiful.
DAN COFFEY: So in a very
short amount of time,
if you cut out all the
debugging time, we suddenly
have a drawing app with just
kind of the default values
except for changing the
line color to white.
But this is kind of cool, right?
All of a sudden, super
simply, I can draw.
[INTERPOSING VOICES]
DAN COFFEY: This blew my mind
because when I did this on my own
the first time, I was just, like,
that was super easy, despite all
the live debugging.
COLTON OGDEN: Everybody got
to experience the trials and--
DAN COFFEY: Yeah.
All right.
Everybody was cheering us on.
Thank you.
Thank you all.
COLTON OGDEN: DJoker07.
Hello from the Miami team.
Daniel here.
So hey, Daniel.
Thanks for tuning in from Miami.
DAN COFFEY: How you doing, Daniel?
COLTON OGDEN: Appreciate it.
DAN COFFEY: Good to see you virtually--
COLTON OGDEN: Yeah.
DAN COFFEY: --if not in person.
COLTON OGDEN: Probably see you
at the fair soon, I imagine.
Asli says, sorry, mistake.
George 1784 with the Bob Ross.
Nice.
Nice.
We are doing art.
DAN COFFEY: This is art, yeah.
COLTON OGDEN: Yeah.
DAN COFFEY: OK.
So let's go ahead and just
change our line a little bit.
So there's a bunch of defaults.
Let's look at the
documentation for path.
So if we go to reference and
then there's a path item.
I want to just look for a
background, or is it color?
Stroke color, so here the stroke
styles that we can play with.
And you can click on these and see.
You can make dash lines, you
can make different things.
But I know we want--
the stroke color we'll
keep as white for now.
And then stroke width, let's
go ahead and look at that.
So it's just a number that it gets.
So let's go ahead in our definition of
the path let's just thicken the line up
a little bit because as you
can see, it's super thin.
COLTON OGDEN: Yeah, it's a bit thin.
DAN COFFEY: All right.
So we say new paper path and
then path that stroke color.
So what we could also do is
just put an object in here
and we'll go ahead and just
move this up into here.
So stroke color is white.
And since it's an object we don't
put a semicolon, we put a comma.
And let's put stroke width equals--
give me a number, Colton.
COLTON OGDEN: Three.
DAN COFFEY: Three.
COLTON OGDEN: Forsunlight
says, can we animate it, too?
Draw it and make it move?
DAN COFFEY: You totally could.
You can imagine using
timeouts and setting--
you can move things around.
So in the final version
of Draw50, once you draw,
you can actually move things around.
And so this is using
the pan feature, but you
could imagine setting a timer on this,
like, translate from here to here
over an amount of time.
And it would be pretty easy as well.
And if you want some
really further reading,
we're doing a very basic tutorial,
but you can see super easy in Paper js
to actually animate things.
And if you missed it, you
can just click on the source
up in the top right corner and see
all the code that makes this happen.
So very easy to get started and
lots of great examples out there.
COLTON OGDEN: Thejasong says, is there
a way to get the video quality to 720p?
We're shooting at 1080.
I don't think Twitch--
Twitch probably doesn't do
live encoding to 720p, right?
If we're shooting a raster to
them in 1080, they probably--
DAN COFFEY: I don't believe that
they're downscaling, but it's possible.
You should be able to get--
COLTON OGDEN: Because
normally they have don't they
have to encode it on their end
to make a 720p stream available?
DAN COFFEY: I'm not sure what they do.
Some places re-encode for you
and some places that don't.
COLTON OGDEN: OK.
DAN COFFEY: Some places just
stream what you're streaming.
COLTON OGDEN: I know a lot of
people have been saying that they
want a 720p version accessible.
It'll be on YouTube, so if you
want to watch it later at 720p,
it will have a 720p version.
But I looked in the UI and
I didn't see a 720p option.
That was a satisfying end of the day.
Going to watch the rest the
stream on YouTube tomorrow.
Goodnight, says Gulyash Thanks, Gulyash.
Appreciate it.
DAN COFFEY: Yeah, thanks for
sticking until we got some victory.
COLTON OGDEN: That was a
very satisfying moment.
DAN COFFEY: OK.
So let me reload this page.
Oh, invalid shorthand.
Oh, this has got to be a colon.
COLTON OGDEN: It's like
a Lua table syntax.
DAN COFFEY: There we go.
So there you go,
Colton, nice thick line.
COLTON OGDEN: That's a nice sized line.
DAN COFFEY: And you can
see, if you look here,
see how this is kind
of like a jagged point?
Let's go ahead and finish drawing our
line and smooth it out at the end.
Because I think that's one of the
cool features that we talked about.
So let's search for simplify
is what it's called.
There's also smooth.
So simplify fits a sequence of curves--
so it really just simplifies the line.
So let's go ahead and just add that.
So if we take our shorthand
here for getting the last child,
we're going to do this on end draw.
And the reason is we don't want
to do this while it's drawing.
It'd be kind of funny to
watch it shift as it goes.
COLTON OGDEN: It looks
a little bit weird.
DAN COFFEY: So here we go.
We got the last layer.
We just have the last
line that we drew is here,
and then we can just do simplify.
And then it just takes I believe
it's just a number, so a tolerance.
Let's see what their example looks like.
Example.
Path.simplify.
I believe-- so you can specify the
tolerance, but they don't actually--
COLTON OGDEN: Yeah, that looks
like an optional parameter.
DAN COFFEY: Tolerance, it's a number.
So default is 2.5.
Let's go ahead and start
with their default.
And then we can change
it and see what it does.
So here we go, reload.
So you can see the kind of jaggies.
I'm not going to pick my mouse up,
but see this corner right here.
Watch this when I let go.
Boom, the whole thing kind
of shifted a little bit.
Let's take this to the
extreme and just see
what happens when we do a
value of, let's say, 10.
Actually, let's even do higher, 20.
Go crazy.
So here comes the line.
Let's go.
Really a lot more smoothing
applied to that, right?
COLTON OGDEN: OK, yeah.
It got very, very smooth, yeah.
Bhavik Knight, it's
auto by default for him
because 1080p sticks a lot while live.
Yeah, I'm not sure.
I don't think they do--
I don't think they have
a downscaled raster live,
maybe after the fact for the
VOD, but definitely for YouTube.
Nuwanda or Asli is asking
why not smooth instead of--
DAN COFFEY: Oh, let's see.
I just don't know what smooth is.
Smooth might do what we want.
But let's read the documentation.
So smooths the path without
changing the amount of segments.
So simplify actually
throws segments away.
So you can see, if we
look at the console
here, how many segments there are.
And so just for simplification, to
get the same line with less data,
that's what simplify does.
It smooths the path and
then throws away the points
that aren't needed to recreate
it if it's a Bezier curve to it.
So that is why we're using simplify, but
you could certainly use smooth as well.
Let's see.
Let's just actually change it to smooth
and see if it does the same thing.
COLTON OGDEN: Does it also
take a tolerance parameter?
DAN COFFEY: I believe so.
Let's see.
Takes options.
COLTON OGDEN: Oh, continuous,
asymmetric, catnull-rom, geometric, so
different algorithms for actually
computing the smoothness.
DAN COFFEY: Yeah, so if you want to
really dive into how you smooth it.
COLTON OGDEN: There's a lot
more complicated stuff for that,
it looks like.
DAN COFFEY: So we'll go back to
simplify, put that onto the next one.
COLTON OGDEN: Hasanain87, hi there.
Thanks for joining us.
Magedrifaat.
I just Googled and it says you
need to be a Twitch partner
or get enough number of viewers
to get the automatic encoding
to different resolution.
Ah.
OK, good to know, good.
To know twitch partner's
a ways away, I think,
but that'll be a nice feature to have.
Forsunlight says, physically,
how would you implement this
on a SMART board or a Promethean?
DAN COFFEY: So I can tell you-- so if we
just go back to the video-- let's see.
Is it in my history here?
If we go back to the
video of David in Sanders,
so here is David using
this to draw on a--
this isn't a SMART board.
This is just a giant touchscreen.
And so the reason we're
using Hammer js is
so that we can use touch input on a
giant screen or on a small screen.
If you have a Microsoft Surface tablet
or something that has-- even an iPad
will work as well.
iOS takes over some of the
events that you might want.
But you can actually
pull up draw.cs50.io
now and see this on a touch
screen, so that would, I guess,
be the implementation on a
touch screen because Hammer
can accept multiple fingers.
And if you missed it, if we just go
to the final version of draw.cs50,
I'm going to simulate
this just by drawing.
But if I use two fingers and I use
it, that initiates the erase feature.
And then five fingers actually
moves it around the screen.
So there's a few features that we
have implemented in the final version.
But for now, we're
going to keep it simple.
So I guess using the right
combination of libraries
would be the answer for that and Hammer
js is a great one because you can--
with all the different features
for it, you can have swipe.
You can have pan.
You can even pinch and zoom.
I found that to be really
finicky because it depends
on how good your touch hardware is.
And the giant Microsoft Surface hub that
is on stage that David is drawing on
is actually not that good
at the pinch feature,
so getting it to scale
appropriately was really hard.
But pan worked fine.
COLTON OGDEN: They
have their own software
and how did you use this and
switch to the display method?
DAN COFFEY: I'm not entirely sure.
So I guess you'd have to see
what API SMART boards have.
I don't know if they have a JavaScript
API, this would be a very easy port.
If you have to build the
app in some other language,
then there would be
a code port for that.
COLTON OGDEN: You have to use whatever
library comes with the hardware.
DAN COFFEY: Yeah.
What we do in CS50 is--
yeah, so what you're seeing
is a giant Surface hub, Forsunlight.
And so basically, what's
happening in reality
is that there's a long USB cable that
runs from the back of that touch screen
TV to a Microsoft Surface hub that's
in the desk that David is standing at.
So you can use that.
But if you have any other-- if you
have a Microsoft Surface or an iPad,
you can just go to the
website, draw.cs50.io,
and actually use this yourself.
And if SMART boards have the ability
to go to a website, you could try that.
I know on the touch screens,
the Microsoft Surface hub,
they do have a web browser built
in and it does work if you--
on the onboard operating system,
you can go to the draw.cs50.io
and it will work as well.
COLTON OGDEN: I'm not super familiar
with what SMART boards are either.
DAN COFFEY: And so also another
cool thing, if we'd look at Hammer,
I just want to point this out.
They have point or type available.
And you can see here that it supports
touch, mouse, pen, or connect.
And so you can have different actions
happen whether you're using your finger
or whether using an actual
stylus, which is kind of cool.
And how I did the emoji thing was
if David was to use the stylus,
it would kick off the emojis.
So it's just kind of like a fun
little Easter egg [INAUDIBLE]..
COLTON OGDEN: How does it know they're
using a stylus versus a finger?
DAN COFFEY: That's all a
hardware thing for you.
So that's the nice thing about
libraries is it is abstracted for you.
So you just say, is the
point or type touch?
Is it mouse?
You can then use an if
condition to kind of choose
what you want to happen based on--
[INTERPOSING VOICES]
COLTON OGDEN: I didn't realize that
it can actually at the hardware level
differentiate.
I always figured that the pen did the
same thing that triggered a touch.
DAN COFFEY: So the only
thing that bothers me is I
really wanted to be able to
flip the pen over and use erase,
and there's no difference.
I looked at the event as we've
been inspecting in the console
and there's no difference in touch
type between the front of the pen
with the stylus and the back.
It just doesn't trigger.
COLTON OGDEN: That is
disappointing, actually.
DAN COFFEY: Because that
would be kind of cool.
COLTON OGDEN: That would be cool.
DAN COFFEY: Forsunlight
says, thank you, Microsoft.
Yeah, Microsoft, I like I have to
say, as far as touch hardware goes,
the new Surface Pro--
not to advertise for them, but
it's a nice piece of hardware.
So it was nice to develop on.
And really, I think most of the
credit goes to Hammer James js that
for just being able to
be such a great library,
so robust for getting so much
touch data from any screen.
So great.
Thanks, Forsunlight.
Appreciate that.
All right.
So look at this.
We pretty much recreated Draw50.
What else should we do?
So we've got smoothing
going on at the end.
Should we do erase?
COLTON OGDEN: Yeah, let's do erase.
DAN COFFEY: All right.
So erase could be very
simply we can copy paste this
and paint black would
probably the easiest way.
Or maybe we could even pass a color.
COLTON OGDEN: Oh, yeah.
Make it more modular that way.
DAN COFFEY: Yeah.
So color equals-- we'll have
the default be black or white.
So we're going to pass
the second parameter.
We only need to pass it to the first
one, because the rest don't matter.
COLTON OGDEN: Right.
DAN COFFEY: But let's see.
Should we use a modifier key to do this?
Like holding at Shift
or something for erase?
COLTON OGDEN: Oh, sure.
Yeah, we could do that.
Yeah, that would probably be
easier than double click, right?
DAN COFFEY: Yeah.
COLTON OGDEN: Or I guess we
could do double click, too.
Thejasong, when is it your
next live tic-tac-toe?
Tomorrow, so at 1:00
PM we'll be doing that.
DAN COFFEY: All right.
So do they have modifier on here?
All right, so it's not
actually documented in here.
But let me show you a fun little thing.
So if we inspect--
sorry.
I'm jumping around screens a lot here.
Let's turn back on our console.log
and just refresh the Draw50 page--
not this one, our develop page--
and just get an event here.
So if I expand this, there's a ton
of information in here, as we know.
But there's also the
source event, which I
believe is the underlying event that's
emitted that Hammer js intercepts.
And so you can look at that
and see is the Alt key pressed?
No.
I don't claim to know
what all these are.
You could certainly
look them up, but you
can see if the Control key is pressed.
You can see movement.
There's so many-- how much
pressure if you're using a pointer.
The pointer type is
a mouse in this case.
COLTON OGDEN: Shift key is one.
DAN COFFEY: Shift key, yeah.
So let's use the Shift key.
And so let's look at the console.
I'm going to go ahead and just clear it.
And if I hold in Shift and click,
let's just look at another event.
So if we go down and look at source
event and let's look for that Shift key
again.
Shift key is true, so clearly if we
are holding the Shift key as we do it,
let's use that as our erase feature.
COLTON OGDEN: So you can actually
dig into the low-level event itself.
DAN COFFEY: Yeah.
It's kind of a fun way around.
So what we'll do in start here,
we'll put if ev dot-- what was is,
source event?
Going to make sure I
get this right here.
COLTON OGDEN: Yeah, source event.
DAN COFFEY: So src event.
COLTON OGDEN: Forsunlight says,
looked like I was spamming there.
I apologize everyone.
I didn't want to write long sentences.
No, you're fine Forsunlight.
Don't worry about it.
DAN COFFEY: Keep it coming.
We like the interactive--
COLTON OGDEN: Yeah, the more
interaction, the better.
DAN COFFEY: Yeah.
All right, source event dot--
was is Shift key?
And that's simply so source
event, Shift key, and that's
simply a Boolean, so we can do that.
So we'll do start draw.
We'll pass in ev and we'll
pass in black, because really
what this is erase if
the Shift key is pressed.
And then we'll just say else--
in this lineup, start drawing.
We could be explicit and say
white here, but we've defined a--
COLTON OGDEN: White's
a default argument.
DAN COFFEY: --a default, yep.
COLTON OGDEN: And then--
DAN COFFEY: And the rest of the line
doesn't actually do anything for--
it smooths at the end.
And I did find when we made
the production version of this,
we didn't want smoothing
applied for erasing.
COLTON OGDEN: Right.
Yeah, I guess that makes sense.
DAN COFFEY: Yeah.
So we could do a simple hack in
here and just get the stroke color
and say, if it is the same as
the background or if it is black,
don't actually smooth or only smooth.
We could use it if condition for that.
But we'll leave that
as is for the moment.
COLTON OGDEN: And you only
have to specify the stroke
color for the first segment?
Because every time you
add a new one, it just
takes over the color
of that first one is?
DAN COFFEY: Exactly.
This new keyword, as we know instantiate
a new path object from Paper js,
you define its values.
And you can actually change this later,
like, if we go into the console--
I love doing this kind of stuff.
So if you just do a
paper.project.activelayer.children,
you can see that there's two of them.
And so if you just-- let's
look at the first line, which
I think is this one here on the left,
we can actually change these things
in here and we'll see it happen.
Where is it?
Was it stroke color?
COLTON OGDEN: It was called
stroke color, I believe.
DAN COFFEY: So we'll scroll down.
COLTON OGDEN: It's got
a lot of attributes.
DAN COFFEY: Yeah.
Stroke color.
Oh, wow.
It's not as simple as a color.
COLTON OGDEN: Yeah, they've got a
lot of saturation, lightness, hue.
DAN COFFEY: So let's just make this
0.5, and you can see it changed--
just by taking half of the red out,
it changed this line to be blue.
So it's not as simple as
passing a color, I guess.
But again, this is the
power of the library is they
abstract all of the stuff away
for us, which is pretty awesome.
COLTON OGDEN: Yeah, that is cool I
just didn't realize you could just
modify things like that in the console.
DAN COFFEY: Yeah, it's
one of my favorite parts
about JavaScript, is the debugger
is just built into your browser.
I mean, there's actually
a debugger, too,
but really handy to
just make quick changes
or check to see if a value is what
you think it is without having to do
a console.log or just print statements.
COLTON OGDEN: Can we send
the background color-- change
the background color other than black?
DAN COFFEY: Oh, absolutely.
Forsunlight, we actually do that in CSS.
We say the background color is black
and so we can simply say, green,
which is going to be really ugly.
But there we go.
Now the background color is green
and we're still coloring in white.
COLTON OGDEN: That's kind of
like a traditional chalkboard.
DAN COFFEY: Yeah.
And we could even, if we
wanted to, there's another--
oh, boy.
Do I want to do this?
So there is another
cool thing in Paper js.
Let's see if we can just search.
Let's see, Reference.
And this is-- it's draw.
What is it?
There's something that
is called Every Frame.
On Frame.
So this is a view.onframe
function, and what
happens is every time, 60
or 100 times per second
or whatever the refresh rate is that
JavaScript is refreshing the canvas,
you can do something every second.
So you can see they're just
simply rotating the square here,
but we could change the color
by one value every frame.
And so it would just be
this, like, oscillation
of colors, which would be kind of cool.
COLTON OGDEN: That is pretty cool.
DAN COFFEY: So there's a
super powerful library.
COLTON OGDEN: Bhavik Knight,
I didn't know that as well.
Great way to debug.
Yeah, no.
Definitely.
I don't do a lot of
JavaScript development,
so I'm a little bit out
of touch with this world,
but it's find it interesting.
Magedrifaat, I remember
doing something like this
in my very first programming course
years ago in Visual Studio Windows
forms.
But I had to make it from
scratch and it was ugly.
Paper js for the win.
DAN COFFEY: Yeah, I
really like Paper js.
Once you get over the
headache of if you're not
using their Paper Script and
their JavaScript instead,
then it's much easier
once you're set up.
COLTON OGDEN: Yeah.
They've done a really good job
of abstracting away the library.
DAN COFFEY: Yeah.
And enough people use it,
and same with Hammer js.
That's the nice thing about
libraries that are very popular.
If you Google Stack Overflow
or any other website
is going to have great examples and
people who can answer questions.
It's not this little tiny
library that nobody uses.
Yeah.
COLTON OGDEN: Forsunlight
says, I mean imitating
the erase for the background color.
Or using the background
color instead of--
[INTERPOSING VOICES]
DAN COFFEY: Yeah.
So let's look at erasing because
there's two different things we can do.
So we're cheating with erase.
So let's actually label what's
going on here so it's clear.
So color matches background, which
is really, essentially, erase.
And this is draw.
All right.
So now if we were--
yeah, so we mirror the background
color if the background color is black.
COLTON OGDEN: Or if
we keep this as green.
it's going to look really funky.
Let's do it.
DAN COFFEY: Here's
draw and here's erase.
Oh, what happened?
COLTON OGDEN: Oh, I think
I know what you did.
Go back to your--
you haven't replaced it
with the variable color.
DAN COFFEY: Oh, yep.
OK, great.
Thank you, Colton.
That's why I got my sidekick here.
OK, so we just--
I had hardcoded it.
I'm uh-hardcoding it.
All right.
Here's the white, and now hold in Shift.
There's the black, so
that's erase, essentially.
COLTON OGDEN: It's a little small, too.
Forsunlight, Colton, thank you.
It's good to be understood.
Yeah, absolutely.
Keep asking questions, everybody.
This is how we--
this is what makes the
Twitch show a good time.
DAN COFFEY: Yeah.
And I would say anything
not too super complicated
that you want us to try to implement,
we could certainly give it a shot.
COLTON OGDEN: Yeah, yeah.
[INAUDIBLE]
DAN COFFEY: That's always
a dangerous request, right?
COLTON OGDEN: Is it, yeah.
DAN COFFEY: OK.
So let's go ahead and
put this back to black.
But what this does highlight
for us is the problem,
if we were trying to erase
our eraser is really small
and so we probably want
the eraser to be bigger.
And so we can just keep adding
parameters to our draw if we want.
So color is white.
We can have the size--
I guess it's the stroke size.
We might as well match
the parameter names.
So instead of color, I'm going to
actually call this stroke color.
And stroke width we'll add
as an optional parameter.
The default will be--
what is our default?
You said, three, right?
COLTON OGDEN: Yeah.
Bhavik Knight says, do the
fly emoji thing, if possible.
DAN COFFEY: We could probably--
I'm on the wrong account.
I was going to say we could
pull it up and trigger it.
COLTON OGDEN: Oh, yeah.
DAN COFFEY: We can walk
through that in a second.
I can show you the code for it.
So stroke color and stroke
width, now the default is white.
The stroke width this three.
So if we want the eraser, we probably
want to have it be, I don't know,
let's say 15 for the eraser.
And actually, let's
keep this as green, just
so we can see what doing for a second.
So I'm going to reload the page.
Here's draw.
Here's erase, and so that
is a much bigger stroke.
And this actually highlights--
see how this is a square end?
They even thought through
this detail in Paper js.
This is a property called end.
Let's actually go to
the path for a second.
Path item maybe, end.
Is it not end cap?
Let's see.
We're going to find it.
Hierarchy, stroke cap.
So this is the shape to be
used at the beginning and end,
and so you can do
round, square, or butt.
And the default is butt,
which is that square end.
And so if we just change that to
round, I think it's much prettier.
So let's go ahead and
go back to our code
and just put that in as
the default for everything.
Stroke-- what did I say?
Stroke cap?
COLTON OGDEN: Yeah.
DAN COFFEY: And we'll put round.
And now if I just-- just quick,
to demonstrate that, I'll reload.
See how that end is just rounded
now instead of the square?
I find that much nicer.
It's much more natural.
COLTON OGDEN: Yeah.
Asli says, whoa.
That's just crazy, the stroke cap.
DAN COFFEY: Yeah.
COLTON OGDEN: Dan, how can we add the
CSS parameter into the erase function
so you don't have to use magic numbers?
DAN COFFEY: The CSS
parameter into erase.
So I think what you're
trying to say is how do we
make it so that you can
just erase without having
to tell it what color to erase?
COLTON OGDEN: Yeah.
I'm not sure if--
Forsunlight, if you could
elaborate on that question.
DAN COFFEY: Yeah.
Happy to answer it.
Well maybe where we can
head next is there's
another feature for erasing which we can
handle, which is called the blend mode.
And so basically in draw.cs50, the
real live app, if I draw this--
and let me just download
this for a second.
So this hidden menu, I can
download this drawing I made.
Let me open that up.
And so you can see that
there's no background.
It's a transparent background on here.
But what happens if I
were to erase on here?
So I just did a big erase.
If I was painting black,
there would be a black line.
Let me hope this isn't broken.
Cross my fingers.
And see now it just takes the section
out instead of painting black.
I actually found this
out the hard way when
I was first implementing because
my erase was to actually just paint
the background color and that was it.
But what we want to do is use this
thing called blend mode, and let's
pull up the documentation for that.
And so blend mode has
a bunch of options,
but it's how it's
composited onto the canvas.
And we basically want to
subtract the top layer from the--
anything below the top layer
we want to just be invisible
so that when we download
the image or if we
were to change the
background color dynamically,
you wouldn't have to worry about--
strokeweight and color could be
parameter, so you could erase anytime.
So I think I'm answering
the question, Forsunlight.
Let me know if I'm not.
So basically, -- if we choose and
I forget what blend mode it is.
I can look it up by cheating real quick.
COLTON OGDEN: Also, MKloppenburg
says, going to go now.
Watch the rest later on.
I've been fiddling around with you
guys, but locally here as well.
Pretty neat stuff.
Thanks, Dan and Colton.
DAN COFFEY: Thanks for joining us.
COLTON OGDEN: Yeah,
thanks for tuning in.
Appreciate it, as always.
DAN COFFEY: Let's see.
[INAUDIBLE]
Stand by.
I recommend alphabetizing your
JavaScript functions, too.
COLTON OGDEN: A lot of these things
people recommend and you're like--
DAN COFFEY: Do as I say.
COLTON OGDEN: --I wonder
why they do it that way.
Real Curious Kiwi, which is Brenda
from the Facebook group, hey, guys.
Thanks for joining us, Brenda.
Appreciate it.
It's a shame that we can't get just
a regular Curious Kiwi user name.
I remember you and I
talked about that before.
DAN COFFEY: I'm going to cheat
and just look at the [INAUDIBLE]..
COLTON OGDEN: Someone stole it from you.
DAN COFFEY: So we're
using the same library.
I can use the same thing--
active layer.
COLTON OGDEN: Just dig into the console.
DAN COFFEY: This is the
production version of this app.
I'm going to look at the last one and
just look at with the blend mode is.
So it's called destination out.
This is what I was trying to look up.
And so let me close are
our images that we opened.
And so what we can change
is the blend mode parameter.
So we're getting to the point where
we're adding a ton of parameters
and it might make sense to
us to actually break these
into separate functions
instead of having
defaults for draw and
then a secondary, pass
a whole bunch of arguments for erase.
But since we've started
here and it wouldn't
be all that exciting to
watch me refactor the code,
we're just going to keep going.
So blend mode, the default--
what is the default?
We've got to look that up for a second.
COLTON OGDEN: It's probably
multiply or normal.
DAN COFFEY: Default is normal.
COLTON OGDEN: OK.
DAN COFFEY: Great.
So the default is normal.
And then we'll do--
whoops-- blend.
COLTON OGDEN: Nice.
DAN COFFEY: And really,
what we should actually
do instead of passing a million
parameter, is just pass an object.
But again, we're not going to
bother with that right now.
COLTON OGDEN: Forsunlight says,
can we get it from the event?
Like, the event.background color?
DAN COFFEY: Oh, interesting.
So I wouldn't use the event for that,
but you can use jQuery for this.
And so I believe it's--
we're changing the canvas element.
So if we use the jQuery selector for--
what is it called?
Draw?
COLTON OGDEN: Yeah.
DAN COFFEY: I'm going to
make sure that that is--
OK, there it is.
So if we do draw.css--
I think it's simply
this, background color.
COLTON OGDEN: Nice.
DAN COFFEY: So there's your RGB value,
by putting several different libraries
together.
Does that answer your
question, Forsunlight?
If not, let me know.
But it's the CSS method of jQuery
just gives you the value back.
COLTON OGDEN: So you have to parse
that, turn that into RGB components,
and feed that into your
erase stroke or whatever.
DAN COFFEY: Exactly.
If you wanted to just do it
that way, if you want it just
write over it with that color.
But we're actually using--
because then that'll
show up in the image
that you're printing like
you were saying before.
And what we want to do
is we want to actually
subtract those values
from the scene so you
get transparency and stuff like that.
COLTON OGDEN: Yeah.
DAN COFFEY: Yeah.
And so you could do that dynamically
by getting this parameter
and using that instead.
Yeah, exactly.
You could take the RGB values
and pass it as the stroke color,
but it's the same issue.
If you're trying to download the
image later as an SPG or as a PNG--
we download it in PNG in our case--
you don't want to have
random colors or whatever
the background color is painted on.
Right?
You probably want just
the lines that you
drew to be opaque with the
background being transparent.
So that's why we implemented
it the way that we did.
COLTON OGDEN: And if somebody were
to implement drawing over an image,
for example, then a
solid color would just--
you would very easily see the
solid color at that point.
Your background doesn't
have a consistent color.
DAN COFFEY: Yeah.
So let me know if that doesn't
answer your question, Forsunlight.
And I'm pretty sure that Paper
js can also take RGB values,
so there's not even a
translation that you have to do.
COLTON OGDEN: Oh, OK.
DAN COFFEY: It's just a
certain way to pass the data
in by looking at the documentation.
So hey, you're welcome.
All right.
So we got our blend mode.
Let's continue down this path here.
All right.
So the blend mode is if we're
erasing, destination out.
I'm going to cross my
fingers that this works now.
COLTON OGDEN: Brenda says, how did you
access the hidden menu on your draw
app?
DAN COFFEY: Oh, Brenda, if you go
to draw.cs50.io, click and swipe
up from the bottom center.
And it's actually got a black background
as well so that you can see it,
and it automatically shows and hides.
But you can click different colors.
You can increase the stroke size.
And it stays up as long as
you're interacting with it.
There's a time out that if you stop
touching it, it will actually hide.
And so you can download your drawing.
COLTON OGDEN: This is all
stuff you've implemented, too.
DAN COFFEY: This is all
stuff that I've implemented.
Swipe up.
It's much easier on the touch screen.
You can click on this number to reset.
You can reload, so if
I reload this page,
it'll reload the last
drawing from local storage.
So if the app crashes
on you, the web page
crashes, you can get your drawing
back, which is also a nice feature.
You can erase everything.
COLTON OGDEN: And draw.cs50.io,
the base route has no online stuff.
DAN COFFEY: Yeah.
COLTON OGDEN: Just because that way you
can just give it to David in Sanders
and just be like, draw here.
No one's going to sign in
and take it with them, right?
DAN COFFEY: Yeah.
And just because we're however
many hours later into the stream,
if we go to /Twitch, this
is a version that's--
hello.
This has been implemented with--
COLTON OGDEN: A lot of
people have drawn on it.
DAN COFFEY: This is awesome.
COLTON OGDEN: Wow.
DAN COFFEY: So you can see that this
is implemented with web sockets.
And so Colton, if you want to
pull it up again one more time,
this is something that
I'm still working on.
It's an active development in
progress, but it's the same thing.
The menu's at the bottom, so you can
click and swipe up from the center.
COLTON OGDEN: And if
anybody's looking at this now
and didn't know earlier the context,
this is a publicly available page
that anybody can draw on right now.
DAN COFFEY: Yeah.
And I'm going to actually
pan this over because pan
is implemented in this version.
That's a pretty awesome drawing.
COLTON OGDEN: Oh, somebody went really--
yeah, that's nice.
That's awesome.
Patrick, we've got more
people drawing stuff.
DAN COFFEY: So people are drawing
in it now, and as I move it,
it's moving across your screen, too.
COLTON OGDEN: And then
Bhavik has the Batman.
I think someone drew the-- he
drew the Batman symbol there.
That's cool.
DAN COFFEY: Yeah.
So it's pretty awesome.
COLTON OGDEN: CS50 TV, there we go.
DAN COFFEY: So this is a version that
we're still very much in development
on, but this is the direction
that you can ultimately head.
And I said it before, but this
is implemented with web sockets.
So it's all the same kind
of functions that we're
defining in our development
version together,
but there's web sockets added, too.
So on the same events I'm transmitting
them to everybody else in the room
as well.
So we're just sending
the coordinates and then
your local JavaScript is drawing
it on your copy of the canvas.
COLTON OGDEN: That's so cool.
DAN COFFEY: All right.
Before that gets too
dangerous, let's go back here.
All right.
So where were we?
Let's see.
OK.
So we were doing our erase
and so, basically, we're
going to start drawing and pass
the destination out parameter
to make our eraser transparent.
So let's see how this works.
So if I reload and I
draw, there's white.
And so it shouldn't
matter whatever color--
we're passing black as the erase
color, but we shouldn't ever
see it because as we start drawing,
it turns to destination out.
So that is actually what happens.
So even though the color
being passed, if we actually
look at the last line on here--
I'm just going to
scroll up and get this.
Let's just do last child.
And let's look at the stroke color.
I bet you it's black.
Stroke color-- so many
different parameters on here.
Stroke color-- oh, yeah.
That's right.
COLTON OGDEN: You could
probably look at components.
DAN COFFEY: Here?
Does he do it?
COLTON OGDEN: Components, probably.
Try that.
DAN COFFEY: Where was that?
Oh, right there, yeah.
[INTERPOSING VOICES]
DAN COFFEY: It says RGB,
all zeroes, so that's black.
White would be 255, 255, 255.
So even though it's black,
we're seeing transparent
and that's because of this blend mode.
Let's go back and just
double check that.
Always good to know
how things are working.
It's been changed to destination
out instead of normal,
which is what gives us this erase.
And if we did the trigger download,
like we do in the final Draw50,
we would simply see the white line.
We wouldn't see the background and we
wouldn't see any of the black paint
from the eraser.
COLTON OGDEN: Forsunlight says,
too dangerous for classrooms
if the user is anonymous.
DAN COFFEY: Yeah, that is the thing.
Anybody can just log
in and draw with us,
which is why I've closed
that window because you never
know what's going to happen.
COLTON OGDEN: Thankfully,
everybody on stream has been very--
DAN COFFEY: Thank you
for being so polite.
COLTON OGDEN: --PG.
DAN COFFEY: Yeah.
All right.
Well, we are an hour and
50 minutes in, Colton.
I'm not sure if there's anything
else you want to implement here.
COLTON OGDEN: Whatever
you have ideas for.
If not, two hours is
how long we normally go,
but we can go as long as you have
stuff you want to talk about.
DAN COFFEY: Should we make a
simple button, a couple of buttons
that we can use to change the
color and the stroke width, maybe?
COLTON OGDEN: Yeah, sure.
That would be cool.
DAN COFFEY: And then we'll
call it a day with that.
COLTON OGDEN: Yeah.
DAN COFFEY: So let's make a little menu.
We won't go through the
business of hiding it
and whatnot, but let's
go ahead and add a menu.
COLTON OGDEN: Oh, Bhavik
says, the emoji thing?
DAN COFFEY: Oh, yeah.
Bhavik, let's see.
Let's see if we can get it to
work by modifying the JavaScript
on the production version.
All right?
Stick with me.
I'm not sure if this is going to work.
So if we go to draw.cs50.io and I open--
I've also disabled right
click on this, you'll see,
because we didn't want the menus
to pop up and use your fingers.
But if you hit Option Command I, you
can bring up your developer tools.
And let's see.
We want to modify the JavaScript itself.
Actually, I know that you can
do this, but how do we do it?
This is all the JavaScript
that makes the code.
So I called it an emoji rain.
Clear emojis.
So I'm looking for that--
what I'm looking for is that
event that triggers it with a pen.
Can I search for pen?
That's going to come up a million times.
No.
All right.
Stand by, Bhavik.
We'll get there.
I want to see if we
can make this happen.
Clear emojis.
I'll make this bigger.
Emoji rain, so this is
the function, Bhavik.
I can at least show you this.
Increase the text size here.
So it takes a number as a parameter
for how many emojis you want on screen.
So what it does is it creates
a new layer called emoji layer.
And if it's already been
instantiated, it doesn't do it again.
So I've got comments here kind
of explaining what's going on.
So if there are no emojis, it's
emoji time, let's go ahead and do it.
So the way that we do
it is we iterate over
all of the emojis that
are defined up top
and we create a new point
text, which is what--
we're using path as we do
our version of Draw50 here.
But a thing called the point
text actually creates a character
on screen, which we used emojis.
For performance reasons, we use this
paper.symbol, so what we're doing
is we're converting each of the
images in the array to a symbol.
And it's kind of like a pointer.
So instead of instantiating--
if you have 300 emojis, then
you ask this function for there's
only 30 emojis in the array.
So instead of making 300 copies,
what you do is the symbol, basically.
X is like a pointer to the copy,
so you only instantiate 30 of them
and then it uses the references instead.
COLTON OGDEN: That makes sense.
DAN COFFEY: And I found a
huge performance difference
in doing this as I made this.
So then we push the
emojis onto the array.
We randomize their position.
We place them randomly.
I'm going to just kind
of skip over this code
because it does get a little bit long.
And we make sure that the
emoji layer is in the back
so that whatever we're
drawing is still on top.
And then we activate
the default layer again
because, again, we're
using two different layers.
COLTON OGDEN: Forsunlight says,
have a great day, everyone.
To regulars, I salute you.
Thanks, Forsunlight.
We salute you as well.
Nuwanda says, see you, Forsunlight.
AC/DC fan, I suppose.
Yeah.
It would seem so.
DAN COFFEY: Forsunlight,
great to see you.
Thanks for the questions.
All right.
So in Hammer.on--
I can't seem to get to
where I want to get to here,
so we may have to abandon this.
Let's see if I can
just modify it in here.
That's Hammer.
It's an index.
Maybe I can't modify it
because it's not coming in
as a separate JavaScript file.
COLTON OGDEN: Yeah.
DAN COFFEY: Because I wanted--
this is how you debug
JavaScript in the browser.
You can actually separate points
and and get to where you want to be.
COLTON OGDEN: Right.
You would think they would have
just made it like a native--
I guess it'd be hard if it's
intermingled with your HTML
or whatever.
DAN COFFEY: Yeah.
Oh, man.
It's unfortunate because--
that's the sockets.
You'd think if you clicked
here, it would come up, or here.
So Bhavik, I'm sorry.
We'll have to get this up and running
so that you can test it somehow.
We'll put it maybe as an Easter
egg in the Draw50 live version
so that you can click on it.
COLTON OGDEN: Yeah, that's true.
Maybe we can amend the YouTube video
with the description link or something.
DAN COFFEY: But the
code is there and I'm
sorry I can't quickly demonstrate it.
COLTON OGDEN: Yeah.
The code's on GitHub, so if you do want
to take a look at it, definitely do.
DAN COFFEY: OK.
COLTON OGDEN: Bhavik says,
no problem, thankfully.
Thanks for sticking with us, Bhavik.
We appreciate it.
DAN COFFEY: Bhavik is a regular.
I've seen him for a long time.
COLTON OGDEN: I think he's been
on every single stream, I think.
Maybe he missed one.
DAN COFFEY: Awesome.
COLTON OGDEN: But I think
he's been on every single one.
DAN COFFEY: All right.
So we were going to build our menu.
So let's go ahead and add--
we'll just add a div
for the menu and then
we'll add some buttons to it for
ease of how it's going to look.
I'm just going to pull
up some paper here.
OK.
We're going to put this right
below the canvas and we're
going to have to use some CSS absolute
positioning for this, but it goes--
we'll just put it along
the bottom in the center.
But this will just be a div.
We'll give it an ID of Menu,
go ahead and just do this.
And then what we'll put into it--
actually, let's start with the CSS for
this because I find if I do too much
and get ahead of myself,
it just doesn't work,
as you have noticed from the debugging.
OK.
So our menu is going to get its own CSS.
And so if we look back previously
at my cheat CSS sheet here, OK.
We're going to give it
a position absolute.
What am I doing wrong?
That should call it, right?
COLTON OGDEN: So position's spelled
wrong and absolute's spelled wrong.
DAN COFFEY: Whoops.
P-O-S-- there we go.
COLTON OGDEN: Nice.
DAN COFFEY: There we go.
Dan'll get there eventually, everybody.
Don't you worry.
We'll give it a width.
Let's just say 50% of the page.
It'll be easier.
Just so we can see it, let's go ahead
and make the background of this screen
and we'll change your
actual drawing to black.
And then we want to put this
into the bottom of the screen.
So we're just going to put
it 0 pixels from the bottom.
Great, and I think that will
make it show up where we want it.
Let's see.
Reload this page.
No.
COLTON OGDEN: I don't think
you put it in your HTML, right?
DAN COFFEY: I think I did.
Div ID Menu, it's below canvas.
COLTON OGDEN: Oh, I see.
DAN COFFEY: Oh, it
doesn't have a height.
We got to give it a height or
else it's not going to show up.
Let's put it 2.5 EM, which
is based on text size.
There it is.
COLTON OGDEN: Nice.
OK.
Cool.
DAN COFFEY: OK.
Let's center it, too.
I forget.
I think it's text align center,
but it might be margins.
COLTON OGDEN: Yeah, margin auto.
DAN COFFEY: Yeah, let's try that.
I think text line center affects
the things within the div, right?
COLTON OGDEN: Yeah.
DAN COFFEY: Margin left, auto.
Margin right, auto.
There is shorthand for this,
but we're not going to use it.
Nope.
Let me look at my cheat sheet.
Left, zero.
COLTON OGDEN: Yeah, I'm
super awesome at CSS, either.
But you could put it all, I think--
you could put it in a div.
DAN COFFEY: Here's
what we're going to do.
We're going to debug this
together because this is
why I love doing stuff in the browser.
So as I mentioned before,
you can come over here
and affect all the properties.
So if I uncheck this, it changes.
We can change the color if we want to.
We can make it white.
We can make it fluoro white,
which is a nice off-white there.
COLTON OGDEN: OK, nice.
DAN COFFEY: But we're
getting away from ourselves,
so I'm going to uncheck left.
Let's do margin left and let's just
see if can give it a pixel value.
Yeah, so that'll do it.
Can we do percent?
50%, so maybe it's 25%.
There we go.
COLTON OGDEN: Nice.
DAN COFFEY: So that'll
center that for us.
COLTON OGDEN: Yeah, since the width
is 50%, I guess that will always work.
DAN COFFEY: Yeah.
And you have to remember, if, I reload
this page these changes don't stick.
So now we're back to as
coded, but we can now
just put those same parameters in here.
So if we do margin left as 25%, reload.
Bam.
There's our menu kind of
stuck to the center for us.
And it's nice because it sticks
to the bottom of our screen
no matter what size it is.
COLTON OGDEN: Nice.
DAN COFFEY: All right.
Let's add some buttons to our menu.
COLTON OGDEN: Let's do it.
DAN COFFEY: So what
do we do here, Colton?
We could add an eraser if we wanted to.
We could add a couple
different colors, and we
could add a plus and minus for
increasing or decreasing stroke size?
COLTON OGDEN: Yeah, we
could do all those, yeah.
DAN COFFEY: OK.
So let's do these as buttons.
Buttons.
COLTON OGDEN: So actual HTML buttons?
DAN COFFEY: Yeah.
Because you can change the styling
of them just like anything else.
So the class for this,
let's call this menu button.
And we'll add-- let's see.
What should we do first?
Should we do colors first?
COLTON OGDEN: Yeah, we could change
the stroke color pretty easily, right?
So we could do, like,
three different colors,
like white, red, and blue maybe?
DAN COFFEY: Yeah.
Let's do it.
COLTON OGDEN: It's very patriotic, too.
DAN COFFEY: Yeah.
So we're going to give these
classes in advance because we know
we're going to change CSS for this.
But let's call the first one is red.
Not going to put
anything in this for now,
I'm just going to leave
it blank because we're
going to make this colorful with CSS.
And I'm adding two classes to this
by putting a space in between them.
COLTON OGDEN: Right, yeah.
DAN COFFEY: Whoops.
I'm going to actually copy the code.
I'm going to copy paste here
for red, white, and blue.
Red, white, blue.
But of course, this doesn't
actually do anything.
If we look at this page, we can
see there are three buttons,
but they don't do anything yet.
COLTON OGDEN: We haven't specified the
class, what it means to be that class.
DAN COFFEY: So let's go ahead and--
let's see.
Did I put a menu button?
All right, so we're
going to make a class
called menu button, which is a dot
for class and not a pound sign.
So now this-- whoops, not dot class.
Menu button.
OK.
So what this is going to do is affect
anything with the class menu button.
And so, looking at my cheat
sheet, we simply look at a height.
So height is related to
the parent, so the parent
being that little menu at the
bottom, is going to just be 100%.
Width is going to be--
I don't know.
Let's just say 8% for now because we
want to leave room for more buttons.
COLTON OGDEN: Right.
DAN COFFEY: I think we need a color.
Actually, we're not going
to specify color, right?
Because we're going
to do that separately.
COLTON OGDEN: Yeah.
DAN COFFEY: Let's see if that's
enough to get us where we need to go.
COLTON OGDEN: Right.
The size, yeah.
DAN COFFEY: And so now I did
red, white, and blue as classes.
So .red is going to just
be background color red.
And I'm literally going to just--
actually, I'll just type it.
Red, white, same thing.
Background.
COLTON OGDEN: They want to
give it to you that time.
DAN COFFEY: Not background
clip, background color
is going to be white and blue is blue.
COLTON OGDEN: Nice.
And CSS gives you the lovely ability
to use the keyword representation
of the color.
DAN COFFEY: Exactly.
COLTON OGDEN: But you could use RGT.
DAN COFFEY: Or hex values, even.
Reload this and there we go.
COLTON OGDEN: Nice.
DAN COFFEY: So now the buttons
are stretched to the right size.
I don't like these lines
around them, so we can also
take that out using the outline none.
And if I want to affect all three of
them, I can do this in the menu button
because I could do it just for one of
the colors, but it doesn't make sense.
So if we do outline none and reload.
Oh, fail.
COLTON OGDEN: Is it border none.
DAN COFFEY: Yeah, it is
probably border none.
COLTON OGDEN: I see it there.
Well, I saw it.
DAN COFFEY: Yep, there
it is, border none.
And if we're not sure we're
and we're messing around,
again, I like to do it like this.
I inspect.
I can now use this thing
to choose an element.
Let's look at the blue.
And we can instead of outline,
then, you said, what, border?
COLTON OGDEN: Yeah, border.
Try border none.
Just border call.
DAN COFFEY: None.
Right and perfect.
The line has now gone away.
So if we want to have
that stick, we just
change it over in our CSS file,
border none, reload the page.
And there we go.
So now we've got our many
buttons for different colors.
So now it's back to the JavaScript
side to implement the color change.
Let me put that back down, and so
that's back in our index.html file.
COLTON OGDEN: Cool.
DAN COFFEY: All right.
Bhavik likes this.
I'm glad, Bhavik.
OK, so there's our red,
white, and blue classes.
And so let's do an on click?
COLTON OGDEN: Sure.
DAN COFFEY: On--
I think it's all lowercase
is the event on the element.
So on click, let's call a function
called change color, which
we haven't defined yet.
And let's pass it a value--
just give it a color.
COLTON OGDEN: Yeah.
So in this case it'd be red, yeah?
DAN COFFEY: Yeah.
I'm going to cross my fingers
that this actually works.
So let me paste this and
this would just be white.
COLTON OGDEN: Bhavik
says, this is great.
We can do CSS there and then change it.
Bella Kir says, it's a
great debugging tool.
Definitely, yeah.
Saves a lot of headaches.
DAN COFFEY: All right.
So this does kind of break
my syntax highlighting.
COLTON OGDEN: No, you want the colon--
[INTERPOSING VOICES]
COLTON OGDEN: There we go.
DAN COFFEY: Quote-- stop
giving me double quotes.
I don't want them.
Save.
So again, nothing's going to happen.
We'll just get an error in the console
because there's no change color.
COLTON OGDEN: No function, yeah.
DAN COFFEY: But it's time to
write that function, right?
COLTON OGDEN: Right.
DAN COFFEY: And so in the same way
that I developed the original Draw50,
let's just go ahead and
put it at the bottom.
COLTON OGDEN: Nice.
DAN COFFEY: Change color equals
and we'll just call it color--
whoops.
Doing it the old way again.
COLTON OGDEN: That's all right.
We're getting it as a habit now, though.
DAN COFFEY: Yeah.
And so I guess this does break
our paradigm of passing things
as parameters because we can no longer--
oh, no.
We can just call start
draw with a color.
I'm being dumb.
OK, so now we just call start--
actually, no.
That's not true.
We need to make a separate
variable for this, right?
COLTON OGDEN: Yeah, just
have a variable at the top.
DAN COFFEY: So I like to define all the
kind of global variables at the top,
so let's call this var paint color.
And we'll just have the
default be white, right?
COLTON OGDEN: Yeah.
And then stroke color there,
you can make that paint color.
DAN COFFEY: Yep.
Great.
And so we can still overwrite it for
the arrays feature, which doesn't even
matter anymore because we
started using that blend mode.
But hey, we've already written it.
We're not going to change it.
COLTON OGDEN: And then all you do there
is just say paint color equals color.
DAN COFFEY: Exactly.
So very simply, we reload this page.
Here's the default.
[INTERPOSING VOICES]
DAN COFFEY: Oh, what did we do?
Change color is not defined.
COLTON OGDEN: Does it have to be--
DAN COFFEY: Is it in the wrong--
COLTON OGDEN: What scope go are we in?
So let's see.
Where is this code written?
DAN COFFEY: Or is it change color?
This is in--
COLTON OGDEN: Oh, this is
in your dot ready function.
That's why.
It needs to be outside of it, I think.
DAN COFFEY: OK.
COLTON OGDEN: Is that true?
DAN COFFEY: I don't
actually think that's true.
But maybe we're calling it
ahead of where it needs to be,
so let me just put it--
maybe.
COLTON OGDEN: Because
I think const has the--
DAN COFFEY: Yeah.
COLTON OGDEN: I think const
is scope just like let.
DAN COFFEY: Yep.
All right.
So let's put it up there.
We'll make our indentation
correct just so it's pretty.
Reload one more time.
Here is our default. All right.
I just clicked on white.
Click on red.
It didn't work.
COLTON OGDEN: OK.
It's recognizing that it does work.
Maybe we take out the debugging
messages you have there and then
output to the console?
Like, change color to x?
DAN COFFEY: That's a good idea.
Let's put it in--
oh, it's because we're out of scope.
I declared paint color
within the ready function
and I need to declare it up here--
COLTON OGDEN: Yep, yeah.
DAN COFFEY: --with paint color.
And the same is actually true
for-- these should probably
be declared outside of
document dot-- oh, no,
actually, because the
elements need to exist.
So I backtrack on that.
COLTON OGDEN: Yeah.
DAN COFFEY: I like a lot of comments
in my code because I forget what I do.
So I'm just going to
put one document ready.
Reload, red.
There we go.
COLTON OGDEN: Nice.
There it is.
Beautiful.
DAN COFFEY: Blue and white.
COLTON OGDEN: Cool.
Easy.
DAN COFFEY: Yeah.
COLTON OGDEN: Can we
remove const, says Bhavik.
We can, but it's good practice to
keep your functions const, generally.
It's the new paradigm.
It just means that you're not
going to change it in the future.
DAN COFFEY: Exactly.
Well said.
All right.
I think, lastly, maybe we'll
implement stroke plus and minus
to increase or decrease stroke size?
COLTON OGDEN: Oh, yeah, yeah, yeah.
Let's do that.
DAN COFFEY: And erase still works no
matter what color I am erasing over.
COLTON OGDEN: Yep.
DAN COFFEY: I just hold
Shift and it erases.
COLTON OGDEN: Beautiful.
DAN COFFEY: All right.
So let's do--
COLTON OGDEN: Everybody's got
some support in the chat there.
Cool, cool, awesome.
DAN COFFEY: Yeah, see?
Once we get past all the headaches,
it gets to be fun, right?
This is a fun thing.
And I don't know if you're
putting this on GitHub.
We could commit this code and--
COLTON OGDEN: Yeah.
If you want to make it you
make a repo and push it,
I'll put the link in
the YouTube description.
DAN COFFEY: OK.
So you can download this
messiness of where we're at.
Bhavik Knight, I meant that
it wasn't changing color.
Can we do CSS then change?
Bhavik, I'm sorry.
I think I'm reading this thread out
of order, so I'm not entirely sure.
But I think we solved the problem
by changing the JavaScript.
COLTON OGDEN: Yeah.
DAN COFFEY: All right.
So we were going to add two more
buttons, a plus and a minus?
COLTON OGDEN: Right.
Yeah, yeah, yeah.
And then we'll need some sort of text
to tell us, oh, your current stroke
order is x.
DAN COFFEY: That's true.
And that's where jQuery
will help us out a lot.
So let's call this
plus minus for a class
because we were going
to have some special--
COLTON OGDEN: I meant the const
thing when it wasn't changing color.
The issue with that was that the const
function was being declared inside
of the document dot on ready function,
so it was just a private function,
and so our code didn't have access
to it outside of that function call,
basically.
DAN COFFEY: Yeah, just the wrong scope.
COLTON OGDEN: Yeah.
DAN COFFEY: Scoping issue.
COLTON OGDEN: We brought that
function out of that function
into a more global
part of our application
so that we could access
it through our HTML.
DAN COFFEY: Change size.
So I'm--
COLTON OGDEN: So you've written
a couple more buttons there
that are just changing the size
a little, take, I'm guessing,
a positive or a negative number.
DAN COFFEY: Well, I'm thinking instead
of clicking and typing in a number,
we'll just get whatever
the size currently is
and increment or decrement.
COLTON OGDEN: Sure.
DAN COFFEY: So we don't need to
actually pass any parameters to it,
but let's just go ahead
and make this one--
actually, instead of change size, we
probably have to make increase size
and decrease size.
We could pass a minus or a plus or a
negative value or a positive value,
but let's just write
two functions for it.
So increase size is going to be a plus.
Decrease size is going to be a minus.
Let's see how this looks.
All right, so those look kind of dumb,
but let's go ahead and do a little--
COLTON OGDEN: Oh, we've got
to give them the style, right?
DAN COFFEY: Yeah.
Let's do a little in-browser styling.
All right.
So we need to change that the text size.
What is it?
Is it font weight?
No, font weight is bold.
Let's go ahead and make it
font weight bold, though.
Font weight bold.
There we go.
[INAUDIBLE]
COLTON OGDEN: Got a little--
DAN COFFEY: Yeah, let's do--
let's make the text the same color
as the background of the menu.
Actually, no, let's make it white.
That didn't work.
So there's some other unknown
property name, font color white.
No.
COLTON OGDEN: Is it just color?
DAN COFFEY: It's just color, yeah.
OK, so now we can't see it,
but we need to change the menu.
We can now grab the actual--
that's menu button, which means we
need to change the background color to,
in this case, green.
So now we can see them again.
Let's see if we can put
a margin on the bottom,
bring those numbers up a little bit.
No.
Maybe 10%, 20%, 25%.
OK, this isn't working.
This is, again, where
I'm just not good at CSS.
But we can quickly iterate through--
oh, I'm sitting right in front of it.
This is really not helpful for people.
COLTON OGDEN: Oh, whoops.
Yeah.
Yeah, we should--
DAN COFFEY: Can you just
drag the window over?
COLTON OGDEN: I can move us over.
DAN COFFEY: Yeah.
Or can you turn our camera off?
COLTON OGDEN: Here, I'll just do
some little something like this.
DAN COFFEY: I'm sorry, everybody.
Just yell at us if--
COLTON OGDEN: And then I'll
shrink us down a little bit.
Do a little bit of magic like that.
DAN COFFEY: All right.
COLTON OGDEN: Now it's larger than life.
DAN COFFEY: Yeah, watch out.
You've got a little line from
where the green screen cuts off.
COLTON OGDEN: Oh,
DAN COFFEY: You're right.
So just move us farther over.
Or top left maybe.
COLTON OGDEN: I'll just
have you right there.
You can--
[INTERPOSING VOICES]
DAN COFFEY: OK, great.
There we go.
Colton's out, I'm in.
COLTON OGDEN: Get rid
of the real problem.
DAN COFFEY: So yeah, sorry that
you couldn't actually see this.
So we're just quickly iterating
here, so background color green.
Top zero, nope.
It should inherit absolute
positioning from its parent.
COLTON OGDEN: Who cares--
why did that button look
differently than the other ones?
Just because it had
text in it, is that why?
DAN COFFEY: Yeah, these are just--
they're all big square boxes.
I just don't know why it's not aligning
appropriately, to be honest with you.
COLTON OGDEN: Oh, vertical align?
DAN COFFEY: Yeah.
It just needs to be-- like,
I want it to be centered.
See how they're so low?
COLTON OGDEN: There's
the vertical line middle.
Is that it?
DAN COFFEY: Oh, maybe.
COLTON OGDEN: I'm sorry.
DAN COFFEY: Yeah.
That's it.
Thank you, Colton.
So we need a vertical line,
middle, and let's make font size--
there.
2EM, that's going to
make it a lot bigger.
So now this is kind of--
it's ugly, but we'll
go with this as the--
and we need to add a
placeholder in the middle,
too, for the actual
value, the current value.
COLTON OGDEN: Right.
DAN COFFEY: So
COLTON OGDEN: David
said, for ratio of five,
you don't need to type equals attribute
for script tag, but if it's there,
it should be a MIME type
tech/JavaScript, not just JavaScript.
So I think the thing that we
figured out earlier on stream,
in the middle stream.
DAN COFFEY: Well, thank you
to David for that correction.
COLTON OGDEN: At 3:02, though.
A little late, but that's OK.
DAN COFFEY: It's OK.
We'll get there next time.
So he's saying that
the script type isn't--
COLTON OGDEN: You don't need
that, is what he's saying.
DAN COFFEY: OK.
COLTON OGDEN: At all.
DAN COFFEY: So this should--
COLTON OGDEN: But if
you do have it, it'll
cause issues if it doesn't say text
slash, which is what you figured out
because it's not a proper mime type.
DAN COFFEY: See, David,
we got there the hard way.
And so the same thing should be up here.
Let's just go ahead and
anywhere I've typed JavaScript,
in case we put this
repo up, let's just--
[INTERPOSING VOICES]
COLTON OGDEN: Asli says,
Alice in Wonderland.
I guess she's referring to
the moving the thing around.
Not sure.
DAN COFFEY: All right.
COLTON OGDEN: Oh, are you
still using this thing?
I can bring us back a bit.
DAN COFFEY: Nope, we're done with that.
I'm going to copy the values
out of it into our style.
COLTON OGDEN: I'll put us right there
so you can at least mostly see it
if we decide to use the editor again.
DAN COFFEY: We're going to
just shrink this code window.
And so we need to make our menu
button have all these parameters.
So we have height, width, border,
font, weight, [INAUDIBLE] bold.
COLTON OGDEN: Shrinking is
what she was referring to.
Yeah, yeah.
DAN COFFEY: Oh, yeah.
Color white.
Bottom zero.
I'm going to hard code
the background color,
but it would be wiser to
do this a different way.
Vertical align middle and font size 2EM.
Great.
[INAUDIBLE] to the page.
COLTON OGDEN: Now it's 2.5,
so it should be close, right?
Oh, maybe not.
DAN COFFEY: Yeah.
So there we go.
Our buttons are now-- we're
getting an error in the console
because increase decrease
size isn't defined.
COLTON OGDEN: We have
to read the functions.
DAN COFFEY: But we can see
that our buttons are working.
And if we wanted to add
a little cherry on top,
there's a hover state
or a click state that we
can change to make these dip down.
I'm going to look at my
cheat sheet for this, though.
COLTON OGDEN: What do
you mean, dip down?
DAN COFFEY: So they'll
actually-- it will
look like the button
depresses as you click on it.
COLTON OGDEN: Oh, I see.
OK.
DAN COFFEY: And I'm just going
to refer to my cheat sheet
because I don't claim to know how
to do this, but I looked it up
and the internet helped me.
Where is it?
There it is.
OK.
So if we go menu, we're going to take
all the buttons on the whole page
and then drill down to just the
menu button, anything that's
got the menu button class on it
and in its active state, which
means it's pressed, what we're
going to do is transform it
by translating its y value.
Translate y 2px.
COLTON OGDEN: So this will only
happen when it's being clicked down?
It will go back to the--
DAN COFFEY: I'll reload.
And look, now if I click, see how
it just feels more like a click?
COLTON OGDEN: Yeah.
DAN COFFEY: And the
colors will do it, too.
COLTON OGDEN: That's cool.
OK.
DAN COFFEY: It's just to kind
of give the user some feedback
that you're actually hitting
it because before I was just
watching the console errors pop up
and I was like, am I clicking it?
Is it working?
COLTON OGDEN: I'm guessing
for the proper app, too,
we'd want to get rid of
that blue square around it?
DAN COFFEY: Yeah, get
rid of the outline.
Sure.
We won't bother [INAUDIBLE].
COLTON OGDEN: Oh, is that
what outline none is?
DAN COFFEY: I think so, yeah.
COLTON OGDEN: OK.
That makes sense.
DAN COFFEY: You want to check real
quick since we're already here?
COLTON OGDEN: Why not?
Bella Kir says, it's nice.
DAN COFFEY: The blue?
COLTON OGDEN: No, I
think she's referring
to the depressed state of the button.
DAN COFFEY: Outline none, so yeah.
Now if I click, there's no border.
COLTON OGDEN: Nice.
There we go.
DAN COFFEY: We went
through all that effort.
Let's go ahead and just--
COLTON OGDEN: This is a
great CSS tutorial for me
because I never look at this stuff.
DAN COFFEY: CSS, I feel like there
are people who are wizards with it.
But for most people, I
think the most helpful thing
is to just have this little
debugger to play with it.
And once you get it right,
just copy the values over.
That's my MO for doing it.
Great.
All right, let's go back to our
code, make this bigger again.
And so I think we were going to add--
we were going to add a
placeholder for text in between.
Right?
COLTON OGDEN: Yeah.
DAN COFFEY: So let's
just put that in a span.
There are actually-- for spacing
reasons, let's put it in a div,
but we'll give it the
class of menu button.
COLTON OGDEN: OK.
DAN COFFEY: I don't know if
this will break, CSS-wide.
And we'll give this an ID of text size
so that we can change it dynamically
later with JavaScript, with
jQuery, which is JavaScript.
There's our div and we'll
put the place holder--
COLTON OGDEN: So the default
stroke is three, right?
DAN COFFEY: Yeah.
COLTON OGDEN: So you probably
just want to put a three there?
DAN COFFEY: Yeah.
Oh, boy.
We broke something, Colton.
COLTON OGDEN: What happened?
Oh, well, don't divs
normally give you a nee line?
DAN COFFEY: Oh, they break, right?
So we could fix this,
but let's put span.
COLTON OGDEN: Oh, nice, more or less.
DAN COFFEY: Our minus
disappeared, though.
Oh, it's because it's slash div.
COLTON OGDEN: HTML.
DAN COFFEY: There we go.
COLTON OGDEN: It's beautiful.
DAN COFFEY: All right.
Great.
And I can still click on my buttons.
And I'll highlight everything.
So there's a nice letter three.
COLTON OGDEN: Cool.
Letter three?
DAN COFFEY: Number three.
Man, it's been two hours
and 20 minutes, Colton.
I'm--
COLTON OGDEN: We've come a long way--
DAN COFFEY: We have.
COLTON OGDEN: --in today's training.
This is beautiful.
DAN COFFEY: All right.
Well, we're almost there.
We're almost across the finish line.
Let's not get ahead of ourselves.
All right, so now we need to make
a function called increase size
and decrease size.
So let's go ahead and do that.
We want to declare these up here.
No arguments to this function, but
what we need is a default font size
and this one is going to change.
Sorry, not font size.
What do we call it?
What do we want to call this?
Stroke size.
COLTON OGDEN: Oh, yeah.
Yeah.
Stroke size, yeah.
DAN COFFEY: And the default is three.
Right?
COLTON OGDEN: So in
this case, you just do--
DAN COFFEY: What we'll actually do, too,
is we'll dynamically set the value here
once the document is ready.
We'll say, hey, jQuery,
go get me the ID of--
crap.
I forget what it's called.
Already--
COLTON OGDEN: Text size.
DAN COFFEY: So we called it--
COLTON OGDEN: Yeah, so
it should be stroke size.
DAN COFFEY: Stroke size.
We didn't use that
anywhere else, did we?
COLTON OGDEN: I don't think so.
DAN COFFEY: Great.
Only used in two places.
So hey, go get me stroke size--
COLTON OGDEN: So it's the
element with the ID stroke size.
DAN COFFEY: Yep.
And I believe it's-- is it
inner HTML or just HTML?
It's just HTML.
COLTON OGDEN: I thought it was--
yeah It's either that or dot text.
DAN COFFEY: No, that's only
for a text field, I think.
We'll see.
We'll try this and this is just
simply going to be stroke size.
COLTON OGDEN: OK.
DAN COFFEY: And we can
test this out by send this
to a sentinel value of just negative 1.
And so that should
change to a three if--
COLTON OGDEN: Nice.
DAN COFFEY: Yep, you can see
quickly, it's negative 1,
and then it changes
when the page is ready.
So I'm going to put
this back to a three.
COLTON OGDEN: So it won't
do the flicker, but--
DAN COFFEY: But now we know
that it's dynamically changing,
which is great because that means we're
getting, actually, pretty close here.
So now, if we say stroke size--
COLTON OGDEN: Plus plus?
DAN COFFEY: Can you do
plus plus in JavaScript?
COLTON OGDEN: I think you
can do plus plus, yeah.
DAN COFFEY: All right.
And then we can simply do this for--
COLTON OGDEN: For folks unfamiliar,
plus plus means increment by 1.
DAN COFFEY: Take the current
value and increment by one.
Decrease size.
Stroke size minus minus
being the inverse of that.
And so the only other thing
that we need to do, let's
actually make a function that
updates that value for us
so we know what size it is.
Every time we hit the button,
it increments or decrements
the number that's on screen for us.
So let's say update stroke
size equals arrow function.
And so now I can copy paste this
code, take that right out of there,
and just leave that like that.
And at the beginning, we can
now just execute this function.
COLTON OGDEN: Nice.
DAN COFFEY: All right.
So simplifying a little bit.
COLTON OGDEN: Cleaner, a little cleaner.
DAN COFFEY: And so--
COLTON OGDEN: Metal Eagle is asking,
what IDE are you using right now?
DAN COFFEY: Oh, this text
editor is simply Sublime Text,
I think Sublime Text 3.
It is free.
I'm unregistered because
I didn't pay for it.
But if you pay for it, it won't bother
you with these pop-ups that say,
have you registered, or
would you like to register.
COLTON OGDEN: David
kindly tossed the link
to Sublime Text there
in the chat as well.
DAN COFFEY: Thank you, David.
Yeah, it's got some handy
things like search and replace.
And I believe there's a ton of plugins
you can you can plug into it as well.
So I've used it for a long time.
I just really like it.
You use-- what do you use?
COLTON OGDEN: I use VS
code nowadays, but I--
DAN COFFEY: You used to use Atom, right?
COLTON OGDEN: Yeah, I used
to use Atom and Sublime Text
was the first modern
text editor that I used.
I think before that I used
Notepad++ and a lot of other ones,
which are not as fancy or nice looking.
DAN COFFEY: Oops.
I have to do this after we
actually change the value.
So what I'm doing is in our increase and
decrease stroke size, or decrease size,
we're just going to update the stroke
size once the value has been changed.
And so now, I think, Colton, if we
cross our fingers, reload the page.
Here is the default of three.
If we hit Plus, that changes to a
four, five, six, and this should be--
oh, it's not going to be thicker
because we didn't take any action yet.
COLTON OGDEN: Yeah, you haven't
actually updated the path.
DAN COFFEY: Yeah.
So let's go ahead and change--
that's an easy fix, though.
So if we go back to our main drawing
function, so we're passing stroke.
COLTON OGDEN: Oh, it's stroke width.
That's the name of it, not size.
But you know.
DAN COFFEY: Well, yeah.
Well, we can-- we'll
demonstrate the find
and replace features of Sublime Text.
COLTON OGDEN: Modern features
such as find and replace.
DAN COFFEY: So stroke size.
COLTON OGDEN: Atom is slow.
VS Code is kind of good, but Vim
for the win, says Bhavik Knight.
Yeah, Atom is a bit slow.
VS Code is a bit faster.
Vim is going to be faster than both
of them, given that it is a compiled--
the other two are electron
apps, so they're kind of
like having web browsers running that
do all your code stuff, but yeah.
Vim is cool.
David uses Vim and Jordan Hayashi,
who taught the react course,
uses Vim as well.
I'm not a huge fan, but I try to--
it's a good editor, though.
If you're good at it,
you can be really fast.
DAN COFFEY: And so in Sublime Text
here you can find and replace values.
You can say, only in selections if
I highlight a portion of the screen
and say, only make the
changes in here, it'll
only changed within whatever
you've got selected.
And you can also change
the whole word, which
means that like it wouldn't
match on update stroke size
because it's not just
stroke size on its own.
But we have 10 matches here.
If I replace all, there we go.
So now it's update stroke width,
although we have a problem here
because I was using Camel Casing--
COLTON OGDEN: Right.
DAN COFFEY: --and I'm not, so
I'm just going to leave it as is.
But that's how you could
use find a replace for it.
COLTON OGDEN: Andre
says, Sublime is cool
because it's got a
really small footprint.
Yeah, that's true.
It's a C++ text editor versus
VS Code and Atom, which are--
they run on electron shell
so they're a little bit--
they could take up more
memory, a little bit slower.
Real Curious Kiwi, I use Atom,
which is Brenda, I use Atom,
But I might try Sublime
Text to see how it goes.
Yeah, definitely try out
as many different programs
as you want and get a sense of
what the landscape looks like.
It's always nice.
DAN COFFEY: And just get comfortable
with it, get to know its features.
Like, I know all the shortcuts
to jump around and change things
in Sublime Text.
But I'm sure if I went to any other text
editor, I would feel completely lost.
All right.
So I'm simply going to change this
chakra and change the stroke width to--
what is it, stroke width?
Perfect, that was easy.
And so there is a corner case here I
can think of that could be problematic.
What if I end up--
actually, let's see it.
So if I reload--
we broke something, Colton.
Last child of null, so let's go to
the top and find the first error.
Stroke width is not defined.
COLTON OGDEN: Oh, because you--
DAN COFFEY: Stroke size.
COLTON OGDEN: Stroke size, still there.
DAN COFFEY: So this is stroke size.
COLTON OGDEN: I thought we changed
everything to be the same word.
DAN COFFEY: I undid because
of the camel casing.
So if I reload, this should fix it.
COLTON OGDEN: Gotcha.
DAN COFFEY: There's our three.
Now if we increase, there's a
thicker line, so this is nice.
But what happens-- what size
is our eraser by default?
Did we say 20-something?
COLTON OGDEN: I think it's 20, just 20.
DAN COFFEY: OK.
So if we draw with the line
size of 37, and then I'm
going to hold Shift and erase,
now our eraser is too small.
So this is a corner case
that we probably want to fix.
We will always want to race to be
bigger than our current stroke.
COLTON OGDEN: Yeah.
DAN COFFEY: Possibly.
So let's just make a var erase size,
and let's set it to stroke size times--
I don't know, four.
So now, oh, this won't
ever get updated, will it?
COLTON OGDEN: No.
You'd have to actually
trigger the erase size in--
what you could do is you could just--
whatever you do in erase, just set
it to stroke size times two or times
whatever.
DAN COFFEY: All right.
COLTON OGDEN: So this is a 15.
DAN COFFEY: Oh, this is hard coded, so
we need it to say stroke size times 4.
So that'll do it for us.
So I don't even need--
COLTON OGDEN: You don't
need that line, yeah.
DAN COFFEY: --erase size at all.
Great.
Shorter code is great.
All right.
So erase, so now if I change
that, our erase should
be at least four times that size.
And if we go straight across, you
can see how much bigger it is.
COLTON OGDEN: Beautiful.
DAN COFFEY: I think we're
pretty close on features here.
COLTON OGDEN: Yeah, I guess the other
thing would be negative stroke size,
but you could just do an if
statement that says if it's--
DAN COFFEY: Yeah I have a base
case, so there's just stops of--
COLTON OGDEN: No
smaller than 1 possibly,
I opened Sublime in with
five files open as tabs.
It's 38 megabytes of RAM
and I don't think I've ever
seen VS Code under 300 megabyte.
Yeah, no.
It's definitely-- it can use
a lot of RAM pretty quickly.
Sublime, it's the nice
thing about Sublime.
Sublime-- the nice thing about
VS Code compared to Sublime
is that Sublime is free to
try, but it's not free free,
at least last time I
looked at Sublime Text.
Technically, you need a license for it.
DAN COFFEY: So you can pay for it.
COLTON OGDEN: So it's kind of
like you get a trial and then--
[INTERPOSING VOICES]
DAN COFFEY: Well, it's not a trial.
I don't pay for it,
so it's unregistered.
It just bugs you with a
pop-up every now and then.
You just have to say no, thank you.
COLTON OGDEN: And then, obviously,
the different text editors
are going to have different
families of plugins and extensions
and things like that, so
it's going to be kind of
up to whatever you're working on.
But yeah, a lot of
text editors are all--
they all have pros and cons for sure.
In Vim you can do that all, but
just a bit hard learning curve.
I lost my Vim RC that I customized.
Now I'm looking for
someone else's Vim RC.
It's kind of hard to set up.
Yeah, no.
That's a rough thing.
It's a bit more of a down to the metal--
not down to the metal, per se,
but a more fundamental text editor
that does have a much higher
startup learning curve.
The nice thing about VS Code, though, is
you can't use it with Vim key bindings.
So if you want to use VS Code
and all of its plugins and stuff,
but also have the feel of
Vim, you have that option.
And I'm sure there's plugins for
Sublime and Atom that do the same thing.
DAN COFFEY: All right, Colton.
So I just put that base case in, so now
we shouldn't be able to go beyond 1.
COLTON OGDEN: Oh, nice.
OK.
DAN COFFEY: So that's our--
[INTERPOSING VOICES]
COLTON OGDEN: Just while I'm talking,
just adding features super fast.
DAN COFFEY: All right.
COLTON OGDEN: OK.
Yeah, no, that's great.
We went from literally no files to
a pretty functional basic drawing
application in just a couple hours.
That's pretty awesome.
DAN COFFEY: Yeah, especially with all
the debugging we did at the beginning.
COLTON OGDEN: Yeah, right.
That was fun and we got a nice tutorial
on how to use the chrome DevTools,
though, so it wasn't for nothing.
It was a good time.
Thanks everybody for tuning in.
We'll stick around if
anybody has questions,
for just a couple of
minutes we'll hang out.
Tomorrow we're doing a
tutorial-- or not a tutorial,
but I'm going to be doing
a live from-scratch stream
on making tic-tac-toe in LOVE 2D.
So pretty simple game, but if you are
completely unfamiliar with game dev,
it will be a nice intro, I think.
We'll use a lot of the things that
we have taken a look at before.
David is asking, where can
users try it out themselves?
We've plugged it a couple of times so
far, but we'll do it one last time.
DAN COFFEY: Draw.cs50.io right
here will take you to a version.
Same thing, you swipe up from the
bottom, you get the hidden menu.
But you can draw and so if there's--
COLTON OGDEN: Let's prove to David
that we have showed it off in stream.
Do you want to pull it up?
DAN COFFEY: Sure.
We'll cross our fingers here.
COLTON OGDEN: We'll see.
Hopefully, nobody's--
DAN COFFEY: So if we got
to /twitch, there we go.
This is what, David,
everybody has done together.
And if you're just
joining us on the stream,
we all can draw on the same time
if you go to draw.cs50.io/twitch.
COLTON OGDEN: People in
different languages, too.
We got a bonjour up in
the top [INAUDIBLE]..
DAN COFFEY: I'm going
to just pan over and see
what else we've got going on here.
COLTON OGDEN: Yeah,
we've got a lot of stuff.
DAN COFFEY: And someone said lagging.
It does start to lag,
depends on how much RAM
you have because this is a
pretty intensive app for drawing.
COLTON OGDEN: Yeah, so it's great.
So it's networked right now
with a couple of caveats.
But if you just want to use it
locally, draw.cs50.io without a--
DAN COFFEY: Without any slash.
COLTON OGDEN: --slash twitch.
DAN COFFEY: And then you've got all the
stuff without anybody interrupting you.
COLTON OGDEN: Nice.
DAN COFFEY: And it works great.
Again, one finger will actually draw.
Two fingers will erase.
Three fingers as large erase and
five fingers will pan around.
I'm simulating that by holding
Shift Command on my Mac
to actually move stuff around, but you
can do that with five fingers as well.
So if you have a touch
device, go for it.
COLTON OGDEN: I might actually
use this for a scratch pad
because lately I've been thinking,
I could use a nice scratch pad
app to do some stuff in.
DAN COFFEY: Well, it's cool because then
you can download it just that simply.
COLTON OGDEN: Yeah.
DAN COFFEY: There it is.
So there's the drawing we just did.
COLTON OGDEN: That's pretty cool.
The next feature would be have
a notebook, like your own set
of pre-configured drawings, I guess.
It would kind of suck to store
all that, I guess, on the servers.
It would be nice if you
could do it locally.
But local storage is only so big.
So it's kind of tough.
DAN COFFEY: Here, we'll
download our shared drawing
so we can remember today.
COLTON OGDEN: That's true.
It's a little bit tricky
to see a lot of it.
DAN COFFEY: This is the
background I was talking about
and this is one of the conditions that
I'm still working out, but there we go.
We've got some memories for today.
This is CS50.
So thank you very much, everybody.
COLTON OGDEN: Yeah, that's amazing.
Yeah, thanks everybody for tuning in.
Bhavik says, I'm using IDE's PyCharm,
IntelliJ, and VS code with Vim plugin,
basically.
Yeah, no, there's plugins
for pretty much anything.
Bhavik Knight, very
good, informative stream,
especially on the debugging parts.
So it's good.
DAN COFFEY: I'm glad I
helped at least one person.
COLTON OGDEN: I'm glad we had some
silver linings associated with that.
That was good, though.
It was useful for me as
well because a lot of this
is I have to kind of refresh my mind on.
Brenda says, thanks, guys.
Thanks for tuning in, Brenda.
DAN COFFEY: Yeah, thanks, Brenda.
COLTON OGDEN: For the first time, the
first time we've seen you in the room.
DAN COFFEY: Yeah, come join us again.
COLTON OGDEN: Yeah, definitely.
Asli says, thanks for downloading.
Yeah we'll keep it forever and ever.
Thank you, Dan and
Colton for the stream.
It's been fun.
Yes.
It was a good time.
DAN COFFEY: It was.
It was fun.
I'm glad we took a look at--
COLTON OGDEN: [INAUDIBLE] CS50 tool
that we sort of built here in house,
and thanks to Dan, it's in use
every Friday in Sanders Theater.
DAN COFFEY: In use and in progress.
COLTON OGDEN: Yes, in const-- yes,
a lot of the software definitely.
Cool.
All right.
Well, let's go to the
middle screen there where
we have a little bit of a larger view.
Yeah, Brenda says, no longer a lurker.
Yeah, she and I chatted
about it the other day.
I convinced her to pop in.
Thank you, Dan, Colton,
and the staff, says Bhavik.
Our pleasure.
Thanks for tuning in.
So again, tune in tomorrow at 1:00
PM for a stream on Lua and LOVE 2D.
We'll make tic-tac-toe.
So going back from 3D to 2D, we'll
revisit unity again in the future.
And on Friday, if I'm
not mistaken, we have
a tutorial on how to use Linux
commands with Nick Wong, who
did a stream last week.
DAN COFFEY: That's so handy.
COLTON OGDEN: Yeah.
Yeah, Linux commands.
That one's at 3:30 on Friday.
So we'll take a look at
what CD and LS and just
using the terminal are all about,
and some of the internals there.
DAN COFFEY: You should be
one on regular expressions.
COLTON OGDEN: I've been asking
David to do a regular expressions.
David, if you're listening, regular
expressions, everybody wants it it.
Came from Dan, too.
Thanks, Dan and Colton.
See you tomorrow,
Colton, hopefully, yeah.
May definitely tune in.
Same time, see tomorrow, Friday.
[INAUDIBLE],, thanks Dan
and Colton says Asli.
Yeah, trying to get a
whole bunch of good stuff.
So all right.
Thanks, everybody.
We're going to end the stream
here, but I look forward
to seeing you all tomorrow.
Anything you'd like to finish off with?
DAN COFFEY: This is CS50.
COLTON OGDEN: Yeah,
this is CS50 on Twitch.
Thanks, everybody, for tuning in.
Catch you soon.
