0.2.1からの変更点。
・SVG管理法を、レイヤー管理に改めた。(但し基本の使用法に変更なし)
・image要素に対応して、他のSVG画像ファイルを読み込めるようにした。
・「xlink:href=''」などの、属性名に於ける名前空間に対応した。
/* * c4se project * svgDraw.js 0.2.2 - 20090517 * * project name: poeml - poems in electrocity * project page: http://c4se.sakura.ne.jp/bi_laboratory/poeml/poeml.html * project leader: Siki Asai * lunatic_faily@yahoo.co.jp * http://c4se.sakura.ne.jp/si_index.html * script author: ne_Sachirou * utakata.c4se@gmail.com * http://c4se.sakura.ne.jp/ne_index.html * * ==License * <c4seFCL 0.1> * * ==What's this? * You can draw easyly SVG by JavaScript by this 'svgDraw.js'. * Those graphics are drawn without using Microsoft VML, Adobe Flash, Sun Java, HTML Canvas. */ if(!Object.prototype._className){ Object.prototype._className = "Object"; Array.prototype._className = "Array"; String.prototype._className = "String"; Date.prototype._className = "Date"; Number.prototype._className = "Number"; Boolean.prototype._className = "Boolean"; Function.prototype._className = "Function"; RegExp.prototype._className = "RegExp"; Error.prototype._className = "Error"; EvalError.prototype._className = "EvalError"; ReferenceError.prototype._className = "ReferenceError"; RangeError.prototype._className = "RangeError"; SyntaxError.prototype._className = "SyntaxError"; TypeError.prototype._className = "TypeError"; URIError.prototype._className = "URIError"; NodeList.prototype._className = "NodeList"; }; if(!Array.prototype.forEach) Array.prototype.forEach = function(f, o){ if(!o) o = undefined; for(var i=0; i<this.length; i++){ if(this[i] === undefined) continue; f.call(o, this[i], i, this); } return this; }; if(!NodeList.prototype.toArray) NodeList.prototype.toArray = function(){ var a = new Array(); for(var i=0, l=this.length; i<l; ++i) a.push(this[i]); return a; }; try{c4sey}catch(e){c4sey = {}; $y = c4sey}; if(!c4sey.mixin) c4sey.mixin = function(hash1, hash2){ for(var prop in hash2) hash1[prop] = hash2[prop]; return hash1; }; (function($y){ var _doc = document; var _ns = "http://www.w3.org/2000/svg"; var mixin = $y.mixin; var _ns_svg = "http://www.w3.org/2000/svg", _ns_xlink = "http://www.w3.org/1999/xlink", _ns_xhtml = "http://www.w3.org/1999/xhtml", _ns_mathml = "http://www.w3.org/1998/Math/MathML"; /*var _defalt_style = { fill:"#000", opacity:1.0, stroke:"#000", "stroke-width":1, "stroke-opacity":1.0 };*/ $y.svgDraw = function(node){return new $y.svgDraw.fn.init(node);}; $y.svgDraw.fn = $y.svgDraw.prototype = { _className: "$y.svgDraw", init: function(node){ node = node || _doc.body; node.appendChild(_doc.createElementNS(_ns, "svg")).setAttribute("class", "svgDraw"); this._private = {}; this._private.canvas = node.lastChild; var g = _doc.createElementNS(_ns, "g"); g.setAttribute("class", "layer"); g.setAttribute("id", "svgDraw_layer_layer0_0"); this._private.canvas.appendChild(g); this._private.layerid = 0; this._private.layerarr = new Array("layer0"); return this; }, draw: function(/*Element | ElementArray ...*/){ var canv = _doc.getElementById("svgDraw_layer_"+this._private.layerarr[this._private.layerid]+"_"+this._private.layerid); for(var i=0, l=arguments.length; i<l; ++i){ if(arguments[i]._className == "$y.svgDraw.svg") arguments[i] = arguments[i].out(); if(arguments[i]._className == "Array") arguments[i].forEach(function(elm){ canv.appendChild(elm); }, this); else canv.appendChild(arguments[i]); } return this; }, width: function(num){ this._private.canvas.setAttribute("width", num); return this; }, height: function(num){ this._private.canvas.setAttribute("height", num); return this; }, viewBox: function(nums){ this._private.canvas.setAttribute("viewBox", nums); return this; }, // Layer changeLayer: function(layername/*|layerid*/){ var arr = this._private.layerarr; for(var i=0, l=arr.length; i<l; ++i) if(arr[i] == "layername"){ this._private.layerid = i; return this; } layername = Number(layername); layername = (layername < 0) ? Math.ceil(layername) : Math.floor(layername); if(layername < 0) layername += arr.length; if(layername >= 0 && arr[layername]){ this._private.layerid = layername; return this; } throw new Error("$y.svgDraw.prototype.changeLayer(): There's no layer of such name."); return this; }, deleteLayer: function(layername/*|layerid*/){ var arr = this._private.layerarr; var ly = this.getLayer(layername); arr[ly["id"]] = undefined; _doc.removeChild(ly["element"]); if(this._private.layerid == ly["id"]){ for(var i=0, l=arr.length; i<l; ++i) if(arr[i]) this._private.layerid = i; } return this; }, getLayer: function(layername/*|layerid*/){ var arr = this._private.layerarr; for(var i=0, l=arr.length; i<l; ++i) if(arr[i] == layername){ return { name: layername, id: i, element: _doc.getElementById("svgDraw_layer_"+layername+"_"+i) }; } layername = Number(layername); layername = (layername < 0) ? Math.ceil(layername) : Math.floor(layername); if(layername < 0) layername += arr.length; if(layername >= 0 && arr[layername]){ return { name: arr[layername], id: layername, element: _doc.getElementById("svgDraw_layer_"+arr[layername]+"_"+layername) }; } throw new Error("$y.svgDraw.prototype.changeLayer(): There's no layer of such name."); return {}; }, makeLayer: function(layername){ var g = _doc.createElementNS(_ns, "g"); g.setAttribute("class", "svgDraw_layer"); g.setAttribute("id", "svgDraw_layer_"+layername.toString()+"_"+this._private.layerarr.length); this._private.canvas.appendChild(g); this._private.layerid = this._private.layerarr.length; this._private.layerarr.push(layername.toString()); return this; } }; $y.svgDraw.fn.init.prototype = $y.svgDraw.fn; $y.svgDraw.svg = function(){return new $y.svgDraw.svg.fn.init();}; $y.svgDraw.svg.fn = $y.svgDraw.svg.prototype = { _className: "$y.svgDraw.svg", init: function(){ this._private = {}; this._private.svg = _doc.createElementNS(_ns, "g"); this._private.style = { fill:"#000", opacity:1.0, stroke:"#000", "stroke-width":1, "stroke-opacity":1.0 }; return this; }, createTagNS: function(ns, elemName, attrHash, node){ // extend createElementNS() ns = ns || _ns; attrHash = attrHash || new Object(); var tag = _doc.createElementNS(ns, elemName); for(var prop in attrHash){ if(prop.indexOf(":") == -1) tag.setAttribute(prop, attrHash[prop]); else{ var _prop = prop.split(":"); switch(_prop[0]){ case "xlink": tag.setAttributeNS(_ns_xlink, _prop[1], attrHash[prop]); break; default: break; } } } if(node){ if(node._className == "$y.svgDraw.svg") node = node.out(); if(node._className == "Array") node.forEach(function(elm){tag.appendChild(elm);}); else tag.appendChild(node); } return tag; }, out: function(){return this._private.svg.childNodes.toArray();}, // style getStyle: function(str){ if(!str) return this._private.style; return this._private.style[str]; }, fill: function(color){ this._private.style.fill = color; return this; }, opacity: function(num){ this._private.style.opacity = num; return this; }, stroke: function(color){ this._private.style.stroke = color; return this; }, stroke_width: function(num){ this._private.style["stroke-width"] = num; return this; }, stroke_opacity: function(num){ this._private.style["stroke-opacity"] = num; return this; }, // draw circle: function(hash, elm){ var style = mixin({cx:10, cy:10, r:10}, hash); style = mixin(style, this._private.style); this._private.svg.appendChild(this.createTagNS(_ns, "circle", style, elm)); return this; }, ellipse: function(hash, elm){ var style = mixin({cx:20, cy:10, rx:20, ry:10}, hash); style = mixin(style, this._private.style); this._private.svg.appendChild(this.createTagNS(_ns, "ellipse", style, elm)); return this; }, line: function(hash, elm){ var style = mixin({x1:0, y1:0, x2:"100%", y2:"100%"}, hash); style = mixin(style, this._private.style); this._private.svg.appendChild(this.createTagNS(_ns, "line", style, elm)); return this; }, rect: function(hash, elm){ var style = mixin({x:0, y:0, width:10, height:10, rx:0, ry:0}, hash); style = mixin(style, this._private.style); this._private.svg.appendChild(this.createTagNS(_ns, "rect", style, elm)); return this; }, polyline: function(hash, elm){ var style = mixin({points:"0,0 100%,0 100%,100%"}, hash); style = mixin(style, this._private.style); this._private.svg.appendChild(this.createTagNS(_ns, "polyline", style, elm)); return this; }, poligon: function(hash, elm){ var style = mixin({points:"0,0 100%,0 100%,100%, 0,100%"}, hash); style = mixin(style, this._private.style); this._private.svg.appendChild(this.createTagNS(_ns, "poligon", style, elm)); return this; }, path: function(hash, elm){ var style = mixin({d: ""}, hash); style = mixin(style, this._private.style); this._private.svg.appendChild(this.createTagNS(_ns, "path", style, elm)); return this; }, text: function(hash, elm){ var style = mixin({x:0, y:0, "font-size":"12pt", "font-family":"serif", "font-weight":"normal", "font-style":"normal", "font-decoration":"none", "word-spacing":"1em", "letter-spacing":1, "text-anchor":"start"}, hash); style = mixin(style, this._private.style); var node = (function(){ if(!elm) return null; else if(elm._className == "String") return _doc.createTextNode(elm); else return elm; })(); var text = this.createTagNS(_ns, "text", style, node); this._private.svg.appendChild(text); return this; }, image: function(hash, elm){ var style = mixin({"xlink:href":"demo.svg", x:0, y:0, width:200, height:200}, hash); //style = mixin(style, this._private.style); this._private.svg.appendChild(this.createTagNS(_ns, "image", style, elm)); return this; }, // animate animate: function(hash){ var anim = mixin({attributeName:"", from:"", to:"", dur:"10s", repeatCount:1, fill:"remove"}, hash); this._private.svg.appendChild(this.createTagNS(_ns, "animate", anim)); return this; }, animateColor: function(hash){ var anim = mixin({attributeName:"fill", from:"rgba(0,0,0,1)", to:"rgba(256,256,256,0)", dur:"10s", repeatCount:1, fill:"remove"}, hash); this._private.svg.appendChild(this.createTagNS(_ns, "animateColor", anim)); return this; }, animateTransform: function(hash){ var anim = mixin(hash, {attributeName:"transform"}); var anim = mixin({type:"translate", from:"10,10", to:"110,110", dur:"10s", repeatCount:1, fill:"remove"}, anim); this._private.svg.appendChild(this.createTagNS(_ns, "animateTransform", anim)); return this; }, animateMotion: function(hash, path, elm){ var anim = mixin({dur:"10s", repeatCount:1, fill:"remove", rotate:""}, hash); var mpath = _doc.createElementNS(_ns, "mpath"); mpath.setAttributeNS(_ns_xlinks, "href", path); this._private.svg.appendChild(this.createTagNS(_ns, "animateMotion", anim, mpath)); return this; } }; $y.svgDraw.svg.fn.init.prototype = $y.svgDraw.svg.fn; })(c4sey);
実際に動作させたプログラム。
(Sen neP det gar deaを任意に表示させる。)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Style-Type" content="text/css"/> <meta http-equiv="Content-Script-Type" content="application/javascript"/> <style> </style> </head> <body> <div id="grd" style="border:red solid 1px;"></div> <script src="../svgDraw/svgDraw.js"></script> <script> (function(){ var cen = [ // 此処を弄る。 1,6,2,21,22,0, 2,7,8,9,10,11,0, 27,13,0, 1,6,2,21,22,0, 14,2,23,7,28,16,0, 1,6,2,17,8,12,0, 15,29,32,26,0, 1,6,2,24,30,25,12,0, 19,10,12,23,31 ]; var list = ['\n', 'ay', 'dax', 'sheyt', 'sheyn', 'shexn', 'bheyr', 'zhaysh', 'me', 'kaye', 'sexs', 'bhexk', 'gheyt', 'eyt', 'nayd', 'neyd', 'kexs', 'dheys', 'dheyd', 'phayr', 'deyt', 'rheyr', 'taxs', 'ma', 'hheyd', 'hhexs', 'pax', 'heybh', 'gey', 'sey', 'shayr', 'zhaxd', 'hhayt', 'ax', 'gaxr', 'deya' ]; var svgt = $y.svgDraw.svg; var svgCanvas = $y.svgDraw(document.getElementById("grd")); var svgTag = svgt(); var pos = [0, 0, 0]; cen.forEach(function(e){ if(e != 0){ svgTag.image({ "xlink:href":"GRD_I/GRD_I_"+(function(n){ n = n.toString(); while(n.split('').length < 4) n = '0' + n; return n; })(e)+"_"+list[e]+".svg", width:200, height:200, x:pos[0], y:pos[1], }); pos[0] += 200; }else{ if(pos[0] > pos[2]) pos[2] = pos[0]; pos = [0, pos[1] + 220, pos[2]]; } }); svgCanvas.width(pos[2]).height((pos[1]+200)).viewBox("0 0 "+(pos[2]*5)+" "+((pos[1]+200)*5)).draw(svgTag); })(); </script> </body> </html>
というか、これを作る為にヴァージョンアップしたようなもの。
ほかに、自動で縦書きを実現するプログラムが動いている。
縦書きプログラムへの実装例 http://c4se.sakura.ne.jp/bi_laboratory/poeml/svgTategaki.html
デモ http://c4se.sakura.ne.jp/bi_laboratory/poeml/svgDraw/svgDraw.html
svgDraw 0.2.1
http://d.hatena.ne.jp/Kureduki_Maari/20090209/1234115676