0

google.com/maps と同様に、マウスが QGraphicsItem の上にある場合、ホイールマウスを前後に動かしたときに、マウスの下の画像の領域が QGraphicsView の中心になるようにしたいと思います。

作成したカスタム QGraphicsIte の wheelEvent メソッドでこれを達成できますか?

このようなコードがあります

update();
qreal factor = 1.2;
if (event->delta() < 0)
  factor = 1.0 / factor;
scale(factor, factor);
scaleFactor *=factor;
this->scene()->setSceneRect(0,0,this->boundingRect().width(), this->boundingRect().height());

望ましい効果を得るために、これに何を追加できますか?

例として、Google マップでマウスを utah の上に置き、ホイール マウスでズームインし続けると、最終的にビューポートに残るのは Utah だけになります。

4

3 に答える 3

0

等式は、、、

margin = -half_overflow + (((center_offset - click_offset) * resize_ratio) - (center_offset - click_offset));

...そして、xとyに対してそれを行う必要があります。

以下に、それを行うコードを貼り付けますが、このコードは正方形の画像を扱うことに注意してください。したがって、幅と高さの両方に幅を使用します。長方形の画像でこれを使用するには、高さを取得し、幅があるすべての Y 計算でそれを使用し、content_width などのように使用しているすべての変数を設定する必要があります。しかし、アルゴリズムはすべてそこにあり、あなたはコードからそれを解決することができます...

        zoomChart: function(e)
        {
                var chart_max = 2048;
                var zoom_max = egapp.user.options.zoom_multiplier || 2; // >= 2
                var chart_bounds = $('#egapp_chart_bounds');
                var chart_imgs = chart_bounds.find('img');
                var width = chart_imgs.width();
                if (width == chart_bounds.width()) { // zoom in
                        // margin = -half_overflow + (((center_offset - click_offset) * resize_ratio) - (center_offset - click_offset));
                        chart_bounds.removeClass('egapp_zoom_in');
                        if (width == chart_max)
                                return;
                        chart_bounds.addClass('egapp_zoom_out');
                        var new_width = parseInt(width * zoom_max);
                        if (new_width > chart_max)
                                new_width = chart_max;
                        var ratio = new_width / width;
                        var moveX = moveY = -((new_width - width) / 2);
                        var chart_offset = chart_bounds.offset();
                        var offsetX = (chart_offset.left + (width / 2)) - e.pageX;
                        var offsetY = (chart_offset.top + (width / 2)) - e.pageY;
                        moveX += parseInt((offsetX * ratio) - offsetX);
                        moveY += parseInt((offsetY * ratio) - offsetY);
                        chart_imgs.animate({width: new_width+'px', height: new_width+'px', marginLeft: moveX+'px', marginTop: moveY+'px'}, 'fast');
                        chart_bounds.addClass('egapp_zoom_out');
                }
                else { // zoom out
                        var new_width = egapp.content_width - 10;
                        chart_imgs.animate({width: new_width+'px', height: new_width+'px', marginLeft: 0, marginTop: 0}, 'fast');
                        chart_bounds.removeClass('egapp_zoom_out').addClass('egapp_zoom_in');
                }
        },

HTMLは次のようなものです...

<div id="egapp_chart_bounds" style="width: 608px; height: 608px;" class="egapp_zoom_in">
    <img id="egapp_timeline_chart" src="some.image" class="egapp_chart" style="width: 608px; height: 608px; margin-left: 0px; margin-top: 0px;">
    <img id="egapp_expression_chart_9" src="overlay.image" class="egapp_chart_overlay" style="width: 608px; height: 608px;">
</div>

そして、CSSは次のようになります...

#egapp_chart_bounds{
        overflow: hidden;
}
.egapp_chart, .egapp_chart_overlay{
        position: absolute;
}

.egapp_zoom_in{
        cursor: -moz-zoom-in;
        cursor: -webkit-zoom-in;
        cursor: zoom-in;
}
.egapp_zoom_out{
        cursor: -moz-zoom-out;
        cursor: -webkit-zoom-out;
        cursor: zoom-out;
}
于 2014-08-29T18:32:07.130 に答える
0

あなたの目的をより直接的な方法で言い換えましょう。ホイール イベント:

  1. シーンはズームイン/ズームアウトする必要があります
  2. マウスの下のシーンの場所は、マウスの下のままにする必要があります

(1) を scale 呼び出しで実装しました。残るは(2)です。ビューを特定の場所にスクロールするには、次のことを行う必要があります。

horizontalScrollbar().setValue(x);
verticalScrollbar().setValue(y);

これによりシーンがスクロールされ、(x, y) がビューの左上隅に表示されます。ただし、(x, y) を (QGraphicsView に関連して) マウスの位置に配置する必要があります。したがって、(x-mx, y-my) までスクロールする必要があります。ここで、(mx, my) は QGraphicsView に対するマウスの位置であり、(x, y) はホイール イベントの前にマウスの下にあったシーンの位置です。

これはテストされておらず、詳細が間違っている可能性があります (たとえば、QScrollBar::setValue の正確な動作) が、数学の概念は正しいため、機能させるには十分なはずです。

于 2011-02-24T18:55:07.927 に答える