20191214のHTMLに関する記事は9件です。

Canvasで作るお絵かきアプリ

この記事はtomowarkar ひとりAdvent Calendar 2019の14日目の記事です。

はじめに

昔に描いたコードを持ってきたので、コードが少し古く、初心者感丸出しですがご容赦を。

スマートフォンに対応させたのがポイントです。

デモサイト

デモサイト

コード全文

index.html

  • 描画エリア設定
  • カラーパッド設定
  • 削除ボタン設定
<!doctype html>
<html>
    <head>
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <title></title>
    </head>
    <body>
        <div id="hitarea"><canvas id="canvas"></canvas></div>
        <input type="color" id="color" value="#ff7f7f">
        <input type="button" id="removePaint" value="clear" onclick="removePaint()">
    </body>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
</html>

style.css

style.css
body {
    margin: 0;
    overflow: hidden;
}
#color{
    position: absolute;
    margin: 0;
    width: 54px;
    height:58px;
    right: 10px;
    bottom: 60px;
    border: none;
    background: none;
}
#removePaint{
    position: absolute;
    margin: 0;
    width: 50px;
    height:50px;
    right: 15px;
    bottom: 10px;
    background: lightgray;
}

script.js

script.js
var canvas = document.getElementById( 'canvas' );
var ctx = document.getElementById("canvas").getContext("2d");
canvas.width  = window.innerWidth;
canvas.height = window.innerHeight;

function drawCoordinates(x,y,mouseX,mouseY){
    ctx.beginPath();
    ctx.moveTo(mouseX, mouseY);
    ctx.lineTo(x, y);
    ctx.lineCap = "round";
    ctx.lineWidth = 10;
    ctx.strokeStyle = defocolor;
    ctx.closePath();
    ctx.stroke();
    mouseX = x;
    mouseY = y;
}

var $document = $(document);
var $hitarea = $('#hitarea');
var $x = $('#x');
var $y = $('#y');
var supportTouch = 'ontouchend' in document;// タッチイベントが利用可能かの判別

var EVENTNAME_TOUCHSTART = supportTouch ? 'touchstart' : 'mousedown';
var EVENTNAME_TOUCHMOVE = supportTouch ? 'touchmove' : 'mousemove';
var EVENTNAME_TOUCHEND = supportTouch ? 'touchend' : 'mouseup';

var mouseX = "";
var mouseY = "";

var updateXY = function(event) {
    var original = event.originalEvent;
    var x, y;
    if(original.changedTouches) {
        x = original.changedTouches[0].pageX;
        y = original.changedTouches[0].pageY;
    } else {
        x = event.pageX;
        y = event.pageY;
    }
    $x.text(x);
    $y.text(y);
    return [x,y];
};

// イベント設定
var handleStart = function(event) {
    event.preventDefault();// タッチによる画面スクロールを止める
    [x,y] = updateXY(event);
    mouseX = x;
    mouseY = y;
    bindMoveAndEnd();
};
var handleMove = function(event) {
    event.preventDefault(); // タッチによる画面スクロールを止める
    [x,y] = updateXY(event);
    drawCoordinates(x,y,mouseX,mouseY)
    mouseX = x;
    mouseY = y;
};
var handleEnd = function(event) {
    [x,y] = updateXY(event);
    drawCoordinates(x,y,mouseX,mouseY)
    mouseX = "";
    mouseY = "";
    unbindMoveAndEnd();
};
var bindMoveAndEnd = function() {
    $document.on(EVENTNAME_TOUCHMOVE, handleMove);
    $document.on(EVENTNAME_TOUCHEND, handleEnd);
};
var unbindMoveAndEnd = function() {
    $document.off(EVENTNAME_TOUCHMOVE, handleMove);
    $document.off(EVENTNAME_TOUCHEND, handleEnd);
};

$hitarea.on(EVENTNAME_TOUCHSTART, handleStart);

let defocolor = "#ff7f7f";
function watchColorPicker(event) {
    defocolor = event.target.value;
}
document.querySelector("#color").addEventListener("change", watchColorPicker, false);

