[JavaScript]animate.cssとjQeuryを使ってスクロールに応じて要素を動かす関数を作ってみました。

縦長にデザインされたサイトで、スクロールするとフェードインしたり震えたりジャンプしたりいろいろ動いてクリックを誘導するデザインはポピュラーですよね。

よく使うものなので、簡単に使いまわせるように関数を作ってみました。

サンプル

demo

codepen

使用するライブラリ

jQuery
animate.css

animate.cssは、要素に様々なエフェクトを与えるCSSのみで書かれたライブラリ。headで読み込んで、動かしたい要素にclassを割り当てるだけで動いてくれるびで、とても便利です。

今回のサンプルでは、bounce(跳ねる)、pulse(膨らんでしぼむ)、swing(揺れる)、fadeIn(フェードイン)の4つを使ってみましたが、animate.cssの配布元サイトには数十にも及ぶエフェクトのサンプルが用意されています。

html

<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width" />
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">
<link href="animate.css" rel="stylesheet">
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
</head>
<body>
    <div class="container">
        <div class="col-xs-12">
            <h1>Please scroll ↓↓↓</h1>
                <p class="ani-bounce">bounce</p>
                <p class="ani-pulse">pulse</p>
                <p class="ani-swing">swing</p>
                <p class="ani-fadeIn">fadeIn</p>
                </div>
	</div>
</body>
</html>

CSS

h1{
  margin-bottom: 800px;
}

p{
  font-size: 24px;
  text-align:center;
  padding: 60px 30px;
  margin: 90px 180px;
  border: 5px solid #CCCCCC;
  background-color:#FFFFFF;
}

JavaScript

function animate($ani, $valPos) {

	if ($ani === 'fadeIn') {
		$(".ani-" + $ani).css("opacity", "0");
	}

	$(".ani-" + $ani).each(function() {

		var imgPos = $(this).offset().top;
		var scroll = $(window).scrollTop();
		var windowHeight = $(window).height();

		if (scroll > imgPos - windowHeight + windowHeight / $valPos) {
			$(this).addClass("animated " + $ani);
		} else {
		$(this).removeClass("animated " + $ani);
		}

	});

}

jQuery(window).on('touchstart scroll', function(){

	//timerID;
	var timer = false;

	if (timer !== false) {
		clearTimeout(timer);
	}

	timer = setTimeout(function() {

		animate('bounce','3');
		animate('fadeIn','7');
		animate('pulse','5');
		animate('swing','5');

	}, 100);

});

スクロール量に応じて引数に指定したanimate.cssのclassを付与したり外したりする関数animate()を、scroll(touchstart)イベントの中で呼び出しています。

scrollイベントはブラウザに負荷がかかるってことで、setTimeout()を使って負荷を減らす処理を入れてみました。

参考にさせていただきました。

jQueryとCSSのtransitionで可視範囲に入ってからアニメーションさせる方法|Webpark
[jQuery] ウインドウのリサイズ操作が終わった時にだけ処理を実行する | CreativeStyle

[WordPress]カスタム投稿のシングルページを条件分岐させるにはis_singular()を使う。

カスタム投稿タイプのシングルページかどうかの判定をしたい場合、該当ページで下記コードを実行すると真偽値が返却されます。

<?php is_singular( $post_types ); ?>

引数$post_typesには、判定したいカスタム投稿名を入力します。

例:

<?php if(is_singular('hoge')): ?> //hogeというカスタム投稿タイプを指定
    <?php get_template_part( 'loop-hoge' ); ?>
<?php else: ?>
    <?php get_template_part( 'loop' ); ?>
<?php endif; ?>

関数リファレンス/is singular

「商品名のエイリアス」投稿タイトルをif~else文で出し分ける。(AdvancedCustomFields使用)

ちょっとした小ネタです。

投稿名を商品名として表示するページを作ったのですが、数点だけ異なるルールの商品があることが後から判明し、回避策として対応したときのコードです。

対応方法

 
「商品名のエイリアス」をカスタムフィールドで作ってif文で出し分ける方法で逃げました。

サンプルコード

※カスタムフィールドの設定等の説明は省略します。

<?php if(have_posts()): while(have_posts()): the_post(); ?>

	<div class="item-name">
	<?php //商品の別名があれば取得して表示する

		$item_alias = get_field('item-alias'); //商品の別名を取得

		if($item_alias){
			echo $item_alias; //商品の別名がある場合はそれを出力する
		}else{
			the_title();
		}

	?>
	</div>

<?php endwhile; endif; ?>

get_field()で値を取得し、if文の条件として使います。
「商品名のエイリアス」がある場合のみそれを出力し、無ければ通常の投稿タイトルを出力します。
get_field()はAdvancedCustomFields用の関数です。

“引っかかり”のあるデザインを考える。

