bata's log

フロントエンド系のTipsとかメモ

画像ロールオーバーをオブジェクト指向的な書き方で実装すると…

大昔のこの記事のURL元がなくなってて、どんなコードだったのか興味があったので書いてみた。

cl.pocari.org - ロールオーバーのオブジェクト指向的実装

まあこの時代なので「<img onMouseOver=''>とかでやってて、それをJSのみで実装して使いやすくしよう」、みたいな内容だったらしいけど、元記事がないのでその辺はわかりません。

書いてみると普通10行以内のものがこれだけ長くなってしまったけど、ある程度の汎用性と拡張性は確保できてると思います。
まあオブジェクト指向かどうかと言われると違う気がする…

JavaScript

function ImgRollover(el,suffix){
    this.el = '.' + el || '.imgOver';
    this.suffix = suffix || '_o';
    this.event();
    this.preload();
}

ImgRollover.prototype = {

    //イベント
    event: function(){
        var that = this;
        $(that.el).on({
            mouseover: function(){
                $(this).attr('src', that.getOnSrc(this));
            },
            mouseleave: function(){
                $(this).attr('src', that.getOffSrc(this));
            }
        });
    },

    //プリロード機能
    preload: function(){
        var that = this;
        $(this.el).each(function(){
            $('<img />').attr('src',that.getOnSrc(this,that.suffix));
        });
    },

    //画像パスを取得
    getSrc: function(self){
        return $(self).attr('src');
    },

    //mouseoverの画像パスを取得
    getOnSrc: function(self,suffix){
        return this.getSrc(self).replace(/^(.+)(\.[a-z]+)$/, '$1' + this.suffix + '$2');
    },

    //mouseleaveの画像パスを取得
    getOffSrc: function(self,suffix){
        return this.getSrc(self).replace(this.suffix,'');
    }

}

実行

$(function(){
    new ImgRollover('on','_o'); //('クラス名','接尾語')
})

GruntでCSSファイルを結合・圧縮する

いろんな理由でSassが使えない案件があった場合でも、機能毎にファイルを分割管理したいので書いてみた。

ググったけどCSSファイルの結合に関してはあまり該当する記事がなかったけど需要ないの?
まあ、JSファイルを結合する時と同じ要領なので誰もわざわざ書かないだけかもしれないので、一応メモとして残しておく。スニペットにもなるし。

module.exports = function(grunt) {

    grunt.initConfig({
        //結合
        concat : {
            css : {
                src : [
                'css/input01.css',
                'css/input02.css',
                'css/input03.css'
                ],
                dest : 'css/output.css'
            }
        },
        //圧縮
        uglify: {
            css: {
                src: "css/output.css",
                dest: "css/output.min.css"
            }
        },
        //監視
        watch: {
            css: {
                files: ["css/*.css"],
                tasks: ['concat']
            }
        }
    });

    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-watch');

};

CSS3で立体を作る

CSS3のtransformをひと通りやりたかったので作ってみた。

表示例

文章でかなり説明しづらいので、最初に動いているものを…
止まっているとよくわからないので回してみました。

立体を表示する画面に設定するプロパティ

perspective

奥行きを設定するプロパティです。
数値が小さいほど奥行きが大きくなります。

perspective-origin

視点を設定します。
前の値が縦軸、後ろの値が横軸です。
50%に設定すると正面から見た視点になります。

立体の親要素に設定するプロパティ

transform-style

要素の子要素が3D空間に配置されるかどうかを設定します。
初期値がflatなので3Dにする場合は設定が必要です。

立体の子要素に設定するプロパティ

実際にtransformを使って変形させる為のプロパティです。

transform: translateZ();

3D空間での前後の位置を設定します。 マイナスの値を入れると元の位置よりも前に、プラスのあたいを入れると元の位置より後ろに配置されます。

transform: rotatoX,Y,Z();

2Dではrotato()で設定しますが、3DではX軸、Y軸、Z軸を基準に回転します。

HTML

<div class="wrap">
    <div class="box">
        <div class="dot parts"></div>
        <div class="red parts">1</div>
        <div class="blue parts">2</div>
        <div class="green parts">3</div>
        <div class="orange parts">4</div>
        <div class="pink parts">5</div>
        <div class="gray parts">6</div>
    </div>
</div>

SCSS

実際に作成する時はperspective-origin: 150% 150%;くらいで角度をつけてやると、各パーツの位置が見やすくなります。

html{
    height: 100%;
}

body {
  background: #fff;
  font: 12px sans-serif;
  height: 100%;
}