function removePaint() {
    ctx.beginPath();
    ctx.fillStyle = "#FFFFFD";
    ctx.fillRect(0, 0, canvas.width,canvas.height);
}

おわりに

以上明日も頑張ります!!
tomowarkar ひとりAdvent Calendar Advent Calendar 2019

参考

https://nymemo.com/jquery/1278

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Bootstrap 4 のcardを使ってWebサイトにオシャレなBOXを加える

オシャレなBOXをBootstrap4の『card』で作る

今回のイメージはこんな感じ。Free、Pro、Enterpriseの3つのBOXのことやね。

スクリーンショット 2019-12-14 22.18.49.png

これは、料金プランの選択肢を作成するときとかにオシャレですよね。

Cardの説明

まずcard単体はこんな感じ。

スクリーンショット 2019-12-14 22.24.12.png

card.html
<div class="card mb-4 shadow-sm">
      <div class="card-header">
        <h4 class="my-0 font-weight-normal">Free</h4>
      </div>
      <div class="card-body">
        <h1 class="card-title pricing-card-title">$0 <small class="text-muted">/ mo</small></h1>
        <ul class="list-unstyled mt-3 mb-4">
          <li>10 users included</li>
          <li>2 GB of storage</li>
          <li>Email support</li>
          <li>Help center access</li>
        </ul>
        <button type="button" class="btn btn-lg btn-block btn-outline-primary">Sign up for free</button>
      </div>
    </div>

簡単に言うと
上のグレーのFreeのところがclass="card-header"で
下の内容のところがclass="card-body"になってるんね。

そして、この単体のCardを最初の画像みたいにデザインする方法がcard-deck。

Card-deckで単体のcardを整列させる

そして、大事なcardsの整列方法。

スクリーンショット 2019-12-14 22.34.38.png

card-deck.html
<div class="card-deck">
  <div class="card">
    <img src="..." class="card-img-top" alt="...">
    <div class="card-body">
      <h5 class="card-title">Card title</h5>
      <p class="card-text">This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
      <p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
    </div>
  </div>
  <div class="card">
    <img src="..." class="card-img-top" alt="...">
    <div class="card-body">
      <h5 class="card-title">Card title</h5>
      <p class="card-text">This card has supporting text below as a natural lead-in to additional content.</p>
      <p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
    </div>
  </div>
  <div class="card">
    <img src="..." class="card-img-top" alt="...">
    <div class="card-body">
      <h5 class="card-title">Card title</h5>
      <p class="card-text">This is a wider card with supporting text below as a natural lead-in to additional content. This card has even longer content than the first to show that equal height action.</p>
      <p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
    </div>
  </div>
</div>

class="card"のdivを例えば3つ作って、それらをclass="card-deck"というdivにまとめて入れるだけ。あら簡単。

参考 Bootstrap4 公式サイト
https://getbootstrap.com/docs/4.4/components/card/

ちなみに、Bootstrapを使用する時はheadタグの中に下記いれないと使えないからご注意を。

getstarted.html
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初心者によるプログラミング学習ログ 184日目

100日チャレンジの184日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

184日目は

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CSSでベルトスクロールゲームを作った。

この記事は CSS Advent Calendar 2019 16日目の記事です。

概要

CSSで昔懐かしのベルトスクロールゲームを作りました。
PC、画面サイズ大きめで遊んでください><
https://codepen.io/Rin_T_T/pen/MWYjJKv?editors=1100

本記事はあくまで作った物の簡単な説明のため、コード,制作過程を一部省略しています。

設計書

必須機能をまとめます。

衝突判定: hoverで判定
ゲーム画面のスクロール: transitionで実装
スタート: hoverで判定
スコア用のアイテムを設置: checkboxで実装
キャラクターの移動: カーソルを画像に置き換える。

早速作っていきます。

最初にスクロールエリアと衝突オブジェクトを作成します。

index.pug
    .gameArea_inner
      .playArea.-test2
        - for(var i = 1; i <= 50; i++)
          .item.-object(class='-o' + i)

衝突判定を実装します。
.item.-objectをhoverすると兄弟要素のFailが最前面に表示するようにします。
※faile要素を最前面に維持するため、.faile要素自体にもhover状態を指定しておきます。
ひとまず判定が通ることが確認できれば良いでしょう。

