角丸++

少し修正。

  • アールを計算するルーチンを修正、よりきれいな弧が描けるように。
  • 自動パディングするとき小要素一つ一つにスタイルを設定していたのを止め、コンテナを作成し、コンテナにスタイルを設定するようにした。

TODO

  • ボーダーの幅を指定できるようにしたい。(現状では1単位で固定)
var Rounder = new function()
{
  var self = this;

  this._bgcolor = '#fff';
  this._color   = '#ccc';
  this._border  = null;
  this._size = 5;
  this._step = 1;

  var css = '<style type="text/css">'
      + 'span.rounderElement {'
      + 'display:block;'
      + 'margin:0;'
      + 'padding:0;'
      + 'overflow:hidden;'
      + 'overflow-x:hidden;'
      + 'overflow-y:hidden;'
      + '}'
      + 'span.rounderCorner {'
      + 'height:' + this._size.toString() + 'px;'
      + 'background-color:' + this._color + ';'
      + '}'
      + 'span.rounderLine {'
      + 'height:' + this._step.toString() + 'px;'
      + 'background-color:' + this._bgcolor + ';'
      + '}'
      + '</style>';
  document.write(css);

  this.round = function()
  {
    self.roundTop.apply(this, arguments);
    self.roundBottom.apply(this, arguments);
  }

  this.roundTop = function()
  {
    var args = self.parseArguments(arguments);
    var target = args.shift();
    target.insertBefore(self.createTop.apply(this, args), target.firstChild);
  }

  this.roundBottom = function()
  {
    var args = self.parseArguments(arguments);
    var target = args.shift();
    target.appendChild(self.createBottom.apply(this, args));
  }

  this.roundAndPad = function()
  {
    var args = self.parseArguments(arguments);
    var target = args[0];
    var bgcolor = args[1];
    var color = args[2];
    var size = args[3];
    var step = args[4];
    var border = args[5];
    if (target.childNodes && target.childNodes.length) {
      var container = document.createElement('div');
      container.style.backgroundColor = bgcolor;
      container.style.margin = '0';
      if (border) {
        container.style.padding = '0 ' +  (size - step).toString() + 'px';
        container.style.borderColor = border;
        container.style.borderStyle = 'solid';
        container.style.borderWidth = '0 ' +  step.toString() + 'px';
      } else {
        container.style.padding = '0 ' +  size.toString() + 'px';
      }
      while (target.childNodes.length) {
        container.appendChild(target.removeChild(target.firstChild));
      }
      target.appendChild(container);
    }
    self.roundTop.apply(this, arguments);
    self.roundBottom.apply(this, arguments);
  }

  this.parseArguments = function(args)
  {
    var params = [];
    if (args.lengs == 0) {
      window.alert('argument #1 is required.');
      return [];
    }
    params[0] = (typeof args[0] == 'string') ? document.getElementById(args[0]) : args[0];
    if (!params[0] || !params[0].appendChild) {
      window.alert('argument #1 must be a DOM Element or an existing Element ID.');
      return [];
    }
    params[1] = (args.length > 1) ? args[1] : self._bgcolor;
    params[2] = (args.length > 2) ? args[2] : self._color;
    params[3] = (args.length > 3 && parseInt(args[3]) > 0) ? parseInt(args[3]) : self._size;
    params[4] = (args.length > 4 && parseInt(args[4]) > 0) ? parseInt(args[4]) : self._step;
    params[3] = Math.max(params[3], params[4])
    params[5] = (args.length > 5) ? args[5] : self._border
    return params;
  }

  this.calcMargin = function(size, level, step)
  {
    return size - Math.floor(Math.sqrt(Math.pow(size, 2) - Math.pow(level + step, 2)) / step) * step;
  }

  this.createCorner = function(color, size)
  {
    var corner = document.createElement('span');
    corner.className = 'rounderElement rounderCorner';
    if (color && color != self._color) {
      corner.style.backgroundColor = color;
    }
    if (size && size != self._size) {
      corner.style.height = size.toString() + 'px';
    }
    return corner;
  }

  this.createLine = function(bgcolor, step, margin)
  {
    var line = document.createElement('span');
    line.className = 'rounderElement rounderLine';
    if (bgcolor && bgcolor != self._bgcolor) {
      line.style.backgroundColor = bgcolor;
    }
    if (step && step != self._step) {
      line.style.height = step.toString() + 'px';
    }
    line.style.marginLeft = line.style.marginRight = margin.toString() + 'px';
    return line;
  }

  this.createTop = function(bgcolor, color, size, step, border)
  {
    if (border) {
      return self.createTopBordered(bgcolor, color, size, step, border);
    }
    var top = self.createCorner(color, size);
    var i, line;
    for (i = 0; i < size; i += step) {
      line = self.createLine(bgcolor, step, self.calcMargin(size, i, step));
      top.insertBefore(line, top.firstChild);
    }
    return top;
  }

  this.createBottom = function(bgcolor, color, size, step, border)
  {
    if (border) {
      return self.createBottomBordered(bgcolor, color, size, step, border);
    }
    var bottom = self.createCorner(color, size);
    var i, line;
    for (i = 0; i < size; i += step) {
      line = self.createLine(bgcolor, step, self.calcMargin(size, i, step));
      bottom.appendChild(line);
    }
    return bottom;
  }

  this.createTopBordered = function(bgcolor, color, size, step, border)
  {
    var top = self.createCorner(color, size);
    var i, line, margin1, margin2, subline;
    for (i = 0; i < size - step; i += step) {
      margin1 = self.calcMargin(size, i, step);
      margin2 = Math.max(step, self.calcMargin(size, i + step, step) - margin1);
      line = self.createLine(border, step, margin1);
      subline = self.createLine(bgcolor, step, margin2);
      top.insertBefore(line, top.firstChild).appendChild(subline);
    }
    line = self.createLine(border, step, self.calcMargin(size, i, step));
    top.insertBefore(line, top.firstChild);
    return top;
  }

  this.createBottomBordered = function(bgcolor, color, size, step, border)
  {
    var bottom = self.createCorner(color, size);
    var i, line, margin1, margin2, subline;
    for (i = 0; i < size - step; i += step) {
      margin1 = self.calcMargin(size, i, step);
      margin2 = Math.max(step, self.calcMargin(size, i + step, step) - margin1);
      line = self.createLine(border, step, margin1);
      subline = self.createLine(bgcolor, step, margin2);
      bottom.appendChild(line).appendChild(subline);
    }
    line = self.createLine(border, step, self.calcMargin(size, i, step));
    bottom.appendChild(line);
    return bottom;
  }
}