Mi in progress

研究者ではなく、エンジニアになることを決意した人のブログ。

clipboard.jsを使って、ColorImportCatchというWebアプリを作りました

今日は人生初のwebアプリを作りました。

その名もColorImportCatchです!

ColorImportCatch

 

1. 概要

ColorImportCatchは、

・最大10色のパレットを、HEXコードを入力するだけで見ることができる

・パレットをクリックするだけでクリップボードにコピーできる

というツールです。

f:id:mi_progress_oOo:20160710182945p:plain

 

2. 作ろうと思ったきっかけ

ボタンや背景などの色を微調整するとき、

「この前の前に書いてみたHEXコードの色がよかったな...あれ、どの色だっけ??」

「この絶妙な色の違いを比較したいな」

「色をクリックするだけでクリップボードにコピーできればいいのに...」

という思いが沸々と沸き起こりました。

 

実は、色をクリックするだけでクリップボードにコピーできるサイトはあります。

Flat UI Colors 

でも、自分でカスタマイズしたパレットの色をクリップボードにコピーできるサイトはありません。

 

なければ作ればいいじゃない。

 

というわけで作りました。

 

3. 作り方

先日のバイトで、「実装に悩んだ時は、出来そうな部分から作っていけばいい」ことを学びました。今回もこの学びを活かして開発を進めました。「指定した色のパレット表示」と、「そのパレットをクリックするとクリップボードにコピー」を同時に実装するのは難しそうだったので、まずは、

・HEXコードを入力すると、パレットを表示してくれるサイト

・パレットをクリックすると、そのHEXコードをクリップボードにコピーしてくれるサイト

をまずは別々に作ってみました。その後、この2つの機能をうまく合わせられるように微調整を行いました。

 

4. ハックした点

初心者の私が、「ここはちょっと頭使ったな」と思ったコードについてお話します。

(4-1) テキストボックスで入力したHEXコードを、指定場所の背景色にする

テキストボックスの値を取得するやり方は簡単に見つかりました。

[JavaScript] テキストボックスの値を取得する

問題は、この取得した文字をどのように指定場所の背景色のHEXコードにすればいいのか?ということです。取得した文字は、テキストボックスへの入力の度に変化する変数です。style属性で、background-color: AAA; (AAAは定義した定数)という書き方はできないし...どうすればいいのかな?としばらく悩みました。結論から言うと、全部javascriptで書きました。そのコードを以下に示します。

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>ColorInport</title>
<style>
.btn {
text-align: center;
width: 200px;
height: 400px;
display: table-cell;
vertical-align: middle;
}
</style>
</head>
<body>
<form name="form1" id="id_form1" aciton="">
<input name="textBox1" id="id_textBox1" type="text" value="">
<input type="button" value="Exec" onclick="onButtonClick();">
</form>
<div id="output" class="btn"></div>


<script type="text/javascript">
function onButtonClick() {
target = document.getElementById("output")
target.innerText = document.forms.id_form1.id_textBox1.value;
var color = target.innerText;
target.style.backgroundColor = color;
target.style.color = 'white';
}
</script>
</body>
</html>

 ポイントは、テキストボックスから取得した文字列を、変数colorで定義したことと、target.style.backgroundColor = color;で、taget(もとのもとを辿れば、id="output"で定義された場所のことです)の背景の色を変数colorにせよ、というコードにしたことです。これで無事、目的が達成されました。

 

(4-2) クリップボードにコピーを実装する

クリップボードにコピーを実装できるとても便利なプラグインを発見しました。

clipboard.js — Copy to clipboard without Flash

こちらのZIPファイルをDLして、デモのhtmlファイル(ルートディレクトリからのパス: clipboard.js-master/demo/target-input.html)を参考にしながら実装を行いました。

ここからがハックなのですが、パレットをクリックするとその色がクリップボードにコピーされるように見えるものの、実際にコピーしているのはテキストボックスの中身です。target-input.htmlでは、ボタンを押すとテキストボックスの中身がコピーされる仕組みなのですが、ボタンをパレットに置き換えてコーディングしてみました。

具体的には以下のとおりです(index.htmlは一部だけ掲載しています)。

index.html

<div class="form-float">

<form name="form1" id="id_form1" aciton="">
<input name="textBox1" id="id_textBox1" type="text" value="" class="textBox_style">
<input type="button" onclick="onButtonClick1();" class="btn-style">
</form>
<div id="output1" class="btn" data-clipboard-action="copy" data-clipboard-target="#id_form1"></div>
</div> 

 

