LoginSignup
2
1

More than 3 years have passed since last update.

jQueryとCSSとDraggableでかっこいいスライダーを作る。

Last updated at Posted at 2020-05-06

はじめに

どんなやつ?

こうゆうやつを作りたい(作った)。Android的にはシークバーっていうんだけどなんて呼ぶのが正しいのだろうか。
kfzmk-n8cn9.gif

どうやって?

最小値0で最大値100で作る。この値はあくまで表示なので値を足したりかけたりすればどんな範囲でも作れる。また、値の変動はスムーズにしたいので四捨五入する。これらの値は独自属性を作り、格納する。

背景(Barとする)と移動する丸(Toggleとする)は別々にしてDivで実装。同一の親に入れとく。

実装

HTML

jQueryとjQueryUIの導入を忘れないように。

index.html
<div class="seekBarParent">
  <div class="seekBar"></div>
  <div class="seekToggle" data-parcent="0"></div>
</div>

命名適当。data-parcentという独自属性を作っています。

CSS

めんどくさいからToggleの大きさはvh単位決め打ちで作る。

index.css
.seekBarParent {
  position: relative;
  /* ご自由に */
}

/* 以下の高さとか大きさとかどうぞ自由に */
.seekBar {
  position: relative;
  width: calc(100% - (5vh * 0.4));
  height: 15%;
  top: 42.5%;
  left: calc(5vh * 0.2);
  border-radius: calc(5vh * 0.15);
  border: solid 1px #e50000;
}

.seekToggle {
  position: absolute;
  height: 40%;
  width: calc(5vh * 0.4);
  top: 32%;
  left: 0%;
  border-radius: 50%;
  background-color: #e50000;
  box-shadow: 2px 2px 3px rgb(51, 51, 51);
}

/* パーセントの数字 */
.seekToggle::before {
  content: attr(data-parcent);
  position: absolute;
  height: auto;
  width: 120%;
  top: -80%;
  left: -10%;
  text-align: center;
  color: #e50000;
  font-size: 0.75em;
}

計算(calc)を多用してしまう...CSSの勉強不足です...

JavaScript

;を後ろにつける派です。

index.js
$(function () {
  // initialize
  init();

  $(".seekToggle").draggable({
    axis: "x",
    containment: "parent",
    drag: function () {
      var nowLeft = $(this).position().left;
      var parentWidth = $(this).parent().outerWidth() - $(this).width();
      var parcent = Math.round(nowLeft * 100 / parentWidth);
      $(this).attr("data-parcent", parcent);
      $(this).parent().children(".seekBar").css(
        {
          "background": "linear-gradient(90deg, #e50000 0%, #e50000 " + parcent + "%, transparent " + parcent + "%, transparent 100%)"
        });
    }
  });
});

ちょっと(かなり)解説。
エレメントにjQueryUIdraggableを指定するとドラッグできるようになります。
axis: "x"で横方向のみ、containment: "parent"で親領域内でのみドラッグできるようにしてます。
drag: function() {}のなかでドラッグ中、毎フレームで実行する処理を書き入れます。
現在の親領域内でのleftnowLeftに格納し、これを親領域で割ればいいのですがここで注意が必要です。


一番左にドラッグしたときのことを考えましょう。nowLeftは0です。これはいいでしょう。しかし一番右にドラッグしたときは少し違います。nowLeft親の横領域いっぱいにはならず、親の横領域-toggleの横領域になります。parentWidthとnowLeftがほぼ一致しないと100%にはなりません。これを考え、parentWidth は$(this).parent().outerWidth() - $(this).width()としています。(わからない人は- $(this).width()を消してやってみて下さい、100%に絶対になりません。)
image.png


Math.round()で四捨五入して整数にしています。Before要素に値を代入し、背景色を変えます。グラデーションを使い、境目まで色を同じにすることで背景色を二色で塗り分けています。

以上で、できました。しかし、初期値を0以外考えていません。初期値を与えたい場合はdata-parcentに0以外を与え、以下のソースコードを追加してください。(0の時も働くので追加しといて損はないと思います)
data-parcentに値を与えるのはJSでもいいですし、HTMLに直接書いてもいいです。

index.js
$(function () {
  // initialize
  init();

  // 省略...
});

function init() {
  // 動的にdata-parcentに値を与える。

  setInitSeek();
}

function setInitSeek() {
  $('.seekToggle').each(function(index, element){
    var parcent = $(element).attr('data-parcent');
    var parentWidth = $(this).parent().outerWidth() - $(this).width();
    var left = parentWidth * parcent / 100;
    $(element).css(
      {
        "left": left
      });
    $(element).parent().children(".seekBar").css(
      {
        "background": "linear-gradient(90deg, #e50000 0%, #e50000 " + parcent + "%, transparent " + parcent + "%, transparent 100%)"
      });
  });
}

さっきはnowLeftからparcentを求めたので逆のことをしてcssを変えています。data-parcentに初期値を入れてから実行しないと意味ないです。init()に他の初期化処理全部まとめたほうがわかりやすいですよ。

最後に

今回は、スライダー?シークバー?可変プログレスバー?を作ってみました。CSSをちょっと変えればいろんなデザインにできると思います。また、今回は0%から100%まで全部赤でしたが、%に応じて色を変えたりすると面白そうです。

Twitter→https://twitter.com/CyberHacnoshuke

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1