2

必要なプロパティまたはオブジェクトが見つかりません..

ドラッグ可能でズーム可能な画像を実装しましたが、画面の外にドラッグできるため、画像がビューから失われます。

画像をボックス内に保持するには、どこに画像を配置する必要がありますか (そして、おそらく素晴らしいバウンス効果があります)?

編集:

事実上、私の画像はズームインの可能性だけで、スタックパネルに残る必要があります。(最初のレンダリングとして最大ズームアウト)。

ちょっとしたコード:

    private void OnPinchStarted(object sender, PinchStartedGestureEventArgs e)
    {
        initialAngle = compositeTransform.Rotation;
        initialScale = compositeTransform.ScaleX;
    }

    private void OnPinchDelta(object sender, PinchGestureEventArgs e)
    {
        compositeTransform.ScaleX = initialScale * e.DistanceRatio;
        compositeTransform.ScaleY = initialScale * e.DistanceRatio;
    }

    private void OnDragDelta(object sender, DragDeltaGestureEventArgs e)
    {
        compositeTransform.TranslateX += e.HorizontalChange;
        compositeTransform.TranslateY += e.VerticalChange;
    }

    <StackPanel x:Name="container">
        <Image x:Name="image_chart">
            <Image.RenderTransform>
                <TransformGroup>
                    <ScaleTransform x:Name="scale" />
                    <TranslateTransform x:Name="transform" />
                    <CompositeTransform x:Name="compositeTransform"/>
                </TransformGroup>
            </Image.RenderTransform>
            <toolkit:GestureService.GestureListener>
                <toolkit:GestureListener PinchStarted="OnPinchStarted" PinchDelta="OnPinchDelta"
                                         DragDelta="OnDragDelta"/>
            </toolkit:GestureService.GestureListener>
        </Image>
    </StackPanel>

EDIT 2 - 半分の答え

元のサイズでズームアウトを停止する方法をついに見つけました!

private void OnPinchDelta(object sender, PinchGestureEventArgs e)
    {
        if (1.0 <= (initialScale * e.DistanceRatio))
        {
            compositeTransform.ScaleX = initialScale * e.DistanceRatio;
            compositeTransform.ScaleY = initialScale * e.DistanceRatio;
        }
    }

If 条件の意味: 拡大している場合 -> e.DistanceRatio が >1 であるため問題ありません。ズームアウトしている場合は、initialScale が同じになるまで停止します!

外へのドラッグを回避する方法については、まだ助けが必要です。

4

3 に答える 3

1

私の解決策:

XAML コード

<StackPanel  x:Name="Scroll" Margin="0">
                    <Image  CacheMode="BitmapCache" Name="FrontCover"   Source="{Binding FullCover}"  >
                        <Image.RenderTransform>
                            <CompositeTransform x:Name="transform" ScaleX="1" ScaleY="1"  />
                        </Image.RenderTransform>
                        <toolkit:GestureService.GestureListener>
                            <toolkit:GestureListener   PinchDelta="OnPinchDelta" PinchStarted="OnPinchStarted" DragDelta="OnDragDelta"  />
                        </toolkit:GestureService.GestureListener>
                    </Image>
            </StackPanel>

 double initialScale;

    private void OnPinchStarted(object sender, PinchStartedGestureEventArgs e)
    {
        initialScale = transform.ScaleX;
    }

    private void OnPinchDelta(object sender, PinchGestureEventArgs e)
    {
        var curZoom = initialScale * e.DistanceRatio;
        if (curZoom >= 1 && curZoom <= 3)
        {
            transform.ScaleX = curZoom;
            transform.ScaleY = curZoom;

        }
    }

    private void OnDragDelta(object sender, DragDeltaGestureEventArgs e)
    {
        transform.CenterX = (transform.CenterX - e.HorizontalChange);
        transform.CenterY = (transform.CenterY - e.VerticalChange);

        if (transform.CenterX < 0)
            transform.CenterX = 0;
        else if ( transform.CenterX > Scroll.ActualWidth)
            transform.CenterX = Scroll.ActualWidth;
        else if (transform.CenterX > (FrontCover.Height * transform.ScaleX))
            transform.CenterX = FrontCover.Height * transform.ScaleX;

        if (transform.CenterY < 0)
            transform.CenterY = 0;
        else if (transform.CenterY > Scroll.ActualHeight)
            transform.CenterY = Scroll.ActualHeight;
        else if (transform.CenterY > (FrontCover.Height * transform.ScaleY))
            transform.CenterY = FrontCover.Height * transform.ScaleY;

    }

他の人を助けるべきだと思う

于 2012-10-26T13:07:00.917 に答える
1

わかりました、解決策を見つけましたが、改善が必要です。スケーリングは機能しますが、画像が右側にある場合はすべて左側になります(top_leftコーナーからスケーリングが開始されるため..

「ブロッキングドラッグ」のコードは次のとおりです。

private void OnDragDelta(object sender, DragDeltaGestureEventArgs e)
    {

        double realWidth = image_chart.ActualWidth*compositeTransform.ScaleX;
        double realHeight = image_chart.ActualHeight * compositeTransform.ScaleY;

        if(compositeTransform.TranslateX>=0)
           compositeTransform.TranslateX = Math.Max(container.ActualWidth - realWidth,
                                                 Math.Min(0, compositeTransform.TranslateX + e.HorizontalChange));
        else
            compositeTransform.TranslateX = Math.Max(container.ActualWidth - realWidth,
                                                     Math.Min(0, compositeTransform.TranslateX + e.HorizontalChange));
        if(compositeTransform.TranslateY>=0)
           compositeTransform.TranslateY = Math.Max(container.ActualHeight - realHeight,
                                                 Math.Min(0, compositeTransform.TranslateY + e.VerticalChange));
        else
            compositeTransform.TranslateY = Math.Max(container.ActualHeight - realHeight,
                                                     Math.Min(0, compositeTransform.TranslateY + e.VerticalChange));

編集:

結局、私は WebBrowser を使用することにしました..はるかに「スムーズ」で楽しい!

于 2012-05-17T11:49:34.897 に答える
0

最初の画像が左上隅にあると仮定します(スケーリング後もこれが機能するかどうかを確認してください):

private void OnDragDelta(object sender, DragDeltaGestureEventArgs e)
{
    compositeTransform.TranslateX = Math.Min(container.ActualWidth - image_chart.ActualWidth,
        Math.Max(0,
            compositeTransform.TranslateX + e.HorizontalChange));
    compositeTransform.TranslateY = Math.Min(container.ActualHeight - image_chart.ActualHeight,
        Math.Max(0,
            compositeTransform.TranslateY + e.VerticalChange));
}
于 2012-05-16T19:27:51.163 に答える