WEBサイト制作の勉強

WEBサイト制作の勉強の為の解説ブログです。

フェリカテクニカルアカデミー

便利なツールや読んでおきたい記事まとめ

note.com



swingroot.com



cocoda-design.com



ctrlq.org




stylifyme.com




ten-navi.com




frontendweekly.tokyo



www.noupe.com



icomoon.io



bitwarden.com



webで生活を便利にするメディア
shogo-log.com



もぐもぐ食べる、おいしいWebデザイン。
mogumogu-design.com


wweb.dev




「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
https://wa3.i-3-i.info/index.html

フィルタリングやソートが出来る高機能プラグイン「muuri.js」

フィルター機能、ソート機能が付いて可変グリッドレイアウトも実現出来さらにレスポンシブにも対応した、無料で商用利用も可能な  Javascriptプラグインの「muuri.js」



haltu.github.io



付いている機能

  • フィルター機能
  • ソート機能
  • 検索機能
  • Masonryレイアウト
  • ドラッグ機能

など、非常に高機能です。


digipress.info




See the Pen
Muuri.js
by yachin29 (@yachin29)
on CodePen.



index.html
<body>
<h1>Grid Layout by Muuri.js</h1>

<section class="grid-wrapper">
<div class="filter-controls">
<div class="control">Search
<input class="search-field form-control" type="text" name="search" placeholder="Enter the fruit name">
</div>
<div class="control">Filter
<select class="filter-field form-control">
<option value="">None</option>
<option value="red">Red</option>
<option value="blue">Blue</option>
<option value="green">Green</option>
</select>
</div>
<div class="control">Sort
<select class="sort-field form-control">
<option value="order">None</option>
<option value="title">Order by number</option>
<option value="color">Order by color name</option>
</select>
</div>
</div><!-- filter-controls -->

<div class="grid">
<div class="item blue w2 h2" data-color="blue" data-title="01">
<div class="item-content">
<!-- Safe zone, enter your custom markup -->
<div class="custom-content">
 Item 1
</div>
</div>
</div><!-- item -->

<div class="item red w2" data-color="red" data-color="blue" data-title="05">
<div class="item-content">
<div class="custom-content">
Item 5
</div>
</div>
</div><!-- item -->

<div class="item green w2" data-color="green" data-color="blue" data-title="03">
<div class="item-content">
<div class="custom-content">
Item 3
</div>
</div>
</div><!-- item -->

<div class="item red w2 h2" data-color="red" data-color="blue" data-title="04">
<div class="item-content">
<div class="custom-content">
Item 4
</div>
</div>
</div><!-- item -->

<div class="item red" data-color="red" data-color="blue" data-title="02">
<div class="item-content">
<div class="custom-content">
Item 2
</div>
</div>
</div><!-- item -->

<div class="item blue" data-color="blue" data-color="blue" data-title="06">
<div class="item-content">
<div class="custom-content">
Item 6
</div>
</div>
</div><!-- item -->

<div class="item red h2" data-color="red" data-color="blue" data-title="12">
<div class="item-content">
<div class="custom-content">
Item 12
</div>
</div>
</div><!-- item -->

<div class="item green h2" data-color="green" data-color="blue" data-title="08">
<div class="item-content">
<div class="custom-content">
Item 8
</div>
</div>
</div><!-- item -->

<div class="item green w2" data-color="green" data-color="blue" data-title="11">
<div class="item-content">
<div class="custom-content">
Item 11
</div>
</div>
</div><!-- item -->

<div class="item blue w2" data-color="blue" data-color="blue" data-title="10">
<div class="item-content">
<div class="custom-content">
Item 10
</div>
</div>
</div><!-- item -->

<div class="item green" data-color="green" data-color="blue" data-title="07">
<div class="item-content">
<div class="custom-content">
Item 7
</div>
</div>
</div><!-- item -->

<div class="item red" data-color="red" data-color="blue" data-title="09">
<div class="item-content">
<div class="custom-content">
Item 9
</div>
</div>
</div><!-- item -->


</div>
</select>


<script src="https://cdnjs.cloudflare.com/ajax/libs/web-animations/2.3.1/web-animations.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js"></script>
<script src="js/muuri.js"></script>
<script src="js/script.js"></script>
</body>
muuri.scss
// ******************************
// Normalize (ignore me!)
// ******************************

