【完成編】「俺が好きなのは妹だけど妹じゃない」の永見涼花ちゃんをナデナデして愛でるブログパーツを作ってみよう

ま、魔が差して仕事をサボって作っちゃっただけです。
魔が差したというのは重要な事なので覚えておいてくださいね!!

繰り返しになりますが…涼花ちゃんカワイイ!!

本企画を考えることになったキッカケであり、上のアイキャッチにも登場しているのが「俺が好きなのは妹だけど妹じゃない」永見 涼花(ながみ・すずか)ちゃんです。

TVアニメ『俺が好きなのは妹だけど妹じゃない』公式サイト

ライトノベル作家を目指す高校生・永見祐には、兄には厳しくどこか冷たい才色兼備で優等生の涼花という妹がいる。ある日、涼花が書いた“兄妹イチャイチャラブコメ”がラノベ大賞を受賞してしまった! ラノベや萌えが実は全く分からないという涼花の頼みで、なぜか祐が代理の作家・永遠野誓として活動することに! 個性的な業界関係者たちに揉まれながら妹のために永遠野誓として奮闘していく。そして、お兄ちゃんラブな雰囲気は微塵も見せていなかった涼花が...!?

マウスイベントのJavascriptについてはネット情報も多いので、今回のブログパーツもすんなりいくと思ってたんですが、マウスイベント以外の部分で手間取っちゃいました。
タイマー多重起動しちゃってたりとか…この辺はイベントドリブン型のプログラミングが感覚的にまだ慣れていないのが原因かな。
アルゴリズムを考えていく際に旧来の手続き型のワンクッションが入っちゃう感じでしょうか。
頭の中身は未だにDOS時代のままなのかもしれません。

作っている途中で「今のご時世スマホ操作にも対応してるのが当たり前だよな。」などと思ったのが運の尽きで、まぁそれからハマるハマる… (^∇^)アハハハハ!
GoogleChromeデベロッパーツールのコンソールログが大活躍でした。

それでもタッチイベントに対する多彩なネット情報のおかげもあって、まずまずスマホ対応と言えるようなものが出来ているんではないかと思います。
体感的にはスマホ操作の方がナデナデしている感がありますので、ぜひスマホでもお試しいただければと思います。

ブログパーツ自体はアレな感じですが、中身のコードについては応用できる部分が多分に含まれているのではないかと思います。
記事終盤でJavascriptコードも紹介していますので、プログラミングに興味のある方はそちらの方も参考に見てもらえればと思ってます。

涼花ちゃんの愛で方。

ブログパーツの内容については先日エントリーした【構想編】でも紹介しておりますが、あらためて涼花ちゃんの愛で方を説明しておきます。

.最初ちょっぴりツン気味な涼花ちゃんが表示されてます。

Suzuka-image1.png

.マウスカーソルを涼花ちゃんの頭のところ持っていくと(スマホは指でタッチすると)、カーソルが手のマークに変わり、照れた表情に切り替わります。

Suzuka-image2.png

.そして涼花ちゃんの頭のところで、マウスカーソルを左右に何回か10回以上振って(スマホは指で左右に擦って)ナデナデすると、デレた表情に切り替わります。

Suzuka-image3.png

ナデナデを止めて5秒経つと照れた表情に戻ります。
またマウスカーソルが頭の部分から外れて(スマホは指が離されて)から5秒経つと元のツン表情に戻ります。

涼花ちゃんをナデナデして愛でよう。

「俺が好きなのは妹だけど妹じゃない」の永見涼花をなでなでする

ブログパーツのHTMLとJavascriptです。

HTML

<img id="nadenade" src="初期画像" alt=""
  data-nadearea="ナデナデ反応範囲(1-100)"
  data-tereimg="照れ画像"
  data-dereimg="デレ画像">

Javascript