catch.js

var clipboard = new Clipboard('.btn');
clipboard.on('success', function(e) { console.log(e); });
clipboard.on('error', function(e) { console.log(e); });

という感じです。

 

生まれて初めて、構想から実装まで一人でやった記念すべきwebアプリです。

めちゃくちゃ楽しかったです!!!!!!!

もっと高度なアプリが作れるように、これからもプログラミングの勉強頑張ります(`・ω・)b 

2016 06 29 の学び - CSVファイルのGUIインポート-エクスポートツールを実装した

方向を見失いそうになってたので、まずは目標を簡略化しました。

 

(1) 目標の簡略化

"ユーザーは「ファイルを選択する」ボタンを押すとファイル選択ウィンドウが出てきてファイルを選べる。CSVファイルを選択して、「アップロード」ボタンを押すと裏でsample.shが動き出し、様式の整った新しいCSVファイルが自動的にユーザーのPCへダウンロードされる。"

(簡略化1) ユーザーがブラウザ上で選択したファイルを、会社サーバーの指定したディレクトリへ保存できる仕組みを実装しよう。

(簡略化2) シェルスクリプトをブラウザ上で実行しよう。

(簡略化3) 会社サーバー内にあるファイルを、ユーザーがブラウザ上からダウンロードできる仕組みを実装しよう。

(簡略化4) 上記3つをまとめてみよう。

全部一気に考えるのではなくて、全部小分けしてみることにしました。

 

(2) 簡略化1について

(2-1) 参考サイト

ファイルのアップロード | PHP Labo

 

(2-2) やったこと

(2-2-1) htmlでフォーム定義

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>sample</title>
</head>
<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
csvファイルをアップロードして下さい<br><br>
<input type="file" name="upfile" size="30"><br>
<br>
<input type="submit" value="アップロード">
</form>
</html>

form タグの method を post にし、enctype を multipart/form-data にすると、ファイルをアップロードすることができるんですね。このenctype="multipart/form-data"に関して素晴らしい記事を見つけたので、貼っておきます。

enctype='multipart/form-data'ってなんだ? - MUGENUP技術ブログ

こういう記事大好きです。

 

(2-2-2) phpでデータ受信

upload.php

<?php

if (is_uploaded_file($_FILES["upfile"]["tmp_name"])) {

if (move_uploaded_file($_FILES["upfile"]["tmp_name"], "import/" . $_FILES["upfile"]["name"])) { chmod("import/" . $_FILES["upfile"]["name"], 0777);

echo $_FILES["upfile"]["name"] . "をアップロードしました。”;

} else {

echo "ファイルをアップロードできません。”; }

} else {

echo "ファイルが選択されていません。”;

}

?>

php不慣れなので以下に訳しました。

(訳) is_uploaded_file関数で、ファイルがアップロードされたか確かめよ。これができなかったら、「ファイルが選択されていません」と表示せよ。mova_uploaded_file関数で、一時的にサーバー上に保存されたファイルを、importという名前のフォルダに移し、オリジナルのファイル名で保管せよ。chmod関数でパーミッションの管理を777に指定せよ。以上がうまくいかなかったら、「ファイルをアップロードできない」と表示せよ。 

以上で無事、ブラウザ上からファイルをアップロードできるようになりました。

 

(3) 簡略化2について

(3-1) 参考サイト

phpでシェルファイルを実行する | hacknote

 

(3-2) やったこと

シェルスクリプト実行用のデモファイルを作りました。

index.php

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>test shell</title>

</head>

<body>

<h1>シェルスクリプト実行</h1>

<?php

$output = shell_exec("sh ./sample.sh");

?>

</body>

</html>

このページを開くと、ちゃんとシェルスクリプトが実行されていました。

 

(4) 簡略化3について 

(4-1) 参考サイト

readfile: ファイルを出力する (ファイルシステム 関数)

 

(4-2) やったこと

こちらも(3)同様、デモファイルを作りました。

export.php

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>export test</title>

</head>

<body>

<h1>ファイルをダウンロードします。</h1>

<?php

$file = 'export/sample.csv';

if (file_exists($file)) {

  header('Content-Description: File Transfer');

  header('Content-Type: application/octet-stream');

  header('Content-Disposition: attachment; filename='.basename($file));

  header('Content-Transfer-Encoding: binary'); header('Expires: 0');

  header('Cache-Control: must-revalidate, post-check=0, pre-check=0');

  header('Pragma: public');

  header('Content-Length: ' . filesize($file));

  ob_clean();

  flush();

  readfile($file);

  exit;

}

?>

</body>

</html>  

できました。よっしゃー!

 

(4) 簡略化4について

あとはこれら3つを1つにまとめる作業です。さらにもう一つやらないといけないことが...指定するファイル名の変数化です。どういうことかと言うと、

・a.csvが指定されたら、a.shシェルスクリプトが実行されて、aexp.csvが出力される

・b.csvが指定されたら、b.shシェルスクリプトが実行されて、bexp.csvが出力される

・c.csvが指定されたら、c.shシェルスクリプトが実行されて、cexp.csvが出力される

このa, b, cの部分を変数化したいという訳です。

 

ファイル名は、$_FILES["upfile"]["name"]で取得できますが、これをechoすると、

a.csv

.csvまで取得されてしまいます。ここを消したいので、

$filename=$_FILES["upfile"]["name"];

$cut=4;

$replace = substr($filename , 0 , strlen($filename)-$cut);

と書きました。(参考: [PHP] 文字列の前後から指定した数の文字を削除する)

今回これを実装できたことが一番嬉しかったです!

あとは、1つにまとめる作業ということで、index.htmlから情報を渡すupload.phpを次のように書きました。

upload.php

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>sample</title>

</head>

<body>

<p>

<?php

if (is_uploaded_file($_FILES["upfile"]["tmp_name"])) {

  if (move_uploaded_file($_FILES["upfile"]["tmp_name"], "import/" .  

    $_FILES["upfile"]["name"]))

    { chmod("import/" . $_FILES["upfile"]["name"], 0777);

    echo $_FILES["upfile"]["name"] . "をアップロードしました。";

    $filename=$_FILES["upfile"]["name"];

    $cut=4;

    $replace = substr($filename , 0 , strlen($filename)-$cut);

    $output = shell_exec("sh shell/".$replace."import.sh");

    $file = 'export/'.$replace.'export.csv';

    if (file_exists($file)) {

    header('Content-Description: File Transfer');

    header('Content-Type: application/octet-stream');

    header('Content-Disposition: attachment; filename='.basename($file));

    header('Content-Transfer-Encoding: binary');

    header('Expires: 0');

    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');

    header('Pragma: public');

    header('Content-Length: ' . filesize($file));

    ob_clean();

    flush();

    readfile($file);

    exit;

    }

    } else {

    echo "ファイルをアップロードできません。";

    }

    } else {

    echo "ファイルが選択されていません。";

   }

?>

</p>

</body>

</html>

実装キタ━━━━(゚∀゚)━━━━!! 

めちゃくちゃ嬉しかったです。

自分がこのようなGUIを作れるようになるなんて夢のようでした。

書いたコードが正常に動き出すのは、最高に気持ちがいいです!

 

これからもプログラミングの勉強頑張ります!

2016 06 28 の学び - Ruby on Railsの設計哲学を理解する

今週は達成感のある仕事ができて、とても嬉しかったので、

時系列でやったことを覚書しておこうと思います。

 

【ミッション】CSVファイルのGUIインポート-エクスポートツールを作る

(1) 内容

ここに、指定されたcsvファイルに対して、「この列は残す、この列は消す」といったように様式を整え、新しいcsvファイルをアウトプットしてくれるシェルスクリプトファイルがあります。(仮にこのシェルスクリプトファイルを、sample.shとします)

このsample.shは、Terminalからアクセスして、sample.shが入っているディレクトリへ移動し、./sample.shコマンドを打つと、命令を実行してくれます。

 

...これをブラウザ上でできるようにするのが、今回のミッションです!!!

"ユーザーは「ファイルを選択する」ボタンを押すとファイル選択ウィンドウが出てきてファイルを選べる。CSVファイルを選択して、「アップロード」ボタンを押すと裏でsample.shが動き出し、様式の整った新しいCSVファイルが自動的にユーザーのPCへダウンロードされる。"

 

まさにGUIツールの開発です。

このミッションを聞いた私は正直申し上げると、

「マジか〜〜〜全く出来る気がしない〜〜〜」

となりました。いかんせん、GUIの意味も.shファイルの意味も知らなかった身です。

不安になりながらも、開発を始めることにしました。

 

(2) やってみたこと: Ruby on Railsで構築にチャレンジ

結論から言うと、やりたいことと使っている道具が全く噛み合ってないことに気付き、Ruby on Railsでの構築は辞めました。

ただ、先日会社HP作成を成し遂げた後に見たRuby on Railsの世界は、

何もわからずひたすら独学で学んでいたときに見た世界とガラリと変わったので、

ここにその感動を書き記したいと思います。

 

(3) 学んだこと: Ruby on Rails

(3-1) まず、Ruby on Railsってなんだ

初めて見た時: なんだろう...プログラミング言語かな?rails new projectコマンド押すと一杯フォルダが作られて怖い(;o;) MVCが全然覚えられない...

今: webアプリ構築に必要な道具が揃ってるし、それぞれフォルダにまとまってて見やすい!超便利!

Ruby on Railsは、オープンソースのwevアプリケーションフレームワークです。聞き慣れない言葉で未だにこの言い方はピンと来ないのですが、要するにwebアプリ構築に必要な道具が全部そろった道具箱なんですね。それは例えるなら、一人暮らしを始めることになって、デパートで布団・まくら・カバー付きセットを買うようなもんです。一つ一つを買うよりも、まとめて買ったほうが楽。そういう感覚です。

余談ですが、Ruby on Railsついに5が登場したんですね...!

どんどん進化しててすごいなぁ。

Riding Rails: Rails 5.0: Action Cable, API mode, and so much more

 

(3-2) Ruby on Railsの設計哲学

1) 設定より規定(Convention over Configuration) - - - webアプリケーションの作り方について、様々なオプションを用意して、開発者の自由に設定させるよりも、規定(すなわち、適切なデフォルトの設定)を用意しておく方がいい、という考え。

2) 繰り返しを避けよ(Don’t Repeat Yourself) - - - DRY原則とも。まったく同じかほとんど同じコードがプログラム中に複数登場するのは無駄なので、できるだけ避けるべきだ、とういう考え。 

 

この哲学、HP作成するまでさっぱりわからなかったのですが、今は共感できるようになりました。特に2に関しては、ヘッダーとフッターの内容を、htmlファイルを作るたびにコピペするの面倒臭い...無駄すぎる!と自分のスキルの無さを呪ったので、今後はDRY原則でサイト構築していきたいと思いました。 

 

(3-3) おまけ

プログラミング言語 擬人化でググったら、ものすごく可愛い擬人化を見つけました。

Java、C++、Python…プログラミング言語擬人化計画! - Tech総研

これを見て更にプログラミングが好きになりました。

CSRF対策の話

先週のバイトで学んだことで書き忘れがあったのでメモ。

 

【やったこと】

ドットインストールを参考にしながら、お問い合わせフォームにCSRF対策を施しました。

#06 CSRF対策を施そう | お問合せ管理システムを作ろう - プログラミングならドットインストール

動画を見ながら思った事。

そもそもCSRFって何だ?

初耳だし何度読んでも覚えられないので、しっかりと調べて記憶を定着させる事にします!

 

【調べた事】

CSRFとは

リクエスト強要(Cross-Site Request Forgery)の略称で、特定の情報を特定のページにユーザーの意図とは無関係に送信させる攻撃のこと。情報漏洩やユーザーの意図しない操作が起こるなどの問題が起きる。Webアプリが以下の仕組みで動作している場合、

 ・Cookieでセッション管理を行っている

 ・HTTPの基本認証、SSLクライアント証明書を利用している

ユーザーからのリクエストを本人のリクエストだと判別する仕組みを持っていないとCSRF脆弱性になる。

 

Cookieとは

Webサイトの提供者が、Webブラウザを通じて訪問者のコンピュータに一時的にデータを書き込んで保存させる仕組みのこと。CookieにはWebサイト(Webサーバ)側が指定したデータを保存しておくことができ、利用者の識別や属性に関する情報や、最後にサイトを訪れた日時などを記憶しておくことが多い。

 

CSRF攻撃具体例

ユーザーがWebアプリケーションにログインすると、CookieにセッションIDが保存される。ブラウザを閉じずその状態のまま他のサイトに移動しても、CookieにセッションIDは残ったままになっている。このとき、ユーザーが罠サイトにアクセスして、WebアプリケーションにPOSTリクエストを送信するリンクをクリックする、またはスクリプトが実行されると、ブラウザはCookieのセッションIDとパラメータをWebアプリケーションに送信してしまう。つまり、Webアプリケーションから見ると、CookieにセッションIDが入っているため、正規のユーザーが正当なリクエストを送信して来たと判断してしまうことが、この攻撃のやっかいなところである。

 

CSRF対策

ワンタイムトークンについて、yahoo知恵袋でとても分かりやすい質問をしている質問者様がいたのでリンク貼っておきます。

PHPでのCSRF対策をしたいと思い調べているのですが... - Yahoo!知恵袋

超分かりやすい。

 

今回CSRF対策を実装してみて、サイバー攻撃の怖さを痛感しました。

小学生の感想文並みの感想ですが、何が怖いって、対策するべき敵を知らない私自身です。ドットインストールさんのレッスンに、CSRF対策の項目が入ってなかったら、私はCSRFのことなんて考えずにHP作成を終えていたと思います。

 

プログラミングの勉強も大切ですが、webについての知識も身につけて行きたいと思いました。

 

ラスボス・文字化けオバケを魔法の呪文で倒した話

今週ようやく会社HP作成が完了しました(*°ω°*)

最後の最後にとんでもないラスボスが現れて、てんてこ舞いに...笑

未来の自分のために、ラスボスとの戦いのここに記録をしておきます。

 

【問題】

・お問い合わせフォームから送ったデータが、MySQL上で文字化け(åがたくさん出てくる)してしまう。

f:id:mi_progress_oOo:20160625000349j:plain

なお、お問い合わせフォームを作り方はドットインストールさんを参考にしました。

お問合せ管理システムを作ろう (全21回) - プログラミングならドットインストール

 

【てこづったこと】

・なにも考えずググッて出てきたものを手当たり次第試したことが失敗でした。肝心な目線が抜けていたのです。それは、今使っているphpMySQLのヴァージョンはいくつなのか?という視点です。会社サーバー内のphpが結構古いヴァージョンだったので、そこが盲点でした。どうやらphpは5.3.6を境に仕様がガラリと変わったみたいですね。

PHP 5.3.6より前のバージョンの PDO MySQL で charset を指定する - Qiita

php 5.3.3とにらめっこしていた私は、見事文字化けオバケの餌食になりました...とほほ。これからはちゃんとヴァージョン確認してググりたいと思います。

 

【魔法の呪文】

ラスボス退治に使った魔法の呪文はこちらに書いてありました。

MySQLで文字化けしたときの対処法 - Qiita

skip-character-set-client-handshake

"クライアントがどういう形で要求してこようがUTF-8で返答する"

問答無用で叩き切る感じがすごいコマンドですね。こちらを追記したら無事MySQLが日本語になりました。

 

【具体的に書いたコード】

(注1: php 5.3.3, MySQL 5.1.73を使っています)

(注2: ドットインストールに則ってファイルを作っています)

function.php

<?php

     function connectDb( ) {

       try {

           array(PDO::MYSQL_ATTR_READ_DEFAULT_FILE => '/etc/my.cnf',

                    PDO::MYSQL_ATTR_READ_DEFAULT_GROUP => 'php',

                    );

           return new PDO(DSN, DB_USER, DB_PASSWORD);

        } catch (PDOException $e) {

        echo $e->getMessage();

        exit;

       }

    }

  (以下の関数は省略)

?>

 

PDOについてはこちらに書いてあります。

PHP: MySQL (PDO) - Manual

/etc/my.cnfのphpグループを読み込めという命令を、ドットインストールで書かれているプログラムに追加しました。

そして、my.cnfファイルを以下のように書きました。

/etc/my.cnf

[mysqld]

character-set-server = utf8

skip-character-set-client-handshake

を、「symbolic-links=0」の下に追記

[php]

default-character-set = utf8

connect-timeout = 1

の項目を最後に追加。

 

こうしたら日本語でMySQLにデータが入るようになりました。

f:id:mi_progress_oOo:20160624235805j:plain

大好きな漫画でテスト投稿してみました。

解決してとても嬉しかったです。

引き続きプログラミングの勉強頑張ります(`・ω・)

