素のjavascriptでCSS操作

背景

以前作った
cssのみで立体な球体を表現
目で追従するやつをriotで実装

という記事を合わせれば、光の当たる点を動かせるのかと思い立ったので実装。
ついでに素のjavascriptのみで実装してみました。

結果

こんな感じで実装できました。

名称未設定.mov.gif

See the Pen Movement of shadow of ball by mouse by hashito (@hashito) on CodePen.

内容

基本的にはCSSは「cssのみで立体な球体を表現」の実装と同じです。

// マウスムーブイベント  
document.onmousemove = function (e){  
  // スタイルシートからお探しの定義を検索する関数  
  // c:対象のスタイルシートオブジェクト  
  // tg:対象の文字列  
  var get_syle=(c,tg)=>{  
    return c[Object.keys(c).filter((v)=>{  
      return c[v].selectorText==tg  
    })[0]]  
  };    
  var styleEl = document.querySelector('style'); // スタイルシートを取得  
  var cssRuleList = styleEl.sheet.cssRules;      // スタイルシート各種定義を取得  
  var mb=get_syle(cssRuleList,".mi1::before");   // .mi1::before定義を取得  
  var ma=get_syle(cssRuleList,".mi1::after");    // .mi1::after定義を取得  
  // 2つのポイントから角度を検索  
  var point2angle=(p1,p2)=>{  
    return Math.atan2((p1.y-p2.y),(p1.x-p2.x));   
  }  
  // 角度から点を算出  
  // r:角度  
  // l:中心点からの距離  
  var angle2point=(r,l)=>{  
    return {x:Math.cos(r)*l,y:Math.sin(r)*l};  
  }  
  
  var _k  = point2angle(e,{x:150,y:150});//差を算出  
  var _p  = angle2point(_k,25);//白い点の移動値  
  var _p2 = angle2point(_k,15);//影の移動値  
  //白い点の更新  
  mb.style.top  =37.5+_p.y+"px";  
  mb.style.left =37.5+_p.x+"px";  
  //影の更新  
  ma.style.boxShadow = 'inset '+ _p2.x +'px '+_p2.y+'px 10px 3px #000';  
};  

思ったこと

  • box-shadowstyle.boxShadowでアクセスする必要がある
  • style.boxShadowとかで設定する時に最後に; とかが有るとエラーが起きず更新もされない
  • スタイルを検索する関数を作ったけど、他にいいアクセスの方法無いかなぁ…

YouTuberになってみた結果【2ヶ月分のデータを全公開】

背景

これからは動画の時代なのではないか?
と思い立ち、動画作成とマーケティングが学べそうだったのでYouTubeを始めてみました。

youtubeチャンネルはこちらです
https://www.youtube.com/channel/UC9ZSQjR4502aRkU5rJpJ7dg/
image.png

やったこと

期間

3月6日-5月6日の2ヶ月間
ほぼ毎日1本程度動画を上げ続けました。(偉い!)
今、現在は127本ほどですね。
多い…

内容

内容はわからないことやっても駄目だと思ったので、技術情報系をメインで行いました。

  • プログラミング学習系
  • 環境構築方法、使い方系
  • 電子工作、RaspberryPI系
  • プログラミング学習用のゲームの実況
    など

作成方法

前半:
基本的に先に声が入った動画を撮影して、それをiMovieで加工しました。

中盤:
基本は前半と同じなのですが、バックグラウンドの音楽と終了画面を追加しました。

後半;
まず、技術的に可能か確認後、台本を作成し、撮影…その後声を入れてそれに合わせて動画加工しています。

台本書くのがすごく辛い…
あとしゃべるとどうしても つっかえたり どもる。

結論(2020年5月6日 現在)

登録者数

登録者:22人

image.png

厳しいですね。
多分ですが前半と後半で来ていただいて見ていただいたときに、
過去動画などがクオリティが異なることも原因だと思っています。
過去のものをある程度消して、必要なものをとりなおすことを検討してみます。
根本的に面白くない説も大いにあります。

視聴回数/総再生時間

視聴回数:1195回

image.png

総再生時間:32.1時間

image.png

全体的に視聴回数はあまり大きく変わっていないですが、視聴時間が増えているのでいい傾向だとは思っています。
もう少し高いクオリティのものを求めているのかなとも思っていますが…そもそも視聴回数が増えないということは
題材/題名が悪いかサムネイルが悪いんですよね。
題材を大きく変えることを検討したほうが良いかも。