$bg_color:#fff;
$font_color:#333;
$link_color:#999;
$link_hover_color:#777;

* {
  &:before,
  &:after{
    box-sizing:border-box;
    padding:0;
    margin:0;
  }
}
body{
  background-color:$bg_color;
  color: $font_color;
  text-align: center;
  a, a:visited{
    color: $link_color;
    text-decoration:none;
  }
  a:hover{
    color: $link_hover_color;
  }
}
// ******************************
// End of Normalize
// ******************************

h1{
  font-size:36px;
  margin:40px auto;
}
.filter-controls{
  text-align:center;
  margin-bottom:30px;
  .control{
    display:inline-block;
    width:240px;
    margin:0 10px;
    *{
      box-sizing:border-box;
    }
    .form-control{
      width:100%;
      height:40px;
      padding:0 20px;
      border:2px solid #ccc;
      border-radius:3px;
      background-color:#fff;
      color:#666;
      font-size:16px;
      cursor:pointer;
      -webkit-appearance:none;
      appearance:none;
      &:focus{
        outline:0;
        border-color:#0CAAF5;
      }
    }
  }  
}

.grid {
  position: relative;
  max-width:80%;
  margin:0 auto;
}
.item {
  position: absolute;
  width:200px;
  height:200px;
  margin: 5px;
  z-index: 1;
  transition:transform .6s ease;
  cursor:move;
  &.blue{
    .custom-content{
      border-color:#0CAAF5;
      color:#0CAAF5;
    }
  }
  &.red{
    .custom-content{
      border-color:#F54487;
      color:#F54487;
    }
  }
  &.green{
    .custom-content{
      border-color:#00DE73;
      color:#00DE73;
    }
  }
  &.w2{
    width:410px;
  }
  &.h2{
    height:410px;
  }
}
.item-content {
  position: relative;
  width: 100%;
  height: 100%;
  display:table;
}
.custom-content{
  display:table-cell;
  vertical-align:middle;
  text-align: center;
  background: #fff;
  color: #666;
  border:2px solid;
  border-radius:3px;
}

// If use dragging
.item.muuri-item-dragging {
  z-index: 3;
  transition:none;
}
.item.muuri-item-releasing {
  z-index: 2;
}

@media ( max-width : 877px ){
  .item{
    width:calc(33.33% - 11px);
    height:calc(33.33vw - 11px);
    &.w2{
      width:calc(33.33% - 11px);
    }
    &.h2{
      height:calc(33.33vw - 11px);
    }
  }
}
@media ( max-width : 640px ){
  .item{
    width:calc(50% - 10px);
    height:calc(50vw - 10px);
    &.w2{
      width:calc(50% - 10px);
    }
    &.h2{
      height:calc(50vw - 10px);
    }
  }
}
CDN
<script src="https://cdn.jsdelivr.net/npm/muuri@0.9.3/dist/muuri.min.js"></script>
muuri.js
document.addEventListener('DOMContentLoaded', function () {
  var grid = null,
      wrapper = document.querySelector('.grid-wrapper'),
      searchField = wrapper.querySelector('.search-field'),
      filterField = wrapper.querySelector('.filter-field'),
      sortField = wrapper.querySelector('.sort-field'),
      gridElem = wrapper.querySelector('.grid'),
      searchAttr = 'data-title',
      filterAttr = 'data-color',
      searchFieldValue,
      filterFieldValue,
      sortFieldValue,
      dragOrder = [];

  // Init the grid layout
  grid = new Muuri(gridElem, {
    dragEnabled: true
  });
  
  // Set inital search query, active filter, active sort value and active layout.
  searchFieldValue = searchField.value.toLowerCase();
  filterFieldValue = filterField.value;
  sortFieldValue = sortField.value;

  // Search field event binding
  searchField.addEventListener('keyup', function () {
    var newSearch = searchField.value.toLowerCase();
    if (searchFieldValue !== newSearch) {
      searchFieldValue = newSearch;
      filter();
    }
  });

  // Filter field event binding
  filterField.addEventListener('change', filter);
  
  // Sort field event binding
  sortField.addEventListener('change', sort);

  // Filtering
  function filter() {
    filterFieldValue = filterField.value;
    grid.filter(function (item) {
      var element = item.getElement(),
          isSearchMatch = !searchFieldValue ? true : (element.getAttribute(searchAttr) || '').toLowerCase().indexOf(searchFieldValue) > -1,
          isFilterMatch = !filterFieldValue ? true : (element.getAttribute(filterAttr) || '') === filterFieldValue;
      return isSearchMatch && isFilterMatch;
    });
  }
  
  // Sorting
  function sort() {
    // Do nothing if sort value did not change.
    var currentSort = sortField.value;
    if (sortFieldValue === currentSort) {
      return;
    }

    // If we are changing from "order" sorting to something else
    // let's store the drag order.
    if (sortFieldValue === 'order') {
      dragOrder = grid.getItems();
    }

    // Sort the items.
    grid.sort(
      currentSort === 'title' ? compareItemTitle :
      currentSort === 'color' ? compareItemColor :
      dragOrder
    );
    sortFieldValue = currentSort;
  }
  
  // Compare data-title
  function compareItemTitle(a, b) {
    var aVal = a.getElement().getAttribute(searchAttr) || '';
    var bVal = b.getElement().getAttribute(searchAttr) || '';
    return aVal < bVal ? -1 : aVal > bVal ? 1 : 0;

  }

  // Compare data-color
  function compareItemColor(a, b) {
    var aVal = a.getElement().getAttribute(filterAttr) || '';
    var bVal = b.getElement().getAttribute(filterAttr) || '';
    return aVal < bVal ? -1 : aVal > bVal ? 1 : compareItemTitle(a, b);
  }
});

