Example usage for com.google.gwt.canvas.dom.client Context2d closePath

List of usage examples for com.google.gwt.canvas.dom.client Context2d closePath

Introduction

In this page you can find the example usage for com.google.gwt.canvas.dom.client Context2d closePath.

Prototype

public final native void closePath() ;

Source Link

Document

Closes the current path.

Usage

From source file:anagram.client.Ball.java

License:Apache License

public void draw(Context2d context) {
    context.setFillStyle(color);/*www. ja  v a2s  .  co  m*/
    context.beginPath();
    context.arc(pos.x, pos.y, radius, 0, Math.PI * 2.0, true);
    context.closePath();
    context.fill();
}

From source file:anagram.client.Lens.java

License:Apache License

public void draw(Context2d back, Context2d front) {
    front.drawImage(back.getCanvas(), 0, 0);

    if (!GWT.isScript()) {
        // in devmode this effect is slow so we disable it here
    } else {//ww w  .ja v a  2  s.c om
        ImageData frontData = front.getImageData((int) (pos.x - radius), (int) (pos.y - radius), 2 * radius,
                2 * radius);
        CanvasPixelArray frontPixels = frontData.getData();
        ImageData backData = back.getImageData((int) (pos.x - radius), (int) (pos.y - radius), 2 * radius,
                2 * radius);
        CanvasPixelArray backPixels = backData.getData();
        int srcIdx, dstIdx;
        for (int i = lensArray.length - 1; i >= 0; i--) {
            dstIdx = 4 * lensArray[i][0];
            srcIdx = 4 * lensArray[i][1];
            frontPixels.set(dstIdx + 0, backPixels.get(srcIdx + 0));
            frontPixels.set(dstIdx + 1, backPixels.get(srcIdx + 1));
            frontPixels.set(dstIdx + 2, backPixels.get(srcIdx + 2));
        }
        front.putImageData(frontData, (int) (pos.x - radius), (int) (pos.y - radius));
    }

    front.setStrokeStyle(strokeStyle);
    front.beginPath();
    front.arc(pos.x, pos.y, radius, 0, Math.PI * 2, true);
    front.closePath();
    front.stroke();
}

From source file:com.google.gwt.maeglin89273.shared.test.volcanogame.component.FireBall.java

@Override
public void draw(Context2d context) {

    context.setFillStyle(ballColor);/*from w  ww  . j  a  v  a 2s. c o  m*/

    //context.setShadowColor(ballShadowColor.toString());
    context.beginPath();
    context.arc(position.getX(), position.getY(), radius, 0, 2 * Math.PI);
    context.closePath();
    context.fill();

}

From source file:com.kk_electronic.kkportal.debug.modules.UsageGraph.java

License:Open Source License

@Inject
public UsageGraph(CpuUsage model) {
    Context2d context = canvas.getContext2d();
    model.addDisplay(this);
    context.setLineWidth(1);//from  ww w  .  java2  s .  c  om
    context.setStrokeStyle("black");
    canvas.getElement().getStyle().setBorderWidth(borderSize, Unit.PX);
    canvas.getElement().getStyle().setBorderStyle(BorderStyle.SOLID);
    canvas.getElement().getStyle().setBorderColor(borderColor);

    context.beginPath();
    context.moveTo(1, 1);
    context.lineTo(1, 50);
    context.lineTo(100, 50);
    context.lineTo(50, 1);
    context.closePath();
    context.stroke();
    timer.scheduleRepeating(100);
}

From source file:com.sencha.gxt.chart.client.draw.engine.Canvas2d.java

License:sencha.com license

/**
 * In the Canvas2d class, this method does more or less what renderSprite does in SVG and VML - it
 * actually renders the sprite to the dom.
 * @param sprite the sprite to draw//from   ww  w.j  av a2s.  c om
 */
