3

を使用して、JavaScript で「偽の」視差効果を実現しようとしています。私が言いたいことを説明するのは本当に難しいですが、試してみます:

マウスを上に置いたときに、ページ上の項目が移動するようにします。後ろにあるものは、前にあるものよりも動きが少ないはずです-通常の視差効果-ただし、そうするためにフラットな画像を使用したい. さて、通常、画像エディターで何かを切り取り、欠落している背景などの一部を置き換える必要があります. しかし、私はこれがある種の「偽の」方法で行われたことがあると思います: 背景をわずかに引き伸ばしたり圧縮したりします.

残念ながら、この効果の例をもう見つけることはできませんが、ディスプレイスメント マップと関係があると確信しています。

この種のライブラリはありますか?または、JavaScript に翻訳できる別の言語の例を少なくとも知っている人はいますか?

4

2 に答える 2

0

あなたが何を求めているのかよくわかりません。しかし、視差シーンをすばやく行うためにスプライトを使用しました。複数の画像レイヤーが含まれますが、簡単に作成できます。 http://www.spritely.net/

このような視差の解決策は他にもいくつかあります。このアプローチでは、同じイメージを繰り返して奥行きを作成します。 http://www.stevefenton.co.uk/cmsfiles/assets/File/imageparallax.html

于 2013-01-16T02:26:16.320 に答える
0

一見したところ、Phrogz の リンクは関連性がないように見えましたが (私も以前に独自の調査を行ったときに同じリンクをたどりました)、詳しく調べてみると、まさに私が探していたものでした。

残念ながら、これは非常に遅いので、が目指している種類のアニメーション、特に画面いっぱいの画像にはあまり適していません。いくつかのマイクロ最適化を行うことで多少速くなりましたが、結局のところ、この種のことは今日の JavaScript には強すぎるようです。

とにかく、これが私が最終的に得たものです。多分それは誰かを助けるか、誰かがそれを30または60 fpsで使用するためにそれをスピードアップする方法を考え出すかもしれません(ワーカー?)。少しいじっただけなので、コードはまったくきれいではありません。出発点として使用してください。

HTML:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
        <script src="displacement.js"></script>
    </head>
    <body>
        <script>
            (function() {
                'use strict';
                var source, map, target;
                var sourceCtx, mapCtx, targetCtx;
                var loaded = false;
                var x = 0, y = 0;
                var filter;

                function render() {
                    filter = new filters.DisplacementMap(
                            source,
                            map,
                            target,
                            new filters.Point(0, 0),
                            x,
                            y,
                            filters.ColorChannel.RED,
                            filters.ColorChannel.RED);
                    filter.draw();
                }

                (function init() {
                    var img = new Image();

                    function prepareCanvases() {
                        // Create canvases and add them to the document
                        source = document.createElement('canvas');
                        map = document.createElement('canvas');
                        target = document.createElement('canvas');
                        [target, source, map].forEach(function(canvas) {
                            canvas.setAttribute('width', img.width);
                            canvas.setAttribute('height', img.height);
                            document.body.appendChild(canvas);
                        });

                        // Get contexts
                        sourceCtx = source.getContext('2d');
                        mapCtx = map.getContext('2d');
                        targetCtx = target.getContext('2d');
                    }

                    // Load source image
                    (function loadImage() {
                        img.onload = function() {
                            prepareCanvases();
                            sourceCtx.drawImage(img, 0, 0);
                            img.onload = function() {
                                mapCtx.drawImage(img, 0, 0);
                                addEventListeners();
                                loaded = true;
                            };
                            // Put your displacement map here
                            img.src = 'jn-map-small.jpg';
                        };
                        // Put your image here
                        img.src = 'jn-edit-small.jpg';
                    }());

                    // Event listener
                    function addEventListeners() {
                        target.onmousemove = function(e) {
                            x = ((-e.offsetX / source.width) * 10) + 5;
                            y = ((-e.offsetY / source.height) * 10) + 5;
                            render();
                        };
                    }
                }());
            }());
        </script>
    </body>
