1 2 /** 3 * @name CeL SVG function 4 * @fileoverview 5 * 本檔案包含了 SVG 的 functions。 6 * @since 7 */ 8 9 10 /* 11 TODO 12 對無顯示 SVG 的多一項警告。 13 14 ASCIIsvg.js 15 http://www1.chapman.edu/~jipsen/svg/asciisvg.html 16 */ 17 18 if (typeof CeL === 'function') 19 CeL.setup_module('interact.integrate.SVG', 20 { 21 require : 'interact.DOM.XML_node|interact.DOM.set_attribute|interact.DOM.remove_all_child|interact.DOM.set_class|data.split_String_to_Object', 22 code : function(library_namespace, load_arguments) { 23 24 // requiring 25 var XML_node,set_attribute,remove_all_child,set_class,split_String_to_Object; 26 eval(library_namespace.use_function(this)); 27 28 29 // ============================================================================ 30 // definition of module SVG 31 32 /* 33 34 TODO: 35 animation 36 .add_image 37 */ 38 39 // in 運算子會檢查物件是否有名稱為 property 的屬性。它也會檢查物件的原型,查看 property 是否屬於原型鏈結的一部分。如果 property 是在物件或原型鏈結中,則 in 運算子會傳回 true,否則會傳回 false。 http://msdn2.microsoft.com/zh-tw/library/11e33275(VS.80).aspx 40 41 //g_SVG[generateCode.dLK]='set_attribute,XML_node,remove_all_child';//removeNode 42 43 /** 44 * module SVG 物件之 constructor。<br/> 45 * 設定 SVG document fragment 並將之插入網頁中。 46 47 * @class generation of Scalable Vector Graphics<br/> 48 * 輔助繪圖的基本功能物件,生成 SVG 操作函數。 49 * @since 2006/12/7,10-12 50 * @deprecated Use toolkit listed below instead:<br/> 51 * <a href="http://code.google.com/p/svgweb/" accessdate="2009/11/15 16:34" title="svgweb - Project Hosting on Google Code">svgweb</a><br/> 52 * <a href="https://launchpad.net/scour" accessdate="2009/11/15 16:35" title="Scour - Cleaning SVG Files in Launchpad">Scour</a> 53 54 * @constructor 55 * @param {int} _width width of the canvas 56 * @param {int} _height height of the canvas 57 * @param {color String} [_backgroundColor] background color of the canvas (UNDO) 58 * @requires set_attribute,XML_node,remove_all_child//removeNode 59 * @type CeL.interact.integrate.SVG 60 * @return {CeL.interact.integrate.SVG} CeL.interact.integrate.SVG object created 61 62 * @see <a href="http://www.w3.org/TR/SVG/" accessdate="2009/11/15 16:31">Scalable Vector Graphics (SVG) 1.1 Specification</a><br/> 63 * <a href="http://zvon.org/xxl/svgReference/Output/" accessdate="2009/11/15 16:31">SVG 1.1 reference with examples</a><br/> 64 * <a href="http://www.permadi.com/tutorial/jsFunc/index.html" accessdate="2009/11/15 16:31" title="Introduction and Features of JavaScript "Function" Objects">Introduction and Features of JavaScript "Function" Objects</a><br/> 65 * <a href="http://volity.org/wiki/index.cgi?SVG_Script_Tricks" accessdate="2009/11/15 16:31">Volity Wiki: SVG Script Tricks</a><br/> 66 * <a href="http://pilat.free.fr/english/routines/js_dom.htm" accessdate="2009/11/15 16:31">Javascript SVG et DOM</a> 67 */ 68 CeL.interact.integrate.SVG 69 = function(_width, _height, _backgroundColor){ 70 var _f = _, _s; 71 /* 72 if(!_f.createENS()){ 73 //alert('Your browser doesn't support SVG!'); 74 return; 75 } 76 */ 77 78 /** 79 * SVG document fragment 80 * @property 81 * @see <a href="http://www.w3.org/TR/SVG/struct.html#NewDocument" accessdate="2009/11/15 16:53">Defining an SVG document fragment: the 'svg' element</a> 82 */ 83 this.svg=_s= // raw 84 arguments.length===1 && arguments[0] && typeof arguments[0]==='object' && arguments[0].tagName.toLowerCase()==='svg' 85 ?arguments[0] 86 :_f.createNode('svg') 87 ; 88 if(!_s)return; // error! 89 90 // http://www.w3.org/TR/SVG/struct.html#DefsElement http://www.svgbasics.com/defs.html 91 _s.appendChild(this.defs=_f.createNode('defs')); // raw 92 93 // 調整大小 94 this.setSize(_width,_height); 95 // set_attribute(_s,{xmlns:_f.NS.SVG}); 96 set_attribute(_s,{xmlns:'http://www.w3.org/2000/svg'}); 97 // may cause error! should use .setAttributeNS()?? 98 _s.setAttribute('xmlns:xlink','http://www.w3.org/1999/xlink'); 99 //viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" 100 101 /** 102 * 包含了插入元件的原始資訊。<br/> 103 * Use {@link #addContain} to add contains. 104 * @property 105 * @type Array 106 */ 107 this.contains = []; 108 /** 109 * 所插入之網頁元素 110 * @property 111 */ 112 this.div = null; 113 114 //document.body.appendChild(this.svg); 115 return this;//return this.createNode(_nodeN); 116 }; 117 //_.NS={SVG:'http://www.w3.org/2000/svg',XLink:'http://www.w3.org/1999/xlink'}; 118 _.defaultColor = '#222'; 119 120 CeL.interact.integrate.SVG 121 . 122 /** 123 * default stroke width. 單位: px 124 * 125 * @unit px 126 * @type Number 127 * @memberOf CeL.interact.integrate.SVG 128 */ 129 defaultStrokeWidth = .5; 130 131 //_.defaultColor='#444';_.defaultStrokeWidth=1; 132 133 CeL.interact.integrate.SVG 134 . 135 /** 136 * 所有造出 id 之 prefix 137 * @type string 138 * @memberOf CeL.interact.integrate.SVG 139 */ 140 idPrefix = 141 // +'_SVG_'; 142 library_namespace.to_module_name(this.module_name) + '.'; 143 144 // _.bout closure. 145 //_.createENS=document.createElementNS?function(){return document.createElementNS(arguments[0],arguments[1]);}:null; 146 CeL.interact.integrate.SVG 147 . 148 /** 149 * create SVG document fragment (only for .createNode) 150 * @param _ns namespaceURI 151 * @param _qn qualifiedName 152 * @param _a propertyA 153 * @param _i innerObj 154 * @return 155 * @memberOf CeL.interact.integrate.SVG 156 * @function 157 * @private 158 */ 159 createENS = function(_ns, _qn, _a, _i) { 160 return ( 161 // document.createElementNS?XML_node(_ns+':'+_qn,_a,0,_i):null; 162 XML_node(_ns + ':' + _qn, _a, 0, _i)); 163 }; 164 165 CeL.interact.integrate.SVG 166 . 167 /** 168 * create SVG document fragment 元件(component)。<br/> 169 * SVG 之 document fragment 與 HTML 不同 namespace,因此我們需要使用到 <a href="http://www.w3.org/2000/svg">http://www.w3.org/2000/svg</a> 來作為 XML elements 的 namespace。為了未來的兼容性,我們將這個功能獨立出來。 170 * @param _nodeN node/tag name 171 * @param {hash|string}_a attribute/property 172 * @param _i inner object 173 * @return node created or null 174 * @memberOf CeL.interact.integrate.SVG 175 * @private 176 * @function 177 */ 178 createNode = function(_nodeN,_a,_i){ 179 //return this.createENS?this.createENS('svg',_nodeN||'svg'):null; 180 return _.createENS('svg', _nodeN || 'svg', _a, _i); 181 182 // Error: uncaught exception: [Exception... "Illegal operation on WrappedNative prototype object" nsresult: "0x8057000c (NS_ERROR_XPC_BAD_OP_ON_WN_PROTO)" location: "JS frame :: file:///C:/kanashimi/www/cgi-bin/program/tmp/JavaScript%20Framework/dojo/dojo-0.4.0-ajax/a.htm :: anonymous :: line 29" data: no] 183 // http://www.codingforums.com/archive/index.php?t-94573.html When you do var x = document.getElementById and then x('hello') you are executing the function x in the context of the window object instead of the document object. Gecko probably utilizes the scoping of the document object to access some internal methods to execute getElementById, which the window object doesn't have. 184 // http://developer.mozilla.org/en/docs/Safely_accessing_content_DOM_from_chrome http://developer.mozilla.org/en/docs/Working_around_the_Firefox_1.0.3_DHTML_regression http://www.codingforums.com/archive/index.php?t-68554.html 185 // OK? 186 //return this.createENS?this.createENS.call(document,'svg',_nodeN||'svg'):null; 187 // fault: 188 //return this.createENS===document.createElementNS?document.createElementNS('svg',_nodeN||'svg'):this.createENS?this.createENS('svg',_nodeN||'svg'):null; 189 //return this.createENS?(alert(this.createENS===document.createElementNS),Function.apply(this.createENS,['svg',(_nodeN||'svg')])):null; 190 //return this.createENS?(alert(this.createENS===document.createElementNS),this.createENS.apply(document.createElementNS,['svg',(_nodeN||'svg')])):null; 191 }; 192 /* 193 _.createLink=function(_ref){ 194 return this.createENS('xLink','xlink:href'); 195 }; 196 */ 197 198 CeL.interact.integrate.SVG 199 . 200 /** 201 * 從 id 獲得 node 202 * @param id id 203 * @return node 204 * @memberOf CeL.interact.integrate.SVG 205 * @private 206 */ 207 getNodeById = function(id) { 208 // return this.svg.getElementById(_i);//useless? 209 210 // lookupPrefix() 211 return document.getElementById(id); 212 }; 213 214 CeL.interact.integrate.SVG 215 . 216 /** 217 * get a random ID to use. 218 * @param tag tag name(nodeType) 219 * @return a random ID 220 * @memberOf CeL.interact.integrate.SVG 221 * @private 222 */ 223 getRandomID = function(tag) { 224 if (typeof tag === 'object') 225 tag = tag.tagName/* nodeType */; 226 var _j; 227 while (_.getNodeById(_j = _.idPrefix + tag + '_' 228 + ('' + Math.random()).slice(2, 6))) 229 ; 230 return _j; 231 }; 232 CeL.interact.integrate.SVG 233 . 234 /** 235 * give a random ID to the specified node. 236 * @param _n node 237 * @return id of the specified node 238 * @memberOf CeL.interact.integrate.SVG 239 * @private 240 */ 241 setRandomID = function(_n) { 242 if (_n && typeof _n === 'object') { 243 /** 244 * id of the specified node 245 * @inner 246 * @ignore 247 */ 248 var _i = set_attribute(_n, 'id'); 249 if (!_i) 250 set_attribute(_n, { 251 id : _i = _.getRandomID(_n) 252 }); 253 return _i; 254 } 255 }; 256 257 CeL.interact.integrate.SVG 258 . 259 /** 260 * 改變 text 261 * @param text_node text object 262 * @param text change to this text 263 * @return 264 * @memberOf CeL.interact.integrate.SVG 265 * @see 266 * <a href="http://www.w3.org/TR/SVG/text.html" accessdate="2009/12/15 0:2">Text - SVG 1.1 - 20030114</a> 267 * <tref xlink:href="#ReferencedText"/> 268 */ 269 changeText = function(text_node, text) { 270 //if (typeof remove_all_child === 'function') 271 // remove_all_child(text_node); 272 //else throw new Error(1, 'changeText: function remove_all_child is not included!'); 273 remove_all_child(text_node); 274 275 if (text) 276 text_node.appendChild(document.createTextNode(text)); 277 //else removeNode(_textO); 278 }; 279 280 CeL.interact.integrate.SVG 281 . 282 addTitle = function(_o, _t_d) { 283 if (_t) 284 _o.appendChild(this.createNode('title', 0, _t)); 285 // A more descriptive label should be put in a <desc> child element 286 if (_t) 287 _o.appendChild(this.createNode('desc', 0, _t)); 288 }; 289 290 291 /* transform http://www.w3.org/TR/SVG/coords.html#TransformAttribute http://archive.dojotoolkit.org/nightly/tests/gfx/test_image.html 292 recommend for performance reasons to use transformation matrices whenever possible. http://www.mecxpert.de/svg/transform.html 293 * @memberOf module SVG 294 */ 295 CeL.interact.integrate.SVG 296 . 297 setTransform = function(_o, _t) { 298 // TODO 299 throw new Error(1, 'setTransform: yet implement!'); 300 set_attribute(_o, { 301 transform : _t 302 }); 303 }; 304 305 // ============================================================================ 306 // definition of module SVG object 307 308 _.prototype={ 309 310 /** 311 * 顯現 this module SVG object 312 * @param _v visible 313 * @return this module SVG object 314 * @memberOf CeL.interact.integrate.SVG 315 */ 316 show : function(_v) { 317 var _d = this.div; 318 if (this.svg) 319 if (_d) {// _s.parentNode 320 _d.style.display = typeof _v == 'undefined' ? _d.style.display === 'none' ? 'block' 321 : 'none' 322 : _v ? 'block' : 'none'; // block怪怪的 323 } else if (_v || typeof _v == 'undefined') 324 this.div = XML_node('div', 0, [ document.body ], 325 this.svg); 326 return this; 327 }, 328 setAttribute : function() { 329 this.svg && this.svg.setAttribute(arguments); 330 return this; 331 }, 332 //setDimensions 333 /** 334 * 調整 canvas 大小 335 * @unit px 336 * @param {Integer} _width width in px 337 * @param {Integer} _height height in px 338 * @return this module SVG object 339 * @memberOf CeL.interact.integrate.SVG 340 */ 341 setSize : function(_width, _height) { 342 _width = parseInt(_width) || 0; 343 _height = parseInt(_height) || 0; 344 345 if (_width > 0 && _height > 0) 346 set_attribute(this.svg, { 347 width : _width, 348 height : _height 349 }); 350 351 return this; 352 }, 353 getSize : function() { 354 return set_attribute(this.svg, 'width,height'); 355 }, 356 357 /** 358 * 將本 Object 附在 _n 上(attach to node) 359 * @param _n HTML/SVG object 360 * @return 361 */ 362 attach : function(_n) { 363 if (typeof _n === 'string') 364 _n = _.getNodeById(_n); 365 366 if (!_n) 367 return this; 368 369 var _t = _n.tagName.toLowerCase(); 370 if (_t === 'svg') 371 // TODO: 若不想創建新 node.. 372 return new _(_n); 373 374 if (_t === 'div') { 375 //if(this.div){TODO: 原先已經 attach} 376 this.div = _n; 377 _n.appendChild(this.svg); 378 } 379 380 return this; 381 }, 382 383 get_XML : function() { 384 var _t = document.createElement('div'), _x, _s = this.svg; 385 386 if (!_s) 387 // error! 388 return; 389 390 // TODO: 效率不高! 391 _t.appendChild(_s = _s.cloneNode(true)); 392 _x = _t.innerHTML; 393 _t.removeChild(_s); 394 // 確保在此環境下 create 出來的會被 destory 395 _t = null; 396 // ugly hack 397 // <?xml version="1.0" encoding="UTF-8" standalone="no"?> 398 _x = _x.replace(/(\s)(href=['"])/g, '$1xlink:$2'); 399 400 return _x; 401 }, 402 403 /** 404 * 清除 canvas<br/> 405 * 很可能會出問題! 406 * @return this SVG 407 * @memberOf CeL.interact.integrate.SVG 408 * @since 2009/12/18 21:17:09 409 */ 410 clean : function() { 411 var s = this.svg; 412 // [0]: <defs> 413 while (s.childNodes.length > 1) 414 //library_namespace.debug(s.childNodes.length + ',' + s.lastChild), 415 s.removeChild(s.lastChild); 416 417 // remove childrens of <defs> 418 //remove_all_child(s.lastChild, 1); 419 s = s.lastChild; 420 while (s.hasChildNodes()) 421 //library_namespace.debug(s.childNodes.length + ',' + s.lastChild), 422 s.removeChild(s.lastChild); 423 424 return this; 425 }, 426 427 /** 428 * 創建本物件之 SVG 群組。<br/> 429 * 利用 SVG 群組我們可以同時操作多個 SVG elements。 430 * @param {hash|string}_a attribute/property 431 * @param _i inner object 432 * @return this SVG 433 * @memberOf CeL.interact.integrate.SVG 434 */ 435 createGroup : function(_a, _i) { 436 var _g = _.createNode('g', _a, _i); 437 this.group = _g; 438 return this; 439 }, 440 /** 441 * 綁定 SVG elements 至本物件群組。<br/> 442 * 這函數將已存在的 SVG elements 綁定至本物件之群組中。若群組不存在,則創建出一個。 443 * @param _n node 444 * @return this module SVG object 445 * @memberOf CeL.interact.integrate.SVG 446 */ 447 attachGroup : function(_n) { 448 if (!this.group) 449 this.createGroup(); 450 this.group.appendChild(_n); 451 return this; 452 }, 453 454 createSymbol : function(_a, _i) { 455 var _s = _.createNode('symbol', _a, _i); 456 this.symbol = _s; 457 return this; 458 }, 459 attachSymbol : function(_n) { 460 if (!this.symbol) 461 this.createSymbol(); 462 this.symbol.appendChild(_n); 463 return this; 464 }, 465 466 // TODO 467 setFill:function(){throw new Error(1,'setFill: yet implement!');}, 468 setStroke:function(){throw new Error(1,'setStroke: yet implement!');}, 469 setShape:function(){throw new Error(1,'setShape: yet implement!');}, 470 setTransform:function(){throw new Error(1,'setTransform: yet implement!');}, 471 472 //<animateMotion>,<animateColor> 473 474 /** 475 * 最後一個增加的 instance 476 * @memberOf CeL.interact.integrate.SVG 477 */ 478 lastAdd: null, 479 /** 480 * 最後一個增加的 definition 481 * @memberOf CeL.interact.integrate.SVG 482 */ 483 lastAddDefs: null, 484 /** 485 * 增加 SVG element。<br/> 486 * 結合 .prototype.addDefs 與 .prototype.addUse,作完定義後隨即使用之。 487 * @param _n tagName(nodeType) 488 * @param {hash|string} _a attribute/property 489 * @param _i inner object 490 * @return 491 * @memberOf CeL.interact.integrate.SVG 492 */ 493 addNode : function(_n, _a, _i) { 494 if (typeof _n == 'string') 495 _n = _.createNode(_n, _a, _i); 496 if (_n) { 497 this.addDefs(_n); 498 this.addUse(_n); 499 } 500 return this; 501 }, 502 503 /** 504 * 增加 SVG 定義。<br/> 505 * SVG 規範中聲明,SVG 的 <use> element 不能引用外部文件或其 elements。因此我們在創建實例之前,需要先在本物件中作定義。 506 * @param _n node 507 * @return 508 * @memberOf CeL.interact.integrate.SVG 509 */ 510 addDefs : function(_n) { 511 // var _d=this.defs; 512 if (_n) { 513 _.setRandomID(_n); 514 this.defs.appendChild(this.lastAddDefs = _n); 515 } 516 return this; 517 }, 518 /** 519 * 增加 SVG 實例。<br/> 520 * 利用本物件中之定義創建實例並增添至本物件中。<br/> 521 * 在裝載 b.svg 時,將 a.svg 中的 defs 中的圖元裝載到 b.svg 中(文件上是兩者是保持獨立的,但在內存中將二者合二為一),這樣就可以在b.svg中直接引用這些圖元了。<br/> 522 * SVG 規範中聲明,SVG 的 <use> element 不能引用外部文件或其 elements。因此我們在創建實例之前,需要先在本物件中作定義。 523 * @param _i id 524 * @param _a 525 * @return 526 * @memberOf CeL.interact.integrate.SVG 527 */ 528 addUse : function(_i, _a) { 529 var _s = this.svg, _o = _.createNode('use', _a); 530 if (_o && _s && _i) { 531 if (typeof _i == 'object') 532 _i = _.setRandomID(_i); 533 set_attribute(_o, { 534 'xlink:href' : '#' + _i 535 }); 536 _s.appendChild(this.lastAdd = _o); 537 } 538 return this; 539 }, 540 541 /** 542 * 增加插入的元件。<br/> 543 * 應該用 <a href="http://www.w3.org/TR/SVG/struct.html#SymbolElement">symbol</a> 544 * @param _o object reference 545 * @param _type type of this component 546 * @param [propertyO] other properties 547 * @return 548 * @requires split_String_to_Object 549 * @memberOf CeL.interact.integrate.SVG 550 */ 551 addContain : function(_o, _type, propertyO) { 552 if (_type && this.contains) { 553 if (typeof propertyO === 'string') 554 propertyO = split_String_to_Object(propertyO); 555 if (propertyO.o || propertyO.t) 556 this.contains.push( { 557 o : _o, 558 t : _type, 559 p : propertyO 560 }); 561 else 562 propertyO.o = _o, propertyO.t = _type, this.contains 563 .push(propertyO); 564 } 565 return this; 566 }, 567 568 569 /** 570 * 繪製直線。<br/> 571 * 此函數利用 _.eNode 造出直線元件之後,再用 .prototype.addNode 將之插入本物件中。 572 * @param _left 573 * @param _top 574 * @param _width 575 * @param _height 576 * @param _color 577 * @param _strokeWidth 578 * @return 579 * @memberOf CeL.interact.integrate.SVG 580 */ 581 addLine : function(_left, _top, _width, _height, _color, 582 _strokeWidth) { 583 var _l = _.createNode('line', { 584 x1 : _top, 585 y1 : _left, 586 x2 : _top + _width, 587 y2 : _left + _height, 588 stroke : _color || this.addLine.defaultColor, 589 'stroke-width' : _strokeWidth || _.defaultStrokeWidth 590 }); 591 if (_l && this.svg) { 592 //this.svg.appendChild(_l); 593 this.addNode(_l); 594 } 595 return this; 596 }, 597 598 599 /** 600 * 繪製曲線路徑。<br/> 601 * 此函數利用 _.eNode 造出路徑元件之後再用 .prototype.addNode 將之插入本物件中。 602 * @param _d 603 * @param _color 604 * @param _strokeWidth 605 * @param _fill 606 * @return 607 * @memberOf CeL.interact.integrate.SVG 608 */ 609 addPath : function(_d, _color, _strokeWidth, _fill) { 610 var _p = _.createNode('path', { 611 d : _d, 612 stroke : _color || this.addLine.defaultColor, 613 'stroke-width' : _strokeWidth || _.defaultStrokeWidth, 614 fill : _fill || 'none' 615 }); 616 if (_p && this.svg) 617 this.addNode(_p); 618 return this; 619 }, 620 621 622 //xml:space="default|preserve" 623 /** 624 * 添加文字。<br/> 625 * 此函數利用 _.eNode 造出文字元件之後再用 .prototype.addNode 將之插入本物件中。 626 * @param _text 627 * @param _left 628 * @param _baseLine 629 * @param _color 630 * @param _font 631 * @return 632 * @memberOf CeL.interact.integrate.SVG 633 */ 634 addText : function(_text,_left,_baseLine,_color,_font){ 635 if (_color) 636 this.addText.defaultColor = _color; 637 else 638 _color = this.addText.defaultColor; 639 640 if (_font) 641 this.addText.defaultFont = _font; 642 else 643 _font = this.addText.defaultFont; 644 645 // http://www.w3.org/TR/SVG/text.html <tref xlink:href="#ReferencedText"/> 646 //var _o=document.createTextNode(_text); 647 //var _o=_.createNode('tspan',{x:_left,y:_baseLine,stroke:_color||this.addText.defaultColor,style:_font?'font-family:"'+_font+'"':null},_text); 648 //this.addNode(_.createNode('text',{x:_left,y:_baseLine,stroke:_color||this.addText.defaultColor,style:_font?'font-family:"'+_font+'"':null},_o)); 649 //this.lastAdd=_o; 650 651 // ugly hack: 說是_baseLine,其實還是會再往下一點點。 652 _baseLine -= 2; 653 this.addNode(_.createNode('text', { 654 x : _left, 655 y : _baseLine, 656 stroke : _color || this.addText.defaultColor, 657 style : _font ? 'font-family:"' + _font + '"' : null 658 }, _text)); 659 //(text|g).pointer-events="none": Make text unselectable 660 661 /* 本法為標準,但FF尚未支援。 662 var _s=this.svg,_i=_.getRandomID('text')_.SVG.createNode('text',{id:_i},_text); 663 this.addDefs(this.lastAddDefs=_o); 664 _o=_.createNode('text',{x:_left,y:_baseLine,stroke:_color||this.addText.defaultColor,style:_font?'font-family:"'+_font+'"':null},0,_t=_.createNode('tref')); 665 _t.setAttributeNS('xLink','xlink:href','#'+_i); 666 _o.appendChild(_t); 667 _s.appendChild(this.lastAdd=_o); 668 */ 669 670 return this; 671 }, 672 673 /** 674 * add numbers 675 * @param _text 676 * @param _left 677 * @param _baseLine 678 * @param _tW 679 * @param _color 680 * @param _font 681 * @return 682 * @see 683 * _left: http://www.w3.org/TR/SVG/text.html#TSpanElementXAttribute 684 */ 685 addNum : function(_text, _left, _baseLine, _tW, _color, _font) { 686 if (!isNaN(_text)) { 687 // 說是_baseLine,其實還是會再往下一點點。 688 _baseLine -= 2; 689 //_text=''+_text; 690 _text += ''; 691 692 var _o = [], _i = 0, _s = this.svg; 693 for (; _i < _text.length; _i++) 694 // _text.split('') 695 _o.push(_.createNode('tspan', { 696 x : _left + _i * _tW 697 //, y:_baseLine 698 }, _text.charAt(_i))); 699 700 if (_s) 701 _s.appendChild(this.lastAdd = _.createNode('text', { 702 y : _baseLine, 703 stroke : _color || this.addText.defaultColor, 704 style : _font ? 'font-family:"' + _font + '"' 705 : null 706 }, _o)); 707 } 708 return this; 709 }, 710 711 712 /** 713 * add parallel graph 714 * @param _ds 715 * @param _h 716 * @param _d 717 * @param _us 718 * @param tramA 719 * @return 720 * @since 2006/12/18 0:35 721 */ 722 addParallelG : function(_ds, _h, _d, _us, tramA) { 723 if (_ds && _h) { 724 if (isNaN(_us) || _us === '') 725 _us = _ds; 726 set_attribute(this 727 .addPath('M' + _ds + ',' + _h + ' H0 L' + (_d || 0) 728 + ',0' + (_us ? ' h' + _us : '') + ' z'), { 729 transform : tramA 730 }); // 0=='' 731 } 732 return this; 733 }, 734 735 lastQuadrilateral : null, 736 lastQuadrilateralDefs : null, 737 /** 738 * 畫簡單長方形或平行四邊形、梯形 739 * @param _ds 740 * @param _h 741 * @param _d 742 * @param _us 743 * @param tramA 744 * @return 745 * @see <a href="http://zh.wikipedia.org/wiki/%E5%B9%B3%E8%A1%8C%E5%9B%9B%E8%BE%B9%E5%BD%A2">平行四邊形</a> 746 * @memberOf CeL.interact.integrate.SVG 747 */ 748 addQuadrilateral:function(_ds,_h,_d,_us,tramA){ // down side,height,upper distance,upper side 749 this.addParallelG(_ds,_h,_d,_us,tramA).addContain(this.lastQuadrilateralDefs=this.lastAddDefs,'quadrilateral',{down_side:_ds,hight:_h,distance:_d,upper_side:_us}); 750 this.lastQuadrilateral=this.lastAdd; // set_attribute(s.lastQuadrilateral,'fill=none'); 751 return this; 752 }, 753 754 lastTriangle : null, 755 lastTriangleDefs : null, 756 /** 757 * 畫簡單三角形 758 * @since 2006/12/17 12:38 759 * @param _ds 760 * @param _h 761 * @param _d 762 * @param tramA 763 * @return 764 * @memberOf CeL.interact.integrate.SVG 765 */ 766 addTriangle : function(_ds, _h, _d, tramA) { 767 this.addParallelG(_ds, _h, _d, 0, tramA).addContain( 768 this.lastTriangleDefs = this.lastAddDefs, 'triangle', { 769 down_side : _ds, 770 hight : _h, 771 distance : _d 772 }); 773 this.lastTriangle = this.lastAdd; 774 return this; 775 }, 776 777 778 /** 779 * 繪製橢圓曲線。<br/> 780 * 此函數利用 _.eNode 造出橢圓曲線元件之後,再用 .prototype.addNode 將之插入本物件中。 781 * @param _rx 782 * @param _ry 783 * @param _cx 784 * @param _cy 785 * @param _color 786 * @param _strokeWidth 787 * @param _fill 788 * @param tramA 789 * @return 790 * @memberOf CeL.interact.integrate.SVG 791 */ 792 addEllipsePath : function(_rx, _ry, _cx, _cy, _color, _strokeWidth, 793 _fill, tramA) { 794 if (_rx) { 795 var _e, _p = { 796 rx : _rx, 797 ry : _ry, 798 cx : _cx, 799 cy : _cy, 800 stroke : _color || this.addEllipsePath.defaultColor, 801 'stroke-width' : _strokeWidth || _.defaultStrokeWidth, 802 fill : _fill || 'none', 803 transform : tramA 804 }; 805 806 if (!_ry) 807 _e = 'circle', _p.r = _rx; 808 else 809 _e = 'ellipse', _p.rx = _rx, _p.ry = _ry; 810 811 _e = _.createNode(_e, _p); 812 813 if (_e && this.svg) 814 this.addNode(_e); 815 } 816 return this; 817 }, 818 819 820 lastCircle : null, 821 lastCircleDefs : null, 822 /** 823 * 繪製圓形。<br/> 824 * 此函數利用 _.type.addEllipsePath 來畫簡單圓形。 825 * @param _r 826 * @param _cx 827 * @param _cy 828 * @return 829 * @memberOf CeL.interact.integrate.SVG 830 */ 831 addCircle : function(_r, _cx, _cy) { 832 if (_r) 833 this.addEllipsePath(_r, '', _cx, _cy).addContain( 834 this.lastCircleDefs = this.lastAddDefs, 'circle', { 835 r : _r 836 }); 837 return this; 838 }, 839 840 lastEllipse : null, 841 lastEllipseDefs : null, 842 /** 843 * 繪製簡單圓形/橢圓。<br/> 844 * 此函數利用 .prototype.addEllipsePath 來畫簡單橢圓。 845 * @param _rx 846 * @param _ry 847 * @param _cx 848 * @param _cy 849 * @return 850 * @memberOf CeL.interact.integrate.SVG 851 */ 852 addEllipse : function(_rx, _ry, _cx, _cy) { 853 if (_rx) { 854 this.addEllipsePath(_rx, _ry, _cx, _cy).addContain( 855 this.lastEllipseDefs = this.lastAddDefs, 'ellipse', 856 { 857 rx : _rx, 858 ry : _ry 859 }); 860 this.lastEllipse = this.lastAdd; 861 } 862 return this; 863 }, 864 865 866 /** 867 * 繪製矩形。<br/> 868 * 此函數利用 _.eNode 造出矩形路徑元件之後,再用 .prototype.addNode 將之插入本物件中。 869 * @param _w 870 * @param _h 871 * @param _x 872 * @param _y 873 * @param _color 874 * @param _strokeWidth 875 * @param _fill 876 * @param tramA 877 * @return 878 * @memberOf CeL.interact.integrate.SVG 879 */ 880 addRect : function(_w, _h, _x, _y, _color, _strokeWidth, _fill, 881 tramA) { 882 this.addNode(_.createNode('rect', { 883 width : _w, 884 height : _h, 885 x : _x, 886 y : _y, 887 stroke : _color || this.addRect.defaultColor, 888 'stroke-width' : _strokeWidth || _.defaultStrokeWidth, 889 fill : _fill || 'none', 890 transform : tramA 891 })); 892 return this; 893 }, 894 895 896 /** 897 * 繪製多邊形。<br/> 898 * 此函數利用 _.eNode 造出多邊形路徑元件之後再用 .prototype.addNode 將之插入本物件中。 899 * @param {int array} _pA [x1,y1,x2,y2,x3,y3,..] 900 * @param _color 901 * @param _strokeWidth 902 * @param _fill 903 * @param tramA 904 * @return 905 * @memberOf CeL.interact.integrate.SVG 906 */ 907 addPolyline : function(_pA, _color, _strokeWidth, _fill, tramA) { 908 var _i = 0, _p = []; 909 while (_i < _pA.length) 910 _p.push(_pA[_i++] + ',' + _pA[_i++]); 911 this.addNode(_.createNode('polyline', { 912 points : _p.join(' '), 913 stroke : _color || this.addRect.defaultColor, 914 'stroke-width' : _strokeWidth || _.defaultStrokeWidth, 915 fill : _fill || 'none', 916 transform : tramA 917 })); 918 return this; 919 }, 920 921 922 addImage : function() { 923 // TODO 924 throw new Error(1, 'addImage: yet implement!'); 925 }, 926 927 /** 928 * 功能正常嗎? 929 * @return {Boolean} 功能正常 930 */ 931 status_OK : function() { 932 // !!: dual-unary operator 933 return !!this.svg; 934 } 935 936 }; // _.prototype={ 937 938 939 // other manual setting 940 with (_.prototype) { 941 addLine.defaultColor = _.defaultColor; 942 addPath.defaultColor = _.defaultColor; 943 addText.defaultColor = _.defaultColor; 944 addText.defaultFont = null; 945 addEllipsePath.defaultColor = _.defaultColor; 946 addRect.defaultColor = _.defaultColor; 947 addPolyline.defaultColor = _.defaultColor; 948 949 } 950 951 // ↑definition of module SVG object 952 953 // ↑definition of module SVG 954 // ============================================================================ 955 956 957 /**#@+ 958 * @description use {@link CeL.interact.integrate.SVG} to draw: 959 */ 960 961 /* 962 draw_circle[generateCode.dLK] 963 =draw_ellipse[generateCode.dLK] 964 =draw_triangle[generateCode.dLK] 965 =draw_quadrilateral[generateCode.dLK] 966 ='g_SVG'; 967 */ 968 969 CeL.interact.integrate.SVG 970 . 971 /** 972 * 繪製圓形。 973 * @since 2006/12/19 18:05 974 * @param _r 975 * @param svgO 976 * @param _color 977 * @param _fill 978 * @return module SVG object 979 * @memberOf CeL.interact.integrate.SVG 980 */ 981 draw_circle = function(_r, svgO, _color, _fill) { 982 var g_SVG = library_namespace.interact.integrate.SVG; 983 if (_r 984 && (svgO || (svgO = new g_SVG( 985 (_r + g_SVG.defaultStrokeWidth) * 2, 986 (_r + g_SVG.defaultStrokeWidth) * 2).show())) 987 && svgO.status_OK()) { 988 svgO.addCircle(_r, _r + g_SVG.defaultStrokeWidth, _r 989 + g_SVG.defaultStrokeWidth); 990 return svgO; 991 } 992 }; 993 CeL.interact.integrate.SVG 994 . 995 /** 996 * 繪製橢圓。 997 * @param _rx 998 * @param _ry 999 * @param svgO 1000 * @param _color 1001 * @param _fill 1002 * @return module SVG object 1003 * @memberOf CeL.interact.integrate.SVG 1004 */ 1005 draw_ellipse = function(_rx, _ry, svgO, _color, _fill) { 1006 var g_SVG = library_namespace.interact.integrate.SVG; 1007 if (_rx 1008 && _ry 1009 && (svgO || (svgO = new g_SVG( 1010 (_rx + g_SVG.defaultStrokeWidth) * 2, 1011 (_ry + g_SVG.defaultStrokeWidth) * 2).show())) 1012 && svgO.status_OK()) { 1013 svgO.addEllipse(_rx, _ry, _rx + g_SVG.defaultStrokeWidth, _ry 1014 + g_SVG.defaultStrokeWidth); 1015 return svgO; 1016 } 1017 }; 1018 1019 1020 CeL.interact.integrate.SVG 1021 . 1022 /** 1023 * 畫簡單梯形。 1024 * @since 2006/12/17 12:38 1025 * @requires split_String_to_Object,set_attribute,XML_node,removeNode,remove_all_child,g_SVG,draw_quadrilateral 1026 * @param _ds 1027 * @param _h 1028 * @param _d 1029 * @param _us 1030 * @param svgO 1031 * @param _color 1032 * @param _fill 1033 * @return module SVG object 1034 * @memberOf CeL.interact.integrate.SVG 1035 */ 1036 draw_quadrilateral = function(_ds, _h, _d, _us, svgO, _color, _fill) { 1037 var g_SVG = library_namespace.interact.integrate.SVG; 1038 if (isNaN(_us) || _us === '') 1039 _us = _ds; 1040 if (_ds 1041 && _h 1042 && (svgO || (svgO = new g_SVG((_ds > _d + _us ? _ds : _d 1043 + _us) 1044 + g_SVG.defaultStrokeWidth, _h 1045 + g_SVG.defaultStrokeWidth).show())) 1046 && svgO.status_OK()) { 1047 set_attribute(svgO.addQuadrilateral(_ds, _h, _d, _us).lastQuadrilateral, 1048 { 1049 stroke : _color, 1050 fill : _fill 1051 }); 1052 return svgO; 1053 } 1054 }; 1055 1056 CeL.interact.integrate.SVG 1057 . 1058 /** 1059 * 畫簡單三角形。 1060 * @since 2006/12/17 12:38 1061 * @requires split_String_to_Object,set_attribute,XML_node,removeNode,remove_all_child,g_SVG,draw_triangle 1062 * @param _ds 1063 * @param _h 1064 * @param _d 1065 * @param svgO 1066 * @param _color 1067 * @param _fill 1068 * @return module SVG object 1069 * @memberOf CeL.interact.integrate.SVG 1070 */ 1071 draw_triangle = function(_ds, _h, _d, svgO, _color, _fill) { 1072 var g_SVG = library_namespace.interact.integrate.SVG; 1073 if (_ds 1074 && _h 1075 && (svgO || (svgO = new g_SVG((_ds > _d ? _ds : _d) 1076 + g_SVG.defaultStrokeWidth, _h 1077 + g_SVG.defaultStrokeWidth).show())) 1078 && svgO.status_OK()) { 1079 set_attribute(svgO.addTriangle(_ds, _h, _d).lastTriangleDefs, { 1080 stroke : _color, 1081 fill : _fill 1082 }); 1083 return svgO; 1084 } 1085 }; 1086 1087 /* 1088 draw_addition[generateCode.dLK] 1089 =draw_multiplication[generateCode.dLK] 1090 =draw_long_division[generateCode.dLK] 1091 ='g_SVG,draw_scale'; 1092 */ 1093 1094 /** 1095 * default 畫筆。 1096 * @inner 1097 * @private 1098 */ 1099 var draw_scale = { 1100 /** 1101 * text width 1102 * @inner 1103 * @private 1104 */ 1105 tW : 10, 1106 /** 1107 * text height 1108 * @inner 1109 * @private 1110 */ 1111 tH : 2 * (10/* tW */- 2), 1112 /** 1113 * decimal separator, 小數點 1114 * @see 1115 * <a href="http://en.wikipedia.org/wiki/Decimal_separator" accessdate="2010/1/20 18:29">Decimal separator</a> 1116 */ 1117 ds : '.', 1118 /** 1119 * width of decimal separator 1120 */ 1121 dsw : 4, 1122 /** 1123 * line height 1124 * @inner 1125 * @private 1126 */ 1127 lH : 4, 1128 /** 1129 * margin left 1130 * @inner 1131 * @private 1132 */ 1133 mL : 0, 1134 /** 1135 * margin top 1136 * @inner 1137 * @private 1138 */ 1139 mT : 0, 1140 /** 1141 * 根號寬, squire width 1142 * @inner 1143 * @private 1144 */ 1145 sW : 10 1146 }; 1147 //draw_scale.tH=22,draw_scale.tW=12; // for print 1148 CeL.interact.integrate.SVG 1149 . 1150 /** 1151 * 利用 module SVG 物件來演示直式加法。 1152 * @since 2006/12/26 17:47 1153 * @param num1 1154 * @param num2 1155 * @param svgO 1156 * @param _color 1157 * @param _font 1158 * @return module SVG object 1159 * @memberOf CeL.interact.integrate.SVG 1160 */ 1161 draw_addition=function(num1, num2, svgO, _color, _font) { 1162 if (!num1 && !num2) 1163 return; 1164 var g_SVG = library_namespace.interact.integrate.SVG; 1165 var _op = '+'; 1166 if (num2 < 0) 1167 _op = '-', num2 = -num2; 1168 1169 var _a = _op == '+' ? (num1 - 0) + (num2 - 0) : num1 - num2, 1170 _h = 3, 1171 _w = (num2 += '').length + 2, 1172 tW = draw_scale.tW, 1173 tH = draw_scale.tH, 1174 lH = draw_scale.lH, 1175 mL = draw_scale.mL, 1176 mT = draw_scale.mT; 1177 1178 if ((_a += '').length + 1 > _w) 1179 _w = _a.length + 1; 1180 if ((num1 += '').length + 1 > _w) 1181 _w = num1.length + 1; 1182 _h = _h * tH + 2 * lH + 2 * mT; 1183 _w = (2 + _w) * tW + 2 * mL; 1184 1185 if (svgO && svgO.status_OK()) 1186 svgO.clean(); 1187 else if (!(svgO = new g_SVG).show().status_OK()) 1188 return null; 1189 1190 svgO.setSize(_w, _h); 1191 1192 _w -= mL + tW; 1193 1194 // TODO: 讓 IE8 顯示起來像 111+111=222, 而非 +111111222 1195 svgO 1196 .addNum(num1, _w - num1.length * tW, mT + tH, tW, _color, _font) 1197 .addNum(num2, _w - num2.length * tW, mT + 2 * tH, tW, _color, _font) 1198 .addText(_op, mL + tW, mT + 2 * tH, _color, _font) 1199 .addPath('M' + mL + ',' + (mT + 2 * tH + lH / 2) + ' H' + (_w + tW)) 1200 .addNum(_a, _w - _a.length * tW, mT + 3 * tH + lH, tW, _color, _font); 1201 1202 return svgO; 1203 }; 1204 //draw_subtraction[generateCode.dLK]='draw_addition'; 1205 CeL.interact.integrate.SVG 1206 . 1207 /** 1208 * 呼叫 draw_subtraction 來演示直式減法。因為直式加減法的運算與機制過程非常相似,因此我們以 draw_addition 來一併的處理這兩個相似的運算過程。 1209 * @since 2006/12/26 17:47 1210 * @param num1 1211 * @param num2 1212 * @param svgO 1213 * @param _color 1214 * @param _font 1215 * @return module SVG object 1216 * @memberOf CeL.interact.integrate.SVG 1217 */ 1218 draw_subtraction = function(num1, num2, svgO, _color, _font) { 1219 return _.draw_addition.call(this, num1, -num2, svgO, _color, _font); 1220 }; 1221 1222 CeL.interact.integrate.SVG 1223 . 1224 /** 1225 * 利用 module SVG 物件來演示直式乘法。<br/> 1226 * TODO: 小數的乘法 1227 * @since 2006/12/26 17:47 1228 * @param num1 1229 * @param num2 1230 * @param svgO 1231 * @param _color 1232 * @param _font 1233 * @return module SVG object 1234 * @memberOf CeL.interact.integrate.SVG 1235 * @see 1236 * <a href="http://203.71.239.19/math/courses/cs04/M4_6.php" accessdate="2010/1/20 18:5">小數篇:小數的乘法</a> 1237 */ 1238 draw_multiplication=function(num1, num2, svgO, _color, _font) { 1239 if (!num1 && !num2) 1240 return; 1241 1242 var g_SVG = library_namespace.interact.integrate.SVG; 1243 var _op = '×', _j, _C = 1, _a = num1 * num2, _h = 0, _w = (num2 += '').length + 2, tW = draw_scale.tW, tH = draw_scale.tH, lH = draw_scale.lH, mL = draw_scale.mL, mT = draw_scale.mT; 1244 if ((_a += '').length > _w) 1245 _w = _a.length; 1246 if ((num1 += '').length > _w) 1247 _w = num1.length; 1248 for (_j = 0; _j < num2.length; _j++) 1249 if (num2.charAt(_j) - 0) 1250 _h++; 1251 if (_h == 1) 1252 _h = 0, _C = 0; 1253 _h = (3 + _h) * tH + 2 * lH + 2 * mT; 1254 _w = (2 + _w) * tW + 2 * mL; 1255 1256 if (svgO && svgO.status_OK()) 1257 svgO.clean(); 1258 else if (!(svgO = new g_SVG).show().status_OK()) 1259 return null; 1260 1261 svgO.setSize(_w, _h); 1262 1263 _w -= mL + tW; 1264 1265 svgO 1266 .addNum(num1, _w - num1.length * tW, mT + tH, tW, _color, _font) 1267 .addNum(num2, _w - num2.length * tW, mT + 2 * tH, tW, _color, _font) 1268 .addText(_op, mL + tW, mT + 2 * tH, _color, _font) 1269 .addPath('M' + mL + ',' + (_h = mT + 2 * tH + lH / 2) + ' H' + (_w + tW)); 1270 1271 _op = ''; 1272 _h += lH / 2; 1273 var _w2 = _w, _n; 1274 if (_C) { 1275 for (_j = num2.length - 1; _j >= 0; _j--) 1276 if (_n = num2.charAt(_j) - 0) 1277 svgO.addNum(_n = (num1 * _n) + _op, _w2 - _n.length 1278 * tW, _h += tH, tW, _color, _font), _w2 -= tW 1279 * (_op.length + 1), _op = ''; 1280 else 1281 _op += '0'; 1282 svgO 1283 .addPath('M' + mL + ',' + (_h += lH / 2) + ' H' 1284 + (_w + tW)); 1285 } 1286 1287 svgO.addNum(_a, _w - _a.length * tW, _h + lH / 2 + tH, tW, _color, _font); 1288 1289 return svgO; 1290 }; 1291 1292 /* 1293 TODO: 1294 小數 1295 換基底 1296 */ 1297 //draw_long_division[generateCode.dLK]='g_SVG,set_class';//split_String_to_Object,set_attribute,XML_node,removeNode,remove_all_child,g_SVG,draw_long_division 1298 CeL.interact.integrate.SVG 1299 . 1300 /** 1301 * 利用 module SVG 物件來展示<a href="http://en.wikipedia.org/wiki/Long_division" title="long division">直式除法</a>。<br/> 1302 * !! 尚有許多 bug<br/> 1303 * @since 2006/12/11-12 11:36 1304 * @param dividend 1305 * @param divisor 1306 * @param digits_after TODO: 小數直式除法: 小數點後位數, how many digits after the decimal separator 1307 * @param svgO 1308 * @param _color 1309 * @param _font 1310 * @return module SVG object 1311 * @example 1312 * // include module 1313 * CeL.use('net.SVG'); 1314 * 1315 * // way 1 1316 * var SVG_object = new CeL.SVG; 1317 * SVG_object.attach('panel_for_SVG').show(1); 1318 * CeL.draw_long_division(452, 34, SVG_object); 1319 * // You can also put here. 1320 * //SVG_object.attach('panel_for_SVG').show(1); 1321 * 1322 * // way 2 1323 * var SVG_object = CeL.draw_long_division(100000, 7); 1324 * SVG_object.attach('panel_for_SVG').show(1); 1325 * 1326 * // 另一次顯示 1327 * CeL.draw_long_division(100, 7, SVG_object); 1328 * @memberOf CeL.interact.integrate.SVG 1329 */ 1330 draw_long_division = function(dividend, divisor, svgO, _color, _font) { 1331 if (isNaN(dividend) || isNaN(divisor) || !divisor) 1332 return; 1333 1334 var g_SVG = library_namespace.interact.integrate.SVG; 1335 /** 1336 * 餘數 remainder 1337 * @inner 1338 * @ignore 1339 */ 1340 var remainder; 1341 /** 1342 * 商 quotient 1343 * @inner 1344 * @ignore 1345 */ 1346 var quotient = '' + Math.floor(dividend / divisor), 1347 tW = draw_scale.tW, 1348 tH = draw_scale.tH, 1349 lH = draw_scale.lH, 1350 mL = draw_scale.mL, 1351 mT = draw_scale.mT, 1352 sW = draw_scale.sW, 1353 bx = mL + ('' + divisor).length * tW + sW, 1354 by = mT + lH + 2 * tH; 1355 1356 dividend += ''; 1357 if (svgO && svgO.status_OK()) 1358 svgO.clean(); 1359 else if (!(svgO = new g_SVG).show().status_OK()) 1360 return null; 1361 1362 svgO 1363 //.show(1) 1364 // 調整大小 1365 .setSize( 1366 2 1367 * mL 1368 + (('' + divisor).length + dividend.length + 2) 1369 * tW + sW, 1370 2 * mT + by + quotient.length * (tH * 2 + lH)) 1371 // 除數 divisor 1372 .addNum(divisor, mL, by, tW, _color, _font) 1373 // 商 quotient 1374 .addNum(quotient, 1375 bx + (dividend.length - quotient.length) * tW, 1376 mT + tH, tW, _color, _font) 1377 // 被除數 dividend 1378 .addNum(dividend, bx, by, tW, _color, _font) 1379 // .addNode('path',{d:'M'+(bx+(dividend.length+1)*tW)+','+(by-lH/2-tH)+' 1380 // H'+(bx-tW)+' a'+tW/2+','+(lH+tH)+' 0 0,1 1381 // -'+tW/2+','+(lH+tH),stroke:'#000',style:'fill:none;'}) 1382 .addPath( 1383 'M' + (bx - (tW + sW) / 2) + ',' + (by + lH / 2) 1384 + ' a' + tW / 2 + ',' + (lH + tH) 1385 + ' 0 0,0 ' + tW / 2 + ',-' + (lH + tH) 1386 + ' h' + (dividend.length + 2) * tW); 1387 1388 svgO.addDefs(g_SVG.createNode('line', { 1389 x1 : 0, 1390 y1 : 0, 1391 x2 : (dividend.length + 1) * tW, 1392 y2 : 0, 1393 // 'stroke-width':'1px', 1394 stroke : svgO.addLine.defaultColor 1395 })); 1396 1397 if (svgO.div) 1398 // svgO.div.className='long_division'; 1399 set_class(svgO.div, 'long_division'); 1400 1401 // 用 symbol?? 1402 svgO.addContain(0, 'long_division', { 1403 dividend : dividend, 1404 divisor : divisor 1405 }); 1406 1407 var _k = 0, a, b, l = svgO.lastAddDefs, 1408 /** 1409 * 被除數處理到第幾位 1410 * @inner 1411 * @ignore 1412 */ 1413 dt = 1; 1414 remainder = dividend.charAt(0); 1415 for (; _k < quotient.length;) { 1416 a = quotient.charAt(_k); 1417 // if(!a)continue; 1418 a = '' + a * divisor, b = dividend.length 1419 - quotient.length + _k + 1; 1420 1421 svgO.addUse(l, { 1422 x : bx, 1423 y : (by + tH + lH / 2) 1424 }).addNum(a, bx + (b - a.length) * tW, by + tH, tW, _color, 1425 _font); 1426 1427 // 以下..ugly hack 1428 // 先算出餘數 1429 while ((a == 0 || remainder - a < 0) && dt < dividend.length) 1430 remainder += dividend.charAt(dt++); 1431 remainder -= a; 1432 if (!remainder) 1433 remainder = ''; 1434 //alert(remainder+','+quotient.charAt(_k+1)+'\n'+(i<quotient.length)) 1435 // 再添加到夠減的位數 1436 while (quotient.charAt(++_k) == 0 && _k < quotient.length) { 1437 b++; 1438 if (remainder || dividend.charAt(dt) > 0) 1439 remainder += dividend.charAt(dt); 1440 dt++; 1441 } 1442 // 顯示位數微調 1443 if (dt < dividend.length) { 1444 b++; 1445 // 加一位 1446 remainder += dividend.charAt(dt++); 1447 } else if (!remainder) 1448 b--; 1449 //alert(remainder+','+a+','+dt+'\n'+(remainder<a)); 1450 svgO.addNum(remainder || 0, bx + (b - ('' + remainder).length) 1451 * tW, by += 2 * tH + lH, tW, _color, _font); 1452 } 1453 1454 return svgO; 1455 }; 1456 1457 1458 /**#@-*/ 1459 // ↑@memberOf module SVG 1460 1461 1462 1463 1464 1465 1466 return ( 1467 CeL.interact.integrate.SVG 1468 ); 1469 } 1470 1471 1472 }); 1473 1474