canvasでテキストのエフェクト

by ethertank

HTML

<table id="setting" border="0">
<tbody>
        
<tr>
<th><label for="text">STRING</label></th>
<td><textarea id="text" placeholder="改行可能。文字サイズは30~150(px)。長文入力は危険。半角だと出力するcanvasの幅が変" type="text">譶鱲鱲龗豔
籲鱻龖龖麤
纛纁躐</textarea>
</td>
</tr>
        
<tr>
<th><label for="fontSizeSelector">FONT SIZE</label></th>
<td><input id="fontSizeSelector" type="number" value="68" min="30" max="150" />
<small>(30 - 150)</small><br />
</td>
</tr>
        
<tr>
<th>
<label for="lineHeightSelector">LINE HEIGHT</label></th>
<td>
<input id="lineHeightSelector" type="number" value="1.5" min="1.0" max="2.0" />
<small>(1.0 - 2.0)</small>
</td>
</tr>

</table>

<button id="button">Generate</button>

<div id="world"></div>

CSS

body {
    font-family: sans-serif; padding:10px;
    background-color:#777;
    color:#fff;
    background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAFklEQVQImWNgYGBwQMIogHQJynTDJQBLZQSBYWz3JAAAAABJRU5ErkJggg==");
    /* Generated by http://jsdo.it/images/capture/e/N/L/eNLr_w.jpg?t=1299664703 */
}

table { font-family: "Menlo","Monaco","Courier New",monospace; color: #bdff00; }
tbody { border: 1px solid #ff0; background: #014400; }
th { vertical-align: middle; font-weight: 300; }

th, td { padding: 2px 8px; border: 1px dotted #ff0; }

textarea { min-width: 270px; min-height: 50px; resize: both; }
input[type="number"] { width: 4em; }
#button { display: block; width: 280px; margin: 10px 0; padding: 4px; }

/*
#world {}
*/

JavaScript

function all() {
    var text = [], line, maxTextWidth, fSize, lHeight, tBlur, tColor, fFamily, font, BGC, cw, ch;
    var d = document,
        t = d.getElementById("text"),
        f = d.getElementById("fontSizeSelector"),
        l = d.getElementById("lineHeightSelector"),
        b = d.getElementById("button"),
        world = d.getElementById("world"),
        canvas = d.createElement("canvas"),
        cImage = d.createElement("img"),
        c = canvas.getContext("2d");

    
    function textEffect() {
        text = t.value.toString().split("\n");
        if (f.value.match(/[^0-9]/g) || parseInt(f.value, 10) + "" != f.value || f.value > 150 || f.value < 30) {
            return false;
        }
        if (l.value < 1 || l.value > 2) { return false; }

        fSize = f.value;
        lHeight = l.value;
        tBlur = 6;
        tColor = "#fff";
        fFamily = "'小塚明朝 Pro R','KozMinPro-regular',serif";
        font = "normal 400 " + fSize + "px/" + lHeight + " " + fFamily;
        BGC = "#000";
        line = text.length; //配列の要素の数
        //※ここからmesureText()
        c.font = font;
        maxTextWidth = c.measureText(text[0]).width;
        for (i = 1; i < line; i++) {
            if (c.measureText(text[i]).width >= maxTextWidth) {
                maxTextWidth = c.measureText(text[i]).width;
            }
        }
        //alert(maxTextWidth);//test
        cw = maxTextWidth + tBlur * 2;
        ch = (fSize * lHeight) * line +tBlur * 2;
        canvas.setAttribute("width", cw);
        canvas.setAttribute("height", ch);
        c.globalCompositeOperation = "source-over";
        c.globalAlpha = 1;
        c.shadowBlur = 0;

        //虹色ブラーエフェクト---------------------------------
        c.save();
        //ブラー付きの淡色テキストを描画
        c.globalCompositeOperation = "source-over";
        c.font = font;
        c.fillStyle = tColor;
        c.textBaseline = "top";
        c.shadowColor = tColor;
        c.shadowBlur = tBlur;
        c.shadowOffsetX =...