ポートフォーリオサイト制作(JavaScript)

Photo by Greg Rakozy on Unsplash プログラミング
Photo by Greg Rakozy on Unsplash

こんにちは、コンスキです。

今回もJavaScriptを書いて要素に動きをつけていきます。

ブログ部分のアニメーション

ブログ部分のパソコンの画像に前回は次のようなアニメーションをつけました。

現在はパソコン画面が切り替わるごとに画像の透明度を変化させているだけです。

これだけでは少し寂しいのでパソコン画面に映っているブログページが切り替わる度に、次のような動きが着くようにアニメーションを追加します。

  • パソコン自体を下から上にスライドインする
  • 画面右側にあるブログタイトルとブログの内容も同じようなアニメーションをつける

アニメーションが完成すると次のようになります。

この動きをつけるために書いたJavaScriptとは次のようなものです。

// 表示されている要素のインデックス
let activeElementIndex = 0;
// 要素を取得する
let imgSlider = document.getElementById('img_slider_item_container');
let nextButton = document.getElementById('down_arrow');
let prevButton = document.getElementById('up_arrow');
let categoryArray = document.getElementsByClassName('blog_category')
let liSlider = document.getElementById('blog_text_list')

function fontSwitching() {
  Object.keys(categoryArray).forEach(function(key)  {
    console.log(categoryArray[key].classList.remove('emphasize'))
  })
  categoryArray[activeElementIndex].classList.add('emphasize');
}

// 表示されている画像以外の位置を「top: 70px;」にリセットする関数
function imgPositionReset() {                      
  Object.keys(imageArray).filter(function(element) {
    return element != activeElementIndex
  }).forEach(function(key)  {
    imageArray[key].style.top = '70px'
  })
}


// 1番目のブログ画像の表示と1番目のカテゴリーの強調
let imageArray = imgSlider.getElementsByTagName('img');
imageArray[activeElementIndex].style.opacity = '1';
imageArray[activeElementIndex].style.top = '0';
categoryArray[activeElementIndex].classList.add('emphasize');

// 1番目のブログタイトルとブログの内容の表示
let textArray = liSlider.getElementsByTagName('li');
textArray[activeElementIndex].style.opacity = '1';
textArray[activeElementIndex].style.top = '0';


// 次の要素を表示に切り替える関数
function nextElement(){
  imageArray[activeElementIndex].style.opacity = '0';
  textArray[activeElementIndex].style.opacity = '0';
  setTimeout(function() {
    imageArray[activeElementIndex].style.top = '-70px';
    textArray[activeElementIndex].style.top = '-70px';
    if(activeElementIndex >= imageArray.length - 1){
      activeElementIndex = 0;
    }else{
      activeElementIndex++;
    }
    setTimeout(function() {
      imageArray[activeElementIndex].style.top = '0';
      textArray[activeElementIndex].style.top = '0';
      setTimeout(function() {
        imageArray[activeElementIndex].style.opacity = '1';
        textArray[activeElementIndex].style.opacity = '1';
        Object.keys(imageArray).forEach(function(key)  {
          console.log(imageArray[key].style.top)
        }, 100)
        imgPositionReset();
      })
    }, 500);
    fontSwitching();
  }, 100)
}

// 前の要素に切り替える関数
function previousElement(){
  imageArray[activeElementIndex].style.opacity = '0';
  textArray[activeElementIndex].style.opacity = '0';
  setTimeout(function() {
    imageArray[activeElementIndex].style.top = '-70px';
    textArray[activeElementIndex].style.top = '-70px';
    if(activeElementIndex <= 0){
      activeElementIndex = imageArray.length - 1;
    }else{
      activeElementIndex--;
    }
    setTimeout(function() {
      imageArray[activeElementIndex].style.top = '0';
      textArray[activeElementIndex].style.top = '0';
      setTimeout(function() {
        imageArray[activeElementIndex].style.opacity = '1';
        textArray[activeElementIndex].style.opacity = '1';
        Object.keys(imageArray).forEach(function(key)  {
          console.log(imageArray[key].style.top)
        }, 100)
        imgPositionReset();
      })
    }, 500);
    fontSwitching();
  }, 100)
}