ゼロから会社のHP作成してみて学んだこと

会社のHP作成をテンプレート等抜きでゼロから自分で作ってみて、

ドットインストールやProgateやTechAcademyだけでは学びきれなかったことを学びました。未来の自分のために覚書きしておきます。

 

cssリセットを忘れずに行うこと。怠ると、違うブラウザやデバイスで見た時に、思わぬところに色がついちゃったりする。

貼り付けておきます: CSS Reset - YUI Library

 

・ヘッダーやフッターなど、どのページでも共通の部分は、事細かにidをつけて定義した方が良い。

(なぜそう思ったか) フッターに<table></table>で情報を書いていて、とあるページで、メインの中にも<table></table>を用いた時、フッターの微調整をするつもりでtableのcssを弄ったら、メインのtableの書式も変わってしまったから。出来る限り細かくidで指定しようと思いました。tableだけに留まらず、<p></p>なんかも、メインとは違うフォントサイズになることが多いので、idつけようっと。

 

・レスポンシブデザインにするべし

(なぜそう思ったか) レスポンシブデザインの真価は、どんなデバイスでも見栄えが良いということではなく、実装側の工数を最小限に抑えることにあるのだと今回身を持って体感しました。スマホサイトを別途作るということは、別のサイトをもう一個作ることと同じなのです...!作るのはそこまで大変じゃないのですが、実装後(リリース後)死ぬほど大変なんですよ