人気の動画

image.png

電子工作系が人気ですね。
Qiitaにもリンクが張ってあるのでそちらからの流入もあると思います。

一番人気の「距離センサ使ってみた」です。
image.png

どこから来たかを確認してみると「ブラウジング機能」から来ていることが分かります。
ブラウジング機能とはYoutubeのトップ画面に出てくるおすすめ動画のことのようです。
image.png

やはり、外部からの流入を期待するのではなく、Googleに気に入られて
お気に入りに表示してもらったほうが視聴回数は伸びそうですね。
このような動画を増やして、気に入られて 伸びないものは削除していったほうが効率が良いような気もします…

リーチ

リーチはどのような人たちにGoogleが私の動画を宣伝したか?
宣伝した結果どうなったのか?などが確認できます。
image.png
image.png

インプレッションのクリック率は上がっていません。
サムネイルと題名のクオリティはそこまで上がっていないという意味なのか…

image.png

image.png
image.png

全動画対象なのでよくわからないですね。

視聴者

image.png

ジャンルが原因なのか、超偏っています。

最後に

散々な結果になりますが、もう少しチャレンジして進めていきたいと思います。
また、このデータが見たい!などがあれば、コメントいただければ追加いたします。

ご観覧ありがとうございました。
どうかチャンネル登録をよろしくおねがいします!
(正直クソほど嬉しいです)

さくらインターネットのメールボックスを他のサーバサービスと併用する話

概要

結構時間を使ったし、あまり書いている人がいなかったのでここに残しておきます。

1.最初に

さくらインターネットのメールアドレスサービスが結構安い!
(月々87円)
image.png

ということで、メールボックスサービスだけを使いたくて契約しました。
が、MXの設定を色々いじってもうまく行かないということで問い合わせました。

2.結論

結論として、こんな感じです。

① 対象ドメインのDNS設定を全部消す。  
② メールボックスサーバへ紐付ける。  
③ 再度、DNSへ他社サービスへの設定を行う。  

(結構、設定変更が色々反映されるまで時間がかかるようなのでゆっくり行うのが吉です。)

ちなみに私はさくらで取得したドメインを使っていたため、他社の場合は異なる可能性があります。
最後にCNAME設定の最後の.は忘れないように注意!

Riot.jsであみだくじ

概要

あみだくじのサイトを利用したのだけど思ったようなものがなかったので作成してみた。

完成品は下記
https://hashito.biz/amidacuji/

作成内容

仕様

あみだくじサイトは下記のような仕様にて作成した。

  • 参加者名/決定項目名を入力可能とする。
  • 参加人数を最初に指定可能
  • あみだくじは最初隠れており、任意のタイミングで公開可能
  • 公開後はどの参加者がどの項目になったかを表示可能とする

ソースコード解説

あみだくじ作成部分

      self.usr_cnt    = usr_cnt;// 参加人数  
      self.vlines = new Array(usr_cnt);//参加人数分用意  
      for(var i=0;i<usr_cnt;i++){  
        var _d=(i%2==0);  
        self.vlines[i]=new Array();  
        // あみだくじの横線は作成予定数の2倍用意する。  
        // これは奇数と偶数部分で線が重ならないようにするため。  
        for(var l=0;l<(ami*2);l++){  
          var _dd=(l%2==0);  
          if(_d)_dd=!_dd;  
          if(l==((ami*2)-1))_dd=true;//最後は強制0 ←表示上一番下の項目が下の要素と重なるため…  
          self.vlines[i].push({  
            d:((_dd)?0:Math.round(Math.random()-0.2))  
          });  
        }  
      }  

