LOADING...

Preview

Pen ID
Unlock Campus Themeforest adv

 

Code
Your browser not supported...
CSS
body {
    font-family: 'Anaheim', sans-serif;
    font-size: 13px;
    padding: 0;
    margin: 0;
    background-repeat: no-repeat;
    background-attachment: fixed;
    background-color: #444;
    background-image: -webkit-radial-gradient(center, circle farthest-side, #444 0%, #222 100%);
    background-image:    -moz-radial-gradient(center, circle farthest-side, #444 0%, #222 100%);
    background-image:     -ms-radial-gradient(center, circle farthest-side, #444 0%, #222 100%);
    background-image:         radial-gradient(center, circle farthest-side, #444 0%, #222 100%);
}

a { text-decoration: none; }


/* WonderHTML5wall Style */

#wall {
    opacity: 0;
    position: relative;
    margin: 80px auto;
    -webkit-transition: opacity .1s ease-out;
       -moz-transition: opacity .1s ease-out;
        -ms-transition: opacity .1s ease-out;
            transition: opacity .1s ease-out;
}

.wall-photo {
    position: absolute;
    top: 0;
    left: 0;
    overflow: hidden;
}


/* User settings */

.wall-photo > a {
    display: inline-block;
    position: absolute;
    width: inherit;
    height: inherit;
    overflow: hidden;
}

/* x3 */
.wall-photo-info {
    position: absolute;
    z-index: 2;
    width: inherit;
    height: inherit;
    padding: 15px;
    color: #fff;
    -webkit-box-sizing: border-box;
       -moz-box-sizing: border-box;
        -ms-box-sizing: border-box;
            box-sizing: border-box;
    -webkit-transition: top .25s ease-out;
       -moz-transition: top .25s ease-out;
        -ms-transition: top .25s ease-out;
            transition: top .25s ease-out;
}

.wall-photo:nth-child(odd) .wall-photo-info { background-color: #0063dc; }
.wall-photo:nth-child(even) .wall-photo-info { background-color: #ff0084; }

.wall-photo-info-title,
.wall-photo-info-owner {
    margin: 0;
    padding: 0;
}

/* x3 */
.wall-photo-info-title {
    font-size: 24px;
    text-align: justify;
    margin-bottom: 18px;
}

.wall-photo-info-owner {
    font-size: 16px;
    font-weight: bold;
}

.wall-photo-info-owner a { color: #fff; }
.wall-photo-info-owner a:hover { background-color: #fff; }
.wall-photo:nth-child(odd) .wall-photo-info-owner a:hover { color: #0063dc; }
.wall-photo:nth-child(even) .wall-photo-info-owner a:hover { color: #ff0084; }

.by { font-weight: 400; }


/* Loading */

#loading, #loading .per {
    width: 150px;
}

#loading {
    display: none;
    position: fixed;
    height: 3px;
    padding: 1px;
    border-radius: 2px;
    background-color: rgba(0, 0, 0, .1);
    
    top: 50%;
    left: 50%;
    margin: -5px 0 0 -75px;
}

#loading .bar {
    width: 0%;
    height: 3px;
    border-radius: 1px;
    background-color: #eee;
    -webkit-transition: width .1s linear;
    -moz-transition: width .1s linear;
    -ms-transition: width .1s linear;
}

#loading .per {
    position: absolute;
    top: 15px;
    text-align: center;
    font-size: 12px;
    color: #eee;
    letter-spacing: 1px;
}

/* Not supported */                  

#not-supported {
    display: none;
    position: absolute;
    top: 50%;
    left: 0;
    width: 100%;
    margin-top: -8px;
    color: #eee;
    font-size: 14px;
    letter-spacing: 1px;
    text-align: center;

}

/* Debug */

.debug-dot {
    width: 3px;
    height: 3px;
    margin: -1px 0 0 -1px;
    position: absolute;
    top: 0;
    left: 0;
}
JS
/**
 * requestAnimationFrame
 */
window.requestAnimationFrame = (function(){
    return  window.requestAnimationFrame       ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame    ||
            window.oRequestAnimationFrame      ||
            window.msRequestAnimationFrame     ||
            function (callback) { window.setTimeout(callback, 1000 / 60); };
})();


/**
 * WonderHTML5Wall
 */
var WonderHTML5Wall = (function() {

    'use strict';

    // true でポイント位置を表示する
    var DEBUG = false;

    /**
     * Vendor prefix
     * @type {String}
     */
    var prefix = (function() {
        var vendors = ['webkit', 'Moz', 'ms'],
            testStyle = document.body.style,
            i, len;

        for (i = 0, len = vendors.length; i < len; i++) {
            if (testStyle.hasOwnProperty(vendors[i] + 'Transform')) return vendors[i];
        }

        return '';
    })();


    /**
     * @constructor
     */
    var WonderHTML5Wall = (function() {

        var _mouse  = { x: 0, y: 0, target: null },
            _scroll = { x: 0, y: 0 };

        /**
         * @constructor
         * @param {String|HTMLElement} element
         * @param {Number} frameWidth フレームの表示上の幅
         * @param {Number} frameHeight フレームの表示上の高さ
         * @param {Integer} cols 列数
         * @param {Integer} rows 行数
         * @param {Number} elementScale
         *     フレームの表示サイズを基準にして要素のサイズを決定する倍率
         *     倍率をあげておくと CSS transform の拡大時に粗くならない
         */
        function WonderHTML5Wall(element, frameWidth, frameHeight, cols, rows, elementScale) {
            this.container = element instanceof HTMLElement ? element : document.querySelector(element);
            this.points = [];
            this.polygons = [];
            this.range = frameWidth * 15;

            if (elementScale < 0 || !elementScale) elementScale = 1;

            this._options = {
                frameWidth: frameWidth,
                frameHeight: frameHeight,
                elementScale: elementScale,
                cols: cols,
                rows: rows
            };

            var container = this.container,
                points = this.points,
                polygons = this.polygons,
                pcol = cols + 1,
                prow = rows + 1,
                maxDist = Math.sqrt(frameWidth * frameWidth + frameHeight * frameHeight) * 0.75,
                p, m, a, x, y, ystep,
                i, len, j;

            for (i = 0, len = pcol * prow; i < len; i++) {
                m = frameWidth * Math.random() * 0.1;
                a = Math.PI * 2 * Math.random();
                p = new Point(
                    frameWidth * (i % pcol) + m * Math.cos(a),
                    frameHeight * (i / pcol | 0) + m * Math.sin(a),
                    maxDist
                );
                points.push(p);
            }

            for (y = 0; y < rows; y++) {
                ystep = y * pcol;
                for (x = 0; x < cols; x++) {
                    j = x + ystep;
                    p = new Polygon(frameWidth * elementScale, frameHeight * elementScale, points[j], points[j + 1], points[j + pcol], points[j + pcol + 1]);
                    container.appendChild(p.element);
                    polygons.push(p);
                }
            }

            // 最初にスクロール位置を取得しておく
            onWindowScroll(null);

            window.addEventListener('scroll', onWindowScroll, false);
            container.addEventListener('mousemove', onContainerMouseMove, false);
            container.addEventListener('mouseout', onContainerMouseOut, false);
        }

        /**
         * 3D Transfrom に対応しているか示す
         * @type {Boolean}
         */
        WonderHTML5Wall.supportTransform3d = (function() {
            var vendors = ['webkit', 'Moz', 'ms', ''],
                testStyle = document.createElement('div').style,
                i, len;

            for (i = 0, len = vendors.length; i < len; i++) {
                if ((vendors[i] ? vendors[i] + 'Perspective' : 'perspective') in testStyle) return true;
            }

            return false;
        })();

        WonderHTML5Wall.prototype = {
            container: null,
            points: null,
            polygons: null,
            range: 0,
            _options: null,

            getOption: function(name) { return this._options[name]; },

            update: function() {
                var offsetX = this.container.offsetLeft,
                    offsetY = this.container.offsetTop,
                    points = this.points,
                    polygons = this.polygons,
                    mouseIsOver = _mouse.target === this.container,
                    i, len;

                for (i = 0, len = points.length; i < len; i++)
                    points[i].update(mouseIsOver ? _mouse : null, this.range, offsetX, offsetY);
                for (i = 0, len = polygons.length; i < len; i++)
                    polygons[i].update();
            }
        };


        // Event listeners

        function onWindowScroll(e) {
            _scroll.x = document.documentElement.scrollLeft || document.body.scrollLeft;
            _scroll.y = document.documentElement.scrollTop || document.body.scrollTop;
        }

        function onContainerMouseMove(e) {
            _mouse.x = e.clientX + _scroll.x;
            _mouse.y = e.clientY + _scroll.y;
            _mouse.target = e.currentTarget;
        }

        function onContainerMouseOut(e) {
            if (_mouse.target === e.currentTarget) _mouse.target = null;
        }

        return WonderHTML5Wall;
    })();


    /**
     * Polygon
     * 写真を格納する要素とその四隅の点を示す Point を持ち
     * 各 Point の位置から CSS matrix3d の値を算出して要素に適用する
     * 行列の計算は https://github.com/edankwan/PerspectiveTransform.js を参考というか丸写し
     * @see https://github.com/edankwan/PerspectiveTransform.js
     * @param {Number} elementWidth  要素の実際の幅
     * @param {Number} elementHeight 要素の実際の高さ
     * @param {Point} topLeft
     * @param {Point} topRight
     * @param {Point} bottomLeft
     * @param {Point} bottomRight
     * @private
     */
    function Polygon(elementWidth, elementHeight, topLeft, topRight, bottomLeft, bottomRight) {
        this.tl = topLeft || new Point();
        this.tr = topRight || new Point();
        this.bl = bottomLeft || new Point();
        this.br = bottomRight || new Point();

        this.element = document.createElement('div');
        this.element.className = 'wall-photo';
        this.element.style.width = Math.floor(elementWidth) + 'px';
        this.element.style.height = Math.floor(elementHeight) + 'px';

        this._computedStyle = window.getComputedStyle(this.element);
    }

    Polygon.prototype = (function() {

        var _aM = [
                [0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0],
                [0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0],
                [0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0]
            ],
            _bM = [0, 0, 0, 0, 0, 0, 0, 0],
            _transformKey       = prefix ? prefix + 'Transform' : 'transform',
            _transformOriginKey = prefix ? prefix + 'TransformOrigin' : 'transformOrigin';

        function _getDeterminant(p0, p1, p2){
            return p0.x * p1.y + p1.x * p2.y + p2.x * p0.y - p0.y * p1.x - p1.y * p2.x - p2.y * p0.x;
        }

        // Return prototype object
        return {
            tl: null,
            tr: null,
            bl: null,
            br: null,
            element: null,
            info: null,
            _computedStyle: null,

            update: function() {
                // @see https://github.com/edankwan/PerspectiveTransform.js

                var det1, det2;
                det1 = _getDeterminant(this.tl, this.tr, this.br);
                det2 = _getDeterminant(this.br, this.bl, this.tl);
                if (det1 <= 0 || det2 <= 0) return;
                det1 = _getDeterminant(this.tr, this.br, this.bl);
                det2 = _getDeterminant(this.bl, this.tl, this.tr);
                if (det1 <= 0 || det2 <= 0) return;

                var aM = _aM,
                    bM = _bM,
                    width = this.element.offsetWidth,
                    height = this.element.offsetHeight,
                    offset,
                    offsetX = 0,
                    offsetY = 0,
                    dst = [this.tl, this.tr, this.bl, this.br],
                    sx, sy, dx, dy,
                    kmax, sum,
                    row, col = [],
                    m = [0, 1, 2, 3, 4, 5, 6, 7],
                    i, j, k, p, tmp;

                offset = this._computedStyle[_transformOriginKey];
                if (offset.indexOf('px') > -1){
                    offset = offset.split('px');
                    offsetX = -parseFloat(offset[0]);
                    offsetY = -parseFloat(offset[1]);
                } else if (offset.indexOf('%') > -1){
                    offset = offset.split('%');
                    offsetX = -parseFloat(offset[0]) * width * 0.01;
                    offsetY = -parseFloat(offset[1]) * height * 0.01;
                }

                for (i = 0; i < 4; i++) {
                    j  = i + 4;
                    sx = i & 1 ? width  + offsetX : offsetX;
                    sy = i > 1 ? height + offsetY : offsetY;
                    dx = dst[i].x + offsetX;
                    dy = dst[i].y + offsetY;
                    aM[i][0] = aM[j][3] = sx;
                    aM[i][1] = aM[j][4] = sy;
                    aM[i][2] = aM[j][5] = 1;
                    aM[i][3] = aM[i][4] = aM[i][5] = aM[j][0] = aM[j][1] = aM[j][2] = 0;
                    aM[i][6] = -sx * dx;
                    aM[i][7] = -sy * dx;
                    aM[j][6] = -sx * dy;
                    aM[j][7] = -sy * dy;
                    bM[i] = dx;
                    bM[j] = dy;
                }

                for (j = 0; j < 8; j++) {
                    for (i = 0; i < 8; i++) {
                        col[i] = aM[i][j];
                    }
                    for (i = 0; i < 8; i++) {
                        row  = aM[i];
                        kmax = i < j ? i : j;
                        sum  = 0;
                        for (k = 0; k < kmax; k++) sum += row[k] * col[k];
                        row[j] = col[i] -= sum;
                    }
                    p = j;
                    for (i = j + 1; i < 8; i++) {
                        if (Math.abs(col[i]) > Math.abs(col[p])) p = i;
                    }
                    if (p != j) {
                        for (k = 0; k < 8; k++) {
                            tmp = aM[p][k];
                            aM[p][k] = aM[j][k];
                            aM[j][k] = tmp;
                        }
                        tmp = m[p];
                        m[p] = m[j];
                        m[j] = tmp;
                    }
                    if (aM[j][j] !== 0) {
                        for (i = j + 1; i < 8; i++) {
                            aM[i][j] /= aM[j][j];
                        }
                    }
                }
                for (i = 0; i < 8; i++) {
                    m[i] = bM[m[i]];
                }
                for (k = 0; k < 8; k++) {
                    for (i = k + 1; i < 8; i++) {
                        m[i] -= m[k] * aM[i][k];
                    }
                }
                for (k = 7; k > -1; k--) {
                    m[k] /= aM[k][k];
                    for (i = 0; i < k; i++) {
                        m[i] -= m[k] * aM[i][k];
                    }
                }

                for (i = 0; i < 8; i++) {
                    m[i] = m[i].toFixed(9);
                }

                this.element.style[_transformKey] = 'matrix3d(' + m[0] + ',' + m[3] + ', 0,' + m[6] + ',' + m[1] + ',' + m[4] + ', 0,' + m[7] + ',0, 0, 1, 0,' + m[2] + ',' + m[5] + ', 0, 1)';
            }
        };
    })();


    /**
     * Point
     * @param {Number} ox 基準となる x 座標
     * @param {Number} oy 基準となる y 座標
     * @param {Number} maxDist 基準点からの最大距離
     * @private
     */
    function Point(ox, oy, maxDist) {
        this.ox = this.x = ox || 0;
        this.oy = this.y = oy || 0;
        this.maxDist = maxDist;

        if (DEBUG) {
            this._odot = new Dot(this.x, this.y, 'red');
            this._pdot = new Dot(this.x, this.y, 'yellow');
        }
    }

    Point.prototype = {
        x:  0, y:  0,
        ox: 0, oy: 0,

        update: function(mouse, range, offsetX, offsetY) {
            var dx, dy, dist, f, ax, ay;

            if (mouse) {
                dx = mouse.x - this.x - offsetX;
                dy = mouse.y - this.y - offsetY;
                dist = Math.sqrt(dx * dx + dy * dy) + 0.00001;

                f  = range / dist;
                ax = dx / dist * f;
                ay = dy / dist * f;
            } else {
                ax = ay = 0;
            }

            this.x += (this.ox - this.x) * 0.1 - ax;
            this.y += (this.oy - this.y) * 0.1 - ay;

            dx = this.x - this.ox;
            dy = this.y - this.oy;
            dist = Math.sqrt(dx * dx + dy * dy);
            if (dist > this.maxDist) {
                this.x = this.ox + dx / dist * this.maxDist;
                this.y = this.oy + dy / dist * this.maxDist;
            }

            if (DEBUG) {
                this._odot.move(this.ox + offsetX, this.oy + offsetY);
                this._pdot.move(this.x + offsetX, this.y + offsetY);
            }
        }
    };

    /**
     * Dot
     * デバッグ用
     * @param {Number} x
     * @param {Number} y
     * @private
     */
    function Dot(x, y, color) {
        this.element = document.createElement('div');
        this.element.className = 'debug-dot';
        this.element.style.backgroundColor = color || '#000';
        this.move(x || 0, y || 0);

        document.body.appendChild(this.element);
    }

    Dot.prototype = {
        element: null,

        move: function(x, y) {
            this.element.style.left = x + 'px';
            this.element.style.top = y + 'px';
        }
    }

    return WonderHTML5Wall;

})();


/**
 * Flickr
 */
window.Flickr = (function() {

    'use strict';

    var API_KEY = '93a3c546cb0d8faa9651b312f5e69b46';

    var Flickr = {

        getRecent: function(options, callback) {
            var param = {
                api_key:      API_KEY,
                method:       'flickr.photos.getRecent',
                format:       'json',
                jsoncallback: 'Flickr._callback',
                per_page:     1
            };

            if (options) {
                for (var p in options) param[p] = options[p];
            }

            if (callback) this._callback = callback;

            var script = document.createElement('script');
            script.type = 'text/javascript';
            script.src  = 'http://www.flickr.com/services/rest/?' + jsonToQuery(param);

            document.body.appendChild(script);
        },

        _callback: function() {},

        utils: {
            pageURL: function(p) {
                if (!p.owner) return '';
                return 'http://www.flickr.com/photos/' + p.owner + '/' + p.id + '/';
            },

            sourceURL: function(p, size) {
                if (!p.farm || !p.server || !p.secret) return '';
                if (!size) size = 'm';
                return 'http://farm' + p.farm + '.staticflickr.com/' + p.server + '/' + p.id + '_' + p.secret + '_' + size + '.jpg';
            },

            photosURL: function(p) {
                if (!p.owner) return '';
                return 'http://www.flickr.com/photos/' + p.owner + '/';
            }
        }
    };

    function jsonToQuery(o) {
        var list = [], p, k, v;
        for (p in o) {
            k = encodeURIComponent(p);
            v = encodeURIComponent(o[p]);
            list.push(k + '=' + v);
        }
        return list.join('&');
    }

    return Flickr;

})();


// Initialize

(function() {

    'use strict';

    // Configs

    var COLS_600_UNDER = 3, // 列数
        COLS_600_OVER = 4,
        ROWS_600_UNDER = 6, // 行数
        ROWS_600_OVER = 8,
        WIDTH = 95, // フレームの幅
        HEIGHT = 120, // フレームの高さ
        SCALE = 3; // 要素の実際のサイズの倍率


    // Vars

    var cols = window.innerWidth < 600 ? COLS_600_UNDER : COLS_600_OVER,
        rows = window.innerWidth < 600 ? ROWS_600_UNDER : ROWS_600_OVER,
        wall,
        photoNum = 0,
        loadedNum = 0,
        notSupportMsg = document.getElementById('not-supported'),
        loading = document.getElementById('loading'),
        loadingBar = loading.querySelector('.bar'),
        loadingPer = loading.querySelector('.per');


    if (!WonderHTML5Wall.supportTransform3d) {
        notSupportMsg.style.display = 'block';
        return;
    } else {
        loading.style.display = 'block';
        loadingPer.innerHTML = 'Sending Request...'
    }


    // Initialize

    function init() {
        wall = new WonderHTML5Wall('#wall', WIDTH, HEIGHT, cols, rows, SCALE);
        Flickr.getRecent({ per_page: cols * rows, extras: 'owner_name' }, onFlickrSearchComplete);
    }


    // Event Listeners

    function onFrameMouseOver(e) {
        var frame = e.currentTarget.querySelector('.wall-photo-info'),
            realHeight = wall.getOption('frameHeight') * wall.getOption('elementScale');
        frame.style.top = (realHeight * 0.6 | 0) + 'px';
    }

    function onFrameMouseOut(e) {
        var frame = e.currentTarget.querySelector('.wall-photo-info'),
            realHeight = wall.getOption('frameHeight') * wall.getOption('elementScale');
        frame.style.top = realHeight + 'px';
    }

    function onFlickrSearchComplete(data) {
        var list = data.photos.photo,
            p, img,
            i, len;

        photoNum = list.length;

        for (i = 0, len = list.length; i < len; i++) {
            p = list[i];
            img = new Image();
            img.addEventListener('load', getOnImageLoadedListener(p, i), false);
            img.src = Flickr.utils.sourceURL(p, 'n');
        }
    }

    // 引数をとってリスナー関数を返す
    function getOnImageLoadedListener(data, index) {
        var onImageLoaded = function(e) {
            var img = e.currentTarget,
                polygon = wall.polygons[index],
                frame, fw, fh,
                scale, dw, dh,
                title,
                link, info,
                per;

            frame = polygon.element;

            fw = frame.offsetWidth;
            fh = frame.offsetHeight;

            // ボックスにフィットさせて中央に揃える
            scale = Math.max(fw / img.width, fh / img.height);
            img.width  *= scale;
            img.height *= scale;
            dw = (fw - img.width) * 0.5 | 0;
            dh = (fh - img.height) * 0.5 | 0;
            img.style.cssText = 'position:relative; left:' + dw + 'px; top:' + dh + 'px';

            // フレーム全体をページへリンクさせる
            link = document.createElement('a');
            link.href = Flickr.utils.pageURL(data);
            link.target = '_blank';
            link.appendChild(img);

            // データ表示部分
            info = document.createElement('div');
            info.className = 'wall-photo-info';
            title = data.title;
            if (!title) title = '(Untitled)';
            else if (title.length > 32) title = title.substr(0, 32) + '...';
            info.innerHTML += '

' + title + '

' + '

' + 'By ' + data.ownername + '

'; info.style.top = (wall.getOption('frameHeight') * wall.getOption('elementScale')) + 'px'; link.appendChild(info); frame.appendChild(link); // マウスオーバーでデータを表示させる frame.addEventListener('mouseover', onFrameMouseOver, false); frame.addEventListener('mouseout', onFrameMouseOut, false); // 読み込みをカウント loadedNum++; per = loadedNum / photoNum * 100; loadingBar.style.width = per + '%'; loadingPer.innerHTML = Math.floor(per) + '%'; // 全ての読み込みが完了したら表示 if (loadedNum === photoNum) { setTimeout(onImageLoadedAllComplete, 300); } }; return onImageLoaded; } function onImageLoadedAllComplete() { var container = wall.container, points = wall.points, p, i, len; container.style.width = (cols * WIDTH) + 'px'; container.style.height = (rows * HEIGHT) + 'px'; // 中央から出現させる for (i = 0, len = points.length; i < len; i++) { p = points[i]; p.x = window.innerWidth * 0.5 - container.offsetLeft; p.y = window.innerHeight * 0.5 - container.offsetTop; } wall.container.style.opacity = 1; loading.style.display = 'none'; update(); } // Update function update() { wall.update(); requestAnimationFrame(update); } // Run init(); })();
Host Instantly Drag and Drop Website Builder

 

Description

Original http://wonder-wall.com/
Term
Mon, 11/27/2017 - 22:00

Related Codes

Pen ID
Pen ID
Pen ID