/* 立体をレンダリングする領域の設定 */
.wrap{
    overflow: hidden;
    height: 100%;
    -webkit-perspective: 250px;
    -webkit-perspective-origin: 50% 50%;
    -moz-perspective: 250px;
    -moz-perspective-origin: 50% 50%;
}

/* 立体の設定 */
.box{
    position: absolute;
    font-size: 50px;
    width: 100px;
    height: 100px;
    top: 0px;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
    -webkit-transform-style: preserve-3d;
    -moz-transform-style: preserve-3d;
}

/* 立体のパーツの基本設定 */
.parts{
    position: absolute;
    width: 100px;
    height: 100px;
    top: 0px;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
    text-align: center;
    line-height: 100px;
}

.dot{
    border: 1px dashed black;
}

/* 立体の各パーツを配置 */
.red{
    background: rgba(red,0.8);
    -webkit-transform: translateZ(50px);
    -moz-transform: translateZ(50px);
}

.blue{
    background: rgba(blue,0.8);
    -webkit-transform: translateZ(-50px);
    -moz-transform: translateZ(-50px);
}

.green{
    background: rgba(green,0.8);
    -webkit-transform: rotateX(-90deg) translateZ(50px);
    -moz-transform: rotateX(-90deg) translateZ(50px);
}

.orange{
    background: rgba(orange,0.8);
    -webkit-transform: rotateX(90deg) translateZ(50px);
    -moz-transform: rotateX(90deg) translateZ(50px);
}

.pink{
    background: rgba(pink,0.8);
    -webkit-transform: rotatey(90deg) translateZ(50px);
    -moz-transform: rotatey(90deg) translateZ(50px);
}

.gray{
    background: rgba(gray,0.8);
    -webkit-transform: rotatey(-90deg) translateZ(50px);  
    -moz-transform: rotatey(-90deg) translateZ(50px);   
}


/* アニメーションの設定 */
.box{
    -webkit-animation: rotateY 5s linear infinite;
    -moz-animation: rotateY 5s linear infinite;
}

@-webkit-keyframes rotateY {
    0% {-webkit-transform: rotateY(0deg) rotateX(0deg)}
    100% {-webkit-transform: rotateY(360deg) rotateX(360deg)}
}

@-moz-keyframes rotateY {
    0% {-moz-transform: rotateY(0deg) rotateX(0deg)}
    100% {-moz-transform: rotateY(360deg) rotateX(360deg)}
}


Jekyllの記事リストの表示件数を設定する方法

Jekyllでポスト記事をリスト表示をする場合はこのように書きます。

<ul>
    {% for post in site.posts %}
        <li>
            <a href="/blog_jekyll/_site{{ post.url }}">{{ post.title }}</a>
        </li>
    {% endfor %}
</ul>

ただこれだと記事があるだけ表示してしまうので表示件数をを制限したいのですが、これに関する記事がどれもTOPページの表示件数を制限してページ送り機能をつける記事ばかりヒットして困りました。

JekyllのPagination設定(2013年11月30日追記) — Genji App Blog

paginatorを使用するとTOPページ以外のページでは全く書き出されなくなってしまうので、 for文に直接表示制限をかける必要があります。

解決策:limitを使用する

Liquidテンプレートのforlimitで表示件数を制限することが出来ます。

#3件だけ表示する
{% for post in site.posts limit:3 %}

Liquid for Designers · Shopify/liquid Wiki · GitHub
このページにLiquidテンプレートをくわしい解説があったので参考にしました。

Jekyllで「前の記事」「次の記事」を簡単に表示する方法

ブログとかによくある記事送りのページネーションを簡単に実装する方法。

page.previous ,page.nextでそれぞれ前の記事、次の記事に関する情報を取得できます。

{% if page.previous %}
#前の記事がある場合この中身が表示される
{% endif %}

そしてページネーションに必要な各要素を取得します。

#前のページのURLを取得する場合
{{ page.previous.url }}

#次のページのタイトルを取得する場合
{{ page.next.title }}

page変数で取得できる各項目は下記参照

Page Variables
http://jekyllrb.com/docs/variables/#page-variables

  

書き方例

{% if page.previous %}
    &lt;&lt; <a href="/blog_jekyll/_site{{ page.previous.url }}">{{ page.previous.title }}</a>
{% endif %}
    |
{% if page.next %}
    <a href="/blog_jekyll/_site{{ page.next.url }}">{{ page.next.title }}</a> &gt;&gt;
{% endif %}