random関数

JavaScriptで乱数を取得したい場合には「random関数」を使います。

覚えるメソッド

Math.random

Math.random()は、0〜0.9999...(1未満)の間から、1つの数値をランダムで返すメソッドです。0は含みますが、1は含みません。

Math.round

Math.floor()は、小数点以下を四捨五入するメソッドです。整数を取得したい場合に利用します。

Math.ceil

Math.floor()は、小数点以下を切り上げるメソッドです。0.999なら1、3.21なら4という数値を返します。

Math.floor

Math.floor()は、小数点以下を切り捨てるメソッドです。0.999なら0、3.21なら3という数値を返します。


<script>
  var a =  Math.random();
 
  document.write(a);
</script>

0から10までの数字をランダムで取得したい場合

<script>
// 0〜10の乱数を発生 ([10]を指定する)
var a = Math.floor( Math.random() * 10 ) ;

 document.write(a);
</script>

各メソッドを実際に表示させる

<script>
 
  var a = Math.round( Math.random() * 10);  //小数点以下を四捨五入
  var b = Math.ceil( Math.random() * 10);  //小数点以下を切り上げ
  var c = Math.floor( Math.random() * 10);  //小数点以下を切り捨て

  document.write(a + '<br>');
  document.write(b + '<br>');
  document.write(c + '<br>');
</script>

任意の範囲での乱数を取得するには

<script>
// 5〜10の乱数を発生 [11-5]と[5]を指定する
var a = Math.floor( Math.random() * 6 ) + 5 ;
</script

画像をランダムで表示する

「img0.jpg」「img1.jpg」「img2.jpg」「img3.jpg」のファイル名をつけた画像を準備する
「img1.jpg」からの場合は、((Math.random()*numOfImg)+1)となる

<script>
var numOfImg = 4;
var num;
num = Math.floor(Math.random() * numOfImg)
document.write('<img src="img/img' + num + '.jpg">');
</script>

画像にあしらいをつける

あしらいとは、デザインにおいての「装飾」のことです。入れる事で雰囲気や華やかさが出るので色々なパターンのあしらいを覚えてみましょう。

radial-gradientを使ったあしらい


f:id:yachin29:20201119002620p:plain


See the Pen
css3での使ったあしらい1
by yachin29 (@yachin29)
on CodePen.



transformのrotateを使ったあしらい

f:id:yachin29:20201119002944p:plain




See the Pen
css3を使ったあしらい2
by yachin29 (@yachin29)
on CodePen.

Canvasを使ってグラフが作れる「Chart.js」

canvasとは

Canvasとは、ブラウザ上に図を描くために策定された仕様です。

これまでHTML上で図を表現するためには、GIFやJPEGといったフォーマットの画像を用意する必要がありました。また、条件に応じて表示する図を変化させたり、アニメーションを実現するために、FlashJavaアプレットが使われてきました。

