Changeset 66

Show
Ignore:
Timestamp:
04/21/07 11:14:43 (21 months ago)
Author:
steadicat
Message:

Refactoring my way towards object-orientation.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • hacks/trunk/canvas/default.js

    r65 r66  
    55var editing = null; 
    66 
    7  
    8 function mouseDown(event) { 
    9     var point = new Point(event.clientX, event.clientY); 
    10 } 
    11  
    12 function mouseMove(event) { 
    13     if (editing) moveDot(editing, event.clientX, event.clientY); 
    14 } 
    15  
    16 function mouseUp() { 
    17     editing = null; 
    18 } 
    19  
    20  
    21 function Point(x, y) { 
    22  
    23     var point = dot(x, y, 10); 
    24     point.g = document.createElementNS("http://www.w3.org/2000/svg", "g"); 
    25     addClass(point.g, "point"); 
    26  
    27     point.handle1 = createHandle(point); 
    28     point.handle2 = createHandle(point); 
    29  
    30     point.handle1.linkedHandle = point.handle2; 
    31     point.handle2.linkedHandle = point.handle1; 
    32  
    33     editing = point.handle2; 
    34  
    35     if (!curve) { 
    36         startCurve(point); 
    37     } else { 
    38         extendCurve(point); 
    39     } 
    40  
    41     $(point.g).append(point); 
    42     $(curve.g).append(point.g); 
     7Object.prototype.beget = function () { 
     8    function F() {} 
     9    F.prototype = this; 
     10    return new F(); 
     11}; 
     12 
     13function callback(instance, method) { 
     14    return function() { 
     15        method.apply(instance, arguments); 
     16    } 
    4317} 
    4418 
     
    6842 
    6943// a dot is either a point or a handle 
    70 function dot(x, y, size) { 
    71     var dot = document.createElementNS("http://www.w3.org/2000/svg", "circle"); 
    72     dot.cx.baseVal.value = x; 
    73     dot.cy.baseVal.value = y; 
    74     dot.r.baseVal.value = size/2; 
    75     $(dot).mousedown(function(event) { 
    76             event.stopPropagation(); 
    77             editing = dot; 
    78             addClass(dot, "editing"); 
    79  
    80             // alt unlinks two handles 
    81             if (event.altKey && dot.linkedHandle) { 
    82                 dot.linkedHandle.linkedHandle = null; 
    83                 dot.linkedHandle = null; 
    84             } 
    85         }); 
    86     $(dot).mouseup(function(event) { 
    87             editing = null; 
    88             removeClass(dot, "editing"); 
    89         }); 
    90     return dot; 
    91 } 
    92  
    93 function startCurve(point) { 
    94     curve = document.createElementNS("http://www.w3.org/2000/svg", "path"); 
    95     curve.g = document.createElementNS("http://www.w3.org/2000/svg", "g"); 
    96     addClass(curve, "stroke"); 
    97  
    98     point.curveTo = curve.createSVGPathSegMovetoAbs(point.cx.baseVal.value, point.cy.baseVal.value); 
    99     curve.pathSegList.appendItem(point.curveTo); 
    100     curve.start = point; 
    101     curve.end = point; 
    102  
    103     $(curve.g).append(curve); 
    104     $("#canvas").append(curve.g); 
    105 } 
    106  
    107 function extendCurve(point) { 
    108     point.curveTo = curve.createSVGPathSegCurvetoCubicAbs( 
    109                                                           point.cx.baseVal.value, 
    110                                                           point.cy.baseVal.value, 
    111                                                           curve.end.handle2.cx.baseVal.value, 
    112                                                           curve.end.handle2.cy.baseVal.value, 
    113                                                           point.handle1.cx.baseVal.value, 
    114                                                           point.handle1.cy.baseVal.value 
    115                                                           ); 
    116     curve.pathSegList.appendItem(point.curveTo); 
    117     point.handle1.leading = point; 
    118     curve.end.handle2.trailing = point; 
    119     curve.end = point; 
    120 } 
    121  
    122 function closeCurve() { 
    123     curve.pathSegList.appendItem(curve.createSVGPathSegClosePath()); 
    124     curve = null; 
    125 } 
    126  
    127 function endCurve() { 
    128     curve = null; 
    129 } 
    130  
    131 function createHandle(point) { 
    132     var handle = dot(point.cx.baseVal.value, point.cy.baseVal.value, 6); 
    133     addClass(handle, "handle"); 
    134     handle.point = point; 
    135     handle.line = document.createElementNS("http://www.w3.org/2000/svg", "path"); 
    136  
    137     handle.moveTo = handle.line.createSVGPathSegMovetoAbs(handle.cx.baseVal.value, handle.cy.baseVal.value); 
    138     handle.lineTo = handle.line.createSVGPathSegLinetoAbs(point.cx.baseVal.value, point.cy.baseVal.value); 
    139     handle.line.pathSegList.appendItem(handle.moveTo); 
    140     handle.line.pathSegList.appendItem(handle.lineTo); 
    141     $(point.g).append(handle.line); 
    142     $(point.g).append(handle); 
    143     return handle; 
    144 } 
    145  
    146  
    147  
    148 function moveDot(dot, x, y) { 
    149     if (dot.line) { 
    150         moveHandle(dot, x, y); 
     44function Dot(x, y, size) { 
     45    this.dot = document.createElementNS("http://www.w3.org/2000/svg", "circle"); 
     46    this.x(x); 
     47    this.y(y); 
     48    this.dot.r.baseVal.value = size/2; 
     49 
     50    $(this.dot).mousedown(callback(this, this.mouseDown)); 
     51    //this.dot.addEventListener("mouseup", this.mouseUp, false); 
     52} 
     53Dot.prototype.x = function(value) { 
     54    if (value) { 
     55        this.dot.cx.baseVal.value = value; 
    15156    } else { 
    152         movePoint(dot, x, y); 
    153     } 
    154 } 
    155  
    156 function movePoint(point, x, y) { 
    157     var dx = x - point.cx.baseVal.value; 
    158     var dy = y - point.cy.baseVal.value; 
     57        return this.dot.cx.baseVal.value; 
     58    } 
     59}; 
     60Dot.prototype.y = function(value) { 
     61    if (value) { 
     62        this.dot.cy.baseVal.value = value; 
     63    } else { 
     64        return this.dot.cy.baseVal.value; 
     65    } 
     66}; 
     67Dot.prototype.mouseDown = function(event) { 
     68    editing = this; 
     69    addClass(event.target, "editing"); 
     70    event.stopPropagation(); 
     71}; 
     72Dot.prototype.move = function(event) { 
     73    alert("abstract"); 
     74} 
     75 
     76Point.prototype = new Dot(); 
     77function Point(x, y) { 
     78    Dot.call(this, x, y, 10); 
     79 
     80    this.g = document.createElementNS("http://www.w3.org/2000/svg", "g"); 
     81    addClass(this.g, "point"); 
     82 
     83    this.handle1 = new Handle(this); 
     84    this.handle2 = new Handle(this); 
     85 
     86    this.handle1.linkedHandle = this.handle2; 
     87    this.handle2.linkedHandle = this.handle1; 
     88 
     89    editing = this.handle2; 
     90 
     91    if (!curve) { 
     92        curve = new Curve(this); 
     93    } else { 
     94        curve.extend(this); 
     95    } 
     96 
     97    $(this.g).append(this.dot); 
     98    $(curve.g).append(this.g); 
     99 
     100} 
     101Point.prototype.move = function(x, y) { 
     102    var dx = x - this.x(); 
     103    var dy = y - this.y(); 
    159104 
    160105    // move the point itself 
    161     point.cx.baseVal.value = x; 
    162     point.cy.baseVal.value = y; 
     106    this.x(x); 
     107    this.y(y); 
    163108 
    164109    // move associated handles 
    165     if (point.handle1) { 
    166         var hx = point.handle1.cx.baseVal.value+dx; 
    167         var hy = point.handle1.cy.baseVal.value+dy; 
    168         moveHandle(point.handle1, hx, hy, true); 
    169         var hx = point.handle2.cx.baseVal.value+dx; 
    170         var hy = point.handle2.cy.baseVal.value+dy; 
    171         moveHandle(point.handle2, hx, hy, true); 
     110    if (this.handle1) { 
     111        var hx = this.handle1.x()+dx; 
     112        var hy = this.handle1.y()+dy; 
     113        this.handle1.move(hx, hy, true); 
     114        var hx = this.handle2.x()+dx; 
     115        var hy = this.handle2.y()+dy; 
     116        this.handle2.move(hx, hy, true); 
    172117    } 
    173118 
    174119    // move curve 
    175     if (point.curveTo) { 
    176         point.curveTo.x = x; 
    177         point.curveTo.y = y; 
    178     } 
    179 } 
    180  
    181 function moveHandle(handle, x, y, stop) { 
    182  
    183     // move linked handle 
    184     if ((!stop) && handle.linkedHandle) { 
    185         var hx = handle.linkedHandle.cx.baseVal.value- (x-handle.cx.baseVal.value); 
    186         var hy = handle.linkedHandle.cy.baseVal.value- (y-handle.cy.baseVal.value); 
    187         moveHandle(handle.linkedHandle, hx, hy, true); 
     120    if (this.curveTo) { 
     121        this.curveTo.x = x; 
     122        this.curveTo.y = y; 
     123    } 
     124}; 
     125 
     126 
     127Handle.prototype = new Dot(); 
     128function Handle(point) { 
     129 
     130    Dot.call(this, point.x(), point.y(), 6); 
     131    addClass(this.dot, "handle"); 
     132    this.point = point; 
     133    this.line = document.createElementNS("http://www.w3.org/2000/svg", "path"); 
     134 
     135    this.moveTo = this.line.createSVGPathSegMovetoAbs(this.x(), this.y()); 
     136    this.lineTo = this.line.createSVGPathSegLinetoAbs(this.x(), this.y()); 
     137    this.line.pathSegList.appendItem(this.moveTo); 
     138    this.line.pathSegList.appendItem(this.lineTo); 
     139    $(point.g).append(this.line); 
     140    $(point.g).append(this.dot); 
     141 
     142} 
     143 
     144Handle.prototype.move = function(x, y, stop) { 
     145 
     146    // move linked this 
     147    if ((!stop) && this.linkedHandle) { 
     148        var hx = this.linkedHandle.x()- (x-this.x()); 
     149        var hy = this.linkedHandle.y()- (y-this.y()); 
     150        this.linkedHandle.move(hx, hy, true); 
    188151    } 
    189152 
    190153    // move the handle itself 
    191     handle.cx.baseVal.value = x; 
    192     handle.cy.baseVal.value = y; 
     154    this.x(x); 
     155    this.y(y); 
    193156 
    194157    // move associated line 
    195     handle.moveTo.x = x; 
    196     handle.moveTo.y = y; 
    197     handle.lineTo.x = handle.point.cx.baseVal.value; 
    198     handle.lineTo.y = handle.point.cy.baseVal.value; 
     158    this.moveTo.x = x; 
     159    this.moveTo.y = y; 
     160    this.lineTo.x = this.point.x(); 
     161    this.lineTo.y = this.point.y(); 
    199162 
    200163    // move curve 
    201     if (handle.leading) { 
    202         handle.leading.curveTo.x2 = x; 
    203         handle.leading.curveTo.y2 = y; 
    204     } else if (handle.trailing) { 
    205         handle.trailing.curveTo.x1 = x; 
    206         handle.trailing.curveTo.y1 = y; 
    207     } 
    208 } 
    209  
     164    if (this.leading) { 
     165        this.leading.curveTo.x2 = x; 
     166        this.leading.curveTo.y2 = y; 
     167    } else if (this.trailing) { 
     168        this.trailing.curveTo.x1 = x; 
     169        this.trailing.curveTo.y1 = y; 
     170    } 
     171}; 
     172Handle.prototype.mouseDown = function(event) { 
     173    Dot.prototype.mouseDown.call(this, event); 
     174 
     175    // alt unlinks two handles 
     176    if (event.altKey && dot.linkedHandle) { 
     177        this.linkedHandle.linkedHandle = null; 
     178        this.linkedHandle = null; 
     179    } 
     180}; 
     181 
     182 
     183function Curve(point) { 
     184 
     185    this.extend = function(point) { 
     186        point.curveTo = this.curve.createSVGPathSegCurvetoCubicAbs( 
     187                                                              point.x(), 
     188                                                              point.y(), 
     189                                                              this.end.handle2.x(), 
     190                                                              this.end.handle2.y(), 
     191                                                              point.handle1.x(), 
     192                                                              point.handle1.y() 
     193                                                              ); 
     194        this.curve.pathSegList.appendItem(point.curveTo); 
     195        point.handle1.leading = point; 
     196        this.end.handle2.trailing = point; 
     197        this.end = point; 
     198    } 
     199 
     200    this.close = function() { 
     201        this.curve.pathSegList.appendItem(this.curve.createSVGPathSegClosePath()); 
     202        curve = null; 
     203    } 
     204 
     205    this.cut = function() { 
     206        curve = null; 
     207    } 
     208 
     209    this.curve = document.createElementNS("http://www.w3.org/2000/svg", "path"); 
     210    this.g = document.createElementNS("http://www.w3.org/2000/svg", "g"); 
     211    addClass(this.curve, "stroke"); 
     212 
     213    point.curveTo = this.curve.createSVGPathSegMovetoAbs(point.x(), point.y()); 
     214    this.curve.pathSegList.appendItem(point.curveTo); 
     215    this.start = point; 
     216    this.end = point; 
     217 
     218    $(this.g).append(this.curve); 
     219    $("#canvas").append(this.g); 
     220} 
     221 
     222// global events 
     223 
     224function mouseDown(event) { 
     225    var point = new Point(event.clientX, event.clientY); 
     226} 
     227 
     228function mouseMove(event) { 
     229    if (editing) { 
     230        editing.move(event.clientX, event.clientY); 
     231    } 
     232} 
     233 
     234function mouseUp() { 
     235    removeClass(editing, "editing"); 
     236    editing = null; 
     237} 
    210238 
    211239// set up 
     
    215243        $(document).mouseup(mouseUp); 
    216244        $(document).keypress(function(event) { 
    217             if (event.keyCode == 27) endCurve(); 
    218             if (event.keyCode == 13) closeCurve(); 
     245            if (event.keyCode == 27) curve.cut(); 
     246            if (event.keyCode == 13) curve.close(); 
    219247        }); 
    220248    });