سؤال

أنا أكتب تطبيق WPF الذي لديه قدرة على التكبير والقدرة ، ولكن ما أريد تنفيذه أيضًا هو القدرة على التكبير والتشكيل "تلقائيًا" (عبر زر النقر).

لدي كل الأساليب المحددة للتكبير والعموم ، لكنني أواجه مشكلة في إخبار التطبيق بإحداثيات X/Y المطلوبة للتصنيع.

في الأساس ، أعلم أنني أريد أن يتم توسيط التحكم على مستوى التكبير المرغوب فيه (على سبيل المثال التكبير في 6 أضعاف) ، لكن نقطة وجهة التقويم ليست هي نقطة التحكم في التحكم لأنه بعد التكبير ، تم تحجيمه.

هل يعرف أي شخص طريقة لحساب الموضع x/y المطلوب إلى PAN ، مع مراعاة التكبير أيضًا؟ هل أقوم فقط بتوسيع نطاق نقطة الوجهة المطلوبة؟ لا يبدو أنه يعمل من أجلي ...

شكرًا جزيلاً

تحرير -مكتمل -

هنا الآن ما لدي الذي يعمل بشكل جيد :)

<Canvas x:Name="LayoutRoot" Background="{DynamicResource WindowBackground}" Width="1024" Height="768">
    <Canvas x:Name="ProductCanvas" Width="1024" Height="768">
        <Canvas.RenderTransform>
            <TransformGroup>
                <ScaleTransform/>
                <SkewTransform/>
                <RotateTransform/>
                <TranslateTransform />
            </TransformGroup>
        </Canvas.RenderTransform>
        <Rectangle x:Name="r1" Fill="White" Stroke="Black" Width="180" Height="103.5" Canvas.Left="131.5" Canvas.Top="121.5" MouseDown="r1_MouseDown"/>
        <Rectangle x:Name="r2" Fill="#FF942222" Stroke="Black" Width="180" Height="103.5" Canvas.Left="617.5" Canvas.Top="121.5" MouseDown="r2_MouseDown"/>
        <Rectangle x:Name="r3" Fill="#FF2B1E9F" Stroke="Black" Width="180" Height="103.5" Canvas.Left="131.5" Canvas.Top="408" MouseDown="r3_MouseDown"/>
        <Rectangle x:Name="r4" Fill="#FF1F6E1D" Stroke="Black" Width="180" Height="103.5" Canvas.Left="617.5" Canvas.Top="408" MouseDown="r4_MouseDown"/>
    </Canvas>
  </Canvas>

---- C#----

    private void r1_MouseDown(object sender, MouseButtonEventArgs e1)
    {
        Rect bounds = r1.TransformToAncestor(ProductCanvas).TransformBounds(new Rect(0, 0, r1.ActualWidth, r1.ActualHeight));
        ZoomInAndPan(5, new Point(bounds.TopLeft.X + (bounds.Width / 2), bounds.TopLeft.Y + (bounds.Height / 2)));
    }

    private void r2_MouseDown(object sender, MouseButtonEventArgs e1)
    {
        Rect bounds = r2.TransformToAncestor(ProductCanvas).TransformBounds(new Rect(0, 0, r2.ActualWidth, r2.ActualHeight));
        ZoomInAndPan(5, new Point(bounds.TopLeft.X + (bounds.Width / 2), bounds.TopLeft.Y + (bounds.Height / 2)));
    }

    private void r3_MouseDown(object sender, MouseButtonEventArgs e1)
    {
        Rect bounds = r3.TransformToAncestor(ProductCanvas).TransformBounds(new Rect(0, 0, r3.ActualWidth, r3.ActualHeight));
        ZoomInAndPan(5, new Point(bounds.TopLeft.X + (bounds.Width / 2), bounds.TopLeft.Y + (bounds.Height / 2)));
    }

    private void r4_MouseDown(object sender, MouseButtonEventArgs e1)
    {
        Rect bounds = r4.TransformToAncestor(ProductCanvas).TransformBounds(new Rect(0, 0, r4.ActualWidth, r4.ActualHeight));
        ZoomInAndPan(5, new Point(bounds.TopLeft.X + (bounds.Width/2), bounds.TopLeft.Y + (bounds.Height/2)));
    }

    public void ZoomInAndPan(double zoomTo, Point translateTarget)
    {
        var group = (ProductCanvas.RenderTransform as TransformGroup);

        var zoomTransform = group.Children[0] as ScaleTransform;
        var translateTransform = group.Children[3] as TranslateTransform;

        Point center = new Point(512, 384);

        destinationPoint.X *= newScale;
        destinationPoint.Y *= newScale;

        var deltaX = center.X - (translateTarget.X);
        var deltaY = center.Y - (translateTarget.Y);

        translateTransform.BeginAnimation(TranslateTransform.XProperty, CreateZoomAnimation(deltaX));
        translateTransform.BeginAnimation(TranslateTransform.YProperty, CreateZoomAnimation(deltaY));

        zoomTransform.BeginAnimation(ScaleTransform.ScaleXProperty, CreateZoomAnimation(zoomTo));
        zoomTransform.BeginAnimation(ScaleTransform.ScaleYProperty, CreateZoomAnimation(zoomTo));
    }

    private DoubleAnimation CreateZoomAnimation(double toValue)
    {
        var da = new DoubleAnimation(toValue, new Duration(TimeSpan.FromMilliseconds(700)))
        {
            AccelerationRatio = 0.1,
            DecelerationRatio = 0.9
        };

        return da;
    }
هل كانت مفيدة؟

المحلول

أنت تتحدث عن تحول - مقلاة ومقياس.

يمكنك القيام بذلك بطريقتين مختلفتين ، ولكن نظرًا لأنك تستخدم WPF ، هل هناك سبب لا يمكنك استخدامه فقط RenderTransforms؟

var pointClicked = (where user clicked)
var myWindow = (whatever your window is);

myWindow.RenderTransform = new TransformGroup();
var pan = new TranslateTransform(pointClicked.X, pointClicked.Y);
var scale = new ScaleTransform(6.0,6.0);
myWindow.RenderTransform.Children.Add(pan);
myWindow.RenderTransform.Children.Add(scale);

إذا كنت لا ترغب في السير في هذا الطريق ، فأنت بحاجة إلى إجراء التحول ثنائي الأبعاد "باليد": ولكن قم بعمل المقلاة أولاً ، ثم المقياس. التحولات ليست عادة مجتمعة. ستحصل على نتائج خاطئة إذا قمت بذلك بترتيب مختلف.

نصائح أخرى

في البداية يكون منفذ العرض الخاص بك في (0،0) وكلا من الصورة ومنفذ العرض من الحجم x بواسطة Y. تريد قياس الحجم من خلال بعض عامل التكبير ، بحيث تكون صورك ذات حجم Mx بواسطة مY ، لكن منفذ العرض الخاص بك (الجزء الذي تعرضه) لا يزال مستطيلًا من الحجم X بواسطة Y ، والذي تم وضعه على (0،0) على الصورة. لذلك تحتاج إلى نقل منفذ العرض.

إذا كانت صورتك الآن مx بواسطة مy ، يمكنك العثور على نقاط الوسط بتقسيم كل منهما. يمكنك بعد ذلك طرح نصف حجم منفذ العرض للحصول على الزاوية اليسرى العلوية. شيء مثل (مx/2 - x/2 ، mY/2 - Y/2).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top