// 下矢印をクリックされたら次の要素に切り替える
nextButton.addEventListener('click', function() {
  nextElement();
  console.log(activeElementIndex)
  console.log(textArray)
});
上矢印をクリックされたら前の要素に切り替える
prevButton.addEventListener('click', function() {
  previousElement();
  console.log(activeElementIndex)
});

JavaScriptに出てくるidやclass、スタイルとの関係がわかるようにHTMLとCSSも下に示します。

<!-- Blogセクション -->
<div class="section" id="blog">
  <div class="heading">
    <div class="heading_text">
      <div class="heading_text_inner">
        <h2 class="heading_name">Blog</h2>
        <div class="to_single_page_container">
          <p class="to_single_page">個別ページはこちら</p>
          <svg class="arrow_circle_right" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M256 8c137 0 248 111 248 248S393 504 256 504 8 393 8 256 119 8 256 8zm-28.9 143.6l75.5 72.4H120c-13.3 0-24 10.7-24 24v16c0 13.3 10.7 24 24 24h182.6l-75.5 72.4c-9.7 9.3-9.9 24.8-.4 34.3l11 10.9c9.4 9.4 24.6 9.4 33.9 0L404.3 273c9.4-9.4 9.4-24.6 0-33.9L271.6 106.3c-9.4-9.4-24.6-9.4-33.9 0l-11 10.9c-9.5 9.6-9.3 25.1.4 34.4z"/></svg>
        </div>
      </div>
    </div>
    <div class="heading_img_container">
      <img src="assets//img/blog_heading.jpg" alt="" class="heading_img" width="720" height="426">
    </div>
  </div>
  <div class="content" id="blog_content">
    <div id="blog_container">
      <h3 id="blog_content_heading">プログラミングやITに関して発信しています。</h3>
      <div id="blog_content_container">
        <div id="blog_categories_list">
          <img src="assets//img/up_arrow_gray.svg" alt="" id="up_arrow" width="28" height="32">
          <ul id="blog_categories">
            <li class="blog_category" id="blog_category1">Vue.js</li>
            <li class="blog_category" id="blog_category2">音読さん</li>
            <li class="blog_category" id="blog_category3">WordPress</li>
          </ul>
          <img src="assets//img/down_arrow_gray.svg" alt="" id="down_arrow" width="28" height="32">
        </div>
        <div id="blog_content_img_container">
          <div id="img_slider_item_container">
            <img src="assets//img/pc_vuejs.png" alt="" id="pc_vuejs" class="img_slider_item" width="850">
            <img src="assets//img/pc_ondokusan.png" alt="" id="pc_ondokusan" class="img_slider_item" width="850">
            <img src="assets//img/pc_wordpress.png" alt="" id="pc_wordpress" class="img_slider_item" width="850">
          </div>
          <div id="blog_content_text_container">
            <ul id="blog_text_list">
              <li class="blog_text" id="blog_text2">
                <h4 class="blog_text_title" id="blog_text2_title">第2回Vue.js入門 導入</h4>
                <p class="blog_text_content" id="blog_text2_content">今回から、Vue.jsの記述方法の説明をしていきます。Vue.jsを始めるために、まずhtmlにscriptタグを使ってVue.jsを導入します。Vueの最新のバージョンがコンテンツを配布してくれているCDNにあるので、「https://unpkg.com/vue」というURLをsrc属性に書きま...</p>
              </li>
              <li class="blog_text" id="blog_text1">
                <h4 class="blog_text_title" id="blog_text1_title">おすすめの読み上げソフト<br>「音読さん」</h4>
                <p class="blog_text_content" id="blog_text1_content">「音読さん」っていうソフト知ってますか?自分の代わりにアナウンサーレベルの声で喋ってくれるソフトです。これは、音読さんを使って大学の遠隔授業でプレゼンをした際の動画です。声はすべて音読さんで...</p>
              </li>
              <li class="blog_text" id="blog_text3">
                <h4 class="blog_text_title" id="blog_text3_title">HTMLで自作したサイトをWordPressで管理する</h4>
                <p class="blog_text_content" id="blog_text3_content">HTMLを使って自分で作ったサイトをWordPressを使って管理する方法を説明します。WordPressを使うことの利点はサイトの編集が手軽になることです。WordPressを使うと、サイトページの内容を変更したい...</p>
              </li>
            </ul>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
