おかゆ++

IT業界の片隅で生き残るブログ

VimとCtagsの連携設定・使い方メモ

Vim と Ctags を連携させます。

何ができるようになる?

まだ使いこなせてないので細かいところはわからないですが、 ソースコードを解析して、関数の定義元へジャンプしたりとかできるようになるハズ。

前提

Ctagsのインストール

chocolateyで入れるのが楽だと思います。

最近はuniversal-ctagsというのがあるらしいですが、chocolateyにパッケージがないみたいなので、昔ながらの?ctagsを使います。 ctagsはもうメンテされてないらしいので、ほんとはuniversal-ctagsを使ったほうがいいみたいですが。

choco install ctags

Ctagsの設定

~/.ctags に設定ファイルを配置して、JavaScript用の拡張を記載します。

Windows環境変数HOMEなどを設定していない場合は、実行ファイルと同じ場所におけばいいのかな? すみません、確認できてません……

--exclude=.git
--exclude=.hg
--exclude=log
--exclude=tmp

--languages=-javascript
--langdef=js
--langmap=js:.js
--langmap=js:+.jsx

--regex-js=/[ \t.]([A-Z][A-Z0-9._$]+)[ \t]*[=:][ \t]*([0-9"'\[\{]|null)/\1/n,constant/
--regex-js=/\.([A-Za-z0-9._$]+)[ \t]*=[ \t]*\{/\1/o,object/
--regex-js=/['"]*([A-Za-z0-9_$]+)['"]*[ \t]*:[ \t]*\{/\1/o,object/
--regex-js=/([A-Za-z0-9._$]+)\[["']([A-Za-z0-9_$]+)["']\][ \t]*=[ \t]*\{/\1\.\2/o,object/
--regex-js=/([A-Za-z0-9._$]+)[ \t]*=[ \t]*\(function\(\)/\1/c,class/
--regex-js=/['"]*([A-Za-z0-9_$]+)['"]*:[ \t]*\(function\(\)/\1/c,class/
--regex-js=/class[ \t]+([A-Za-z0-9._$]+)[ \t]*/\1/c,class/
--regex-js=/([A-Za-z$][A-Za-z0-9_$()]+)[ \t]*=[ \t]*[Rr]eact.createClass[ \t]*\(/\1/c,class/
--regex-js=/([A-Z][A-Za-z0-9_$]+)[ \t]*=[ \t]*[A-Za-z0-9_$]*[ \t]*[{(]/\1/c,class/
--regex-js=/([A-Z][A-Za-z0-9_$]+)[ \t]*:[ \t]*[A-Za-z0-9_$]*[ \t]*[{(]/\1/c,class/
--regex-js=/([A-Za-z$][A-Za-z0-9_$]+)[ \t]*=[ \t]*function[ \t]*\(/\1/f,function/
--regex-js=/(function)*[ \t]*([A-Za-z$_][A-Za-z0-9_$]+)[ \t]*\([^)]*\)[ \t]*\{/\2/f,function/
--regex-js=/['"]*([A-Za-z$][A-Za-z0-9_$]+)['"]*:[ \t]*function[ \t]*\(/\1/m,method/
--regex-js=/([A-Za-z0-9_$]+)\[["']([A-Za-z0-9_$]+)["']\][ \t]*=[ \t]*function[ \t]*\(/\2/m,method/

Vimでの操作

大体このあたりを使っていきたいです。

操作 動作
C-] カーソル位置でタグジャンプ実行
C-t ジャンプ元に戻る
g C-] ジャンプ先一覧を表示

参考

自作キーボードを作ります① きっかけ&買ったもの

きっかけ

1月ごろ、とうとうHappy Hacking Keyboard Pro2を購入しました。

ずっとRealforceのJIS配列を使っていましたが、もっとコンパクトなキーボードが欲しくなり、 どうせならってことでUS配列のHHKBを選びました。 最初は配列の違いに戸惑いましたが、今はもうほかのキーボードには戻れない身体になってしまいました。

HHKBに慣れてきたころ、TwitterやQiitaで自作キーボードの記事を見つけました。 どうやらキーボードを簡単に作れるArduinoがあって、自作キーボードがにわかに流行っているらしいですね。

ということで、自分も作ることにしました。

方針とか

自分はエンジニアではありますが、完全なソフト畑の人間で、Webアプリの知識がメイン。 電子工作は完全な初心者です。

しかしC言語は勉強したことがあるので、Arduinoの言語であるProcessingはなんとなくわかります。

基本方針は以下の通り。

  • 左右分離型
  • 60%キーボード
  • なるべく安く?
  • せっかくなのでファームウェアも自作する
  • 格子配列の5×6
  • 特に変わった機能をつける予定なし(自作すること自体が目的の半分なので……)
  • つまり劣化Helix

購入したもの

購入元は秋月電子、AliExpress、ebayAmazonなど。

はんだづけの道具なども欲しかったので色々なところから購入したけど、 道具がそろっていて、自作キーボードに必要なものだけ買うなら、 以下のショップで全て揃いそう。(値段が安いかどうかは不明)

TALP KEYBOARD

[2018/03/05 追記]
TALP KEYBOARDで買ってみました。AliExpressよりも数十円~数百円高いですが、国内発送で、注文した翌日に発送されました。 商品がすぐに手元に欲しい場合や、中華サイトが怖い場合はTALP KEYBOARDで買うのがベストだと思います。 キーキャップの色も豊富で、好きな色が買えるのがいいですね。 AliExpressだとアソートが多いので……

キースイッチ

Gateron RGB 茶軸 × 70個を購入。 60%キーボード(キーが60個のキーボード)を作るつもりだけど、余裕を見て多めに注文。 購入元はebay。AliExpress より安かったです。

あとから追加で Gateron RGB 赤軸 も買ってしまった。これは2台目に使う予定です。 赤軸のほうは AliExpress で購入。

キーキャップ

DSAのキーキャップをAliExpressで購入。 DCSのほうがいいかもしれないけど、とりあえずは使ってみながら交換していく予定です。

マイコンボード

完全な初心者なので、最初は勉強・練習用にArduino Microを2台購入。 購入は秋月電子で、1台¥2,800くらい。

Arduino Microでファームウェアの原型ができた頃に、本番用にPro Microを追加購入しました。 こっちはAliExpressで1台¥650くらいでした。

ダイオード

回路に必要なダイオードは、ネットで見ていると1N4148というのが良く使われているみたいです。

今回は秋月電子で1N4148を買ったけれど、代用品として勧められていた1SS178も買ってみました。 1N4148は50本/¥100、1SS178は100本/¥100でした。 1SS178のほうが半値で買えるので、結構良さげ。(使えないかもしれないけど)

[2018/03/05 追記]
普通に使えるんで、秋月電子で買う場合は1SS178がいいと思います。

電子工作用の道具

はんだづけの道具(はんだ、はんだごて、こて台)に加えて、 ブレッドボード、ジャンパワイヤ、タクトスイッチ等も購入。

その他に必要なもの

筐体 or プレート

キーボードの外枠として、筐体となるような箱や、アクリルプレートなどが必要です。

PlankやLet's Splitなどではアクリルプレート二枚で挟み込むタイプが多い印象。 ただ、この場合はPCBがないとマイコンや接続用端子を固定するのに工夫が必要。

今回は3Dプリンタを使って作ることにしました。 3D CADも完全初心者なので要勉強です。

PCB

キースイッチやダイオードを配置する基盤が必要です。 今回は筐体を3Dプリンタで作り、空中配線する予定なので、不要(のハズ)。

参考にしていく記事

基本的には ゆかりめも 様のブログで勉強したままに作っていく予定です。 eucalyn.hatenadiary.jp

2017年の自作キーボード Advent Calendarはいろいろな記事があって参考になりそうです。 adventar.org

時間はかかりそうですが、ぼちぼち作っていきます。

Ubuntuで/bootの容量不足でapt-get upgradeできない時の対処

Ubuntu Server 16.04 で、apt-get upgrade した時にエラーが発生。

エラーメッセージを見ると、どうも /boot の容量が 100% になってるのが原因っぽい。

参考: munibus.hatenablog.com www.mmpp.org

最終的には、/boot 配下の不要なカーネル類を削除して、容量を開けてから sudo apt-get -f upgrade で解決しました。

sudo rm -f /boot/*24*
sudo rm -f /boot/*32*
# そのほかいろいろ削除して容量を確保してから
sudo apt-get -f upgrade
sudo apt autoremove

しかし容量不足でエラーになるということは、定期的に古いカーネルを削除していったほうがいいってことですかね。 apt autoremove で消えるんであればいいですけど、明示的にapt-get removeしないと消えないのなら面倒ですね。

MSYS2でVim8をコンパイル(Windows)

前提

2017/12/28時点の情報です! なるべく更新しますが、今後もこの通りとは限りません。

+perl、+python、+python3、+lua、+rubyが有効なVimコンパイルします。

基本的にはvim-jpの記事を参考にしますが、Perl、Python2、Python3、RubyはChocolateyでインストールします。 LuaもChocolateyでインストールしますが、ソース(lua.hなど)がダウンロードされないので、 ソースだけ別途取得します。

vim-jp.org

chocolateyでのインストール

choco install -y StrawberryPerl --version 5.26.1.1
choco install -y python2 --version 2.7.9
choco install -y python3 --version 3.6.4
choco install -y ruby --version 2.3.3
choco install -y lua53 --version 5.3.3

それぞれ、以下の場所にインストールされる。

  • python2:C:\tools\python2
  • python3:C:\Python36
  • RubyC:\tools\ruby23
  • PerlC:\Strawberry\perl
  • LuaC:\ProgramData\chocolatey\lib\lua53\tools

MSYS2の準備

pacman -Suuy
# ここで一度minttyを閉じて、再度開く
pacman -Suu
pacman -S git mingw-w64-i686-toolchain mingw-w64-x86_64-toolchain
pacman -S python3

作業用のディレクトリ作成、ソースの取得

mkdir -p ~/src/vim
cd ~/src/vim
# Lua
wget http://www.lua.org/ftp/lua-5.3.3.tar.gz
tar xzvf lua-5.3.3.tar.gz
# Vim
git clone https://github.com/vim/vim.git

ビルド

cd ./vim/src
rm -rf ./build
mkdir -p ./build/vimfiles

# メッセージファイルを生成
python3 C:/Python36/tools/i18n/msgfmt.py ./po/ja.po

# ビルド(CUI)
mingw32-make -f Make_ming.mak  \
  GUI=no \
  ARCH=x86-64 \
  IME=yes \
  MBYTE=yes \
  ICONV=yes \
  FEAT_TERMGUICOLORS=yes \
  clean
mingw32-make -f Make_ming.mak \
  ARCH=x86-64 \
  IME=yes \
  MBYTE=yes \
  ICONV=yes \
  FEAT_TERMGUICOLORS=yes \
  PERL=C:/Strawberry/perl DYNAMIC_PERL=yes PERL_VER=526 \
  PYTHON=C:/tools/python2 DYNAMIC_PYTHON=yes PYTHON_VER=27 \
  PYTHON3=C:/python36 DYNAMIC_PYTHON3=yes PYTHON3_VER=36 \
  RUBY=C:/tools/ruby23 DYNAMIC_RUBY=yes RUBY_VER=23 RUBY_API_VER_LONG=2.3.0 \
  LUA=~/src/vim/lua-5.3.3/src DYNAMIC_LUA=yes LUA_VER=53 \
  GUI=no
cp vim.exe ./build/

# ビルド(GUI)
mingw32-make -f Make_ming.mak  \
  GUI=yes \
  ARCH=x86-64 \
  IME=yes \
  MBYTE=yes \
  ICONV=yes \
  FEAT_TERMGUICOLORS=yes \
  clean
mingw32-make -f Make_ming.mak \
  ARCH=x86-64 \
  IME=yes \
  MBYTE=yes \
  ICONV=yes \
  FEAT_TERMGUICOLORS=yes \
  PERL=C:/Strawberry/perl DYNAMIC_PERL=yes PERL_VER=526 \
  PYTHON=C:/tools/python2 DYNAMIC_PYTHON=yes PYTHON_VER=27 \
  PYTHON3=C:/python36 DYNAMIC_PYTHON3=yes PYTHON3_VER=36 \
  RUBY=C:/tools/ruby23 DYNAMIC_RUBY=yes RUBY_VER=23 RUBY_API_VER_LONG=2.3.0 \
  LUA=~/src/vim/lua-5.3.3/src DYNAMIC_LUA=yes LUA_VER=53 \
  GUI=yes \
  STATIC_STDCPLUS=yes \
  DIRECTX=yes
cp gvim.exe ./build/
cp vimrun.exe ./build/

# パッキング
cp C:/msys64/mingw64/bin/libiconv-2.dll ./build/
cp C:/msys64/mingw64/bin/libintl-8.dll ./build/
cp C:/msys64/mingw64/bin/libwinpthread-1.dll ./build/

cp C:/Strawberry/perl/bin/perl526.dll ./build/
cp C:/tools/ruby23/bin/x64-msvcrt-ruby230.dll ./build/
cp C:/Windows/System32/python27.dll ./build/
cp C:/Python36/python36.dll ./build/
cp C:/ProgramData/chocolatey/lib/lua53/tools/lua53.dll ./build/
cp -r ../runtime ./build/vim80
mkdir -p ./build/vim80/lang/ja/LC_MESSAGES
cp ./po/ja.mo ./build/vim80/lang/ja/LC_MESSAGES/vim.mo

# 実行ファイル置き場に移動
mkdir ~/bin/vim/
cp -r ./build/* ~/bin/vim/

vimrcをファイル分割する&VimとNeoVimで共通化する

vimrc分割の理由

Vimを使っていれば、プラグインを追加したり、設定を変えたり等々でvimrcは長くなっていく一方です。 ということで、読みやすさと拡張性を確保するためにも当然分割したいわけです。

分割ついでに、VimとNeoVimの両方で同じvimrcを使うようにしたい。vimrcの中身が同じって意味ではなくて、同じvimrcファイルをVimとNeoVimの両方で参照するってことです。

分割の仕組みというか、sourceについて

Vimのコマンドに source というのがあります。まんま指定したVim scriptファイルを読み込むコマンドです。これを使えば複数ファイルに分割できそうですね。実際には source をラップした関数を作るのがいいんじゃないでしょうか。

今回のディレクトリ構成

以下の方針でディレクトリを分けます。

  • 全ての設定ファイルは ~/.dotfiles/vim に配置して、所定の位置にはシンボリックリンクを張る。
  • プラグイン管理には dein を使う
  • Vim で dein を使った時のファイル類や、その他のファイルは ~/.vim に配置する。
  • NeoVim で dein を使った時のファイル類、その他のファイルは ~/.nvim に配置する。
  • 設定ファイル類は *.rc.vim という名前にする。

ということで、こんな感じ。

~/
├─.vim
│  ├─dein    deinがダウンロードしたリポジトリとかが入る
│  └─rc      ~/dotfiles/vim/rc へのシンボリックリンク
├─.nvim
│  ├─dein    deinがダウンロードしたリポジトリとかが入る
│  └─rc      ~/dotfiles/vim/rc へのシンボリックリンク
└─dotfiles
    └─vim
        └─rc  色々な設定ファイル類が入る。vimrcからsourceで読み込む。

VimとNeoVimの判定

vimrcの先頭でVimとNeoVimの判定を実施して、ディレクトリパスなどをグローバル変数に入れておきます。以後はこの変数を使うようにします。

NeoVimの場合は has('nvim') がTrueになるので、これを使います。

if has('nvim')
    let g:vim_home = expand('~/.nvim')
    let g:rc_dir = expand('~/.nvim/rc')
else
    let g:vim_home = expand('~/.vim')
    let g:rc_dir = expand('~/.vim/rc')
endif

読み込み用の関数

基本的には rcディレクトリからのみ読み込むようにするので、それ用に関数を作ります。 また、VimとNeoVimではディレクトリが違うので、そのあたりもさっきのグローバル変数で吸収します。

" rcファイル読み込み関数
function! s:source_rc(rc_file_name)
    let rc_file = expand(g:rc_dir . '/' . a:rc_file_name)
    if filereadable(rc_file)
        execute 'source' rc_file
    endif
endfunction

call s:source_rc('init.rc.vim') のような感じで書けば、dotfiles/vim/rc/init.rc.vim が読み込まれます。

最終的なvimrc

最終的には以下のようになりました。

if has('nvim')
    let g:vim_home = expand('~/.nvim')
    let g:rc_dir = expand('~/.nvim/rc')
else
    let g:vim_home = expand('~/.vim')
    let g:rc_dir = expand('~/.vim/rc')
endif

" rcファイル読み込み関数
function! s:source_rc(rc_file_name)
    let rc_file = expand(g:rc_dir . '/' . a:rc_file_name)
    if filereadable(rc_file)
        execute 'source' rc_file
    endif
endfunction

"------------------------------------------------------------------------------

" 基本設定
call s:source_rc('init.rc.vim')

" エディタの設定
call s:source_rc('editor.rc.vim')

" Dein.vim
call s:source_rc('dein.rc.vim')

" カラースキーマ
call s:source_rc('color.rc.vim')

" ターミナル設定(今の所NeoVimの :terminal の設定)
call s:source_rc('terminal.rc.vim')

" neocomplete
call s:source_rc('neocomplete.rc.vim')

" unite
call s:source_rc('unite.rc.vim')

" caw.vim
call s:source_rc('caw.rc.vim')

" NERDTree
call s:source_rc('nerdtree.rc.vim')

" lightline.vim
call s:source_rc('lightline.rc.vim')

ちょっと設定ファイルを分けすぎた感もあるけど、まぁ許容範囲かなーということで。

インストール用のスクリプトも作っておく

install.sh とか install.bat とかを作っておけば、git clone して sh install.sh すれば環境が整うはず。

Unix用のinstall.shはこんな感じ。

#!/bin/sh
cd $(dirname ${0}) 

vim_home=~/.vim
mkdir -p ${vim_home}
ln -sf `pwd`/vim/vimrc ~/.vimrc
ln -sf `pwd`/vim/rc ${vim_home}/rc

nvim_home=~/.nvim
mkdir -p ${nvim_home}
mkdir -p ~/.config/nvim
ln -sf `pwd`/vim/vimrc ~/.config/nvim/init.vim
ln -sf `pwd`/vim/rc ${nvim_home}/rc

Windows場合、シンボリックリンクの作成に管理者権限で実行する必要があることだけ注意が必要です。 また、vimrcの置き場所とかも色々*1だと思いますので、以下はあくまでも例です。

@echo off
@setlocal
cd %~dp0
set current=%~dp0

set vim_home=%HOME%\.vim
mkdir %vim_home%
mklink "%HOME%\.vimrc" "%current%vim\vimrc"
mklink "%HOME%\.gvimrc" "%current%vim\gvimrc"
mklink /D "%vim_home%\rc" "%current%vim\rc"

set nvim_initdir=%userprofile%\AppData\Local\nvim
mkdir "%nvim_initdir%"
mklink %nvim_initdir%"\init.vim" "%current%vim\vimrc"

@endlocal
@echo on

*1:自分は環境変数HOMEを用意して、vimrcなんかもそこに置いてます。

はてなブログの背景にアニメーションをつける(自作テーマ不使用)

このブログの背景にアニメーションをつけてみました。コードはGitHubで公開しています。

github.com

はてなブログではhead要素の中に自由に要素を追加できるので、こういうちょっとした改造がすぐできていいですね。

自作テーマを作ることでも実現できると思いますが、そこまでは……という気持ちだったので、JavaScriptでゴリゴリやりました。

ざっくりした方法

  1. canvas要素を画面いっぱいのサイズで最背面に追加する
  2. canvas要素に適当なアニメーションを描画する(アニメーションはsetIntervalとかで愚直に書く)
  3. ウィンドウがリサイズしたときに、canvasも合わせてリサイズする

さくっと自分のはてなブログに適用したい方へ

はてなブログの 設定>詳細設定 を開きます。

f:id:okayu-moka:20170929164807p:plain
はてなブログ 設定>詳細設定

headに要素を追加 に、以下のソースを貼り付けます。

<script>
!function(n){function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var e={};t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{configurable:!1,enumerable:!0,get:i})},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},t.p="",t(t.s=0)}([function(n,t){!function(){var n=15,t=null,e=null,i=[];window.addEventListener("load",function(n){o(),a(),r(),d()});var o=function(){t=document.createElement("canvas"),t.id="__background_animation_canvas__",t.style.position="fixed",t.style.top=0,t.style.left=0,t.style.zIndex=-1,t.style.margin="0",t.style.padding="0",t.width=window.innerWidth,t.height=window.innerHeight,e=t.getContext("2d"),document.body.appendChild(t)},a=function(){var e=window.innerWidth;n=e>1920?20:e>1600?15:e>1024?10:7;for(var o=0;o<n;o++)i.push({x:t.width/2,y:t.height/2,angle:2*Math.PI*Math.random(),size:30+70*Math.random(),speed:.02+(.05-.02)*Math.random()})},r=function(){var n=null;window.addEventListener("resize",function(){null===n&&window.clearTimeout(n),n=window.setTimeout(function(){t.width=window.innerWidth,t.height=window.innerHeight,n=null},200)})},l=function(){e.beginPath(),e.clearRect(0,0,t.width,t.height),e.closePath();for(var n=0;n<i.length;n++){var o=i[n];e.beginPath(),e.fillStyle="rgba(255, 170, 1, 0.1)",e.arc(o.x,o.y,o.size,0,2*Math.PI,!1),e.fill(),e.closePath()}},u=function(){var n=null;return function(){var e=t.width,o=t.height,a=Date.now();null===n&&(n=a);for(var r=0;r<i.length;r++){var l=i[r],u=l.speed*(a-n),d=u*Math.cos(l.angle),c=u*Math.sin(l.angle);l.x+=d,l.y+=c,(l.x<=0||e<=l.x)&&(l.angle=Math.atan2(c,-d),l.x=l.x<=0?0:e),(l.y<=0||o<=l.y)&&(l.angle=Math.atan2(-c,d),l.y=l.y<=0?0:o)}n=a}}(),d=function(){var n=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame,t=function(t){n?n(t):window.setTimeout(t,33)},e=function(){try{u(),l()}catch(n){console.log(n)}t(e)};t(e)}}()}]);
</script>

以上でアニメーションは適用されますが、全面の要素で隠れてしまう場合があります。その場合はCSSで背景を透明にします。このブログでは記事の部分(#content の部分)に背景色 #ffffff が設定されており、アニメーションが隠れてしまったので、記事部分の背景を透明にします。

cssはデザイン設定からも上書きできますが、コードが近いほうがわかりやすそうなので、同じく headに要素を追加 の部分に以下を追記します。

<style>
#content{ background-color: transparent !important; } /* 背景透過 */
</style>

このあたりは使用しているブログテーマによってまちまちなので、調整が必要です。

コードの解説

簡単にポイントのみ解説します。

jQueryを使うかどうか

ブログテーマによってはjQueryが使用されているものがあり、今使わせてもらっているこのテーマでも読み込まれています。

が、今回は使わずに素のJavaScriptだけにしました。jQueryを使わないと面倒なところが特になかったのと、他のブログテーマに乗り換えたときにも使えるようにしたかったのが主な理由です。

canvas要素を画面いっぱいに追加する

document.createElementcanvas要素の生成して、body要素の直下に追加します。

画面いっぱいに広げる際に注意が必要なのが、canvasのサイズはcssで設定せず、canvas.widthとcanvas.heightで設定する点です。canvas自体のサイズを調整せずにcsswidth:100% などとすると、canvasの解像度はそのままに、横に引き伸ばした表示になってしまいます。今回はウィンドウサイズ=canvasサイズとしたいので、canvas.widthとcanvas.heightを設定します。

var canvas = null;
var context = null;
var createCanvas = function() {
    canvas = document.createElement('canvas');
    canvas.id = '__background_animation_canvas__';
    canvas.style.position = 'fixed';
    canvas.style.top = 0;
    canvas.style.left = 0;
    canvas.style.zIndex = -1;
    canvas.style.margin = '0';
    canvas.style.padding = '0';

    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    context = canvas.getContext('2d');

    document.body.appendChild(canvas);
};

初期化とアニメーション開始のタイミング

案としては DOMContentLoaded イベント時と、windowの load イベント時があります。

はてなブログでは DOMContentLoaded 後にも色々スクリプトが走ったりしているぽいので、今回は load イベントで初期化・アニメーション開始としました。実際、 DOMContentLoaded だとアニメーション開始後のカクツキがひどかったので、load が無難だと思います。

window.addEventListener('load', function(event) {
    createCanvas();
    createCircles();
    initOnResize();
    startTimer();
});

アニメーションの描画

canvasにアニメーションを描画するために、タイマーを回します。タイマーとしては setInterval などでも良いですが、こういう画面更新の用途としては requestAnimationFrame を使うのが良いみたいです。

ただ requestAnimationFrame は対応していないブラウザなんかもあるみたいなので、対応していない場合は setTimeout で代用するようにしておきます。

var startTimer = function() {
    var requestAnimationFrame = 
            window.requestAnimationFrame || window.mozRequestAnimationFrame ||
            window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
    var requestFrame = function(loopFunc) {
        if (requestAnimationFrame) {
            requestAnimationFrame(loopFunc);
        } else {
            window.setTimeout(loopFunc, 33);
        }
    };
    var loopFunc = function() {
        try {
            move();
            draw();
        } catch (e) {
            console.log(e);
        }
        requestFrame(loopFunc);
    };
    requestFrame(loopFunc);
};

JavaScriptの圧縮(minify)

そのままのコードでだいたい130行くらいになってしまったので、圧縮して短くします。Webにオンラインで圧縮してくれるサービスがいくつもあるので、それを利用するのが一番手軽だと思います。

ただ今後のことも考えて、webpack3でminifyするようにしました。plugins にminifyプラグインを指定すると出力時に圧縮してくれます。

const webpack = require("webpack");

module.exports = {
    entry: {
        'build': './src/bubble-anim.js',
        'docs': './src/bubble-anim.js'
    },
    output: {
        filename: "./[name]/bubble-anim.min.js"
    },
    plugins: [
        new webpack.optimize.UglifyJsPlugin()
    ],
}

まとめ

ブログのカスタマイズは楽しいですね。<head> に自由に追加できるということは、実質何でもできると思うので、色々試していきたいです。

Debian 9 stretch インストール直後から環境を整える

自分用の最低限の環境を整えるための手順です。

本当は何らかの方法で自動化したいところですが、それはまたの機会に。

[2018/03/15 追記]
末尾にシェルスクリプト貼りました。

sudoできるように

sudo 入ってなかった!

$ apt install sudo
$ adduser [username] sudo

Gnomeを整える

こだわりはないので、Dash To Dockだけ入れておけばそれなりに使えます!

Dash to Dock - GNOME Shell Extensions

ホームディレクトリの英語化

ホームディレクトリの「デスクトップ」とか「ダウンロード」を英語にします。

sudo apt-get install xdg-user-dirs-gtk
LANG=C xdg-user-dirs-gtk-update

Git、GitKraken

たしかGitが入ってなかった気がするので導入します。 クライアントはGitKrakenがお気に入りです。

sudo apt-get install -y git
wget https://release.gitkraken.com/linux/gitkraken-amd64.deb
sudo apt install -y ~/gitkraken-amd64.deb
rm -y gitkraken-amd64.deb

VimGVim、NeoVim、ついでにPython3

これがないと何もできない……

sudo apt-get install -y vim vim-gnome neovim
sudo apt-get install -y python3 python3-pip
sudo pip3 install --upgrade neovim
git clone [dotfilesリポジトリ] ~/dotfiles
sh ~/dotfiles/install.sh

Vivaldi

最強ブラウザ。 最新版を取ってくるようなURLが見つからなかったので都度探すしかないかも……

wget https://downloads.vivaldi.com/stable/vivaldi-stable_1.12.955.36-1_amd64.deb
sudo apt install -y vivaldi-stable_1.12.955.36-1_amd64.deb
rm -y vivaldi-stable_1.12.955.36-1_amd64.deb

Node.js

公式サイト通りの手順で、aptで入れます。

パッケージマネージャを利用した Node.js のインストール | Node.js

setup_8.x のところは適宜最新版にします。

sudo apt-get install -y curl
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs
sudo npm install -g npm-check-updates

その他

sudo apt-get install -y build-essential
sudo apt-get install -y peco
sudo apt-get install -y byobu
sudo apt-get install -y chromium chromium-l10n

一括でやるスクリプト

できないこと:

  • sudoの設定(事前にやっておく必要あり)
  • ホームディレクトリの英語化
  • Gnomeの設定(Dash to Dockの追加)
  • Vivaldiのインストール(最近はFirefoxなので)
  • Vimの設定(dotfilesのcloneなど)
#!/bin/bash

# install packages
sudo apt install -y build-essential git peco byobu curl libssl-dev libreadline-dev zlib1g-dev libsqlite3-dev

# Vim (from source)
sudo apt build-dep -y vim 
sudo apt install -y python-dev 
mkdir ~/src
cd ~/src
git clone https://github.com/vim/vim.git ~/src/vim
cd ~/src/vim/src
./configure --with-features=huge --enable-fail-if-missing --enable-pythoninterp=dynamic --enable-python3interp=dynamic --enable-rubyinterp=dynamic --enable-luainterp=dynamic --enable-perlinterp=dynamic
make
sudo make install


# Node
curl -sL https://deb.nodesource.com/setup_9.x | sudo -E bash -
sudo apt install -y nodejs
sudo npm install -g npm-check-updates


# Ruby
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
cd ~/.rbenv
./src/configure 
make -C src
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
source ~/.bashrc
rbenv install 2.5.0
rbenv global 2.5.0