プログ

’14修了無内定理系院卒の活動雑記||プー太郎ログ||プログラミング雑記

canvas への芒星の描き方と入力補助

魔法陣ジェネレータで使わせて頂いてるフォント
フリーフォント「MagicRing」
の製作者がもっと他に面白いもの公開してないかなーと見て回ってたら見つけてしまいました・・・

MCE2

本家本元魔法陣ジェネレータ「魔法陣エンジンMCE2」(白目)
サイトから特にURL貼ってないから気づかなかったよ・・・完全にネタ被りな上にあっちの方が遥かに手が込んでるというね.1行に1処理でインデントが意味持つ言語ってPythonだっけか,裏で色々動いてるんだろうけど割と短めなコード(スクリプト?)でここまで色々描けるのは良いなと思った.まぁこの魔方陣言語を覚えることなく単純にテキストだけでお手軽に作れるってのと,作成後の加工やら何やらで差別化を目指すことにします.いずれにせよ公開する際にはフォントの使用報告に加え,ネタ被りの謝罪と誘導の許可を得ないとなぁ・・・

装飾

前述のサイトやこれまでに紹介したサイト見ると凝ってる魔法陣が多く,高々3周それっぽい文字(しかも借り物)を配置しただけじゃ片腹痛いのでは?と思い,多少なりの装飾を増やすことにしました.ただあまり設定項目を増やしたくないので,円を3つと星を1つにとどめることに.星は割とスマートに描けたんじゃないかと思うので紹介.

//半径rのn/m星形多角形を描く
function inputStar(n,m,r){
  //描く準備
  var canvas  = document.getElementById("srcImg");
  var context = canvas.getContext("2d");
  context.setTransform(1,0,0,1,240,240);

  context.beginPath();
  context.moveTo(0,-r);
  for(var i=1;i<=n;i++){
    //円周を n 個に分け, m 個先の点に飛ぶ
    context.rotate(360/n/180*Math.PI*m);
    context.lineTo(0,-r);
    //約数が存在する時,その約数に達したらズラす
    if(n%m===0&&i%(n/m)===0){
      context.closePath();
      context.stroke();
      context.rotate(360/n/180*Math.PI);
      context.moveTo(0,-r);
    }
  }
  context.closePath();
  context.stroke();
}

最初は図形6種類くらいから選択にしようかと思ったけど,1つの関数で描けることや数字を大きくしてもかなり綺麗に描けることから n と m を指定する形に.その際にフォーカス当てて↑↓キーで値を変更できる入力補助機能を付けようと思ったら,こっちはあまり綺麗に書けなかった.

var numFocus=[false,false];
$("#numN").focus(function(){ numFocus[0]=true;}).blur(function(){ numFocus[0]=false;})
$("#numM").focus(function(){ numFocus[1]=true;}).blur(function(){ numFocus[1]=false;})
$(window).keyup(function(evt){
  //中略

  if(numFocus[0]){
    if(evt) var kc = evt.keyCode;
    else    var kc = event.keyCode;
    var chr = String.fromCharCode(kc);
    //↑キー
    if(chr==="&"){
      $("#numN").val(parseInt($("#numN").val())+1);
    }
    //↓キー
    else if(chr==="("){
      $("#numN").val((parseInt($("#numN").val())-1>0)?(parseInt($("#numN").val())-1):0);
    }
  }
  else if(numFocus[1]){
  //同様のため略
  }
  renewText();
});

フォーカスが当たっているかどうかを管理する変数を用意しておいて,そこが true の状態で上下が入力されると値を変更する,という処理.何故こんな周りくどいことをしたかというと,単純に focus のイベントから上下入力の関数を起動すると,フォーカスが起きる度にその関数が作られる様で1回のキー入力に対し2以上の刻み値で変動してしまったため.「フォーカスが当たっている間」という状態を管理できないなんてことはないと思うのでちゃんとしたやり方があるはず.似たような内容2回書いてるのも気に入らないしそのうち直したい.

参考
stroke()-Canvasリファレンス
星型多角形 - Wikipedia
HTML5のCanvasで点線が書けないなんて... : 時々、失業SEの開発日誌
与えられた値が数値かどうかの判定 (NaN) - web newbie
押されたキーコードを取得する

OpenCVjs

//canvasエレメントからIplImageへ転送
//入力
//canvasElement canvasエレメント canvasのオブジェクト
//出力
//IplImage型
function cvGetIplImageAtCanvasElement(canvasElement)

ありました,例のごとく親ウィンドウからエレメント取得してこの関数に投げたら割と普通に表示できたという.ただこれだけだとデータが不十分な様でフィルタを掛けようとすると値が足りないって言われるので,他の関数を参考にもう少し読み込んでみる必要がありそうです.

進捗?

f:id:triplog:20140527234144p:plain