<script>
//----- 画像読込が完了してから起動する
window.addEventListener('load', function() {

  //===== グローバル変数宣言 =====
  var imgobj = document.getElementById("nadenade") ; // ナデナデ画像要素を取得

  var default_img = imgobj.src ;  // 初期画像保存
  var old_mouseX = 0 ;            // 前回マウスX軸位置クリア
  var direction_flg = 0 ;         // 前回マウス移動方向クリア
  var nade_count = 0 ;            // ナデナデ回数クリア
  var nade_timer_id = null;       // インターバルタイマーIDクリア
  var timeup_img ;                // タイムアップ時画像

  if ("ontouchstart" in window) {  //----- スマホ(タッチイベント搭載)の時 -----
      // 画像がタッチされたらナデナデ監視する
    imgobj.ontouchstart = CheckNadeNade ;
      // 画像の上で指が動いたらナデナデ監視する
    imgobj.ontouchmove = CheckNadeNade ;
      // 画像から指が外れたらナデナデ監視終了
    imgobj.ontouchend = EndNadeNade ;
  }
  else{  //----- PC(タッチイベント未搭載)の時 -----
      // マウスが画像の上にきたらナデナデ監視クリアする
    imgobj.onmouseover = ClearNadeNade ;
      // マウスが画像の上で動いたらナデナデ監視する
    imgobj.onmousemove = CheckNadeNade ;
      // マウスが画像から外れたらナデナデ監視終了
    imgobj.onmouseout = EndNadeNade ;
  }

  //=====  ナデナデ監視クリア =====
  function ClearNadeNade() {
    old_mouseX = 0 ;        // 前回マウスX軸位置をクリア
    direction_flg = 0 ;     // 前回マウス移動方向をクリア
    nade_count = 0 ;        // ナデナデ回数をクリア
  }

  //===== ナデナデ監視終了 =====
  function EndNadeNade() {
    ClearNadeNade() ;              // ナデナデ監視クリア
    timeup_img = default_img ;     // タイムアップ時に初期画像に戻す
    imgobj.style.cursor = "auto" ; // カーソルを矢印に戻す
  }


  //=====  ナデナデ監視 =====
  function CheckNadeNade(e){
    var mouseX, mouseY, offsetX=0, offsetY=0 ;

    //----- 画像の位置を取得する
    offsetX = this.offsetLeft ;
    offsetY = this.offsetTop ;

    //----- 画像内でのマウス位置座標を計算する
    if ("ontouchstart" in window) {  // スマホ(タッチイベント搭載)の時
      mouseX = e.changedTouches[0].pageX - offsetX ;
      mouseY = e.changedTouches[0].pageY - offsetY ;
    }
    else{  // PC(タッチイベント未搭載)の時
      mouseX = e.pageX - offsetX ;
      mouseY = e.pageY - offsetY ;
    }

    //----- マウスが頭のところにある時
    if (mouseY < imgobj.height * 0.01 * imgobj.dataset.nadearea){
      if (old_mouseX > mouseX){      // マウスが右に振られた時
        if (direction_flg == 2){       // 前回マウスが左に振られていた時
          nade_count++ ;               // ナデナデ回数をカウント
        }
        direction_flg = 1 ;            // マウスが右に振られた事を記録
        NadeNadeTimerClear() ;         // ナデナデ監視タイマークリア
      }
      else if (old_mouseX < mouseX){ // マウスが左に振られた時
        if (direction_flg == 1){       // 前回マウスが右に振られていた時
          nade_count++ ;               // ナデナデ回数をカウント
        }
        direction_flg = 2 ;            // マウスが左に振られた事を記録
        NadeNadeTimerClear() ;         // ナデナデ監視タイマークリア
      }

      if (nade_count >= 10){    // ナデナデ10回以上した時にデレ画像を表示
        imgobj.src = imgobj.dataset.dereimg ;
      }
      else {                    // ナデナデ10回未満の時にテレ画像を表示
        imgobj.src = imgobj.dataset.tereimg ;
      }
      timeup_img = imgobj.dataset.tereimg ; // タイムアップ時にテレ画像に戻す
      imgobj.style.cursor = "grab"          // カーソルを手の形にする

      if (nade_timer_id == null){ // タイマー未起動時、5秒タイマーを起動
        nade_timer_id = setInterval(function(){NadeNadeTimeup();}, 5000);
      }
      old_mouseX = mouseX ;       // マウスのX軸現在位置を記録
    }
    else{  //----- マウスが頭のところから外れている時、ナデナデ監視終了
      EndNadeNade() ;
    }
  }

  //===== ナデナデ監視タイムアップ(5秒で起動) =====
  function NadeNadeTimeup() {
    imgobj.src = timeup_img ; // タイムアップ指定画像を表示
    nade_count = 0 ;          // ナデナデ回数をクリア
    NadeNadeTimerClear() ;    // ナデナデ監視タイマークリア
  }

  //===== ナデナデ監視タイマークリア =====
  function NadeNadeTimerClear() {
    if (nade_timer_id != null){      // インターバルタイマーが起動している時
      clearInterval(nade_timer_id) ; // インターバルタイマーをクリア
      nade_timer_id = null ;         // タイマーID値をクリア
    }
  }
});
</script>