index.pug
    .gameArea_inner
      .playArea.-test2
        - for(var i = 1; i <= 50; i++)
          .item.-object(class='-o' + i)
        + .faile
           .faile_inner
             .faile_contents   
style.scss
.faile {
    position: absolute;
    width: 100%;
    height: 100%;
    z-index: -100;//初期状態では非表示
    display: none;//初期状態では非表示
    &:hover{
      opacity: 1;
      z-index: 100;
      display: block;
    } 
    &_inner{
      display: flex;
    }
    &_contents{
      text-align: center;
      background-image: url('https://portfolio.littledemon.pw/cssadvent/failed.png');
      background-size: 386px 160px;
      width: 100%;
      height: 100vh;
    & > *{
      margin-top: 15px;
    }
  }
}


.item{
  width: 30px;
  height: 30px;
  background-color: #9c290d;
  position: absolute;
  z-index: 100;
  opacity: 1;
 &.-object{//衝突オブジェクトクラス
    position: absolute;
   &:hover{
      & ~ .faile{
        z-index: 100;
        opacity: 1;
        display: block;
      }
    }
  }
}

ゲーム画面のスクロールを実装します。

.gameArea_innerのサイズをプレイエリアとし最大値を560vwに設定します。
animationを指定し、スクロールスピードを設定します。

ついでにスタート/リスタート用のanimationも作っておきます。

style.scss

.gameArea{

  &_inner{
    width: 560vw;
    display: flex;
    position: relative;
    z-index: 0;
    left: 0;
    animation: areaScroll 70s linear forwards;
  }
}

@keyframes areaScroll {
  0% {
    position: relative;
    left: 0vw;
  }
  100% {
    position: relative;
    left: -560vw;
  }
}


@keyframes areaScrollBack {
  0% {
    position: relative;

  }
  100% {
    position: relative;
    left: 0vw;
  }
}

スクロールを制御できるスタート/リスタートを作成します。

CSSは常に親から子へもしくは兄弟要素のみ指定できます。
スタートはスクロールしている要素と同じレイヤーに配置します。
hoverで先ほど作成したareaScrollBackを発火できるよう設定します。

index.pug
+ .wrap
+  .gameArea
+   .startArea
+     .startChecker
+     .startLine 
+       .startLine_text START 
    .gameArea_inner
      .playArea
        .item.-object.-ribbon.-top
        .item.-object.-ribbon.-bottom
        - for(var i = 1; i <= 50; i++)
          .item.-object(class='-o' + i)

style.scss
.startArea{
  display: flex;
  z-index: 10;
  &:hover + .gameArea_inner{// 兄弟要素を指定し、animationを発火する。
    animation: areaScrollBack 150s ease forwards;
  }
}
.startChecker{
  width: 160px;
  background: linear-gradient(45deg, black 25%, transparent 25%, transparent 75%, black 75%),
              linear-gradient(45deg, black 25%, transparent 25%, transparent 75%, black 75%);
  background-color: white;
  background-size: 40px 40px;
  background-position: 0 0, 20px 20px;
}

.startLine{
  background-color: white;
  height: 100%;
  padding: 0 15px;
    &_text{
    writing-mode: vertical-rl;
    height: 100%;
    text-align: center;
  }
}


.gameArea{
  width: 100%;
  height: 100vh;
  background-color: white;
  overflow: hidden;
  display: flex;
  &_inner{
    ~~~
  }
}

スコア用のアイテムを作成します。

index.pug
 .wrap
  .gameArea
   .startArea
     .startChecker
     .startLine 
       .startLine_text START 
    .gameArea_inner
      .playArea
        .item.-object.-ribbon.-top
        .item.-object.-ribbon.-bottom
        - for(var i = 1; i <= 50; i++)
          .item.-object(class='-o' + i)
+    - for(var i = 1; i <= 24; i++)
+         label.present
+           input(type="checkbox")
+           .present_item(class='-p' + i)