あみだくじ結果検索部分

    // i = 検索対象の参加者のインデックス  
    // f = クラスをどうするかの指定 ("remove" or "add")   
    in_search(i,f,e){  
      var idx      = i*1;//念の為 数値化  
      var tgclass  = 'active-in';//追加/削除するクラス名  
      var ng_user  = self.usr_cnt-1;//対象外参加者インデックス(最後の横線は無視する)  
      if(self.status!=2)return false;//あみだくじが公開されていないときは処理しない  
      self.refs['in'+idx].classList[f](tgclass);//参加者ボックスに要素を追加 or 削除  
      for(var l=0;l<(ami*2);l++){  
        //tate  
        self.refs["tate"+idx+"-"+l].classList[f](tgclass);//縦線に要素を追加 or 削除  
        //yoko 横線に要素を追加 or 削除  
        if((ng_user!=(idx))&&self.vlines[idx][l].d){  
          self.refs["yoko"+idx+"-"+l].classList[f](tgclass);  
          idx=idx+1;//右に移動する  
        }else if(idx&&self.vlines[idx-1][l].d){  
          idx=idx-1;//左に移動する  
          self.refs["yoko"+idx+"-"+l].classList[f](tgclass);  
        }  
      }  
      self.refs['an'+idx].classList[f](tgclass);//項目ボックスに要素を追加 or 削除  
    }  

python2からpython3に対応させる時に詰まった事

はじめに

python2からpython3に環境を切り替えたのですが、色々と詰まった部分があったのでここに記載しておきます。

#詰まった部分

1. pipが異なる

当たり前ですが…
linux系でやっているとpipがpython2でpip3がpython3に紐付いています。
必要なモジュールはpip3でインストールし直しましょう。

pip install xxxx  # <-X  
pip3 install xxxx # <-O  

2. 対応しないモジュールがある

例えばSimpleHTTPServerではなくhttp.serverなどになっています。
まぁ実行時に怒られるので分かると思いますが…
ちなみにSimpleHTTPServerの以降につては、http.server内に似たクラスがありますので、そちらを利用すれば簡単に移管できます。

3. bytes型の登場

これまで利用していたモジュールで文字列を返した関数が、これになっている例が多いです。
こんな感じで、文字コード指定して文字列に直してあげましょう

# x = bytes型  
x.decode('utf-8')  

4. エラー発生時の変数Exceptionmessageが利用できない

これは見逃すとエラー発生時のみしか発生しないバグを含んでしまうので、気をつけてください。

#最後に
他にも色々とあるかと思いますが…
ご指摘やご意見ある方はコメント部分にください。

ありがとうございました。

canvasを画面比に応じて可変にする(canvasでお絵かきアプリ)

背景

canvasを画面サイズに応じて可変させたい。
純粋にそのまま実行するとjavascriptにて操作するときにcssで書いた値は有効にならず、「幅300px 高さ150px」という認識で動くのです…

結論

回避策としては下記…

  
window.onresize =//<- resize時も対応  
window.onload  = function() {  
var cnv=document.getElementsByClassName('cnv')[0];  
var ctx=cnv.getContext('2d');  
cnv.setAttribute('width',cnv.clientWidth);  //<- sizeを教えてあげる  
cnv.setAttribute('height',cnv.clientHeight);//<- sizeを教えてあげる  
  
var p=false;  
cnv.addEventListener('mousemove', (e)=>{  
  console.log(e.which,cnv);  
  if(e.which==1){  
    if(!p){  
      ctx.beginPath();  
      ctx.strokeStyle="#fff";  
      ctx.moveTo(e.x, e.y);  
      p=true;  
    }else{  
      ctx.lineTo(e.x, e.y);  
      ctx.stroke();  
    }  
  }else{  
    p=false;  
  }  
});  
};  

属性として書き込んであればそれをもとに動くようです。

追加

表記の機能を利用して簡単なお絵描きキャンバスを実装したので、ここに共有させていただきます…
消しゴム・色選択・ペンサイズ変更は実装済みです。

See the Pen canvas by hashito (@hashito) on CodePen.

[電子工作入門] 1,452円で試すLEDチカチカ

#概要
超初級編を書いてみました。
出来る限り安くしたつもりです…

動画も作成してみましたので参考にいただけると幸いです。
IMAGE ALT TEXT HERE

#部品
リンクに購入先を貼っておきます。
Arduino UNO互換機
699円
img.png

LEDセット
259円
img.png

抵抗セット
136円
img.png

ブレッドボード
231円
img.png

配線セット
127円
img.png

#手順

1.部品の動作確認

何分安物が多いので一度動作確認を行います。
ArduinoUNOから5V取得し、LEDと抵抗を挟んでGNDに接続します。
スクリーンショット 2020-03-14 7.07.02.png

