Namespaces

Variants
Actions

Javascript in Max 16 - MGraphics Quick Start Guide

From Cycling '74 Wiki
Revision as of 12:11, 28 November 2012 by Timtation (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Contents

Required initialization and Routines

In order for you to use the mgraphics system within the jsui object, you need to have the following lines of code somewhere within the global section of your code:

mgraphics.init( ); mgraphics.relative_coords = 1; mgraphics.autofill = 0;

Every call to the mgraphics system requires the preface of the ‘mgraphics.’ identifier, which makes sure that the call is routed properly. The mgraphics.init() call sets up all of the internal state variables and pointers for the mgraphics subsystem. The setting for mgraphics.relative_coords determines which coordinate system will be used (more on this later…). Finally, setting mgraphics.autofill to zero tells the system to not automatically fill geometry when you use the stroke() functions, although you can fill them in manually if you wish.

The only function that you are required to provide is a paint() function, which is where you put your drawing code (or function calls that do the drawing). This function is called every time that the jsui object decides that the object needs to draw itself. You can also force a repaint by calling the function mgraphics.redraw().

So, a simple paint method might look like this:

function paint() { mgraphics.rectangle(-.2, .2, .2, -.2); mgraphics.fill( ); }

Line and Shape Drawing Concepts

Drawing functions within the mgraphics system all take the same form:

  • Set the colors and line sizes that will be used to sketch and/or fill a segment of the drawing.
  • Create a path using coordinate points within your display area that describes the segment.
  • Call a function that executes the path drawing.

So, a typical drawing routine might look like this:

with (mgraphics) { set_source_rgba(.2, .2, .2, 1.); set_line_width(.03); move_to(-1.0, -1.0); line_to(1.0, 1.0); stroke( ); }

In this case, we’ve set the line color to a fairly dark, completely opaque color, defined a medium width line, moved to one location and drew to another using a “stroke” execution. Notice the use of the “with” qualifier – this lets us use a number of mgraphics routines without having to use the mgraphics prefix on each function call.

You can find the available path creation routines listed below. Remember that these are part of the mgraphics subsystem, so the either need to be performed inside of a ‘with (mgraphics)’ block, or use the ‘mgraphics.’ prefix.

The biggest question you should have about the above code is “What are the coordinates that you are using for the drawing?” That question gives us the change to discuss the two coordinate systems that are available for the mgraphics system.

The mgraphics Coordinate Cystems

The mgraphics system supports two coordinate systems, as determined by the mgraphics.relative_coords setting described above. When the relative_coords setting is 0, the mgraphics system uses a pixel-based coordinate system. In this scenario, the origin (0,0) is at the top-left, with positive numbers moving to the right and bottom. Therefore, if the display area of the jsui object is a 400x200 rectangle, you could draw a large “X” in this area with the following paint method:

function paint() { with (mgraphics) { move_to(0, 0); // the top-left line_to(400,200); // the bottom-right stroke( ); // draw it

move_to(400,0); // the top-right line_to(0, 200); // the bottom-left stroke( ); } }

This works fine if you know that your jsui display area will be exactly 400x200, or if you want the object to clip information that is outside of its range. However, if you want to scale your drawing to the size of the display area, your paint routine would have to have a lot of scaling code built in.

An alternate to using this scaling math is to use the relative coordinate system (set using the mgraphics.relative_coords value to 1). This allows you to work with a standard number range and let the mgraphics system place it on the screen for you.

The coordinates for your drawing area are based off an origin located at the center of the rectangular display area. Positions moving to the right or toward the top are given positive number, while positions moving to the left or toward the bottom are given negative numbers. The vertical number range is always from -1.0 (bottom) through +1.0 (top), but the left and right extents vary based on the aspect ratio of the display area.

It is probably easiest to see this with some code. The following jsui code will draw an “X” in the middle of the jsui display area, and will automatically resize to fit the drawing space. However, if the display area is not square, the end-points will not reach to the corners.

mgraphics.init( ); mgraphics.relative_coords = 1; mgraphics.autofill = 0;

function paint() { with (mgraphics) { move_to(-1.0, -1.0); // the bottom-left line_to(1.0, 1.0); // the top-right stroke( ); // draw it

move_to(1.0, -1.0); // the bottom-right line_to(-1.0, 1.0); // the top-left stroke( ); // draw it } }

In order to make the lines reach all the way to the corners (regardless of the aspect ratio of the display area), we need to calculate the aspect ratio and alter the X coordinates to suit. Here is a simple example of that calculation put to use:

mgraphics.init( ); mgraphics.relative_coords = 1; mgraphics.autofill = 0;

function paint() { var aspect = calcAspect( );

with (mgraphics) { move_to(-1.0 * aspect, -1.0);// the bottom-left line_to(1.0 * aspect, 1.0); // the top-right stroke( ); // draw it

move_to(1.0 * aspect, -1.0); // the bottom-right line_to(-1.0 * aspect, 1.0); // the top-left stroke( ); // draw it } }

function calcAspect() { var width = this.box.rect[2] - this.box.rect[0]; var height = this.box.rect[3] - this.box.rect[1]; return width/height; }

With this change using the aspect calculation (width divided by height), our “X” figure now occupies the entire drawing area regardless of the size of the object.

General mgraphics Routines and Settings

Setup Values

autosketch = [0/1];

When autosketch is set to “1”, the drawing commands will immediately be drawn without waiting a drawing execution command. While this is convenient, it is less flexible than working with autosketch set to “0”.

autopaint = [0/1];

<unknown use…>

autofill = [0/1];

When autofill is set to “1”, any shape command will immediately be filled without requiring a fill execution command. While this is convenient, it is less flexible than working with autofill set to “0”.

relative_coords = [0/1];

As described in the narrative above, the relative_coords setting determines whether the locations in the drawing area range from 0,0 through the size in pixels (relative_coords = 0), or if the drawing area ranges from (-aspect, 1.0) through (aspect, -1.0).

Setup, State and Execution Routines

init( );

The init routine is the first thing that an mgraphics-based Javascript program needs to call. It initializes the library, sets up the internal mgraphics variables and prepares the jsui object for drawing.

redraw( );

Force a redraw of the display area by calling the paint() function.

restore( );

Restore the Mgraphics system to a previously saved state.

save( );

Save the current Mgraphics state for later restoration. This is particularly useful when doing multiple transformations or matrix manipulation of the user space.

position = user_to_device(location);

Given a user location (such as from get_current_point()), returns the device location. This helps find one’s position even with transform matrices in place.

location = device_to_user(position);

Given a device position, returns the user space location. This will determine a location despite user space deformation (using matrix transforms).

Query Routines

in_fill( );

Given a fillable path, determine if a point is within the fill zone. Returns 0 (false) or 1 (true).

fill_extent( );

Determine the enclosing rectangle for the current fill area. Returns an array that contains the top/left and bottom/right points of the fill area.

get_current_point( );

Returns an array with the current X and Y coordinates of the path ending position.

Path Setup and Creation Routines=

Setup Routines

The following routine set up the look of lines and shapes that are drawn. These need to be called before the path segments are drawn.

set_line_cap(line_cap);

Set the appearance of the end-point of a drawn line. The options are butt, round, or square.

get_line_cap( );

Retrieve the appearance attribute of the current line_cap setting. The returned value is the same as the values used by set_line_cap.

set_line_join(line_join);

Set the appearance of the connection point between lines. The options are miter, round, or bevel.

get_line_join( );

Retrieve the appearance attribute of the current line_join setting. The returned value is the same as the values used by set_line_join.

set_line_width(width);

Set the width of path lines drawn using the stroke() function. The width value is dependent on the coordinate system in use.

get_line_width( );

Retrieve the current line width as a floating-point number.

Path Creation Routines

The following routines are used for creating/extending a path for drawing execution.

arc(xc, yc, radius, angle1, angle2);

Add a circular, clockwise, arc to the current path.

xc: The horizontal coordinate of the arc's center.

yc: The vertical coordinate of the arc's center.

radius: The radius of the arc.

angle1: The starting angle of the arc in radians. Zero radians is center right (positive x axis).

angle2: The terminal angle of the arc in radians. Zero radians is center right (positive x axis).

arc_negative(xc, yc, radius, angle1, angle2);

Add a circular, counter-clockwise, arc to the current path.

xc: The horizontal coordinate of the arc's center.

yc: The vertical coordinate of the arc's center.

radius: The radius of the arc.

angle1: The starting angle of the arc in radians. Zero radians is center right (positive x axis).

angle2: The terminal angle of the arc in radians. Zero radians is center right (positive x axis).

ovalarc(xc, yc, radiusx, radiusy, angle1, angle2);

Add a non-circular arc to the current path.

xc: The horizontal coordinate of the arc's center.

yc: The vertical coordinate of the arc's center.

radiusx: The horizontal radius of the arc.

radiusy: The vertical radius of the arc.

angle1: The starting angle of the arc in radians. Zero radians is center right (positive x axis).

angle2: The terminal angle of the arc in radians. Zero radians is center right (positive x axis).

curve_to(x1, y1, x2, y2, x3, y3);

Add a cubic Bezier spline to the current path.

x1: The first control point.

y1: The first control point.

x2: The second control point.

y2: The second control point.

x3: The destination point.

y3: The destination point.

rel_curve_to(x1, y1, x2, y2, x3, y3);

Add a cubic Bezier spline to the current path, using coordinates relative to the current point.

x1: The first control point.

y1: The first control point.

x2: The second control point.

y2: The second control point.

x3: The destination point.

y3: The destination point.

line_to(x, y);

Add a line segment to the current path.

x: The destination point.

y: The destination point.

rel_line_to(x, y);

Add a line segment to the current path, using coordinates relative to the current point.

x: The destination point.

y: The destination point.

====move_to(x, y); </code>

Move the cursor to a new point and begin a new subpath.

x: The new location.

y: The new location.

====rel_move_to(x, y); </code>

Move the cursor to a new point and begin a new subpath, using coordinates relative to the current point.

x: The new location.

y: The new location.

rectangle(x, y, width, height);

Add a closed rectangle path in the context.

x: The horizontal origin.

y: The vertical origin.

width: The width of the rect.

height: The height of the rect.

rectangle_rounded(x, y, width, height, ovalwidth, ovalheight);

Add a closed rounded-rectangle path in the context.

x: The horizontal origin.

y: The vertical origin.

width: The width of the rect.

height: The height of the rect.

ovalwidth: The width of the oval used for the round corners.

ovalheight: The height of the oval used for the round corners.

ellipse(x, y, width, height);

Add a closed elliptical path in the context.

x: The horizontal origin.

y: The vertical origin.

width: The width of the rect.

height: The height of the rect.

close_path( );

Create a line that connects the current path point to the origin of the path, thereby closing the path into a fill-able shape.

Utility Routines

copy_path( );

Returns a copy of the current path to be stored and reused at a later time.

append_path(path);

Appends a stored path to the current path at the current end point.

push_group( );

Define a starting point for a path execution group. This group can be used for creating an image from a set of path functions without actually drawing the results to the screen.

image = pop_group( );

Complete a path execution group, returning the results as an Image object. This image can be used for later drawing of the group results.

Path Execution Routines=

path_roundcorners(radius);

Using the current path, round the corners to the radius provided (or as close as possible given the path’s angle).

stroke( );

Draw the outline of the path with the color and line size chosen. When the drawing is complete, the path is deleted.

stroke_preserve( );

Draw the outline of the path with the color and line size chosen, but do not destroy the path when completed. This is useful for situations where you need to both fill a path and draw its outline.

stroke_with_alpha(alpha);

Draw the outline of the path with the color and line size chosen, but override the alpha value of the color with a new alpha channel value. This allows you to change transparency without resetting the color values.

stroke_preserve_with_alpha(alpha);

A combination of the above two routines, this will draw the line, preserve the path, and override the alpha value in a single routine call.

fill( );

Fill the path with the current source color. When the fill is completed, the path will be destroyed.

fill_preserve( );

Fill the path with the current source color, but do not destroy the path when the fill is completed.

fill_with_alpha(alpha);

Fill the path with the current source color, but override the alpha value for a fill-specific transparency.

fill_preserve_with_alpha(alpha);

A combination of the two previous routines, this fills the path with the source color, but overrides the alpha value. It does not destroy the path when the fill is complete.

Transformation Routines=

set_source_rgba(red, green, blue, alpha);

Set the color and alpha channels to be used for drawing routines.

set_source_rgb(red, green, blue);

Set the color channels to be used for drawing routines. Since the alpha channel is not provide, it is defaulted to completely opaque.

scale_source_rgba(sc_red, sc_green, sc_blue, sc_alpha);

Create a transform for the color and alpha channels using scale amounts to determine a color multiplier (either positive or negative). Note: One of the set_source_* routines must be called to apply this transform to an actual color.

translate_source_rgba(t_red, t_green, t_blue, t_alpha);

Create a transform for the color and alpha channels by absolute delta amounts to determine a color offset (either positive or negative). Note: One of the set_source_* routines must be called to apply this transform to an actual color.

scale(sc_x, sc_y);

Modifies the transform matrix that scales all X and Y values by the values provided.

Note: This affects everything from size to location, and also scales line widths.

rotate(rot);

Modifies the transform matrix by rotating it. The rotation values is in radians (2-pi for a complete rotation).

translate(t_x, t_y);

Modifies the transform matrix by moving it by absolute (positive or negative) delta amounts.

transform(xx, xy, yx, yy, x0, y0);

Directly modify the transform matrix (and therefore the user space) using six values. The xx and yy values provide scaling support, xy and yx provide rotational warping, and x0 and y0 provide location offset.

set_matrix(xx, xy, yx, yy, x0, y0);

Directly set the tranform matrix for the current drawing context.

array = get_matrix( );

Retrieve the current transform matrix for the current drawing context.

identity_matrix( );

Revert the transform matrix to default (normal) values.

Font Routines=

fontlist = getfontlist( );

Returns a Javascript array where each value is the text name of a font installed on your system. You can determine the length of the array by using the variable fontlist.length.

select_font_face(fontname);

Sets the current font face by name.

set_font_size(fontsize);

Sets the current font size, using either an integer or floating-point value.

text_path(display_text);

Create a path that uses the display text, the current font and the current size. The result is subject to all of the transforms ordinarily available to paths.

show_text(display_text);

Places the display text in the drawing area at the current location, and using the current font and size. Since a path is not being created, it does not conform to the transformations otherwise available with paths.

font_extents( );

Returns an array with three values: ascent, descent and height.

text_measure(text);

Returns an array with two values: width and height. This is the measurement of the provided text using the current font and size.

Pattern Routines=

name = pattern_create_linear(x1, y1, x2, y2);

Create a linear gradient, with an influence point for each gradient section. When in relative_coordinate mode, these influence points still need to be defined in pixels rather than relative coordinates.

This routine returns a pattern object value that is used by other functions.

pattern = pattern_create_radial(x1, y1, rad1, x2, y2, rad2);

Create a radial gradient, with an influence point for each gradient section. When in relative_coordinate mode, these influence points still need to be defined in pixels rather than relative coordinates.

This routine returns a pattern object value that is used by other functions.

pattern = pattern_create_rgba(red, green, blue, alpha);

Create a solid color pattern.

pattern = pattern_create_for_surface(image);

Create a pattern using an image for the background. Repeating patterns depends on the extend value set using the set_extend() function.

value = pattern.get_extend( );

Returns the extend value of the pattern. Options include: “none”, “repeat”, “reflect”, and “pad”.

pattern.set_extend(extend_type);

Determines how the pattern will be created when there is more space than available information. Options include: “none”, “repeat”, “reflect”, and “pad”.

value = pattern.get_matrix( );

Returns the current transform matrix for the pattern

pattern.set_matrix(xx, xy, yx, yy, x0, y0);

Directly sets the transform matrix used in the creation of the pattern.

pattern.add_color_stop_rgba(index, red, green, blue, alpha);

A function called on a previously created pattern, the add_color_stop_rgba will define a color value for one of the influence points of the pattern. The index parameter determine which influence point is being defined.

pattern.identity_matrix( );

Revert the user space transform matrix to its default (normal) orientation.

pattern.rotate(rotation);

Apply a rotation transform on the user space in which the pattern is displayed.

pattern.scale(x, y);

Scale the pattern by a factor in both X and Y coordinate spaces.

pattern.translate(x, y);

Apply a translation transform (spatial offset) on the user space in which the pattern is displayed.

set_source(pattern);

Sets the pattern to be used for the next fill() call. The name parameter must be a previously created pattern.

value = pattern.get_type( );

Returns the type of pattern that was created.

Image and Surface Routines

instance = new MGraphics(width, height);

Creates a new Mgraphics instance, which can be used as a drawing context for creating saved or persistent images. To move the contents of an MGraphic instance into a Image object, you just pass the MGraphic into the Image during instantiation (myImage = new Image(mgraphic_instance)).

image_surface_draw(myImage [,source_top, source_left, source_width, source_height]);

Place an image (typically stored as an Image object) into the current surface. The drawing is placed at the top-left of the drawing context, changeable using a transform matrix or translate function. You can also choose the section of the image to draw using four optional arguments that describe a rectangle taken from the image.

svg_render(filename);

Render an SVG file into the current user context.

set_source_surface(surface);

Sets the provided surface as the source for drawing routines.