Canvasは、FlashJavaのようにプラグインを使わずに、JavaScriptベースで図を描くことができます。
Canvasは、もともとはAppleが発祥で、当初、Mac OSでおなじみのDashboardで使われた技術仕様です。その後、AppleMozilla FoundationOpera Softwareといったブラウザベンダが立ち上げたWHATWGという団体にて策定作業が行われていた「Web Applications」と呼ばれる規格に採用されました。

www.htmq.com



https://canvas.apps.chrome/



Chart.js

折れ線グラフ、棒グラフ、円グラフ、レーダーチャートなど、6種類のグラフが描けるJavascriptのライブラリです。
HTML5Canvasを使って描画され、誰でも簡単に編集ができるようになっています。

www.chartjs.org


今回はCDNにあるバンドルファイルを使用します。

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js"></script>




qiita.com






作例

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
 <title>円グラフ</title> 
<style>
h1 {
text-align: center;
}
#box {
width: 800px;
margin: 50px auto 0;
}
</style>
</head>
<body>
  <h1>円グラフ</h1>
  <div id="box">
  <canvas id="myChart"></canvas>
  </div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js"></script>

  <script>
  var ctx = document.getElementById("myChart");
  var myDoughnutChart = new Chart(ctx, {
    type: 'doughnut',
    data: {
      labels: ["A型", "O型", "B型", "AB型"],
      datasets: [{
          backgroundColor: [
              "#BB5179",
              "#EBB350",
              "#6ABB77",
              "#29A3D5"
          ],
          data: [38, 31, 21, 10]
      }]
    },
    options: {
      title: {
        display: true,
        text: '血液型 割合'
      }
    }
  });
  </script>
</body>
</html>


See the Pen
radar-chart
by yachin29 (@yachin29)
on CodePen.

Sassを使ってレスポンシブサイトをコーディングしてみる

f:id:yachin29:20190815141115j:plain


素材
http://school.yachin29.com/0815test.zip


レスポンシブサイトを作る際にはメディアクエリーが必須ですが、これもSassのmixinを使う事で見通しの良い記述に変える事が出来ます。
またブレイクポイントやメインのカラーコードを変数化する事で効率化が図れます。

さらに、今回はmarginやpaddingの値を8pxの倍数に設定します。

変数の設定
$point-tablet: 959px;
$point-sp: 767px;
mixinの使い方
@mixin 名前 {
  @media (max-width:$point-tablet) {
    @content;
  }
}
@mixin sp {
  @media (max-width:$point-sp) {
    @content;
  }
}

body {
  background: #222;
  @include tablet {
      background: #f00;
  }
   @include sp {
      background: #df9e3d;
  }
}


index.html

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>THAI-NAMA|SASSを使ったコーディング</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<header>
<div class="inner">
<h1>THAI-NAMA</h1>
<nav class="g-nav">
<ul>
    <li><a href="#">CONCEPT</a></li>
    <li><a href="#">MENU</a></li>
    <li><a href="#">ACCESS</a></li>
    <li><a href="#">CONTACT</a></li>
</ul>
</nav>
</div>
</header>
    
<div class="main-visual">
<img src="img/main.jpg" alt="">
</div>
<p class="main-copy">THAI-NAMAは<br>
タイ風の家庭的な料理をご提供しているお店です。<br>
季節感を大切に、旬のものを使いつつ、楽しんで貰えるメニューを揃えています。</p>

<ul class="food">
<li><img src="img/sub1.jpg" alt=""></li>
<li><img src="img/sub2.jpg" alt=""></li>
<li><img src="img/sub3.jpg" alt=""></li>
</ul>

<div class="news">
<h2>NEWS</h2>
<dl>
<dt>2020/03/03</dt>
<dd>春のメニューを追加しました</dd>
</dl>
</div> 

<footer>
<ul class="footer-nav">
    <li><a href="#">CONCEPT</a></li>
    <li><a href="#">MENU</a></li>
    <li><a href="#">ACCESS</a></li>
    <li><a href="#">CONTACT</a></li>