この状態でUSBを接続すれば点灯するはずです。
この時、LEDの足が短いほうがGNDになり、長いほうが5Vになるので気をつけましょう。
スクリーンショット 2020-03-14 5.55.51.png

[不具合]
点灯しない場合1:線が接続されているかを確認
点灯しない場合2:LED接続が逆転していないか確認
点灯しない場合3:他の5Vポート、GNDポートで試す
点灯しない場合4:抵抗、LEDなどを交換してみる

2.配線

配線は、先程の5Vに接続されていたものを2番ポートに接続します

スクリーンショット 2020-03-14 5.55.51.png img.png

3.ソースコード

ソースコードはスケッチ例を利用します。
[スケッチ例]>[01.Basics]>[Blink]
img.png

img.png

このソースコードのLED_BUILTINの部分を2に書き換えます。
また、delayの引数を適当に書き換えます。
ms単位ですので、どれくらい光らせるかを考えながら変更しましょう。

img.png

また、書き込み前にボードをArduino UNOに変更しておきましょう。
[ツール]>[ボード]>[Arduino UNO]
img.png

この状態で画面上部のボタンを押すと書き込みが開始されます。

[不具合]
書き込みが開始されない:ボード選択が間違えていないか確認しましょう
書き込みが開始されない:[ツール]>[シリアルポート]でシリアルポートが接続されていることを確認しましょう
書き込みが開始されない:USB to シリアルのドライバが存在しない可能性があります。インストールしましょう

4.動作確認

このようにLEDが点滅します。

download.gif

音センサ(KY-038KY-037)を使ってみた。

概要

音センサを購入したので試してみました。

部品

音センサ:KY_038/KY_037
49円
image.png

表示機:TM1637が組み込まれた7セグLED
73円
image.png

コンピュータ:Arduino UNO互換機
699円
img.png

#配線
スクリーンショット 2020-03-24 6.05.02.png

#ソースコード

アナログ信号を受け取り、10回の平均を表示するようにしています。

  
#include <Arduino.h>  
#include <Wire.h>  
#include <TM1637Display.h>  
#define SERIAL_BAUD 115200  
  
#define CLK 2  
#define DIO 3  
TM1637Display display(CLK, DIO);  
#define KY_03x_LEN 10  
int KY_03xs[KY_03x_LEN] = {0,0,0,0,0,0,0,0,0,0};  
int KY_03xs_idx = 0;  
  
void setup() {  
  Serial.begin(SERIAL_BAUD);  
  while(!Serial) {}  
  
  uint8_t data[] = { 0xff, 0xff, 0xff, 0xff };  
  display.setBrightness(0x0f);  
  display.setSegments(data);  
  delay(1000);  
}  
  
void loop() {  
  int ave = 0;  
  int KY_03x;  
  KY_03xs_idx++;  
  if(! (KY_03x_LEN > KY_03xs_idx) )  
    KY_03xs_idx = 0;  
  KY_03xs[KY_03xs_idx] = analogRead(A0);  
  for(int i=0 ; i<KY_03x_LEN;i++){  
    ave+=KY_03xs[i];  
  }  
  ky_03x = ave/KY_03x_LEN;  
  
  display.showNumberDec(ky_03x, false);   
  Serial.print("ky_03x: ");  
  Serial.print(ky_03x);  
  delay(100);  
}  

github

動作確認

gif動画で上げても分かりにくかったので、Youtubeにて確認いただけると幸いです。
IMAGE ALT TEXT HERE

Riot.jsで神経衰弱

背景

CSSを色々と触っていてそれっぽいトランプ形状にできそうだったので、神経衰弱ゲームを作ってみました。

結論

こんな感じで完成しました
http://game.hasito.com:3001/

猿の絵柄にしたんだけどなんか…ムカつく

名称未設定.mov.gif

実装について

処理系