※記事編集の詳細設定で<改行の扱い>を【HTMLタグのみ】にしてください。

コードのポイント解説。

今回HTML部分でHTML5のカスタムデータ属性(data-xxxx)を使ってみました。
Javascript内のコードを変更せずに、HTMLだけで切り替える画像やナデナデ反応範囲のカスタマイズを行えるようになっています。

<img id="nadenade" src="初期画像" alt=""
  data-nadearea="35"
  data-tereimg="照れ画像"
  data-dereimg="デレ画像">

2行目の「data-nadearea=」にはナデナデ反応範囲を指定しています。
レスポンシブに対応させるために画像全体高さに対する画像上端からの%比率で設定できます。
上のコードでは35を設定していますので、画像高さが300pxで表示されている時は画像上端から300px×35%=105pxがナデナデ反応範囲となります。

3・4行目はそれぞれナデナデ反応範囲にマウスが乗った時の「照れ画像」と、ナデナデ操作が行われた時の「デレ画像」を設定することができるようにしてあります。


画像の読み込みが完了していないと画像に対するマウスイベントが発生しませんでした。
まぁ当然と言えばそうなのですが、最初コレが分らなくて出だしからつまずいてしまいました。 なのでページ読み込み完了イベントでJavascriptを走らせるようにしてあります。

window.addEventListener('load', function() { // 画像読込が完了してから起動する
  :
省略
  :
});

こんなことならimgタグ内からマウスイベント属性を使って関数コールした方が楽だったかもしれませんが、HTMLが煩雑にならないようにスマホ操作に対応させたかったこともあって、Javascript内でのマウス(タッチ)イベント処理にこだわってみました。


今回は涼花ちゃんの頭へのマウスオンやナデナデをスマホでも操作できるようにしたかったので、タッチイベント搭載有無でマウス(タッチ)イベント処理を切り替えて関数を設定しています。

if ("ontouchstart" in window) {  //----- スマホ(タッチイベント搭載)の時 -----      // 画像がタッチされたらナデナデ監視する
  imgobj.ontouchstart = CheckNadeNade ;
    // 画像の上で指が動いたらナデナデ監視する
  imgobj.ontouchmove = CheckNadeNade ;
    // 画像から指が外れたらナデナデ監視終了
  imgobj.ontouchend = EndNadeNade ;
}
else{  //----- PC(タッチイベント未搭載)の時 -----
    // マウスが画像の上にきたらナデナデ監視クリアする
  imgobj.onmouseover = ClearNadeNade ;
    // マウスが画像の上で動いたらナデナデ監視する
  imgobj.onmousemove = CheckNadeNade ;
    // マウスが画像から外れたらナデナデ監視終了
  imgobj.onmouseout = EndNadeNade ;
}

またスマホ操作ではマウス座標の取得方法も変わってきますので、プログラミングする時は注意が必要です。


  //----- 画像内でのマウス位置座標を計算する
if ("ontouchstart" in window) {  // スマホ(タッチイベント搭載)の時
  mouseX = e.changedTouches[0].pageX - offsetX ;
  mouseY = e.changedTouches[0].pageY - offsetY ;
}
else{  // PC(タッチイベント未搭載)の時
  mouseX = e.pageX - offsetX ;
  mouseY = e.pageY - offsetY ;
}
スポンサーサイト
ブログツールアニメ俺が好きなのは妹だけど妹じゃない永見涼花

0 Comments

Post a comment