例えば、「役員の写真を差し替えといて―」という状況になったときに、imgフォルダを2ついじらないといけなくなる。つまり、

/var/www/pc/img

/var/www/pc/sp/img (sp...スマホサイト用のディレクトリの意)

の2つをいじるということです。

「いやいや、/var/www/pc/imgだけ設置しておいて、スマホサイト用のhtmlやcss相対パスを弄ればいいんでないの」

というご意見もあるかと思います。私もそう思ってました。

しかし、.htaccessで「PC以外のデバイスでアクセスした時に自動的にspディレクトリへリダイレクトする」という設定を行ったところ、相対パスで指定した部分が読み込めなくなるという事態に陥りました。具体的には、サーバーに上げた会社HPディレクトリにvim .htaccess.htaccessファイルを作って、

.htaccess

RewriteEngine on

RewriteCond %{REQUEST_URI} !/sp/

RewriteCond %{HTTP_USER_AGENT} (iPod|iPhone|iPad|Android|Windows\ Phone)

RewriteRule ^(.*)$ sp/$1 [R]

RewriteBase /

 

RewriteCond %{REQUEST_URI} /sp/

RewriteCond %{HTTP_USER_AGENT} !(iPod|iPhone|iPad|Android|Windows\ Phone)

RewriteRule ^sp/(.*)$ $1 [R]

