1

Here's something I wrote ages ago as Java applet. I want to convert it into JavaScript and run in html5 canvas in the browser. From what I can see, canvas makes the most sense here. (SVG / DIV techniques aren't so friendly for what I want to do.) The canvas does allow for mouse drag and visual update, something you need to be able to understand the concepts displayed.

four java applets

Actually that is four separate applets. This doesn't translate perfectly well to canvas. I'm not sure the best way to make this update to JavaScript/Canvas. I think I have three choices:

  • One large canvas, divided into fourths. (The problem here is when you grab and drag the control elements there is nothing stopping that drag from hitting a neighboring technique. I could program internal boundaries, but where is the fun in that? This is my least favorite option.)
  • Four individual canvases (spelling?), each with its own #id.
  • four iframes with each canvas as a stand alone in its own html file. These would all be hosted at the same server.

Anybody got an opinion on best technique to proceed for displaying four functional graphic boxes (and why?) As I understand it, because I'm asking for an opinion, this question doesn't really fit over at stackoverflow...

zipzit
  • 119

3 Answers3

3

I think you'd be best with 4 canvas elements. That would give each its own context, and allow you to respond to mouse events on them more simply. Plus from the drawing perspective, you won't have to worry about clipping. iframes would be completely unnecessary here.

By the way, you may want to look into some Canvas based libraries like Fabric.js, as they may make interactions with the graphics easier to do.

GrandmasterB
  • 39,412
1

By all means, the best solution would be to use a canvas for each pane.

You noted in one of your comments:

Using iframes does reduce the coding workload a significant amount. You don't have to manage four different contexts. In fact you could code the boxes all the same way, with a flag element (flag = ellipse or bezier or bspline or nurb) (That was how the original applet was coded...)

But I don't see how using iframes would especially reduce the coding. More than likely you'd eventually code more if you used an iframe, you potentially could come to encounter painful issues due to the iframes.

Here's how you may approach resolving your issue, the code speaks for itself:

/**
 * Pane object is a map from ID to options specific to a pane.
 * The id will be used for each canvas element, and the options will determine
 * what will be drawn on a canvas.
 * @type object
 */
var pane = {
    "ellipse": {
        label: "Simple Straight Line & Ellipse Technique",
        degree: null,
        buttons: [{
                label: "Information",
                execute: function () {
                    // implementation of what happens when the 'Information'
                    // button on the ellipse canvas is clicked.
                }
            },
            {
                label: "Reset Frame",
                execute: function () {
                    // implementation of what happens when the 'Reset Frame'
                    // button on the ellipse canvas is clicked.
                }
            }]
    },
    "beizer": {
        label: "Beizer Technique",
        degree: null,
        buttons: [/* You have a pattern to follow above */]
    },
    "b-spine": {
        label: "B-Spine Technique with ...",
        degree: 3,
        buttons: [/* You have a pattern to follow above */]
    },
    "nurbs": {
        label: "NURBS with uniform ...",
        degree: 3,
        buttons: [/* You have a pattern to follow above */]
    }
};

// Extract the IDs for each canvas, and call `draw` for each one of them.
Object.keys(pane).forEach(draw);

/**
 * Draws on the canvas with the given id.
 * @param {string} id ID of a canvas element
 * @returns {undefined}
 */
function draw(id) {
    var option, canvas, context;

    option = pane[id];
    canvas = document.getElementById(id);

    // Now you are ready to implement your drawing,
    context = canvas.getContext("2d");
    // if you wanted the label you can have it from `option.label`.
    // The rest is up to your imagination...
}

Based on the option associated with each pane, you may branch to a special drawing logic.

Igwe Kalu
  • 103
0

Ouch. It turns out because of a significant problem not previously mentioned (or even understood at the time of the original posting) it was WAY easier to go with four iframes.

Note that a significant portion of the display is common to all, and would have to be re-created four times.

The problem issue was a help oriented text screen that would over-write the canvas. From what I can see Canvas and text divs can't occupy the same space in time. for whatever reason, Canvas elements alway bleed thru the div including background images, etc... I ended up using jQuery to show and hide different elements. When you add up overlaps, the four canvas elements on a single page got way ugly.

Additionally, I had a heck of a time with CSS and multiple canvas elements. Its fine if you have a fixed size screen, floating elements, no so much. I know iframes are "bad".. so be it.

using iframes made the job way easier..

    <div class="container">
        <iframe src="./bezier_curve.html?lineType=Simple"></iframe>
        <iframe src="./bezier_curve.html?lineType=Bezier"></iframe>
    </div>
    <div style="clear: both;"></div>
    <div class="container">
        <iframe src="./bezier_curve.html?lineType=BSpline"></iframe>
        <iframe src="./bezier_curve.html?lineType=NURB"></iframe>
    </div>
    <div style="clear: both;"></div>

ref: How to pass a URL parameter...

zipzit
  • 119