# TinyTurtle
**TinyTurtle** is a minimalist
[Turtle Graphics](http://en.wikipedia.org/wiki/Turtle_graphics) implementation
using the [Canvas element](http://en.wikipedia.org/wiki/Canvas_element),
consisting of about 60 lines of JavaScript code.
The library is intended for use in teaching scenarios where learners have access
to a simple HTML editing environment such as
[Thimble](https://thimble.webmaker.org) or [jsbin](http://jsbin.com). Learners
should have a basic knowledge of HTML, but do not need any JavaScript
experience.
The implementation is kept as minimal as possible so that learners are
encouraged to view its source, understand it, and build upon it.
## Import
There are three ways to use this template. The easiest way is to use the
`import` statement and the URL of the text-file of the master branch or any
other branch or version. But you can also copy the required functionality
directly into the header of your Markdown document. And of course, you could
also clone this project and change it, as you wish.
1. Load the macros via
`import: https://github.com/liaTemplates/tiny-turtle/README.md`
2. Copy the definitions into your Project
3. Clone this repository on GitHub
## `@TinyTurtle(width,height,?shell)`
Simply attach the `@TinyTurtle(300,300,true)` macro directly to the end of your
JavaScript code snippet, in order to make it executable. The first two
parameters will define the width and the height of the canvas, the turtle will
walk around. The last parameter is optional, set it to `true` if you want to
enable a console input, which lets you enter your commands dynamically.
``` JavaScript
function box(length) {
for (var i = 0; i < 4; i++) {
forward(length);
right(90);
}
}
penStyle = 'purple';
box(90);
left(10);
box(80);
left(10);
box(70);
```
@TinyTurtle(300,300,true)
## TinyTurtle - Methods
**`forward(amount)`**
Move the turtle forward by the given number of pixels. If the pen is down, a
line is drawn from its previous position to its new position.
The `fd` method can be used as shorthand for this.
**`left(degrees)`**
Rotate the turtle to its left by the given number of degrees.
The `lt` method can be used as shorthand for this.
**`right(degrees)`**
Rotate the turtle to its right by the given number of degrees.
The `rt` method can be used as shorthand for this.
**`stamp()`**
Draw the turtle as a triangle that represents its current state in the following
ways:
* The triangle is drawn at the turtle's current position.
* The triangle is pointing in the direction that the turtle is currently
oriented towards.
* If the pen is up, the triangle is drawn as an outline; otherwise, it's
filled.
* The color and outline of the triangle is drawn using the current pen
style and pen width.
**`penUp()`**
Put the pen up, so that movements by the turtle don't draw anything on the
canvas.
**`penDown()`**
Put the pen down, so that movements by the turtle draw a path on the canvas.
**`clear()`**
Clear the canvas with all drawings.
### Properties
**`penStyle`** (read/write)
A string describing the style that the turtle's path is drawn in. This
can be represented as any one of:
* A hexadecimal color like `#00FF00`
* A [RGBA](http://www.w3.org/TR/css3-color/#rgba-color) quad like
`rgba(0, 255, 0, 0.5)`
* A [HSLA](http://www.w3.org/TR/css3-color/#hsla-color) quad like
`hsla(50, 100%, 50%, 0.5)`
* A [CSS color name](http://www.w3.org/TR/css3-color/#svg-color) like `red`.
**`penWidth`** (read/write)
The width of the turtle's path, in pixels.
**`canvas`** (read-only)
The
[HTMLCanvasElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement)
the turtle is drawing on.
**`rotation`** (read-only)
The current rotation of the turtle, in degrees.
**`position`** (read-only)
The current position of the turtle, as an object with `x` and `y` properties.
**`pen`** (read-only)
The string `up` or `down` indicating the current state of the turtle's pen.
## Supported Browsers
This code has been tested on Internet Explorer 10, Safari 6 (desktop and iOS),
Chrome 30, Opera 17, and Firefox 24.
## License
Public Domain
[CC0 1.0 Universal](http://creativecommons.org/publicdomain/zero/1.0/).
# Tutorial
Before embarking on this journey, you may want to check out
[JavaScript For Cats](http://jsforcats.com) or
[Eloquent JavaScript](http://eloquentjavascript.net) to understand the basics of
the language. Or you can just start hacking and learn things from the glossary
as you go.
> __Tinkering Tips__
>
> > Programmers care more about making it work eventually rather than trying to
> > make it work the very first time. The best way to learn is by making
> > mistakes!
> >
> >[@maxogden](https://twitter.com/maxogden), JavaScript for Cats
>
> __Fear not.__ Nothing you type on this page will damage your computer in any
> way. Programming is all about tinkering, with curiosity guiding your path.
>
> __Play around.__ If you don't understand what a piece of code is doing, try
> changing it. What happens when you remove the code? Or when you change a
> number in it? Or when you copy and paste it somewhere else?
>
> __Ask for help.__ If you're stumped, you can always invite a friend to help
> you out.
## I. Square
> Turtle geometry is a different style of doing geometry, just as Euclid’s
> axiomatic style and Descartes’s analytic style are different from one another.
> Euclid’s is a logical style. Descartes’s is an algebraic style. Turtle
> geometry is a computational style of geometry.
>
> Seymour Papert, Mindstorms
The TinyTurtle API makes it easy to experiment with Turtle geometry.
The `forward` function tells the Turtle to move forward by some number of
pixels.
The `right` function tells it to turn right by some number of degrees.
The `stamp` function tells it to draw its current state: that is, its position
and orientation. This is visualized as a small, pointy triangle.
Can you add to the code below to make the Turtle draw a square 100 pixels wide
and end with the same state that it started?
``` javascript
forward(100);
right(90);
stamp();
```
@TinyTurtle(400,300,true)
See Atul's solution
``` javascript
// Here is Atul's solution to the square problem.
forward(100);
right(90);
forward(100);
right(90);
forward(100);
right(90);
forward(100);
right(90);
stamp();
```
@TinyTurtle(400,300)
> __Hint:__ If you're having trouble, try to "play Turtle." Stand up and move
> your body as the Turtle on the screen must move in order to make the pattern
> you want.
## II. Squares
If we encapsulate our square-drawing code into a function that takes an argument
specifying the size of square to draw, we can use it as a building block for
more interesting things.
Can you complete the code below?
``` javascript
function square(width) {
// Fill in this function!
}
square(100);
right(20);
square(80);
right(20);
square(60);
stamp();
```
@TinyTurtle(400,300,true)
See Atul's solution
``` javascript
// Here is Atul's solution to the squares problem.
function square(width) {
for (var i = 0; i < 4; i++) {
forward(width);
right(90);
}
}
square(100);
right(20);
square(80);
right(20);
square(60);
stamp();
```
@TinyTurtle(400,300)
> __Code Is For People__
>
> > Programs must be written for people to read, and only incidentally for
> > machines to execute.
> >
> > -- _Hal Abelson & Gerald Sussman,_
> > _Structure and Interpretation of Computer Programs_
>
> > See, all my procedures are mind-size bites.
> >
> > -- _Robert, a seventh grader, Mindstorms_
>
> Writing functions keeps our code compartmentalized into mind-size bites that
> are easy for humans to understand. Whenever you're having trouble
> understanding your own code—and especially when you notice yourself
> copying-and-pasting lots of chunks of it—consider splitting it up into
> functions to make it more concise and easier to grasp. This process is called
> refactoring and it's a useful practice that even professional programmers
> struggle to do regularly.
## III. Triangle
One of the principles of Turtle geometry is called the
__Total Turtle Trip Theorem__:
> If a Turtle takes a trip around the boundary of any area and ends up in the
> state in which it started, then the sum of all turns will be 360 degrees.
>
> _Seymour Papert, Mindstorms_
Can you use this theorem to fix the code below, which is trying to draw an
equilateral triangle and finish with the Turtle in the same state that it
started? You just need to replace `SOMETHING` with an actual number.
``` javascript
for (var i = 0; i < 3; i++) {
forward(100);
right(SOMETHING);
}
stamp();
```
@TinyTurtle(400,300,true)
See Atul's solution
``` javascript
// Here is Atul's solution to the triangle problem.
for (var i = 0; i < 3; i++) {
forward(100);
// The turtle needs to make 3 identical turns to draw a triangle, and
// since they all need to add up to 360, that means each turn should be
// 360 divided by 3, or 120 degrees.
right(120);
}
stamp();
```
@TinyTurtle(400,300)
## IV. Circle
Can you use the Turtle Total Trip Theorem to finish this function that draws a
circle based on a given circumference, and returns with the Turtle in its
original state?
``` javascript
function circle(circumference) {
// Draw a circle here.
}
circle(300);
stamp();
```
@TinyTurtle(400,300,true)
See Atul's solution
``` javascript
// Here is Atul's solution to the circle problem.
function circle(circumference) {
// When we walk in a circle, we move forward a tiny bit and turn right
// a tiny bit. By the end, we will have traveled circumference distance
// and rotated 360 degrees.
for (var i = 0; i < 360; i++) {
forward(circumference / 360);
right(1);
}
}
circle(300);
stamp();
```
@TinyTurtle(400,300)
> __Hint:__ It may help conceptually to think of the circumference as the total
> distance the Turtle must travel before it returns to its original state. Also,
> play Turtle!
## Going Further
Playing with Turtle Graphics in this tutorial is nice, but you might be
wondering how to put your design into a real webpage. See the TinyTurtle
documentation for instructions on how to do this.
You might also want to take a look at the TinyTurtle source code,
tiny-turtle.js, to see how it works. It's pretty short, and reading other
people's code—especially code you use yourself—is one of the best ways to learn.
If you find bugs, you can even file an issue and fix it.
Finally, consider reading Mindstorms by Seymour Papert, which explains the
pedagogy behind Turtle graphics, among many other revolutionary ideas about
education.
## Glossary
Here's some terminology used in the tutorial that you might be unfamiliar with.
__API__
> APIs are the filament that connects what i want to _do_ with what i want to
> _learn_.
>
> _Diana Kimball,_
> _[Coding as a Liberal Art](http://www.cbc.ca/player/Radio/ID/2332634295/)_
Technically, API stands for _Application Programming Interface_. Practically
speaking, it's really just a collection of (hopefully) well-documented functions
and similar abstractions that allow you to do what you want to do with a
programming language.
If a programming language is a _language_, then an API is a bit like a
specialized _dictionary_, providing useful nouns and verbs that programs can use
to do their job.
See the TinyTurtle API for an example.
__Function__
A function is like a verb, or action, in a programming language. It's easy to
create your own; see the Making new functions section of JavaScript for Cats to
learn how.
In some programming languages, functions are referred to as procedures or
subroutines. They're all basically the same thing.
__JavaScript__
> JavaScript is an astonishing language, in the very worst sense.
>
> _[Douglas Crockford](http://javascript.crockford.com/popular.html)_
JavaScript is a programming language created by Brendan Eich in 1995 under the
time constraints of the First Browser War and some marketing constraints imposed
by Netscape's partnership with Sun Microsystems. These contributed to it being a
very misunderstood programming language.
Because of this, JavaScript is not a very easy language to learn, and it's a lot
less readable than languages that lacked its constraints. However, it's also
ubiquitous: it runs in web pages, which makes it extremely easy to share, and it
can also be used to program robots, financial trading platforms, web servers,
and a lot more. In other words, if there's something you want to do, there's
probably an API for it in JavaScript, which makes it an extremely useful
language despite its flaws.