protected void append(Sprite sprite) {
    if (sprite.isHidden() || sprite.getOpacity() == 0) {
        return;
    }
    Context2d ctx = getContext();
    ctx.save();
    //set global stuff, fill, stroke, clip, etc

    //clip - deal with translation or normal rectangle
    if (sprite.getClipRectangle() != null) {
        PreciseRectangle clip = sprite.getClipRectangle();
        if (sprite.getScaling() != null || sprite.getTranslation() != null || sprite.getRotation() != null) {
            PathSprite transPath = new PathSprite(new RectangleSprite(clip));
            transPath = transPath.map(sprite.transformMatrix());
            appendPath(ctx, transPath);
        } else {
            ctx.beginPath();
            ctx.rect(clip.getX(), clip.getY(), clip.getWidth(), clip.getHeight());
            ctx.closePath();
        }
        ctx.clip();
    }

    if (sprite.getScaling() != null || sprite.getTranslation() != null || sprite.getRotation() != null
            || (component.isViewBox() && viewbox != null)) {
        Matrix matrix = sprite.transformMatrix();
        if (matrix != null) {
            //TODO consider replacing this transform call with three distinct calls to translate/scale/rotate if cheaper
            ctx.transform(matrix.get(0, 0), matrix.get(1, 0), matrix.get(0, 1), matrix.get(1, 1),
                    matrix.get(0, 2), matrix.get(1, 2));
        }
        if (component.isViewBox() && viewbox != null) {
            double size = Math.min(getWidth() / viewbox.getWidth(), getHeight() / viewbox.getHeight());

            ctx.scale(size, size);
            ctx.translate(-viewbox.getX(), -viewbox.getY());
        }
    }

    //TODO see about caching colors via the dirty flag? If we don't use a color/gradient for a pass or three, dump it
    double opacity = Double.isNaN(sprite.getOpacity()) ? 1.0 : sprite.getOpacity();
    PreciseRectangle untransformedBbox = sprite.getPathSprite().dimensions();
    if (sprite.getStroke() != null && sprite.getStroke() != Color.NONE && sprite.getStrokeWidth() != 0) {
        ctx.setLineWidth(Double.isNaN(sprite.getStrokeWidth()) ? 1.0 : sprite.getStrokeWidth());
        ctx.setStrokeStyle(getColor(sprite.getStroke(), untransformedBbox));//TODO read bbox from cache
    }
    if (sprite.getFill() != null && sprite.getFill() != Color.NONE) {
        ctx.setFillStyle(getColor(sprite.getFill(), untransformedBbox));//TODO read bbox from cache
    }

    if (sprite instanceof PathSprite) {
        appendPath(ctx, (PathSprite) sprite);
    } else if (sprite instanceof TextSprite) {
        TextSprite text = (TextSprite) sprite;
        //TODO style and weight
        ctx.setFont(text.getFontSize() + "px " + text.getFont());
        ctx.setTextAlign(getTextAlign(text.getTextAnchor()));
        ctx.setTextBaseline(getTextBaseline(text.getTextBaseline()));
        ctx.fillText(text.getText(), text.getX(), text.getY());
    } else if (sprite instanceof RectangleSprite) {
        RectangleSprite rect = (RectangleSprite) sprite;
        if (Double.isNaN(rect.getRadius()) || rect.getRadius() == 0) {
            if (sprite.getFill() != null && sprite.getFill() != Color.NONE) {
                ctx.setGlobalAlpha(
                        Double.isNaN(sprite.getFillOpacity()) ? opacity : opacity * sprite.getFillOpacity());
                ctx.fillRect(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
            }
            if (sprite.getStroke() != null && sprite.getStroke() != Color.NONE
                    && sprite.getStrokeWidth() != 0) {
                ctx.setGlobalAlpha(Double.isNaN(sprite.getStrokeOpacity()) ? opacity
                        : opacity * sprite.getStrokeOpacity());
                ctx.strokeRect(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
            }
        } else {
            appendPath(ctx, rect.getPathSprite());
        }
    } else if (sprite instanceof CircleSprite) {
        CircleSprite circle = (CircleSprite) sprite;
        ctx.beginPath();
        ctx.arc(circle.getCenterX(), circle.getCenterY(), circle.getRadius(), 0, 2 * Math.PI);
        ctx.closePath();
        if (sprite.getFill() != null && sprite.getFill() != Color.NONE) {
            ctx.setGlobalAlpha(
                    Double.isNaN(sprite.getFillOpacity()) ? opacity : opacity * sprite.getFillOpacity());
            ctx.fill();
        }
        if (sprite.getStroke() != null && sprite.getStroke() != Color.NONE && sprite.getStrokeWidth() != 0) {
            ctx.setGlobalAlpha(
                    Double.isNaN(sprite.getStrokeOpacity()) ? opacity : opacity * sprite.getStrokeOpacity());
            ctx.stroke();
        }
    } else if (sprite instanceof EllipseSprite) {
        appendPath(ctx, sprite.getPathSprite());
    } else if (sprite instanceof ImageSprite) {
        ImageSprite image = (ImageSprite) sprite;
        ImageElement elt = Document.get().createImageElement();
        elt.setSrc(image.getResource().getSafeUri().asString());
        ctx.drawImage(elt, image.getX(), image.getY(), image.getWidth(), image.getHeight());
    }

    ctx.restore();

    if (!REDRAW_ALL) {
        renderedBbox.put(sprite, getBBox(sprite));
    }

    sprite.clearDirtyFlags();
}

From source file:com.sencha.gxt.chart.client.draw.engine.Canvas2d.java

License:sencha.com license

private PathCommand appendPathCommands(Context2d ctx, List<PathCommand> commands, PrecisePoint currentPoint,
        PrecisePoint movePoint, PrecisePoint curvePoint, PrecisePoint quadraticPoint) {
    PathCommand last = null;// w  w  w  .ja  va2  s. co  m
    for (PathCommand cmd : commands) {
        last = cmd;
        if (cmd instanceof MoveTo) {
            MoveTo move = (MoveTo) cmd;

            quadraticPoint.setX(currentPoint.getX());
            quadraticPoint.setY(currentPoint.getY());
            movePoint.setX(move.getX());
            movePoint.setY(move.getY());
            currentPoint.setX(move.getX());
            currentPoint.setY(move.getY());
            curvePoint.setX(move.getX());
            curvePoint.setY(move.getY());

            ctx.moveTo(move.getX(), move.getY());
        } else if (cmd instanceof LineTo) {
            LineTo line = (LineTo) cmd;

            quadraticPoint.setX(currentPoint.getX());
            quadraticPoint.setY(currentPoint.getY());
            currentPoint.setX(line.getX());
            currentPoint.setY(line.getY());
            curvePoint.setX(line.getX());
            curvePoint.setY(line.getY());

            ctx.lineTo(line.getX(), line.getY());
        } else if (cmd instanceof CurveTo) {
            CurveTo curve = (CurveTo) cmd;

            quadraticPoint.setX(currentPoint.getX());
            quadraticPoint.setY(currentPoint.getY());
            currentPoint.setX(curve.getX());
            currentPoint.setY(curve.getY());
            curvePoint.setX(curve.getX2());
            curvePoint.setY(curve.getY2());

            ctx.bezierCurveTo(curve.getX1(), curve.getY1(), curve.getX2(), curve.getY2(), curve.getX(),
                    curve.getY());
        } else if (cmd instanceof CurveToQuadratic) {
            CurveToQuadratic curve = (CurveToQuadratic) cmd;
            double ax = 2.0 * curve.getX1() / 3.0;
            double ay = 2.0 * curve.getY1() / 3.0;

            quadraticPoint.setX(curve.getX1());
            quadraticPoint.setY(curve.getY1());
            currentPoint.setX(curve.getX() / 3.0 + ax);
            currentPoint.setY(curve.getY() / 3.0 + ay);
            curvePoint.setX(curve.getX1());
            curvePoint.setY(curve.getY1());

            ctx.quadraticCurveTo(curve.getX1(), curve.getY1(), curve.getX(), curve.getY());
        } else if (cmd instanceof ClosePath) {
            quadraticPoint.setX(currentPoint.getX());
            quadraticPoint.setY(currentPoint.getY());

            ctx.closePath();
        } else {
            assert cmd instanceof EllipticalArc || cmd instanceof CurveToQuadraticSmooth
                    || cmd instanceof CurveToSmooth || cmd instanceof LineToHorizontal
                    || cmd instanceof LineToVertical : cmd.getClass() + " is not yet implemented";
            last = appendPathCommands(ctx, cmd.toCurve(currentPoint, movePoint, curvePoint, quadraticPoint),
                    currentPoint, movePoint, curvePoint, quadraticPoint);
            CurveTo curve = (CurveTo) last;
            currentPoint.setX(curve.getX());
            currentPoint.setY(curve.getY());
            curvePoint.setX(curve.getX2());
            curvePoint.setY(curve.getY2());
        }

    }
    return last;
}

From source file:edu.umb.jsPedigrees.client.Pelican.PelicanLines.java

License:Open Source License

public static Canvas drawLines(AbsolutePanel panel) {

    Canvas canvas = Canvas.createIfSupported();
    Context2d ctx = canvas.getContext2d();

    canvas.setCoordinateSpaceHeight(panel.getOffsetHeight());
    canvas.setCoordinateSpaceWidth(panel.getOffsetWidth());

    ctx.setStrokeStyle(CssColor.make("0,0,0"));
    ctx.setLineWidth(1.0f);/*from   ww  w . ja va2  s.c o  m*/
    ctx.setFont("12px sans-serif");

    int fontHeight = 15;
    int fontAscent = 15;

    int dropSize = Math.max(2, Math.min(PelicanPerson.symbolSize / 2,
            3 * (PelicanPerson.ySpace - PelicanPerson.symbolSize - fontHeight) / 4));
    for (int i = 0; i < panel.getWidgetCount(); i++)
        if (panel.getWidget(i) instanceof PelicanPerson) {
            // draw a line from this person to its parents
            PelicanPerson person = (PelicanPerson) panel.getWidget(i);
            if (person.father != null && person.mother != null) {
                //System.out.println("HERE "+String.valueOf(i));
                // find the mother and father
                PelicanPerson father = person.father;
                PelicanPerson mother = person.mother;
                if (father != null && mother != null) {
                    // line between parents
                    int fatherX = panel.getWidgetLeft(father)
                            + ((panel.getWidgetLeft(father) < panel.getWidgetLeft(mother))
                                    ? PelicanPerson.symbolSize
                                    : 0);
                    int motherX = panel.getWidgetLeft(mother)
                            + ((panel.getWidgetLeft(mother) < panel.getWidgetLeft(father))
                                    ? PelicanPerson.symbolSize
                                    : 0);
                    int fatherY = panel.getWidgetTop(father) + PelicanPerson.symbolSize / 2;
                    int motherY = panel.getWidgetTop(mother) + PelicanPerson.symbolSize / 2;
                    int leftX = fatherX;
                    int leftY = fatherY;
                    int rightX = motherX;
                    int rightY = motherY;
                    if (motherX < fatherX) {
                        leftX = motherX;
                        leftY = motherY;
                        rightX = fatherX;
                        rightY = fatherY;
                    }
                    int gap = PelicanPerson.xSpace - PelicanPerson.symbolSize;
                    // see if any subjects lie between the father and mother
                    if (!adjacent(panel, father, mother) && father.generation == mother.generation) {
                        // draw lines which avoid other symbols

                        // g2.drawLine(leftX,leftY,leftX+gap/4,leftY);
                        ctx.beginPath();
                        ctx.moveTo(leftX, leftY);
                        ctx.lineTo(leftX + gap / 4, leftY);
                        ctx.closePath();
                        ctx.stroke();

                        // g2.drawLine(rightX,rightY,rightX-gap/2,rightY);
                        ctx.beginPath();
                        ctx.moveTo(rightX, rightY);
                        ctx.lineTo(rightX - gap / 2, rightY);
                        ctx.closePath();
                        ctx.stroke();

                        leftX += gap / 4;
                        rightX -= gap / 2;

                        // g2.drawLine(leftX,leftY,leftX,leftY-(PelicanPerson.symbolSize+dropSize)/2);
                        ctx.beginPath();
                        ctx.moveTo(leftX, leftY);
                        ctx.lineTo(leftX, leftY - (PelicanPerson.symbolSize + dropSize) / 2);
                        ctx.closePath();
                        ctx.stroke();

                        // g2.drawLine(rightX,rightY,rightX,rightY-(PelicanPerson.symbolSize+dropSize)/2);
                        ctx.beginPath();
                        ctx.moveTo(rightX, rightY);
                        ctx.lineTo(rightX, rightY - (PelicanPerson.symbolSize + dropSize) / 2);
                        ctx.closePath();
                        ctx.stroke();

                        leftY -= (PelicanPerson.symbolSize + dropSize) / 2;
                        rightY -= (PelicanPerson.symbolSize + dropSize) / 2;
                    }

                    // g2.drawLine(leftX,leftY,rightX,rightY);
                    ctx.beginPath();
                    ctx.moveTo(leftX, leftY);
                    ctx.lineTo(rightX, rightY);
                    ctx.closePath();
                    ctx.stroke();

                    // line up from child
                    // g2.drawLine(person.getX()+PelicanPerson.symbolSize/2,person.getY(),person.getX()+PelicanPerson.symbolSize/2,person.getY()-dropSize);
                    ctx.beginPath();
                    ctx.moveTo(panel.getWidgetLeft(person) + PelicanPerson.symbolSize / 2,
                            panel.getWidgetTop(person));
                    ctx.lineTo(panel.getWidgetLeft(person) + PelicanPerson.symbolSize / 2,
                            panel.getWidgetTop(person) - dropSize);
                    ctx.closePath();
                    ctx.stroke();

                    // line across from child
                    // try to attach to an orphan parent
                    int parentX = fatherX;
                    if (father.isOrphan() || mother.isOrphan()) {
                        parentX = Math.max(fatherX, motherX) - gap / 2;
                    } else {
                        // if no orphan parents, go straight up from
                        // middle laid out sib
                        int nsib = 0;
                        for (int j = 0; j < panel.getWidgetCount(); j++)
                            if (panel.getWidget(j) instanceof PelicanPerson) {
                                PelicanPerson sib = (PelicanPerson) panel.getWidget(j);
                                if (areSibs(person, sib))
                                    nsib++;
                            }
                        int sibs = 0;
                        for (int j = 0; j < panel.getWidgetCount() && sibs <= nsib / 2; j++)
                            if (panel.getWidget(j) instanceof PelicanPerson) {
                                PelicanPerson sib = (PelicanPerson) panel.getWidget(j);
                                if (areSibs(person, sib))
                                    sibs++;
                                parentX = panel.getWidgetLeft(sib) + PelicanPerson.symbolSize / 2;
                            }
                        if (nsib > 1 && nsib % 2 == 0)
                            parentX -= PelicanPerson.xSpace / 2;
                        if (parentX <= leftX)
                            parentX = leftX + PelicanPerson.symbolSize / 2;
                        if (parentX >= rightX)
                            parentX = rightX - PelicanPerson.symbolSize / 2;
                    }

                    // g2.drawLine(person.getX()+PelicanPerson.symbolSize/2,person.getY()-dropSize,parentX,person.getY()-dropSize);
                    ctx.beginPath();
                    ctx.moveTo(panel.getWidgetLeft(person) + PelicanPerson.symbolSize / 2,
                            panel.getWidgetTop(person) - dropSize);
                    ctx.lineTo(parentX, panel.getWidgetTop(person) - dropSize);
                    ctx.closePath();
                    ctx.stroke();

                    // line up to parents
                    // Draw a vertical line up to the line joining the parents
                    // if this happens to be not between the parents,
                    // change it to a line to the midpoint between the parents
                    int parentY = (rightX != leftX)
                            ? leftY + (rightY - leftY) * (parentX - leftX) / (rightX - leftX)
                            : (leftY + rightY) / 2;
                    if (rightX == leftX || parentY > Math.max(leftY, rightY)
                            || parentY < Math.min(leftY, rightY)) {
                        // g2.drawLine(parentX,person.getY()-dropSize, (leftX+rightX)/2,(leftY+rightY)/2);
                        ctx.beginPath();
                        ctx.moveTo(parentX, panel.getWidgetTop(person) - dropSize);
                        ctx.lineTo((leftX + rightX) / 2, (leftY + rightY) / 2);
                        ctx.closePath();
                        ctx.stroke();

                    } else {
                        // g2.drawLine(parentX,person.getY()-dropSize,parentX,parentY);
                        ctx.beginPath();
                        ctx.moveTo(parentX, panel.getWidgetTop(person) - dropSize);
                        ctx.lineTo(parentX, parentY);
                        ctx.closePath();
                        ctx.stroke();

                    }
                }
            }

            // write out id
            int verticalPosn = panel.getWidgetTop(person) + PelicanPerson.symbolSize + fontAscent;
            String idString = String.valueOf(person.id);
            int fontWidth = (int) ctx.measureText(idString).getWidth();
            // g2.drawString(idString, 
            //      person.getX() + PelicanPerson.symbolSize/2 - fontWidth/2,
            //      verticalPosn);
            ctx.fillText(idString, panel.getWidgetLeft(person) + PelicanPerson.symbolSize / 2 - fontWidth / 2,
                    verticalPosn);
            verticalPosn += fontAscent;
        }
    return canvas;
}

From source file:examples.geometry.AbstractExample.java

License:Open Source License

@Override
public void draw() {
    Context2d context = canvas.getContext2d();
    // reset//from   www.ja va2  s.  co  m
    context.clearRect(0, 0, canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight());
    context.setFillStyle("black");
    context.setStrokeStyle("black");
    context.setLineWidth(1);

    for (ControllableShape shape : getControllableShapes()) {
        //         e.gc.setForeground(canvas.getDisplay().getSystemColor(shape.shapeColor));
        //         e.gc.setBackground(canvas.getDisplay().getSystemColor(shape.shapeColor));

        shape.onDraw(canvas);
    }

    for (ControllableShape shape : getControllableShapes()) {
        if (shape.isActive()) {
            FillStrokeStyle fillStyle = context.getFillStyle();

            for (ControlPoint cp : shape.controlPoints) {
                context.beginPath();
                context.arc(cp.getX(), cp.getY(), shape.controlRadius, 0, 180);
                context.setFillStyle(shape.controlColor);
                context.fill();
                context.closePath();
            }
            context.setFillStyle(fillStyle);
        }
    }
}

From source file:examples.geometry.containment.PolygonLineContainment.java

License:Open Source License

@Override
protected AbstractControllableShape createControllableShape2(final Canvas canvas) {
    return new AbstractControllableShape(canvas) {
        @Override//ww w. j  av  a  2s.  c om
        public void createControlPoints() {
            addControlPoint(new Point(100, 100));
            addControlPoint(new Point(300, 300));
        }

        @Override
        public Line createGeometry() {
            Point[] points = getControlPoints();
            return new Line(points[0], points[1]);
        }

        @Override
        public void drawShape() {
            Line line = createGeometry();
            Context2d c = canvas.getContext2d();
            c.beginPath();
            c.moveTo(line.getX1(), line.getY1());
            c.lineTo(line.getX2(), line.getY2());
            c.closePath();
            c.stroke();
        }

        @Override
        public void fillShape(CssColor color) {
            Context2d context2d = canvas.getContext2d();
            FillStrokeStyle style = context2d.getFillStyle();
            context2d.setLineWidth(3);
            context2d.setStrokeStyle(color.value());

            drawShape();

            context2d.setLineWidth(1);
            //            context2d.setStrokeStyle(CssColor.make(0, 0, 0).value());
            context2d.setStrokeStyle(style);
        }
    };
}

From source file:examples.geometry.demos.CubicCurveDeCasteljauExample.java

License:Open Source License

@Override
protected ControllableShape[] createShapes(Canvas canvas, EventBus eventBus) {
    return new ControllableShape[] { new ControllableShape(canvas, eventBus) {
        {/*w ww. j  ava2  s  . com*/
            /*
             * These are the control points used to construct the CubicCurve
             * later.
             */
            addControlPoints(new Point(100, 200), new Point(200, 100), new Point(300, 300),
                    new Point(400, 200));
        }

        @Override
        public CubicCurve getShape() {
            /*
             * Constructs the CubicCurve of the defined control points.
             */
            return new CubicCurve(getPoints());
        }

        @Override
        public void onDraw(Canvas canvas) {
            Context2d context = canvas.getContext2d();
            /*
             * Draws the CubicCurve and the de Casteljau construction for
             * the current parameter value.
             */

            // Construct the CubicCurve from the defined control points.
            CubicCurve curve = getShape();
            CanvasDrawer.strokePath(curve.toPath(), context);

            /*
             * Retrieve control points to compute the linear interpolations
             * of the de Casteljau algorithm.
             */
            Point[] points = getPoints();

            /*
             * Define the colors for the intermediate lines. We have three
             * stages and therefore three different colors for a cubic
             * Bezier curve. This is the case, because the de Casteljau
             * algorithm reduces the number of control points in each
             * iteration until it reaches the actual point on the curve.
             */
            String[] colors = new String[] { "green", "blue", "red" };

            for (int ci = 0; ci < colors.length; ci++) {
                for (int i = 0; i < 3 - ci; i++) {
                    context.beginPath();
                    context.moveTo(points[i].x, points[i].y);
                    context.lineTo(points[i + 1].x, points[i + 1].y);
                    context.setStrokeStyle(colors[ci]);
                    context.stroke();
                    context.closePath();

                    // interpolate point for the next iteration
                    points[i] = new Line(points[i], points[i + 1]).get(parameterValue);

                    // draw point                  
                    context.beginPath();
                    context.arc(points[i].x, points[i].y, 2, 0, 180);
                    context.setStrokeStyle("black");
                    context.stroke();
                    context.closePath();
                }
            }
        }
    } };
}