RewriteBase /

を作りました。

参考: htaccessによるデバイス振り分け - Qiita

 

これは私の推測ですが、

スマホ用HTMLさんとCSSさん「背景を取得しに、pcディレクトリ内のimgディレクトリ行って来まーす」

.htaccesさん「PC以外はspディレクトリに強制リダイレクトじゃ〜〜〜〜」

スマホ用HTMLさんとCSSさん「NOOOOOO !」

ということだと思います。つまり、PC以外はspディレクトリよりも上の階層のディレクトリへのアクセス権がないということです。

このめんどくささ、おわかりいただけたでしょうか。

次の仕事でHP作成するときはどのページも全部レスポンシブにします(´;ω;`)

.htaccessと4時間くらい戦ったんですが、見事敗北しました。

どのページにも共通するようなファイルは一括で管理したいと思ったので、他の戦法を考えました。

 

そんな私の解決策は以下のとおりです。

(前提条件)

・会社HPのトップ、採用情報、企業情報はPC用とスマホ用の2種類のHTMLがある(例: index.htmlとindex-mob.html)

・その他のページはPC用とスマホ用で共通

(やりたいこと)

・トップ、採用情報、企業情報にアクセスしたときに、PC以外からのアクセスだったら、スマホ用のページに自動的に飛ばす

(やったこと) 

・PC用HTMLにJavaScriptで呪文を書いた。

index.html

<!DOCTYPE html>

<html lang="ja">

<head>

<meta charset="utf-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>株式会社XXXX</title>

<link rel="stylesheet" href="css/index.css">

<!-- リダイレクト -->

<script>

if ((navigator.userAgent.indexOf('iPhone') > 0 && 

navigator.userAgent.indexOf('iPad') == -1) ||

navigator.userAgent.indexOf('iPod') > 0 ||

navigator.userAgent.indexOf('Android') > 0) { location.href =

'http://XXX/index-mob.html'; }

</script>

<!-- jQuery読み込み -->

...

参考: リダイレクトだけじゃない!スマートフォンサイトを作ったら設定するべき3つのこと | Web制作会社スタイル

これで無事PC以外でのアクセスでは、スマホ用サイトへ自動的に飛ばすことができました。すごいよ、実装5秒で終わったよ。

JavaScript信者になりました。

 

勉強頑張ります!

nanoemで初音ミクちゃんを動かしてみたよ

MikuMikuDancewikipediaを読んでいたら...

MikuMikuDance - Wikipedia

MMDニコニコ動画で大きな反響を呼び、ソフトウェアの完成度の高さに感動し、金を払って買いたいが作者が金銭を受け取る気が無いため買わせてくれないとして「振り込めない詐欺」とも評された[7][4]。樋口はこうした反響に対し「寄付してもいいと言ってもらえるのはたいへん光栄だが、それほど気に入っていただけたら、ぜひこのソフトを使ってすばらしい動画を作って公開してもらい、私をニコニコさせてほしい」とコメントしている[4]。

作者の樋口さんのコメントがあまりにもかっこよすぎで、これぞまさに理想のハッカーだと思い、プロダクトに触れたいと思ったのがきっかけでした。

 

しかし、残念ながらMMDmacでは使えません。

諦めきれずググったらこんな記事を発見しました。

MacでもMMDが出来る!?その名も"nanoem"!! - NAVER まとめ

早速DLページヘ...

こんな素晴らしいソフトウェアを作ってくださって、

しまぴょんさんありがとうございます(´;ω;`)