</html>

変位.js:

/**
 * Based on Romuald Quantin's code
 * @see http://www.soundstep.com/blog/2012/04/25/javascript-displacement-mapping/
 */
var filters = {} || filters;
(function() {

    filters.ColorChannel = {
        RED: 0,
        GREEN: 1,
        BLUE: 2,
        ALPHA: 3
    };

    filters.Point = function(x, y) {
        this.x = x || 0;
        this.y = y || 0;
    };

    filters.DisplacementMap = function(source, map, target, point, scaleX, scaleY, channelX, channelY) {
        this.source = source;
        this.map = map;
        this.target = target;
        this.sourceCtx = this.source.getContext("2d");
        this.mapCtx = this.map.getContext("2d");
        this.targetCtx = this.target.getContext("2d");
        this.point = point || new filters.Point();
        this.scaleX = scaleX || 0;
        this.scaleY = scaleY || 0;
        this.channelX = channelX || filters.ColorChannel.RED;
        this.channelY = channelY || filters.ColorChannel.RED;
        if (this.channelX !== 0 && this.channelX !== 1 && this.channelX !== 2 && this.channelX !== 3)
            this.channelX = filters.ColorChannel.RED;
        if (this.channelY !== 0 && this.channelY !== 1 && this.channelY !== 2 && this.channelY !== 3)
            this.channelY = filters.ColorChannel.RED;
    };

    var p = filters.DisplacementMap.prototype;

    p.draw = function() {
        var sourceData = this.sourceCtx.getImageData(0, 0, this.source.width, this.source.height);
        var mapData = this.mapCtx.getImageData(0, 0, this.map.width, this.map.height);
        var targetDataX = this.sourceCtx.getImageData(0, 0, this.source.width, this.source.height);
        var targetDataY = this.sourceCtx.getImageData(0, 0, this.source.width, this.source.height);
        var pixelsLength = mapData.data.length / 4;
        var colorValue,
                alphaValue,
                ratio,
                ratioWithAlpha,
                pixelShift,
                sourcePosition,
                targetPosition,
                x,
                y;
        var i = 0;
        var map = this.map;
        var point = this.point;
        var channelX = this.channelX;
        var channelY = this.channelY;
        var scaleX = this.scaleX;
        var scaleY = this.scaleY;
        var source = this.source;
        var target = this.target;
        while (i < pixelsLength) {
            x = ((i % map.width) + point.x) | 0;
            y = (((i / map.width) | 0) + point.y) | 0;
//            alphaValue = mapData.data[i * 4 + filters.ColorChannel.ALPHA];
//            ratioWithAlpha = ratio * (alphaValue / 0xFF);
            targetDataX.data = this.setPixels(targetDataX.data, (target.width * y) + x + ((((mapData.data[i * 4 + channelX]) / 0xFF * 2) - 1) * scaleX | 0), sourceData.data, (source.width * y) + x);
            i++;
        }
        i = 0;
        while (i < pixelsLength) {
            x = ((i % map.width) + point.x) | 0;
            y = (((i / map.width) | 0) + point.y) | 0;
//            alphaValue = mapData.data[i * 4 + filters.ColorChannel.ALPHA];
//            ratioWithAlpha = ratio * (alphaValue / 0xFF);
            targetDataY.data = this.setPixels(targetDataY.data, (target.width * (y + ((((mapData.data[i * 4 + channelY]) / 0xFF * 2) - 1) * scaleY | 0))) + x, targetDataX.data, (source.width * y) + x);
            i++;
        }
        this.targetCtx.putImageData(targetDataY, 0, 0);
    };

    p.setPixels = function(target, pos, source, i) {
        i = i * 4;
        pos = pos * 4;
        target[i] = source[pos];
        target[i + 1] = source[pos + 1];
        target[i + 2] = source[pos + 2];
        target[i + 3] = source[pos + 3];
        return target;
    };

})();
于 2013-01-22T17:13:42.043 に答える