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...

  • Opinion? Here we go: Using only dots to display the lines does show the discretisation of the curve, not necessarily that it's parametric. Better ways to illustrate that there's a parameter could be to let the user pick any value for the parameter (with a slider for example, think Manipulate) or to use every possible value to draw a smooth continuous line (that is, discretize to the pixel level). A bunch of disconnected points can hardly be called a line. – null Sep 4 '15 at 12:21
  • Well spoken. My point in using dots is to illustrate that each location is calculated based on inputs, and that I'm not 'cheating' and using somebody else's functions. I think of curved lines as a form of mathematical regression analysis, similar to digital filtering in the audio world. – zipzit Sep 14 '15 at 22:02
  • What do you mean "somebody else's functions"? It's unclear to me how your comment relates to mine. My point was that it should be a connected line, not just a few dots with clearly visible gaps between them. Regression fits a continuous curve to points and in the realm of audio signal processing, sampling time is chosen in a way to make the discretion signal appear to be continuous. If you really think of curved lines like regression or audio filters than it should actually be a line and not unconnected dots. – null Sep 16 '15 at 17:12
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.

  • that's sort of where I was going. Is there any downside to using iframes? I have been looking at fabric.js, but for the goal of showing how something works, its largely unnecessary. I want to show the logic behind using a bezier curve, not simply to draw one. – zipzit Sep 3 '15 at 19:05
  • I just don't see what the benefit of using iframes would be here. It doesn't give you any more flexibility, and it complicates the page. – GrandmasterB Sep 3 '15 at 19:12
  • 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...) What I'm not sure is are there other downsides towards using iframe elements. (Potential Server issues? browser inconsistencies? Other weirdness?) aha...http://www.rwblackburn.com/2012/07/iframe-evil/ – zipzit Sep 3 '15 at 19:18
  • @zipzit If you want to "show the logic behind using a bezier curve", then why also show 3 other curves at the same time? Why present the user 4 different things if the goal is to understand each individual one? Are the 4 display areas linked in any way? For example, does changing the control points in one change them in the others, too? – null Sep 4 '15 at 12:33
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.

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...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.