nanoem-macOS-1.11.2.0-beta - BowlRoll

 

インストールを完了し、アプリを開くとこのような画面が出てきます。

f:id:mi_progress_oOo:20160614233149p:plain

日本語で非常にわかりやすいです。

メニューバーからファイル→読み込み→モデル

を選択し、モデルファイルを読みこめばOKです!

モデルファイルは簡単に言うと、

・動かしたいモデルさん

・モデルさんを動かせたいステージ

の2つを指します。

 

今回はこちらの2つを用いました。

動かしたいモデルさん: Tda式初音ミク・アペンドVer1.00 - BowlRoll

モデルさんを動かせたいステージ: 

【MMDステージ配布】静穏な月夜 WW2【スカイドーム】 / 怪獣対若大将P さんのイラスト - ニコニコ静画 (イラスト)

それぞれDLして解凍します。注意書きも熟読します。

ディレクトリの中にはたくさんのファイルがありますが、拡張子が.pmxのものを選択すればOKです。

f:id:mi_progress_oOo:20160614233909p:plain

そうすると、満月の夜空の下に美しいミクちゃんの姿が現れます!

マウスを適当に動かしたり、適当に色んな物をクリックして、画面に慣れてみてください。ミクちゃんが変になったら(あらぬ方向に曲がったりとか)、1回アプリを終了させて、もう一度読みこめば大丈夫です。私もよくわからず動かしてミクちゃんが曲がってしまい、何度も終了しました(笑)

 