主たるところは下記

        open(i,m){  
// 時間がfalseの場合は 神経衰弱ゲーム開始! 今の時間を取得  
            if(!self.usr.tm){  
                self.usr.tm=moment();  
            }  
            // --選択しているcardが無い場合--  
            if(self.usr.select===false){  
                self.usr.select=[i];// 選択したカードを追加  
                self.closes.forEach(v=>{// close要望がある場合はclose状態(0)に更新  
                    self.cards[v].st=0;  
                })  
                self.closes=[];  
            // --選択しているcardがある場合--  
            }else{  
                self.usr.select.push(i);// 選択カードに追加  
                //**もし、選択したカード2枚が同じ数の場合は取得処理を開始**  
                if(self.cards[i].num == self.cards[self.usr.select[0]].num){  
                    self.usr.log.push({tm:moment(),get:self.usr.select})// ログに追加  
                    Array.prototype.push.apply(self.usr.cards,self.usr.select);//取得カードに追加  
                    // 取得されたカードを手持ちカード置き場に移動  
                    // ※CSSでアニメーション設定しているため移動がアニメーションになります  
                    self.usr.select.forEach((v,i)=>{  
                        self.refs[`card${v}`].style.zIndex  = self.usr.cards.length*10;  
                        self.refs[`card${v}`].style.top      = `${10+Math.random()*5-2.5}vh`;  
                        self.refs[`card${v}`].style.left     = `${70+i*3+Math.random()*5-2.5}vw`;  
                        self.refs[`card${v}`].style.transform= `rotate(${220*Math.random()+500}deg)`;  
                    });  
                    // もし、全カード取得している場合は終了  
                    if(self.usr.cards.length>=self.cards.length){  
                        end();  
                    }  
                    // 選択カードをクリア  
                    self.usr.select = false;  
                //**選択したカードの番号が異なる場合**  
                }else{  
                    self.closes = self.usr.select;// クローズ対象に追加  
                    self.usr.select = false;// 選択カードをクリア  
                }  
            }  
            self.cards[i].st=4;//選択されたカードをオープン状態(4)へ  
        }  

コード全体

<html>  
  <head>  
    <title>神経衰弱</title>  
    <meta charset="UTF-8"/>  
  </head>  
  <style>  
    body{  
      margin: 0%;  
    }  
  </style>  
  <body>  
    <index></index>  
    <script type="riot/tag" src="index.tag"></script>  
    <script src="https://cdn.jsdelivr.net/npm/riot@3.9/riot+compiler.min.js"></script>  
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>  
    <script>riot.mount('index')</script>  
  </body>  
</html>  
  