img {
  display: block;
}

/* ヘッダートップ */
#header_top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  position: fixed;
  left: 0;
  top: 0;
  z-index: 10000;
  width: 100vw;
  height: 64px;
  padding: 0 43px 0;
  background-color: #ffffff;
}
#navigation_bar_container {
  height: 18px;
}
#navigation_bar {
  display: flex;
  margin: auto 0 auto;
}
.nav_item {
  height: 18px;
}
.nav_text {
  margin-right: 46px;
}
#nav_text_last {
  margin-right: 0;
}
#first_view {
  margin-top: 64px;
}

/* ファーストビュー */
#first_view {
  display: flex;
  padding: 85px 110px;
  background-color: #C9e8de;
}
#fv_tagline_main_container {
  margin-bottom: 18px;
}
.fv_tagline_main {
  font-size: 52px;
}
#fv_tagline_sub_container {
  margin-bottom: 153px;
}
.fv_tagline_sub {
  font-size: 18px;
}
#fv_contact_button {
  margin-bottom: 18px;
  padding: 15px 30px;
  border-radius: 30px;
  background-color: #000000;
  color: #ffffff;
  font-size: 18px;
}
#fv_contact_button:hover {
  opacity: 0.7;
}
#more_info_container {
  display: flex;
  align-items: center;
}
#more_info_container:hover #info_icon {
  fill: #658686;
} 
#more_info_container:hover #more_info {
  color: #658686
}
#info_icon {
  width: 22px;
  height: 22px;
  margin-right: 5px;
}
#more_info {
  font-size: 18px;
}

#fv_img_container {
  margin-top: 170px;
}

/* メインの全セクション共通スタイル */
/* 見出し */
.heading {
  display: flex;
  width: 100%;
  height: 426px;
  box-sizing: content-box;
  border-top: 1px solid #000000;
  border-bottom: 1px solid #000000;
  background-color: #000000;
}
.heading_img_container {
  width: 50%;
}
.heading_text {
  width: 50%;
  padding: 130px 150px 180px 120px;
}
.heading_name {
  display: inline;
  color: #ffffff;
  font-size: 52px;
}
.to_single_page_container {
  display: flex;
  align-items: center;
  margin-top: 10px;
}
.to_single_page {
  display: inline;
  margin-right: 5px;
  color: #9e9e9e;
  font-style: 18px;
}
.arrow_circle_right {
  width: 20px;
  height: 20px;
  fill: #6e6e6e;
}
.to_single_page_container:hover .to_single_page {
  color: #658686;
}
.to_single_page_container:hover .arrow_circle_right {
  fill: #658686;
}

/* 内容 */
.content {
  margin: 0 150px 0;
}

/* Aboutセクション */
#about {
  margin-top: 64px;
}
/* 内容 */
#about_content {
  position: relative;
  top: 0;
  left: 0;
  padding: 100px 0;
}
#name_heading,
#age_heading,
#name_content, 
#age_content {
  font-size: 32px;
}
#skills_heading,
#where_i_work_heading,
#what_i_value_heading,
#where_i_work_content,
#what_i_value_content,
.skills {
  font-style: 18px;
}
.about_content_heading {
  margin-bottom: 18px;
  font-weight: 600;
}
#about_content_line1 {
  display: flex;
}
#about_content_line2 {
  display: flex;
}
#name_container {
  margin-right: 100px;
  margin-bottom: 60px;
}
#skills_container {
  margin-right: 100px;
}
#skills_contents {
  list-style: square inside;
}
#where_i_work_container {
  margin-right: 100px;
}
#what_i_value_container {
  width: 446px;
}
#what_i_value_content {
  position: relative;
  z-index: 1000;
  background-color: #ffffff;
}
#about_content_img_container {
  position: absolute;
  bottom: 50px;
  right: -160px;
}