style.scss
.present{
  &_item{
    position: absolute;
    width: 40px;
    height: 40px;
    display: block;
    background-size: 30px 30px;
    transition: left 7s;
    &.-p1{//ゲームエリア上の位置(checkboxがfalseの時)
        top: 45vh;
        left: 20.5vw;
     }
  }
  & input{
    display: none;
    &:checked {
      & + .present_item {
            pointer-events: none;
            transition: left 4s;
            &.-p1{//アイテムを取得した後の位置(checkboxがtrueの時)
             top:60vh;
             left: 585vw;
        }
      }
    }
  }
}

scssが少し複雑ですね、メインのデザインは.present_itemに担当してもらいます。
input要素は非表示にしておき、checkBoxがtureの時、後述するゴールエリアに遷移するように設定します。

キャラクターの移動

Cursolを画像に変更します。
利用できるサイズは最大128*128のようですが、
ブラウザの互換性から考えると32*32が推奨のようです。
※今回は少し小さかったため、64pxにしました。

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property

以上で完成です。

反省点。

遊んでいただけると気づくかもしれませんが、hover要素はカーソルの移動時に現在位置を再取得します。強制スクロールというゲーム上、衝突オブジェクトの手前で停止するとhoverの判定されず貫通します。
とりあえずゴールを見たいという人はカーソル放置でゴールまでたどり着きます(笑)

スコア用のカーソル衝突オブジェクトはもっとCSS芸的なもので、頑張りたかった...時間が足りませんでした...

chrome PCのみの対応です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初めてのJavaScript~ペンの色・太さが変更できるお絵かきアプリを作ったよ~

Webアプリを作りたいなと思いながらなんとなーく先延ばしにしてたところ
初心者向けのJavaScript,HTML,CSSを使ったワークショップを見つけたので参加してみました。
その時作ったお絵かきアプリに機能を追加してペンの太さ・ペンの色の変更・画面の全消しができるようにしてます.

動作環境

あんまりよくわかってないけどCodeSandboxにsign inしてVanillaを使って作りました笑

おそらく…
・CodeSandbox
・Vanilla
・HTML
・JavaScript
・CSS
があればできるんだと思います.
違ってたらすみません.

やること

1.HTMLで部品を作ります

今回はお絵かきする部分とボタンを作成しました.

<!DOCTYPE html>
<html>
  <head>
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
  </head>

  <body>
    <div id="app"></div>
    <!--お絵かきする画面を消すボタン-->
    <div>
      <button id="pen-ss">極細</button>
      <button id="pen-s"></button>
      <button id="pen-m"></button>
      <button id="pen-l"></button>
      <button id="pen-ll">極太</button>
    </div>
    <!--お絵かきするところ-->
    <div>
      <canvas
        id="draw-area"
        width="400px"
        height="400px"
        style="border: 1px solid #000000"
      >
      </canvas>
    </div>
    <!--色を変えるボタン-->
    <div>
      <button id="color-red"></button>
      <button id="color-blue"></button>
      <button id="color-green"></button>
      <button id="color-black"></button>
      <button id="eraser">消しゴム</button>
      <button id="clear-button">全消し</button>
    </div>
    <script src="src/index.js"></script>
  </body>
</html>

おそらくこんな感じになるかと…
スクリーンショット 2019-12-14 17.25.34.png

これでは動かないのでJavaScriptさんに動かしてもらいましょう

2.JavaScriptの登場

特にどうってこともないのでコード載せます

import "./styles.css";

const canvas = document.querySelector("#draw-area");
const context = canvas.getContext("2d");