そしていよいよ、ミクちゃんに好きなポーズになってもらいます。

実は踊らせることも可能です。

ポーズや踊りなどの"動き"のデータは、モデルのデータとはまた別の拡張子なんです。

最近HP作成ばっかりやってるからか、HPに似ているなぁと思いました。

HP作成でいうところの、HTMLファイル, CSSファイルで静的な実装を行い、JSファイルで動きをつける、そんな感じです。

 

というわけで、ポーズのファイルを読み込みましょう。

【ポーズ配布】いろいろなポーズ / lite さんのイラスト - ニコニコ静画 (イラスト)

今回はこれのB1を利用させて頂きました。.vpdという拡張子のファイルです。

 

先ほどのスクリーンショット画面左側にある、

▼モデル

 ・Tda式ミク・アペンド

をクリックして下さい。

f:id:mi_progress_oOo:20160614234746p:plain

 

そうするとモーション選択ができるようになります。

モーション▶モーションの読み込み

をクリックして、先ほどの.vpdファイルを開きます。

そうすると、ミクちゃんがそのポーズになってくれます!このとき、このポースが確定されていないので、登録ボタンを押すのを忘れないようにして下さい。

そうしたらほぼほぼ完成です!!!!

 

あとは影を消したり、カメラワークを凝ったり、光源を調整すれば、こんな感じになります。

f:id:mi_progress_oOo:20160614235159p:plain

超楽しいです。

皆さんもぜひ遊んでみてください。