<index>  
    <div class="bk">  
        <div each={v,i in cards} class="card" ref={"card"+i} style="transform:rotate({v.r}deg);top:{Math.floor(i/10)*12+5}vh;left:{(i%10)*4.9+5}vw;">  
            <div onclick={open.bind(this,i)} if={v.st==0} class="cardbk">  
                🐒  
            </div>  
            <span if={v.st==4}  style="color:{v.color};">  
                <div class="num1">{v.num}</div>  
                <div class="type">{v.t}</div>  
                <div class="num2">{v.num}</div>  
            </span>  
        </div>  
        <div class="board">  
            <div class="name_text">  
                <label>お名前</label>  
                <input type="text" oninput={chg_name} ref="name"></input>  
            </div>  
            <div onclick={restart} class="btn">restart</div>  
            <div if={usr.tm} class="watch">{ms2time(moment()-usr.tm)}</div>  
            <div if={usr.lap} class="watch" style="color:red">{usr.lap}</div>  
            <div if={usr.tm||usr.lap} class="log">  
                <label>LOG</label>  
                <div each={v in usr.log}>  
                    {ms2time(v.tm-usr.tm)} >> {("00"+cards[v.get[0]].num).slice(-2)} GET!  
                </div>  
            </div>  
            <div if={rank} class="log">  
                <label>ランキング</label>  
                <div each={v,i in rank}>  
                    {i+1}位 {v.name} >> {v.record}sec  
                </div>  
            </div>  
  
        </div>  
    </div>  
    <style>  
    .name_text{  
        margin:10px;  
    }  
    .log{  
        height:20vh;  
        overflow: scroll;  
    }  
    .watch{  
        font-size:4vw;  
    }  
    .btn{  
        height:5vh;  
        width:5vw;  
        background-color:#222;   
        line-height:5vh;  
        margin:10px;  
        cursor:pointer;  
    }  
    .board{  
        position:fixed;  
        top:30vh;  
        left:60vw;  
        height:70vh;  
        width:40vw;  
        background-color:#111;   
    }  
    .bk{  
        width:100vw;  
        height:100vh;   
        background-color:#000;   
        text-align:center;  
        color:#fff;  
        padding:30px;  
    }  
    .card{  
        overflow: hidden;  
        cursor:pointer;  
        position:fixed;  
        width:4.9vw;  
        height:12vh;     
        margin:0.1vw;  
        background-color:#eee;   
        border-radius: 15%;  
        border: double 1px #000;  
        transition: all 1000ms 0s ease;  
    }  
    .num1{  
        text-align:right;  
        margin:5px;  
    }  
    .num2{  
        text-align:left;  
        margin:5px;  
        position: absolute;  
        bottom: 0;  
    }  
    .type{  
        text-align:center;  
        font-size:30px;       
    }  
    .cardbk{  
        width:4.9vw;  
        height:12vh;    
        line-height:12vh;  
        text-align:center;  
        font-size:4vw;  
    }  
  
  
    </style>  
    <script>  
        var self = this;  
        self.cnst_nums=[...Array(13)].map((v,i)=>{return i+1;})  
        self.cnst_types={'♥':'red','♦':'red','♣':'black','♠':'black'}  
        self.cards =[];  
        self.rank  =[];  
        self.name  ="";  
        // 名前変更イベント  
        chg_name(){  
            self.name=self.refs.name.value;  
        }  
        // 秒数を00:00:00 という形式の文字列に変更する関数  
        ms2time(ms){  
            var h = Math.floor(ms/(3600000))  
            var m = Math.floor((ms-h*3600000)/60000)  
            var s = Math.floor((ms-h*3600000-m*60000)/1000)  
            var _ms = (ms-h*3600000-m*60000-s*1000)  
            return `${('0'+h).slice(-2)}:${('0'+m).slice(-2)}:${('0'+s).slice(-2)}:${('00'+_ms).slice(-3)}`;  
        }  
  
        // カード初期化関数(カード生成)  
        // ※「st」は0:close 4:open  
        var card_init=()=>{  
            var _random=()=>{return Math.random()*20-10}// 回転角のランダム  
            self.cards=[];  
            self.cards.push({t:'jk',num:0,color:'black',st:0,r:_random()});  
            self.cards.push({t:'jk',num:0,color:'black',st:0,r:_random()});  
            Object.keys(self.cnst_types).forEach((t)=>{  
                self.cnst_nums.forEach((n)=>{  
                    self.cards.push({t:t,num:n,color:self.cnst_types[t],st:0,r:_random()});  
                })  
            });  
        };  
        // カード初期化関数(カードシャッフル)  
        var card_shuffle=()=>{  
            self.cards = self.cards.sort((a,b)=>{return (Math.random()-0.5)});  
        };  
        // タイマーストップ関数  
        var timer_stop=()=>{  
            if(self.usr && (self.usr.timer!==false)){  
                clearInterval(self.usr.timer);  
                self.usr.timer=false;  
            }  
        }  
        var cnt=0;  
        // User情報初期化関数  
        var usr_init=()=>{  
            timer_stop();  
            self.usr={cards:[],select:false,tm:false,log:[],timer:false,lap:false,rhis:[]};  
            setInterval(()=>{  
                self.update();  
            },89);  
            self.closes=[];  
        }  
        // 全体初期化  
        var init=()=>{  
            card_init();  
            card_shuffle();  
            usr_init();  
        }  
        // 終了関数  
        var end=()=>{  
            timer_stop();  
            self.usr.lap=self.ms2time(moment()-self.usr.tm);  
            self.usr.tm =false;  
        }  
        // マウント時に初期化  
        self.on("mount",_=>init());  
        // リセットボタンでリセット  
        restart(){init();}  
  
        open(i,m){  
// 時間がfalseの場合は 神経衰弱ゲーム開始! 今の時間を取得  
            if(!self.usr.tm){  
                self.usr.tm=moment();  
            }  
            // --選択しているcardが無い場合--  
            if(self.usr.select===false){  
                self.usr.select=[i];// 選択したカードを追加  
                self.closes.forEach(v=>{// close要望がある場合はclose状態(0)に更新  
                    self.cards[v].st=0;  
                })  
                self.closes=[];  
            // --選択しているcardがある場合--  
            }else{  
                self.usr.select.push(i);// 選択カードに追加  
                //**もし、選択したカード2枚が同じ数の場合は取得処理を開始**  
                if(self.cards[i].num == self.cards[self.usr.select[0]].num){  
                    self.usr.log.push({tm:moment(),get:self.usr.select})// ログに追加  
                    Array.prototype.push.apply(self.usr.cards,self.usr.select);//取得カードに追加  
                    // 取得されたカードを手持ちカード置き場に移動  
                    // ※CSSでアニメーション設定しているため移動がアニメーションになります  
                    self.usr.select.forEach((v,i)=>{  
                        self.refs[`card${v}`].style.zIndex  = self.usr.cards.length*10;  
                        self.refs[`card${v}`].style.top      = `${10+Math.random()*5-2.5}vh`;  
                        self.refs[`card${v}`].style.left     = `${70+i*3+Math.random()*5-2.5}vw`;  
                        self.refs[`card${v}`].style.transform= `rotate(${220*Math.random()+500}deg)`;  
                    });  
                    // もし、全カード取得している場合は終了  
                    if(self.usr.cards.length>=self.cards.length){  
                        end();  
                    }  
                    // 選択カードをクリア  
                    self.usr.select = false;  
                //**選択したカードの番号が異なる場合**  
                }else{  
                    self.closes = self.usr.select;// クローズ対象に追加  
                    self.usr.select = false;// 選択カードをクリア  
                }  
            }  
            self.cards[i].st=4;//選択されたカードをオープン状態(4)へ  
        }  
  
    </script>  