canvas.addEventListener("mousemove", event => {
  draw(event.layerX, event.layerY);
});
canvas.addEventListener("touchmove", event => {
  draw(event.layerX, event.layerY);
});
//パソコンでクリックしてる間だけ描けるようにした機能
canvas.addEventListener("mousedown", () => {
  context.beginPath();
  isDrag = true;
});
canvas.addEventListener("mouseup", () => {
  context.closePath();
  isDrag = false;
});
//スマホで描けるようにする機能
canvas.addEventListener("touchstart", () => {
  context.beginPath();
  isDrag = true;
});
canvas.addEventListener("touchend", () => {
  context.closePath();
  isDrag = false;
});
//お絵かきするところをきれいにする機能
const clearButton = document.querySelector("#clear-button");
clearButton.addEventListener("click", () => {
  context.clearRect(0, 0, canvas.width, canvas.height);
});
//ペンの色を変える機能
const colorRed = document.querySelector("#color-red");
colorRed.addEventListener("click", () => {
  context.strokeStyle = "red";
});
const colorBlue = document.querySelector("#color-blue");
colorBlue.addEventListener("click", () => {
  context.strokeStyle = "blue";
});
const colorGreen = document.querySelector("#color-green");
colorGreen.addEventListener("click", () => {
  context.strokeStyle = "green";
});
const colorBlack = document.querySelector("#color-black");
colorBlack.addEventListener("click", () => {
  context.strokeStyle = "black";
});
//消しゴムの機能
const eraser = document.querySelector("#eraser");
eraser.addEventListener("click", () => {
  context.strokeStyle = "white";
});
//ぺんの太さを変える機能
const penSS = document.querySelector("#pen-ss");
penSS.addEventListener("click", () => {
  context.lineWidth = 1;
});
const penS = document.querySelector("#pen-s");
penS.addEventListener("click", () => {
  context.lineWidth = 5;
});
const penM = document.querySelector("#pen-m");
penM.addEventListener("click", () => {
  context.lineWidth = 10;
});
const penL = document.querySelector("#pen-l");
penL.addEventListener("click", () => {
  context.lineWidth = 15;
});
const penLL = document.querySelector("#pen-ll");
penLL.addEventListener("click", () => {
  context.lineWidth = 20;
});

let isDrag = false;
//線をかく機能
function draw(x, y) {
  if (!isDrag) {
    return;
  }
  context.lineTo(x, y);
  context.stroke();
}

ここまでできればとりあえず動きます
デザインにも凝りたいって方はCSSをいじってください

3.CSSでも書きますか

今回はこだわりがなかったのでとりあえず実装しました程度です

/*お絵かきするところからはみ出た部分を隠してみた*/
body {
  overflow: hidden;
}

完成

スクリーンショット 2019-12-14 17.34.16.png

できました!
一応完成したやつのURL載せときます
パソコンでもスマホでも動くようにしました.
Androidで動くかはわかんないです
完成版

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

サイトに某ほとけ風な何かを呼び出すjQueryプラグイン・hotoke.jsを作った

ご存知の方は知っている某ドラマで現れる、「ほとけ」風ななにかを自分のサイト内に呼び寄せるjQueryプラグインを作成しました。

デモ

実装サンプルはこちらになります。ページを開いてから数秒後に登場します。
hotoke.jsのサンプルページ

使い方

以下のファイルを表示させたいページに読み込みます。

  • hotoke.css
  • jQuery(今回はバージョン2.2.4を使用して作成しました。他のバージョンで動くかは未検証です。)
  • hotoke.js
<link rel="stylesheet" href="hotoke.css">
<script src="jquery-2.2.4.js"></script>
<script src="hotoke.js"></script>

ファイルを読み込むパスはそれぞれ変更してください。
そして使用したいページで以下を記述します。

<script>
$(function(){
  $('body').hotoke();
});
</script>

これで実行されます。

カスタマイズ方法

オプション

オプションが2つあり、

  • timeStart ほとけ呼びかけるまでの時間を指定(ミリ秒)
  • hotokeImgPath ほとけの画像へのパス(読み込むHTMLからのパス)
<script>
$(function(){
  $('body').hotoke({
    timeStart : 3000,
    hotokeImgPath : '../../hotoke.png'
  });
});
</script>

デフォルトでは3000ミリ秒でほとけが呼びかけ始めます。画像はそのHTMLと同階層のhotoke.pngを読み込みます。

セリフの変更

最初の呼びかけと、その後のセリフの編集はhotoke.jsを編集します。hotoke.jsの以下の部分を編集してください。ファイルの上部にあります。

//最初の呼び出し文言
var hotokeShout = [
  'ヨ○ヒコー',
  'ヨ○ヒコよー'
];