/* Worksセクション */
/* 内容 */
#works_content {
  padding: 100px 0;
}
.site_sumbnail {
  margin-bottom: 5px;
}
#site_sumbnails_line1 {
  display: flex;
  margin-bottom: 20px;
}
#site_sumbnails_line2 {
  display: flex;
}
.site_sumbnail_container {
  margin-right: 30px;
}
#site_sumbnail3_container,
#site_sumbnail6_container {
  margin-right: 0;
}

/* Blogセクション */
/* 内容 */
#blog_content {
  height: 495px;
  margin: 0 80px 0;
  padding: 80px 0 80px;
  box-sizing: content-box;
}
#blog_content_heading {
  margin-bottom: 30px;
  font-size: 18px;
}
#blog_content_container {
  position: relative;
}
#blog_content_img_container {
  position: relative;
  top: 0;
  left: 0;
  transition: all 0.3s 0s ease;
}
#blog_categories_list {
  position: absolute;
  z-index: 1000;
  top: 60px;
  left: 60px;
}
#up_arrow {
  position: relative;
  top: 0;
  left: 0;
  width: 20px;
  height: 32px;
  margin-left: auto;
  transition: top 0.5s;
}
#up_arrow:hover {
  top: -5px
}
.blog_category {
  width: 125px;
  margin: 20px 0;
  color: #9e9e9e;
  font-size: 20px;
  transition: all 0.5s 0s ease;
}
#blog_category1 {
  width: 70px;
  margin-left: auto;
}
#blog_category2 {
  width: 85px;
  margin-left: auto;
}
#blog_category3 {
}
#down_arrow {
  position: relative;
  top: 0;
  left: 0;
  width: 20px;
  height: 32px;
  margin-left: auto;
  transition: top 0.5s;
}
#down_arrow:hover {
  top: 5px;
}
#pc_ondockusan {
  position: absolute;
  top: 0;
  left: 0;
}
#blog_content_text_container {
  position: absolute;
  top: 70px;
  left:700px;
  width: 600px;
}
#blog_text_list {
  /* opacity: 0; */
}
.blog_text {
  position: absolute;
  top: 0;
  left: 0;
  opacity: 0;
  transition: all 0.3s 0s ease;
}
.blog_text_title {
  margin-bottom: 20px;
  font-size: 48px;
}
.blog_text_content {
  color: #9e9e9e;
  font-size: 18px;
}

/* Contactセクション */
/* 内容 */
#contact_content {
  padding: 90px 0;
  height: 1050px;
}

/* フッター */
footer {
  padding: 36px 100px 0;
  background-color: #000000;
}
#footer_hr {
  height: 1px;
  border: none;
  background-color: #9e9e9e;
}
#copyright_contaier {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 150px;
} 
#copyright {
  color: #ffffff;
}


.img_slider_item_container {
  position: relative;
}
.img_slider_item {
  position: absolute;
  top: 70px;
  bottom: 0;
  opacity: 0;
  transition: all 0.5s 0s ease;
}
.emphasize {
  color: #000000;
  font-weight: bold;
}

おわりに

今回は、ブログページを切り替える時のアニメーションを工夫してみました。

透明度を変化させるフェードインフェードアウトだけでも良いのですが、スライドインスライドアウトのアニメーションを加えたことでページが切り替わったことがはっきりわかるようになったと思います。

次回は、WordPressとの結びつけを行います。

WordPressと結びつければ、お問い合わせフォームの部分をようやく表示することができるので楽しみです。

コメント

タイトルとURLをコピーしました