たとえば 、宮崎駿さんは 、 『崖の上のポニョ 』の制作の際に 「上手な線を描くな 」 「なめらかな線を描くな 」という指示を出していたといいます 。別の言い方だと 、 「引っかかりがある線を描け 」ということらしいのです 。素直な線というのは 、みんなが見ているから飽きられている 。ちょっと歪んでいることで 、みんなが気にするようになるでしょう 。だから 「他人が描けない線を描け 」と 、非常に難しい注文をつけるわけです 。

コンテンツの秘密 僕がジブリで考えたこと 川上量生

この考え方、自分がWEBデザインを作るときに非常に参考になりました。

自分が作るデザインの傾向として、フラット”すぎる”デザインというか、きれいだけどのっぺりとしてやや物足りない、ということがままあるのですが、「引っかかりがある」ようにするための「装飾」を入れてみたところ、以前よりも少し良くなった気がします。

フラットな線やモチーフがある程度続いたら、よしなに線を傾けたり、色の色相や明度彩度を変化させたり、少しずらしたり、といった「ノイズ」を配置するように心がける。

今までの考え方では、そういった装飾は意図や意味がないから極力省くべきもの、と思っていたのですが、実はそうじゃなくて、「引っかかり」を作るという役割を担っていたことにようやく気づけたような気がします。よく言われるメリハリを出すとか、リズムをつける、というような原理原則なのでしょう。

役割を持った装飾であれば、デザインに組み入れるのに抵抗はありません。なんだか楽になってきました。が、理解して消化して成果物に反映させていくには実装力が必要。これからは適切な「引っかかり」を作れるようにさらにデザイン力を高めていかなくては。おお忙しい!

[gulp]パッケージをアップデートし、gulpfile.jsをgulp-ruby-sass1.0以降に対応させました。

しばらく放置していたgulpのパッケージをアップデートしました。最新版になって気持ちが良いです!

「gulp-ruby-sass」を使っているのですが、アップデート後、バージョンが1.0.5となりました。1.0以降はタスクの書式が変わるらしく、gulpfile.jsの記述変更も実施。

元から抱えていたソースマップとベンダープレフィックスの不具合も修正し、(自分の環境で)うまく動作するようになりました。

以下、実際のコードになります。

gulpfile.js

var gulp = require('gulp');
var sass = require('gulp-ruby-sass');
var plumber = require("gulp-plumber");
var autoprefixer = require("gulp-autoprefixer");
var sourcemaps = require('gulp-sourcemaps');

gulp.task("sass", function() {
return sass('sass/', { //コンパイルしたいscssファイルを、「sass」ディリクトリに全て配置する
sourcemap: true ,
style: 'expanded'
})
.pipe(plumber())
.pipe(autoprefixer("last 3 version"))
.pipe(sourcemaps.write())
.pipe(gulp.dest('./'));
});

gulp.task('watch', function () {
gulp.watch('sass/**/*.scss', ['sass']);
});

scssファイルのコンパイル(出力スタイルはexpanded)、ソースマップの出力、ベンダープレフィックスの付与ができます。ライブリロードとか使ってみたいパッケージが他にもありますが、それはおいおいで。

今までソースマップは独立したファイルとして出力されていましたが、今回の修正でdestされたcssの中に記述される方式になったようです。

参考サイト

パッケージのアップデートは以下のサイトを参考にさせて頂きました。

Node.jsアプリでのパッケージ更新確認

gulpfile.jsの新しい書式は以下から。
gulp-sass から gulp-ruby-sass へ
gulp-ruby-sass – npm

Sublime Textでパッケージを管理するためのメモ

Sublime Textの魅力の一つとして、様々なパッケージをインストールして機能を拡張できることが挙げられますが、使っているうちに動作が不安定になったり、不要になったり、何をインストールしたのか忘れてしまったり何かと不都合が出るかと思います(私は出ました汗)。

そんなときに問題解決の役に立つメモをまとめてみました。

※Package Controlが導入されていることが前提です。

インストールしたパッケージを確認したい。

1.コマンドパレットで「List Packages」と入力すると出ます。

2.以下のメニューからも閲覧できます。こちらは設定ファイル的なものを開くので、テキストとしてコピーしたり別名保存したりできます。

Preferences » Package Settings » Package Control » Settings – User

SublimeText 3の導入パッケージをリスト化 – Qiita

パッケージを削除したい。

コマンドパレットで「Remove Package」と入力すると、インストール済みのパッケージリストが表示されるので、削除したいものを選んでenterキーで削除できます。

Sublime Textにインストールしたパッケージ(プラグイン)を削除する手順 | TechMemo

パッケージを一時的に無効化したい。

コマンドパレットで「Disable Package」と入力します。その後、無効化したいものを選びます。

パッケージを有効化したい。

コマンドパレットで「Enable Package」と入力します。その後、有効化したいものを選びます。

まとめ

Sublime Textはカスタマイズが容易な反面、自分独自の環境を維持するのに多少気を使いますね。
パッケージに関しては、とりあえず何をインストールしたかを最低限抑えておき、必要に応じて有効化/無効化/アンインストールしてクリーンな状態を保ちたいものです。