//ほとけ降臨後の文言
var hotokeWords = [
  'ここにセリフを入れることができます。',
  'セリフ2',
  'セリフ3'
];

ここに文言を追加・編集することで表示されるセリフが変わります。最後の項目以外は文末にカンマが必要です。

見た目の変更

hotoke.cssを編集してください。ちなみに、最初の呼び出し文言は文字数によって、降臨後の文言は画像の幅によって吹き出しのサイズが変わりますがCSSで変更可能です。

画像の変更

hotoke.pngを差し替えてください。デモの画像はフリー素材を組み合わせただけなので、あなただけのほとけを降臨させてください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

mediaを使ってNavigation SideMenuを実現する

はじめに

事故マップというサービスを個人開発しています。

このWebアプリでは、画面サイズが小さい場合は自動的にSideMenuを閉じるという動きを入れてレスポンシブなUIを実現しています。

Dec-13-2019 23-58-04.gif

これはCSSのmediaクエリを使えば簡単に実現できるのでその方法を紹介します。

mediaとは

CSS の media を指定すると、一つまたは複数のメディアクエリの結果に基づいて、適用するスタイルシートを変えることができます。

例えば、スクリーンのサイズが 600px 以下の場合に背景の色を変えたい時は次のように指定をします。

@media screen and (max-width: 600px) {
    body {background-color: #99cc00;}
}

Navigation SideMenuの作り方

まずは、HTML全体を3つに分けます。

  • main : コンテンツを配置するエリア
  • topnav : ナビゲーションバー
  • sidenav : サイドメニュー

スクリーンショット 2019-12-14 9.36.54.png

ポイントは、topnavはmainの子要素として配置し、mainはsidenavのwidthの分だけleft-marginを取るようにします。

<html>
<head>
<style>
.main {
  margin-left: 160px;
}
.sidenav {
  width: 160px;
}
</style>
</head>
<body>
<div class="sidenav"></div>
<div class="main">
  <div class="topnav" id="myTopnav"></div>
</div>
</body>
</html>

次はmediaをを指定します。

やりたいことは、画面サイズが600px以下になったときにsidenavを非表示にしてmainをsidenavの分大きくすることです。

具体的には次のCSSの指定を行います。

  • 非表示 → display: none;

  • サイズ変更 → margin-left: 0px

@media screen and (max-width: 600px) {
  .sidenav {display: none;}
  .main {margin-left: 0px;}
}

最終的なコード例

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<style>
body {
  margin: 0;
  font-family: Arial, Helvetica, sans-serif;
}

.topnav {
  overflow: hidden;
  background-color: #333;
}

.topnav a {
  float: left;
  display: block;
  color: #f2f2f2;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
  font-size: 17px;
}

.topnav a:hover {
  background-color: #ddd;
  color: black;
}

.topnav a.active {
  background-color: #4CAF50;
  color: white;
}

.topnav .icon {
  display: none;
}

.main {
  margin-left: 160px; /* Same as the width of the sidenav */
  font-size: 28px; /* Increased text to enable scrolling */
  padding: 0px;
}

.sidenav {
  height: 100%;
  width: 160px;
  position: fixed;
  z-index: 1;
  top: 0;
  left: 0;
  background-color: #111;
  overflow-x: hidden;
  padding-top: 20px;
}

.sidenav a {
  padding: 6px 8px 6px 16px;
  text-decoration: none;
  font-size: 25px;
  color: #818181;
  display: block;
}

.sidenav a:hover {
  color: #f1f1f1;
}

@media screen and (max-width: 600px) {
  .topnav a.icon {
    float: right;
    display: block;
  }
  .sidenav {display: none;}
  .main {margin-left: 0px;}
}
</style>
</head>
<body>
<div class="sidenav">
  <a href="#about">About</a>
  <a href="#services">Services</a>
  <a href="#clients">Clients</a>
  <a href="#contact">Contact</a>
</div>
<div class="main">
  <div class="topnav" id="myTopnav">
    <a href="#home" class="active">Home</a>
    <a href="javascript:void(0);" class="icon" onclick="myFunction()">
      <i class="fa fa-bars"></i>
    </a>
  </div>
  <div style="padding-left:16px">
    <h2>Responsive Topnav Example</h2>
    <p>Resize the browser window to see how it works.</p>
  </div>
</div>
</body>
</html>

上記のコードはここですぐに試す事ができます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Bootstrap 4 のcarouselを使ってWebサイトにスライドショーを作成する

Bootstrap 4 のcarouselで作るスライドショー

WEBサイトにスライドショーを作成したい。でもなかなか難しそうだし、どうやってやるかわからない。。そんな人におすすめなのがBootstrap4のcarouselです。ちなみにcarouselは英語でメリーゴーランドって意味です。

実際どんな感じになるの

イメージはこんな感じ。(Bootstrap4の公式サイトから引用)

スクリーンショット 2019-12-14 08.15.12.png

このスライドショーがなんと、、コピペでできてしまう。あぁBootstrap恐ろしや。

carousel.html
<div id="carouselExampleControls" class="carousel slide" data-ride="carousel" data-interval="2500" data-pause="hover">
  <div class="carousel-inner">
    <div class="carousel-item active" style="background-color: red;">
      <img src="..." class="d-block w-100" alt="...">
    </div>
    <div class="carousel-item"  style="background-color: yellow;">
      <img src="..." class="d-block w-100" alt="...">
    </div>
    <div class="carousel-item"  style="background-color: blue;">
      <img src="..." class="d-block w-100" alt="...">
    </div>
  </div>
  <a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
    <span class="sr-only">Previous</span>
  </a>
  <a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
  </a>
</div>

いろんなスライドショーがあるので、興味ある方は公式サイト見て見てね。
https://getbootstrap.com/docs/4.4/components/carousel/

※複数あるclass="carousel-item"のうち、1つはclass="carousel-item active"にしなければならないので注意。

変えられる要素

要素を追加することで、スライドショーをカスタマイズすることができます。

・『interval』で切り替え時間を変える

intervalのdefault設定は5000ミリ秒。
今回は一行目に data-interval="2500"と設定し、2.5秒に1回画面が切り替わるようにしました。

・『pause』でスライドショーを止める

pauseは何かのactionが行われた時に、スライドを止めるもの。
data-pause="hover"を設定すると、hoverされた時にスライドが止まるのです。
読みたいのにどんどん流れて行っちゃうスライドショーってたまにあるよね笑

・『carousel-fade』でオシャレにスライドする

上記のコードではclass="carousel slide"だけなので普通に画面がスライドしていく感じになります。しかし、class="carousel slide carousel-fade"と記載すると、画面がふわっとfadeしながら変わります(表現下手か)

・『ride』で自動スライドか手動スライドか選ぶ

コード内の
data-ride="carousel" → 自動スライド
data-ride="false" → 手動スライド
になります。

ちなみに、Bootstrapを使用する時はheadタグの中に下記いれないと使えないからご注意を。

getstarted.html
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CSSだけで球体!?錯視トリックで世界を騙せ

この記事は CSS Advent Calendar 2019 14日目の記事です。

伝えたいこと

本来、CSSだけでは球体の表現は難しく、グラデーションでそれっぽくするほかありませんでした。
この課題、アニメーションと周辺環境による錯視のトリックで解決します。

深く考えないでね

ここで紹介するテクニックは実務に応用できません。
CSSアニメーションのジョーク記事としてお楽しみください。
タイトルもジョークです...笑

先に完成図

まずはこのサンプルをご覧ください。
お急ぎの方は、このサンプルを見ておしまいです!
Qiita上では少し動作が重いので、サンプル右上のCodePenロゴをクリックしてご覧ください。

See the Pen Only CSS: Particles Following Camera 1 by Yusuke Nakaya (@YusukeNakaya) on CodePen.

小さな球体が大量に、グルグルと旋回しているように見えませんか?
影も落ちてるし。

このトリックを解説します。
読み進めると、何かわかった感じになります。

下準備

まずは簡単に円を描き、グラデーションでそれっぽいテクスチャを与えます。
とても妥協すれば球体に見えなくもないですが、より確実に「球体」と認識できるよう、チューニングします。

See the Pen Camera following: Step1 by Yusuke Nakaya (@YusukeNakaya) on CodePen.

錯視のテクニック

それっぽいテクスチャだけを与えられ、ちょっと嘘っぽい、ただの円。
「3D空間にある球体」として誤認させるため、3DTransformsでアニメーションを与えます。

ただし、このコントロールには少し癖があります。
CSSの場合、ひとつの要素にはひとつのtransformしか与えることができない。
この制約をうまく回避して実装する必要があります。

2つのアプローチ

ポイントは、円のテクスチャを常に正面を向けながら移動すること。
これをコントロールするアニメーションのアプローチとして、2つ考えられます。

1つは、そもそもrotate系を使わない手法。
比較的簡単ですが、円運動など、複雑な立体機動には向きません。

もう1つは、親要素にrotateを指定し、子要素には逆方向のrotateを指定して打ち消す手法。
こちらのアプローチはコントロールが難しいですが、複雑な立体機動が可能です。

今回は、後者のアプローチで実装します。
迷ったときは難しい道を選べって親父が言ってた。

Y軸回転してみよう

まずは回転専用の要素を追加し、rotateY(縦を軸に回転)で回転させます。
円はコインのように、その場でクルクルと回っています。

See the Pen Camera following: Step2 by Yusuke Nakaya (@YusukeNakaya) on CodePen.

当たり前ですが、この時点ではまったく球体に見えません。

Z軸移動してみよう

次に、移動専用の要素を追加し、translateZ(奥行き方向に移動)させます。
円は、大きな旋回の軌道で、手前から奥へと立体的にグルグル廻っています。

See the Pen Camera following: Step3 by Yusuke Nakaya (@YusukeNakaya) on CodePen.

奥行きは感じますが、まだ球体には見えません。

周回軌道を打ち消すY軸回転を追加しよう

本記事のメインです。
回転打ち消し専用の要素を追加し、旋回とは逆方向にrotateYさせます。
旋回はそのままに、円が常に正面を向くようになります。

See the Pen Camera following: Step4 by Yusuke Nakaya (@YusukeNakaya) on CodePen.

おや?
ひょっとして球体に見えなくもない?

X軸回転で傾けてみよう

ここからは、円をとりまく周辺環境も整えます。
傾き専用の要素を追加し、rotateX(横を軸に回転)で傾きをつけます。
やや斜め上から見下ろしているような視点になります。

See the Pen Camera following: Step5 by Yusuke Nakaya (@YusukeNakaya) on CodePen.

残念、球体には見えなくなりました。

傾きを打ち消すX軸回転を追加しよう

傾き打ち消し専用の要素を追加し、傾きとは逆方向にrotateXします。
ふたたび、円が正面を向くようになります。

See the Pen Camera following: Step6 by Yusuke Nakaya (@YusukeNakaya) on CodePen.

傾きでより強い立体感を演出できました。

グラフィックを調整しよう

ボールに影を落としたり、背景にグラデーションを敷いたりして、全体のグラフィックを整えます。
物理や光源処理、素材感、床の反射率など、リアリティに気を配ります。

See the Pen Camera following: Step7 by Yusuke Nakaya (@YusukeNakaya) on CodePen.

これを見た10人中、7〜8人は球体に見えるのでは。

円を増やしてみよう

トドメだ。
円を3つに増やして、それぞれ旋回のアニメーションにディレイを与えます。
円同士が近すぎるとバレやすいので、ギリギリのところで追いかけているように調整します。

See the Pen Camera following: Step8 by Yusuke Nakaya (@YusukeNakaya) on CodePen.

これを見た10人中、9.5人くらいは球体に見えるのでは。

まとめ

擬似的な球体表現を紹介しました。
大切なポイントは2つ。

  • 円を常に正面に向ける(回転を打ち消す)
  • ひとつの動きに、ひとつの要素

うまく活用できれば、本来は難しいはずの球体表現という圧倒的アドバンテージを得られるでしょう。
なるほどこれは、マジックですね。

フォローミー!

楽しんでいただけたら、フォローしてくれると嬉しいです!?
また、Meguro.cssというCSS勉強会も運営しているので、よかったら遊びに来てね!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む