リハビリエンジニア

エンジニアリングのリハビリ中

複数スクロールコンテンツがあるときの、ユーザーによるスクロールの制御

タイトルがものすごいわかりづらいですね。 要は面白法人カヤックのサイトのこのページ(https://www.kayac.com/news)。

「タグ」をホバーしてスクロールすると分かるのですが、 下のメインコンテンツのスクロールは止まっていますね。 このような細かいところに気を使えているとイケてるサイトだなと思います(身内をほめているようでこそばゆい)

これは、bodyにoverflow:hiddenをかけてあげるだけで、実現できるようです(実証しました)。 簡単なのでコードは書きません。

PSDからフォントファミリーを抽出する

デザイナーからいただく.psdファイルにGoogleフォントが含まれていれば、 Google Fontsにおもむき、埋め込みコードを用意する必要があります。 その際いちいち使用しているテキストレイヤーの情報をみていてはとても時間がかかります。

github.com

githubからダウンロードしてきた.jsxファイルを、 Adobe Photoshop CC 2017 > Presets > Scripts に配置すれば、 Photoshopの「ファイル > スクリプト」から利用できます。

f:id:umadash:20170225230439p:plain

以下の記事も同じことをやってはいるんですが、 僕のPhotoShopのバージョンだと動かなかったので、 僕はこちらを使わせていただいています。

PhotoshopでWebデザインを効率化するための便利な使い方 | 株式会社LIG | PSD からテキスト情報を抽出するスクリプト (フェンリル | デベロッパーズブログ)

nfcopyでNFCをやってみたんだぜ(1)

実験的にNFCを試してみたく、
RC-S380とFelicaを購入し、nfcopyのexample/tagtool.pyを動かしてみました。
一部ハマったので、それをメモに残しておきます。

基本的には、以下のURLを参考に追っていくだけで、
サンプルの実行までたどりつけるはずです。
http://nfcpy.readthedocs.io/en/latest/topics/get-started.html
http://techblog.qoncept.jp/?p=165

しかし、僕の環境ではサンプル実行時に、
以下のようなエラーが出てサンプルが実行されませんでした。

AttributeError: dlsym(0x7f81ca493370, EC_KEY_set_public_key_affine_coordinates): symbol not found

いろいろ調べていたところ、
stackoverflowにて「OpenSSLを最新にしろ」とのことだったので、 最新版をつっこんだところ問題なくサンプルを実行できるようになりました。

stackoverflow.com

$ brew upgrade openssl
$ brew link openssl --force

CSS - フォントサイズの指定はremでやろう

久々にHTMLとCSSを書いている僕ですが、
今までfont-sizeの指定はお恥ずかしながら、全て%(またはem)で設定していました。(下のような感じ)

<html>
<body>
<div class='child'></div>
</body>
</html>
html {
   font-size: 16px;
}

body {
   font-size: 90%;//0.9em
}

.child {
   font-size: 90%;//0.9em
}

このときchildのフォントサイズは、bodyのfont-sizeの90%なので、 font-size = 16 * 0.9 * 0.9 となります。
これでは子要素が増えるたびに、フォントの大きさがわかりづらくなってしまいます。

rem = root em

remは親要素ではなくroot、
いわゆるhtmlに設定されたフォントの大きさを元に大きさを決定します。 *remを使用する時は、htmlのフォントサイズは%を指定する。

html {
   font-size: 62.5%; 
   //主要ブラウザのデフォルトサイズ16pxに対する62.5% => 10px;
}

body {
   font-size: 1rem; // 10px
}

.child {
   font-size: 1.6rem; // 16px
}

わかりやすいですね。

Photoshop - Photoshop CCでの画像の書き出し

Slicyを使ってスライスをするのが一番手っ取り早いなんて思っていたのですが、
PhotoshopCCにはさらに楽になる方がありました!

レイヤー名に〜.png, 〜.jpgとつけるだけ

ファイル > 生成 > 画像アセットをオン。
あとはレイヤー名につけたい画像名と拡張子をつけてあげてPSDを保存するだけで、 PSDと同じ階層に画像が保存されます。

便利すぎて泣ける。

いまさらBower入門

Gulpでタスクも自動化したところで、Cocoapodsのようにライブラリも管理したくなった。
そのため、いまさらBowerに手を出しました。

Bowerとは?

Twitter社製のフロントエンド用のパッケージマネージャー

なにができるのか?

・ライブラリのインストール
・ライブラリのバージョン管理
・管理するライブラリを減らす など。
いちいちライブラリをDLする作業がなくなるのは非常に良いことです。

Bowerのインストール

Node.jsをインストールした後、Bowerをグローバルインストールします。

npm install bower -g

Bower init

プロジェクトフォルダのルートまで移動して、Bower initしましょう。

cd PROJECT_ROOT_PATH
bower init

したらば、npm initと同様に対話形式で話が進みます。
質問内容は以下のリンクを参考にしたら良いと思います。

qiita.com

bower.json

npmのpackage.jsonと同様にbower.jsonがフォルダに確認できます。

jQueryのバージョン2系をインストール

私がフロントエンジニアを離れているうちにjQueryもいつのまにか2が・・・。
ということでjQueryの2系をbowerを使ってインストールしてみます。

bower install jquery#2 --save

--saveをつけておくとbower.jsonにdependencies(依存関係)が追記されます。
bower.json内に dependencies が記述されていれば、
指定しなくとも「bower install」だけでライブラリがインストールされる。

--save-devと--saveの違いについては、以下のリンクをご参考に。 nakagaw.hateblo.jp 開発に必要な物は--save-dev、
プロジェクトの実行に必要なものは--save
という関係だけ覚えておけば問題ない気もする。

読み込もう

下のように書いて読み込みこんでもいいと思います。

<script type="text/javascript" src="bower_components/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>

しかし、なんかイケてない感がある方は gulpを利用して、以下のように一つにまとめてlib.jsなんかに書き出しとかしたいと思います。

<script type="text/javascript" src="/js/lib.js"></script>

Gulp + Bowerだ!

もう散々色んな所で紹介されているのではしょります。 僕はこんな感じでbower_componentsの中をまとめてます。

gulp.task('bower', function(callback) {
  return runSequence(
    'concat.bower',
    'minify.bower',
    callback
  );
})

var files = mainBowerFiles()
gulp.task('concat.bower', function() {
  console.log(files)
  return gulp.src(files)
    .pipe(concat('lib.js'))
    .pipe(gulp.dest('_build/tmp/js'))
})

gulp.task('minify.bower', function() {
  return gulp.src('_build/tmp/js/lib.js')
    .pipe(plumber({
      errorHandler: notify.onError('<%= error.message %>')
    }))
    .pipe(uglify({preserveComments: 'license'}))
    .pipe(gulp.dest('./js'));
})

ソースはこちら

github.com

いまさらGulp(4)

そんなこんなで二日間Gulpfile.jsを調整していたのですが、
どうにか自分が納得いくGulpfile.jsができました。

'use strict';

var gulp        = require('gulp');
var connect     = require('gulp-connect');
var plumber     = require('gulp-plumber');
var notify      = require('gulp-notify');
var concat      = require('gulp-concat');
var sass        = require('gulp-sass')
var pleeease    = require('gulp-pleeease');
var uglify      = require('gulp-uglify');
var runSequence = require('run-sequence');
var del         = require("del");


gulp.task('default', ['connect', 'watch'])

gulp.task('watch', function() {
  gulp.watch('./_build/scss/**', ['css']);
  gulp.watch('./_build/js/**', ['js']);
  gulp.watch('./*.html', ['reload']);
});

gulp.task('connect', function() {
  connect.server({
    root: './',
    livereload: true
  });
})

gulp.task('reload', function () {
  gulp.src('./*.html')
    .pipe(connect.reload());
});

gulp.task('css', function(callback) {
  return runSequence(
    'clean.css',
    'compile.css',
    'concat.css',
    'optimize.css',
    'reload',
    callback
  );
})

gulp.task('js', function(callback) {
  return runSequence(
    'clean.js',
    'concat.js',
    'minify.js',
    'reload',
    callback
  );
})

gulp.task('concat.js', function() {
  return gulp.src('./_build/js/**')
    .pipe(plumber({
      errorHandler: notify.onError('<%= error.message %>')
    }))
    .pipe(concat('main.min.js'))
    .pipe(gulp.dest('./_build/tmp/js'));
});

gulp.task('minify.js', function() {
  return gulp.src('./_build/tmp/js/*.js')
    .pipe(plumber({
      errorHandler: notify.onError('<%= error.message %>')
    }))
    .pipe(uglify({preserveComments: 'some'}))
    .pipe(gulp.dest('./js'));
});

gulp.task('compile.css', function() {
  return gulp.src('./_build/scss/*.scss')
    .pipe(plumber({
      errorHandler: notify.onError('<%= error.message %>')
    }))
    .pipe(sass({style: 'expanded'}))
    .pipe(gulp.dest('./_build/tmp/css'))
})

gulp.task('concat.css', function() {
  return gulp.src('./_build/tmp/css/*.css')
    .pipe(plumber({
      errorHandler: notify.onError('<%= error.message %>')
    }))
    .pipe(concat('layout.css'))
    .pipe(gulp.dest('./css'))
})

gulp.task('optimize.css', function() {
  return gulp.src('./css/*.css')
    .pipe(plumber({
      errorHandler: notify.onError('<%= error.message %>')
    }))
    .pipe(pleeease({
      autoprefixer: true,
      minifier: false,
      mqpacker: true
    }))
    .pipe(gulp.dest('./css'))
})

gulp.task('clean', function(callback) {
  return runSequence(
    'clean.js',
    'clean.css',
    callback
  );
})

gulp.task('clean.css', function() {
  del(['./_build/tmp/css/*.css'])
})

gulp.task('clean.js', function() {
  del(['./_build/tmp/js/*.js'])
})

解説はとくになし。

github.com