</ul>
<div class="footer-wrapper">
<div class="footer-info">
<p class="tel"><a href="tel:03-1234-4567">03-1234-4567</a></p>
<p class="mail">reservation@thai-nama.net</p>
</div>
<div class="footer-address">
<p class="address-txt">〒150-0001 東京都渋谷区神宮前3-4-5 タイ生ビル1F</p>
<p class="jr">JR渋谷駅徒歩5分</p>
<p class="jr"></p>JR原宿駅徒歩6分</p>
<p class="subway">副都心線、千代田線明治神宮前徒歩7分</p>
</div><!-- /.footer-address -->
</div><!-- /.footer-wrapper -->
<p class="copy-right"><small>Copyright 2020 THAI-NAMA</small></p>
</footer>
</body>
</html>


style.scss

@import "_reset.scss";

//変数セット
$main-color:#c94343;
$footer-color:#60911d;
$unit:8px;
$point-tablet: 979px;
$point-sp-l:640px;
$point-sp-s:480px;

//mixinセット
@mixin tablet {
    @media (max-width:$point-tablet) {
      @content;
    }
}
@mixin sp-l {
    @media (max-width:$point-sp-l) {
      @content;
    }
}
@mixin sp-s {
    @media (max-width:$point-sp-s) {
      @content;
    }
}

/* pcレイアウト */
header{
width: 100%;
border-bottom: 4px solid $main-color;
}
.inner{
max-width: 980px;
margin: 0 auto;
display: flex;
justify-content: space-between;
 @include tablet{
 display: block;
 }
}
h1{
width: 280px;
height: 42px;
margin: 10px 0;
background: url(../img/logo.png)no-repeat;
white-space: nowrap;
text-indent: 100%;
overflow: hidden;
@include tablet{
 margin: 10px auto;
}
}
.g-nav{
align-self:flex-end;
}
.g-nav>ul{
display: flex;
@include tablet{
 justify-content: center;
}
}
.g-nav li{
margin: 0 10px;
@include sp-s{
 width: 25%;
 margin: 0;
 &:nth-of-type(-n+3)>a{
  border-right: 1px solid $main-color;
 }
}
}
.g-nav a{
display: block;
padding: 10px 20px;
color: $main-color;
@include sp-s{
 padding: 10px 0;
 font-size: 14px;
 text-align: center;
}
  &:hover{
   color:#907f7f;
  }
}
/* メインビジュアル */
.main-visual{
 max-width: 980px;
 margin: 0 auto $unit*10;
&>img{
 max-width: 100%;
}
}
.main-copy{
 text-align: center;
 line-height: 1.8;
 margin-bottom: $unit*7;
 padding: 0 $unit;
 box-sizing: border-box;
}

.food{
 max-width: 980px;
 margin: 0 auto $unit*10;
 display: flex;
 justify-content: space-between;
 @include sp-l{
  display: block;
  text-align: center;
  &>li{
   margin-bottom: $unit*2;
  }
 }
 & img{
  max-width: 100%;
 }
 &>li:hover{
  opacity: 0.7;
 }
}
.news{
 max-width: 980px;
 margin: 0 auto $unit*14;
 @include tablet{
  padding: 0 $unit*2;
 }
 &>h2{
  margin-bottom: $unit;
 }
 & dt{
  float: left;
  border-left: $unit*2 solid $main-color;
  padding-left: $unit*2;
 }
 & dd{
  padding-left: $unit*20;
 }
}

footer{
 background: $footer-color;
 color: #FFF;
}
.footer-nav{
 display: flex;
 justify-content: center;
 margin-bottom: $unit*4;
 &>li{
  margin: 0 $unit*3;
  @include sp-l{
   margin: 0;
   width: 25%;
  }
  &>a{
   display: block;
   padding: $unit*2;
   color: #FFF;
   @include sp-l{
    padding: $unit*2 0;
    text-align: center;
    font-size: 14px;
   }
   &:hover{
    text-decoration: underline;
   }
  }
 }
}
.footer-wrapper{
 max-width: 980px;
 margin: 0 auto;
 display: flex;
 justify-content: space-between;
 border-bottom: 1px solid #FFF;
 padding-bottom: $unit*3;
 @include sp-l{
  display: block;
 }
 &>div{
  width: 48%;
  @include sp-l{
   width: 90%;
   margin: 0 auto $unit*2;
   font-size: 14px;
  }
  & a{
   color: #FFF;
  }
 }
}
.copy-right{
 text-align: center;
 padding: $unit*4 0;
}