c4se記:さっちゃんですよ☆

.。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆)

.。oO(此のblogは、主に音樂考察Programming に分類されますよ。ヾ(〃l _ l)ノ゙♬♪♡)

音樂は SoundCloud に公開中です。

考察は現在は主に Scrapbox で公表中です。

Programming は GitHub で開發中です。

svgDraw.js 0.2.2

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を任意に表示させる。)
SarHes *サイレン*

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