Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Own products

  • 新規事業のアイディア創造機

Introduce

#打線組んだ をウェブサービス化!「打線くん(仮)」作りましたの巻

この記事の読了時間:約88

  • このエントリーをはてなブックマークに追加

久しぶりにノリとイキオイの一本勝負でネタ系サービス作っちゃいました♪

まとめサイトとか、たまにTwitterでも流れてくる「●●で打線組んだwww」みたいなの、見覚えないですか?

個人的にアレ結構好きで、おすすめの洋楽だとか面白い映画だとか、意外と参考になるんですよねー。

打線打順ということで重み付けが分かりやすいし、その順列によってニュアンスみたいなのも感じることが出来るので、なかなか良い表現方法だなーと思うんです。

んで、正月にちょっと勉強でもしよかっつーコトで手を出したvue.jsが思いの外しんどくて、その反動で軽ーく気楽になんか作りたいって衝動が溢れてしまったので、この「打線組んだ」を題材にしたウェブサービスでも作ろうかと数日ほどイジイジして出来たのが今回ご紹介するサービス。

その名も「「打線くん(仮)」」!

サービス内容自体はシンプルながら、中身では地味にいろんな技術を使ってたりするので、今回はその辺をゆるやかにいんとろでゅーすしましょうか。

あ、結局vue.jsはビタイチ使ってませんw

#打線組んだ をウェブサービス化した「打線くん(仮)」

「打線くん(仮)」とは

サービス内容的には前述の通り、いわゆる「打線組んだ」というヤツをウェブ上で作れるってゆーモノです。

投稿はTwitterログインをしてから行ってもらうような動線にして、各投稿にはコメントが付けられるようにもなっており、コメント数による人気ランキング機能や、各投稿をシェアした時には自動生成したOGP画像が反映されるようにもなってます。

あと、後ほど詳細は記しますが、投稿時に守備位置が選べるようになってて、そこで「同じ守備位置がかぶらないように自動変化する」という処理をしてたり、自動生成OGP画像にiMagick使ったりと、細々といろいろやっておりますです。

技術詳細

今回のサービスの機能的な部分で特に作り込んだところというと、「OGP画像の自動生成」と「守備位置の投稿時に、値がかぶらない処理」のふたつかと。

OGP画像の自動生成

これはそもそもとして、昨年末に爆発的な注目を浴びた質問箱サービス「Peing」で、質問に答えた際にTwitter上で表示される画像がOGP画像で、なるほどOGPなら画像欄を圧迫しないしリンクをシェアすれば自動で画像も出回るから面白そうだな、というとこから始まってます。

んで、投稿時にタイトルと打順をDBに入れるついでに画像としても生成して、それをOGPとして使おうと。

画像生成はiMagickという定番ライブラリを使用して、まずはタイトルを中央寄せ、打順は左寄せで画像生成します。

//白紙キャンバスの生成
$canvas = new Imagick();

//タイトル文字箇所の生成
$draw_title = new ImagickDraw();
////iMagickは自動で文字改行してくれないので、文字数17で決め打ち改行
////str_split_utf8()はマルチバイト用str_split(自作関数)
$title = implode("\n", str_split_utf8('ここにはタイトル文字が入りますよ', 17));

//文字出力用のフォントを設定
$draw_title->setFont(__DIR__.'/config/font/mplus-1p-light.ttf');
$draw_title->setFontSize(32);

//文字出力の詳細情報を取得
$metrics = $canvas->queryFontMetrics($draw_title, $title);

//画像をキャンバスの天地中央に描画する
$draw_title->setGravity(imagick::GRAVITY_CENTER);
$draw_title->setFillColor('white');
$draw_title->annotation(0, 0, $title);

//横幅は600px、縦幅や上余白は文字出力の詳細情報から使う(20は余白)
$canvas->newImage(600, $metrics['textHeight'] + $metrics['ascender'] + 20, '#184818');
$canvas->drawImage($draw_title);

//打順文字箇所の生成
$draw_content = new ImagickDraw();
$content_array = 'ここには打順の記述配列が入るのよ';
$content = '';
foreach($content_array as $k => $v){
	$content .= '■'.$k.' ('.$v['position'].')'."\n";
	$content .= implode("\n", str_split_utf8($v['player'], 31))."\n\n";
}
$content = trim($content);

$draw_content->setFont(__DIR__.'/config/font/mplus-1p-light.ttf');
$draw_content->setFontSize(18);

$metrics = $canvas->queryFontMetrics($draw_content, $content);

$draw_content->annotation(20, $metrics['ascender'] + 20, $content);

$canvas->newImage(600, $metrics['textHeight'] + $metrics['ascender'] + 20, '#ffffff');
$canvas->drawImage($draw_content);

$canvas->resetIterator();
//タイトルと打順の生成画像を縦に並べる魔法の関数
$combined = $canvas->appendImages(true);

//画像を生成
$filename = 'ユニークなOGP画像名.png';
$combined->setImageFormat('png');
$combined->writeImage(__DIR__.'/img/'.$filename);

守備位置の投稿時に、値がかぶらない処理

//みんなだいすきjQuery
$(function(){
	//守備位置変更の連動
	$('#order-box select').on('change', function(){
		var thisSelect = $(this).val();
		//あらかじめ守備位置指定のcheckboxにdata-latest-position(直前の指定守備位置)を記述しておく
		var thisSelectLatestPosition = $(this).attr('data-latest-position');
		$('#order-box .form-box').each(function(i, el){
			//変更された守備位置と同じ「直前の指定守備位置」を見つけたら
			if($(el).find('select').attr('data-latest-position') == thisSelect){
				//「変更された守備位置」のcheckboxの値を書き換え
				$(el).find('select').val(thisSelectLatestPosition).attr('data-latest-position', thisSelectLatestPosition.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&#039;").replace(/</g,"&lt;").replace(/>/g,"&gt;"));
			}
		});
		$(this).attr('data-latest-position', thisSelect.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&#039;").replace(/</g,"&lt;").replace(/>/g,"&gt;"));
	});
});

おまけ

いやー、やっぱjQueryはこなれてて楽だわー☆

「打線くん(仮)」

ということで、なかなか楽しい年始一発目でした。

さて、今度は何つくろっかなー!!

  • このエントリーをはてなブックマークに追加

コメントを投稿する

お名前

ご連絡先メールアドレス※非公開

コメント

CAPTCHA


  • このブログのRSSを購読する
  • このブログをtwitterでつぶやく
  • このブログをFacebookで共有する
  • このブログをはてなブックマークで共有する

Contact

    お名前※必須

    ご連絡先メールアドレス

    お問い合わせ内容※必須

    CAPTCHA

    captcha

    Blog parts

    Affiliate