</index>  

残課題

  • 🐒がムカつく
  • 縦横比がパソコンでしか確認していないためiPhoneなどで見ると悲惨 スクリーンショット 2018-06-11 3.17.05.png
  • 開くときのアニメーションはない
  • リンク先にランキング機能を実装したがココらへんのサバクラ通信に関する学習が不足している
  • 全て画面の大きさに依存するためリサイズ時に重たく感じる

デジタル数字表示CSS

背景

デジタル数字表がCSSのみで出来たら楽しいかなぁと思ったので作ってみました。
完全な個人的な備忘録になります。

ただ、@n4o847 様の記事のヤツのほうがかっこいいです…要素1つですし…
@n4o847 様の記事はこちらです!
CSSを駆使してDIV要素1つでデジタル数字を作る

完成品

完成品はこちらになります。

See the Pen seven-segment display CSS by hashito (@hashito) on CodePen.

#コーディング
##棒部分

私は1つの棒毎に要素を割り当てて書いてみました。

.b{  
  transform:translateX(0px) translateX(0px);  
  background-color:var(--font-color);    
  height:var(--line-h-body);  
  width:var(--line-w);  
  top:var(--line-h-tr);  
  position:absolute;  
}  
.b:before{  
  position:relative;  
  content  :"";  
  display:block;  
    width: 0;  
    height: 0;  
  top:calc(var(--line-h-tr)*-2);  
    border-top:    var(--line-h-tr) solid transparent;  
    border-right:  var(--line-h-tr) solid transparent;  
    border-bottom: var(--line-h-tr) solid var(--font-color);  
    border-left:   var(--line-h-tr) solid transparent;  
}  
.b:after{  
  position:relative;  
  content  :"";  
  display:block;  
    width:0;  
    height:0;  
  top:calc(var(--line-h-body) - var(--line-h-tr)*2);  
    border-top:    var(--line-h-tr) solid var(--font-color);  
    border-right:  var(--line-h-tr) solid transparent;  
    border-bottom: var(--line-h-tr) solid transparent;  
    border-left:   var(--line-h-tr) solid transparent;  
}  
  

数値化

各要素に数値クラスn0~`n9`を割り当てて表示しました。
※ここも変数にしたかった…

.num .b:nth-child(1){top: 30px;  left:10px; }  
.num .b:nth-child(2){top:-10px;  left:45px; transform:rotate(90deg);}  
.num .b:nth-child(3){top: 30px;  left:80px; }  
.num .b:nth-child(4){top: 70px;  left:45px; transform:rotate(90deg);}  
.num .b:nth-child(5){top:110px;  left:10px; }  
.num .b:nth-child(6){top:110px;  left:80px; }  
.num .b:nth-child(7){top:150px;  left:45px; transform:rotate(90deg);}  
  
.n0 .b:nth-child(1){}  
.n0 .b:nth-child(2){}  
.n0 .b:nth-child(3){}  
.n0 .b:nth-child(4){display:none;}  
.n0 .b:nth-child(5){}  
.n0 .b:nth-child(6){}  
.n0 .b:nth-child(7){}