elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.


 


Tema destacado: Como proteger una cartera Bitcoin


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  GDI+. Hacer zoom respecto a la posición del Mouse en evento MouseWheel de un Pic
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: GDI+. Hacer zoom respecto a la posición del Mouse en evento MouseWheel de un Pic  (Leído 5,298 veces)
Harold23

Desconectado Desconectado

Mensajes: 7


Ver Perfil
GDI+. Hacer zoom respecto a la posición del Mouse en evento MouseWheel de un Pic
« en: 3 Julio 2017, 18:42 »

Muy buenas tardes;

Mi idea es poder hacer zoom con uso de GDI+ en un dibujo que estoy haciendo de prueba, cuyo centro de enfoque sea la posición del mouse, el cual aplica el zoom por medio de un ScaleTransform en el evento MouseWheel del Picture. Lo que pasa actualmente es lo siguiente:

1. Ubicado en un punto del PictureBox con el cursor, hago uso del Scrool, con el fin de acercar o alejar el dibujo con respecto al punto de posición del mouse.


2. Luego de que se activa el evento MouseWheel, si se aleja o acerca el dibujo, pero lo que hace es alejarse del punto de foco(que corresponde a la posición del mouse).


La idea es, como clos programas CAD por ejemplo, es que se acerque o aleje el dibujo respecto a la posición del mouse, es decir, que la posición del mouse sea el centro de foco de la ampliación o reducción de lo dibujado. ¿Cómo puedo solucionar esto?.

El código que tengo actualmente es el siguiente:

Código
  1. Option Strict On
  2. Option Explicit On
  3.  
  4. Imports System.ComponentModel
  5. Imports System.Text
  6. Imports System.Drawing
  7. Imports System.Drawing.Drawing2D
  8.  
  9.  
  10. Partial Public Class Form1
  11.    Shared Sub New()
  12.        DevExpress.UserSkins.BonusSkins.Register()
  13.        DevExpress.Skins.SkinManager.EnableFormSkins()
  14.    End Sub
  15.    Public Sub New()
  16.        InitializeComponent()
  17.        'Me.pe_dibujo.Properties.AllowZoomOnMouseWheel = DevExpress.Utils.DefaultBoolean.True
  18.        ' Me.pe_dibujo.Properties.ZoomingOperationMode = DevExpress.XtraEditors.Repository.ZoomingOperationMode.MouseWheel
  19.  
  20.    End Sub
  21.  
  22.    Private Sub RadioGroup1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles rg_unidades.SelectedIndexChanged
  23.  
  24.        'Se verifica cual es el sistema de unidades seleccionado.
  25.        Select Case rg_unidades.SelectedIndex
  26.  
  27.            'Caso pixeles.
  28.            Case 0
  29.  
  30.                'Se describe el dibujo y relación de dibujo.
  31.                lbl_comentario.Text = "Rectángulo de 50 x 50 pixeles" & Environment.NewLine &
  32.                "en la posición (50,50)" & Environment.NewLine &
  33.                "La regla mayor es de 50 pixeles."
  34.  
  35.            'Caso pulgadas.
  36.            Case 1
  37.  
  38.                'Se describe el dibujo y relación de dibujo.
  39.                lbl_comentario.Text = "Rectángulo de 1 x 1 pulgada" & Environment.NewLine &
  40.                "en la posición (1,1)" &
  41.                Environment.NewLine & "La regla mayor está cada pulgada."
  42.  
  43.            'Caso centímetros.
  44.            Case 2
  45.  
  46.                'Se describe el dibujo y relación de dibujo.
  47.                lbl_comentario.Text = "Rectángulo de 1 x 1 centímetro" & Environment.NewLine &
  48.                "en la posición (1,1)" &
  49.                Environment.NewLine & "La regla mayor está cada centìemtro."
  50.  
  51.        End Select
  52.  
  53.        'Se actualiza el dibujo.
  54.        pe_dibujo.Invalidate()
  55.  
  56.    End Sub
  57.  
  58.    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  59.  
  60.        'Al cargar el formulario se selecciona el sistema de unidades en Pixel por defecto.
  61.        'Se envìa la selecciòn activando el control.
  62.        rg_unidades.SelectedIndex = 1
  63.        rg_unidades.Select()
  64.  
  65.    End Sub
  66.  
  67.    Private Sub pe_dibujo_Paint(sender As Object, e As PaintEventArgs) Handles pe_dibujo.Paint
  68.        '
  69.        'Variables para trabajar con el dibujo.
  70.        Dim Rectangulo, Rectangulo2 As Rectangle
  71.        Dim pincel_ancho_mm As Pen
  72.        Dim pincel_acotar_mm As Pen
  73.        Dim largo_linea_regla As Decimal
  74.        Dim tickStep As Single
  75.        Dim tickSize As Single
  76.        Dim counter As Integer
  77.        Dim marcas_principales_regla As Single
  78.        Const ticks As String = "1424142414241"
  79.  
  80.        ' Se limpia el contenido dibujando previamente en el control.
  81.        e.Graphics.Clear(Color.White)
  82.  
  83.        '---Se verifica que el sistema de unidades sea el Pixel.
  84.        If (rg_unidades.SelectedIndex = 0) Then
  85.            '
  86.            'Se dibuja un rectángulo de 50 x 50 pixeles. Ubicado en las coordenadas de
  87.            ' la pàgina a 50 pixeles a la derecha e inferior de la parte superior izquierda del control.
  88.            Rectangulo = New Rectangle(50, 50, 50, 50)
  89.            Rectangulo.Offset(50, 50)
  90.            '
  91.            'Se dibuja un rectángulo de 50 x 50 pixeles. Ubicado en las coordenadas de
  92.            ' la pàgina a 50 pixeles a la derecha e inferior de la parte superior izquierda del control.
  93.            Rectangulo2 = New Rectangle(100, 50, 50, 50)
  94.  
  95.            'El largo de la lìnea de la regla se harà siempre de 5 mm. Se convierte asì:
  96.            '--- Largo = 5 mm*(a.Pix/Pulg)*(1 Pulg/25.4 mm)
  97.            largo_linea_regla = CDec(CSng(5.0F * e.Graphics.DpiX / 25.4F))
  98.            'Las marcas principales de la regla se haràn cada 50 pixeles de separamiento.
  99.            marcas_principales_regla = 50.0F
  100.            ' Se crea un pincel de dibujo de color determinado con un grosor en mm.
  101.            pincel_ancho_mm = New Pen(Color.Black, CSng(0.1 * e.Graphics.DpiX / 25.4) / scale_zoom)
  102.            '
  103.            ' Se crea un pincel de dibujo de color determinado con un grosor en mm para las cotas.
  104.            pincel_acotar_mm = New Pen(Color.Black, CSng(0.1 * e.Graphics.DpiX / 25.4) / scale_zoom)
  105.  
  106.            '
  107.            '---Se verifica que el sistema de unidades sea la Pulgada.
  108.        ElseIf (rg_unidades.SelectedIndex = 1) Then
  109.            '
  110.            ' Se escala a unidades de página en Pulgadas.
  111.            e.Graphics.PageUnit = GraphicsUnit.Inch
  112.            '
  113.            ' Se crea un rectángulo de 1"x 1"( 1 pulgada cuadrada). Ubicado en las coordenadas de
  114.            ' la pàgina a 1 pulgada a la derecha e inferior de la parte superior izquierda del control.
  115.            Rectangulo = New Rectangle(1, 1, 1, 1)
  116.            '
  117.            ' Se crea un rectángulo de 1"x 1"( 1 pulgada cuadrada). Ubicado en las coordenadas de
  118.            ' la pàgina a 1 pulgada a la derecha e inferior de la parte superior izquierda del control.
  119.            Rectangulo2 = New Rectangle(2, 1, 1, 1)
  120.            'El largo de la lìnea de la regla se harà siempre de 5 mm. Se convierte asì:
  121.            '--- Largo = 5 m * (1 Pulg/25.4 mm)
  122.            largo_linea_regla = CDec((5 / 25.4))
  123.            'Las marcas principales de la regla se haràn cada 1 pulagada de separamiento.
  124.            marcas_principales_regla = 1.0F
  125.            '
  126.            ' Se crea un pincel de dibujo de color determinado con un grosor en mm.
  127.            pincel_ancho_mm = New Pen(Color.Black, CSng(0.1 / 25.4) / scale_zoom)
  128.            '
  129.            ' Se crea un pincel de dibujo de color determinado con un grosor en mm para las cotas.
  130.            pincel_acotar_mm = New Pen(Color.Black, CSng(0.1 / 25.4) / scale_zoom)
  131.            '
  132.            '---Se verifica que el sistema de unidades sea el Centímetro.
  133.        Else
  134.            '
  135.            ' Se usa escala unidades de la página a milímetros. Debe convertirse para centíemtros.
  136.            e.Graphics.PageUnit = GraphicsUnit.Millimeter
  137.            '
  138.            'Se crea un rectángulo de 1cmx 1cm( 1 centímetro cuadrado). Ubicado en las coordenadas de
  139.            ' la pàgina a 1 centímetro a la derecha e inferior de la parte superior izquierda del control.
  140.            '
  141.            '***Nota: 10 mm hacen 1 cm.
  142.            '
  143.            Rectangulo = New Rectangle(1 * 10, 1 * 10, 1 * 10, 1 * 10)
  144.            '   '
  145.            Rectangulo2 = New Rectangle(2 * 10, 1 * 10, 1 * 10, 1 * 10)
  146.            '
  147.            'El largo de la lìnea de la regla se harà siempre de 5 mm.
  148.            largo_linea_regla = 5
  149.            '
  150.            'Las marcas principales de la regla se haràn cada 1 centímetro de separamiento.
  151.            marcas_principales_regla = 1 * 10.0F
  152.            '
  153.            ' Se crea un pincel de dibujo de color determinado con un grosor en mm.
  154.            pincel_ancho_mm = New Pen(Color.Black, 0.1F / scale_zoom)
  155.            '
  156.            ' Se crea un pincel de dibujo de color determinado con un grosor en mm para las cotas.
  157.            pincel_acotar_mm = New Pen(Color.Black, 0.1F / scale_zoom)
  158.  
  159.        End If
  160.        '
  161.        '
  162.        'Escalamos el dibujo de acuerdo al Zoom.
  163.        e.Graphics.ScaleTransform(scale_zoom, scale_zoom, MatrixOrder.Append)
  164.        e.Graphics.TranslateTransform(ultimaPosicion.X, ultimaPosicion.Y)
  165.  
  166.        '
  167.        'Se pinta un área de la regla, la cual siempre es de 5 mm, independientemente
  168.        'de la unidad de las coordenadas de la página.La regla se dibujarà siempre de 3" x 3"
  169.        '--------------
  170.        '
  171.        'Se crea un cepillo o pintura Brush, teniendo en cuenta que su ancho siempre
  172.        'serà de 5 mm por un largo de 3"(76.2 mm). Uno para la regla horizontal y otro para la
  173.        'regla vetical. Existen 5 tipos: SolidBrush, HatchBrush, TextureBrush,LinearGradientBrush, PathGradientBrush(personalizado).
  174.        '
  175.        Dim fill_rec_horizontal As New SolidBrush(Color.LightYellow)
  176.        Dim fill_rec_vertical As New SolidBrush(Color.BlanchedAlmond)
  177.        'Punto de tipo Single, de la coordenada inicial de dibujo de el pintado del rectángulo.
  178.        Dim coor_ini_fill As New PointF(0, 0)
  179.        '
  180.        'Para hacer el llenado del Brush debe tenerse en cuenta que para que se visualice de forma correcta, debe
  181.        'tenerse en cuenta que al dibujar la regla en el For, se empezaràn a colocar cada (50 pix or 1" o 1 cm) des
  182.        'fasado 5 mm(ancho de la regla), por lo que para dibujar bien el Brush con un largo de 3"(independiente de la unidad de medida)
  183.        'debe tenerse en cuenta ese ancho adicional de llenado,
  184.        'y su longitud debe calcularse asì L = largo_linea_regla + largo_linea_regla*(3"*25.4mm/largo_linea_regla(5 mm)) = largo_linea_regla*(1+15.24)
  185.        'Recordar que 3" pulgadas es el largo de la regla a dibujar y que su valor en relaciones es:
  186.  
  187.        'Se rellena la regla en su parte vertical.
  188.        e.Graphics.FillRectangle(fill_rec_vertical, coor_ini_fill.X, coor_ini_fill.Y, (largo_linea_regla / scale_zoom), largo_linea_regla * (1 + 15.24D))
  189.        'Se rellena la regla en su parte horizontal.
  190.        e.Graphics.FillRectangle(fill_rec_horizontal, coor_ini_fill.X, coor_ini_fill.Y, largo_linea_regla * (1 + 15.24D), largo_linea_regla / scale_zoom)
  191.        'Se dibuja la lìnea de  borde la regla hasta donde se hace el relleno con color del Brush. Regla vertical.
  192.        e.Graphics.DrawLine(pincel_ancho_mm, largo_linea_regla / scale_zoom, largo_linea_regla / scale_zoom, largo_linea_regla / scale_zoom, largo_linea_regla * (1 + 15.24D))
  193.        'Se dibuja la lìnea de  borde la regla hasta donde se hace el relleno con color del Brush. Regla horizontal.
  194.        e.Graphics.DrawLine(pincel_ancho_mm, largo_linea_regla / scale_zoom, largo_linea_regla / scale_zoom, largo_linea_regla * (1 + 15.24D), largo_linea_regla / scale_zoom)
  195.        '
  196.        '
  197.        ' Dibuja las marcas principales y secundarias de la regla.
  198.        For counter = 1 To ticks.Length
  199.  
  200.            If counter = 1 Then
  201.  
  202.                ' ----- Get the tick measurements. The "ticks" constant
  203.                '       includes a set of "1", "2", and "4" values. "1"
  204.                '       gives a full-size tick mark (for whole units),
  205.                '       "2" gives a half-size tick mark, and "4" gives
  206.                '       a 1/4-size tick mark.
  207.                tickSize = CSng(Mid(ticks, counter, 1))
  208.                tickStep = largo_linea_regla + ((marcas_principales_regla / 4) * (counter - 1))
  209.  
  210.                ' ----- Draw the horizontal ruler ticks.
  211.                e.Graphics.DrawLine(pincel_ancho_mm, tickStep / scale_zoom, 0,
  212.                   tickStep / scale_zoom, (largo_linea_regla / tickSize) / scale_zoom)
  213.  
  214.                ' ----- Draw the vertical ruler ticks.
  215.                e.Graphics.DrawLine(pincel_ancho_mm, 0, tickStep / scale_zoom,
  216.                  (largo_linea_regla / tickSize) / scale_zoom, tickStep / scale_zoom)
  217.  
  218.            Else
  219.                ' ----- Get the tick measurements. The "ticks" constant
  220.                '       includes a set of "1", "2", and "4" values. "1"
  221.                '       gives a full-size tick mark (for whole units),
  222.                '       "2" gives a half-size tick mark, and "4" gives
  223.                '       a 1/4-size tick mark.
  224.                tickSize = CSng(Mid(ticks, counter, 1))
  225.                tickStep = largo_linea_regla + ((marcas_principales_regla / 4) * (counter - 1))
  226.  
  227.                ' ----- Draw the horizontal ruler ticks.
  228.                e.Graphics.DrawLine(pincel_ancho_mm, tickStep, 0,
  229.                   tickStep, (largo_linea_regla / tickSize) / scale_zoom)
  230.  
  231.                ' ----- Draw the vertical ruler ticks.
  232.                e.Graphics.DrawLine(pincel_ancho_mm, 0, tickStep,
  233.                  (largo_linea_regla / tickSize) / scale_zoom, tickStep)
  234.            End If
  235.  
  236.        Next counter
  237.  
  238.        'Se transforma el eje del sistena de coordenadas de la pàgina a las del mmundo
  239.        'desfasándolas 5.00 mm a la derecha e inferior del vèrtice superior izquierdo
  240.        'que son el eje del sistema de coordendas del dispositivo y pàgina. Esto inde-
  241.        'pendiente de las unidades de la pàgina.
  242.        e.Graphics.TranslateTransform(largo_linea_regla, largo_linea_regla)
  243.        '
  244.        'Dibuja un rectángulo de un ancho determinado del pixel(siempre en mm), con
  245.        'un tamaño determinado.
  246.        e.Graphics.DrawRectangle(pincel_ancho_mm, Rectangulo)
  247.        '
  248.        'Dibujo un rectangulo pegado al anterior.
  249.        e.Graphics.DrawRectangle(pincel_ancho_mm, Rectangulo2)
  250.        '
  251.        'Código para dibujar una regla en el PictureBox.
  252.        Dim gp As New Drawing.Drawing2D.GraphicsPath
  253.        gp.AddLine(0, 0, 2, -5)
  254.        gp.AddLine(0, 0, -2, -5)
  255.        gp.AddLine(-2, -5, 2, -5)
  256.        pincel_acotar_mm.CustomEndCap = New Drawing2D.CustomLineCap(gp, Nothing)
  257.        pincel_acotar_mm.CustomStartCap = New Drawing2D.CustomLineCap(gp, Nothing)
  258.        e.Graphics.DrawLine(pincel_acotar_mm, New PointF(CSng(Rectangulo.X * 0.95), Rectangulo.Y), New PointF(CSng(Rectangulo.X * 0.95), Rectangulo.Y + Rectangulo.Height))
  259.        Dim myFont As New Font("Courier", 2, FontStyle.Regular, GraphicsUnit.Millimeter, 0)
  260.        e.Graphics.DrawString(Rectangulo.Height.ToString, myFont, Brushes.Black, CSng(Rectangulo.X * 0.5), CSng(Rectangulo.Y + Rectangulo.Height / 2))
  261.        '
  262.        'Se librea el picenl de dibujo.
  263.        pincel_ancho_mm.Dispose()
  264.  
  265.    End Sub
  266.  
  267.    'Factor de aumento o disminución del zoom(10%).
  268.    Dim factor_Delta_zoom As Single = 0.1
  269.    'Escala de un 100%, cuya variable será la que variará de acuerdo al MouseWheel.
  270.    Dim scale_zoom As Single = 1
  271.  
  272.    Private Sub pe_dibujo_Properties_MouseWheel(sender As Object, e As MouseEventArgs) Handles pe_dibujo.Properties.MouseWheel
  273.  
  274.        'Verifico que el delta del cambio del Scrool haya sido positivo.
  275.        If e.Delta > 0 Then
  276.            '
  277.            'En este caso aumento la escala del zoom
  278.            scale_zoom += factor_Delta_zoom
  279.        Else
  280.            '
  281.            'En este caso disminuyo la escala del zoom.
  282.            scale_zoom -= factor_Delta_zoom
  283.            '
  284.        End If
  285.        '
  286.        'Invoco el redibujado del control del PictureBox.
  287.        pe_dibujo.Invalidate()
  288. '
  289.    End Sub
  290.  
  291. End Class
  292.  

Agradeciera mucho me pudieran guiar en este caso, porque la verdad ya no se como lograrlo.

Muchas gracias.

MOD: Imagenes adaptadas a lo permitido. Etiquetas GeSHi.


« Última modificación: 3 Julio 2017, 22:36 por MCKSys Argentina » En línea

ivancea96


Desconectado Desconectado

Mensajes: 3.410


ASMático


Ver Perfil WWW
Re: GDI+. Hacer zoom respecto a la posición del Mouse en evento MouseWheel de un Pic
« Respuesta #1 en: 3 Julio 2017, 23:31 »

Tienes un punto en una imagen (el cursor, con respecto a la imagen), con su X y su Y.
Si escalas esa imagen, ¿sabrías decir dónde está ese mismo punto ahora?

Ya tenemos el nuevo punto. Ahora hay que colocar ese nuevo punto de la imagen para que coincida con la posición del cursor (con respecto a la pantalla). ¿Podrías hacerlo?

Y si no se me queda nada, listo.

¿Puedes responder a esas preguntas? Si sí, entonces hazlo paso a paso, y verás que sale solo.
Si no, di cuál y por qué, para que te podamos ayudar.

En estos casos, ver el proceso visualmente es lo mejor. Y hacerse las preguntas correctas. ¿Qué es exactamente lo que queremos? En este caso, es escalar, y mover la imagen de forma de que coincida con el cursor, nada más.

Oh, y cuando tengas una duda así, es preferible que te abstengas de poner tanto código. Una pregunta bien hecha y concisa es más fácil de responder que poner un programa (cosa que puede desmotivar a la hora de responder :D)


En línea

Harold23

Desconectado Desconectado

Mensajes: 7


Ver Perfil
Re: GDI+. Hacer zoom respecto a la posición del Mouse en evento MouseWheel de un Pic
« Respuesta #2 en: 3 Julio 2017, 23:49 »

Hola, muy buenas tardes;

Tienes razón en eso, solo traté de ser lo más explícito posible. El inconveniente es que no es una imagen(es un objeto vectorial que en el proyecro dibujaré); sé que la solución está con el Graphics.TraslateTransform y ScaleTransform, combinándolas correctamente, lo cual he intentado de varias formas, pero no he logrado.

Seré lo más conciso:

1. La idea es que al hacer zoom con el MouseWheel del Picture, el gráfico dibujado se escale de tamaño teniendo como punto de origen la Posición Actual del Mouse. La idea es como este GIF.


La idea es emular lo mismo que hace Autocad, cuando se quiero hacer Zoom.



¿Es entendible lo que quiero decir?.

Agradezco pudieras ayudarme con una explicación más concisa, por ejemplo con un simple dibujo de un Rectángulo, y cuando se quiera hacer zoom con el Scroll del mouse(MouseWheel) el dibujo se acerque o se aleje, teniendo en cuenta el punto donde está el puntero del mouse.

Agradezco pueda ayudarme en esto compañero, pues compartir el conocimiento es lo mejor que podemos heredar.

Gracias por todo.
« Última modificación: 4 Julio 2017, 00:24 por Harold23 » En línea

ivancea96


Desconectado Desconectado

Mensajes: 3.410


ASMático


Ver Perfil WWW
Re: GDI+. Hacer zoom respecto a la posición del Mouse en evento MouseWheel de un Pic
« Respuesta #3 en: 4 Julio 2017, 00:01 »

El tema es dividir el proceso en pasos.
En primer lugar: es una imagen vectorial, bien, pero: ¿La puedes escalar? ¿La puedes mover? Me refiero, a si tienes el algoritmo para ello o si puedes hacerlo. En caso afirmativo, eso ya no es un problema.

Entiendo lo que quieres hacer, y eso es lo que expliqué en el primer mensaje.
Entrando a detalles... Probablemente lo que te interese es, teniendo el origen de la transformación en la esquina superior izquierda de la imagen (en adelante, (0,0), el origen), aplicar una escala primero, para hacer grande la imagen, y luego la translación que comenté antes.

Puedes empzar haciendo que el zoom siempre se haga en el centro de la imagen. Si logras esto, lo otro es casi igual.



La idea sería esa.

Edito: Es evidente que la imagen no la hice bien "del todo", sinó al escalarlo, también se saldría por arriba de la pantalla. Pero, you know, paint D:
« Última modificación: 4 Julio 2017, 00:06 por ivancea96 » En línea

Harold23

Desconectado Desconectado

Mensajes: 7


Ver Perfil
Re: GDI+. Hacer zoom respecto a la posición del Mouse en evento MouseWheel de un Pic
« Respuesta #4 en: 4 Julio 2017, 00:07 »

Compañero, creame que llevo más de 2 semanas y no lo he logrado, le rogaría el favor que con un simple ejemplo de un rectángulo, pudiera ayudarme, que ya de ahí yo tomo la idea. Yo soy un igeniero civil, que me dedico a crear pequeños programas de utilidad, y estoy en un punto que ya no me sobran las ideas, pues lo que usted hace ver simple, ya para mí se ha vuelto un dolor de cabeza.

Añado un video ejemplar hecho en Autocad, con lo que deseo lograr:

https://www.dropbox.com/preview/autocad.mp4

Le pido por favor, con un simple ejemplo pequeño, me ilustre y yo de ahí en adelnate me voy.

Dios me lo bendiga.
« Última modificación: 4 Julio 2017, 00:34 por Harold23 » En línea

ivancea96


Desconectado Desconectado

Mensajes: 3.410


ASMático


Ver Perfil WWW
Re: GDI+. Hacer zoom respecto a la posición del Mouse en evento MouseWheel de un Pic
« Respuesta #5 en: 4 Julio 2017, 01:13 »

Un ejemplo, en javascript:

Pega el código en el cuadro de texto y haz click en "Execute" en http://ivancea.xyz/canvasScript.html
El mismo código lo tienes en los "templates" a nombre de "Loading images".

Es lo que tú has dicho, zoom centrado en el ratón. Además, tiene para desplazar con click. No es 1 imagen, sinó que son líneas e imágenes dibujadas al momento.
En ese ejemplo, las transformaciones las ejecuto antes de dibujar, con lo que afectan a todo lo que dibujaré después. Aquí primero aplico la translación, y después la escala.

Está todo un poco comentado, pero bueno, lo importante son las ecuaciones.

Código
  1. // Canvas: 500x500
  2. // Global variable: 'global'
  3. var canvas = document.getElementById("canvas");
  4. var context = canvas.getContext("2d");
  5.  
  6. function clear(){
  7.    context.setTransform(1, 0, 0, 1, 0, 0);
  8.    context.fillStyle = "rgb(255,255,255)";
  9.    context.rect(0,0,500,500);
  10.    context.fill();
  11. }
  12.  
  13. function line(x,y, toX,toY, r,g,b){
  14.    context.strokeStyle = "rgb("+r+","+g+","+b+")";
  15.    context.beginPath();
  16.    context.moveTo(x,y);
  17.    context.lineTo(toX,toY);
  18.    context.stroke();
  19. }
  20.  
  21. /* VARIABLES */
  22.  
  23. var image = new Image();
  24. var isImageLoaded = false;
  25.  
  26. var mousePosition = false;
  27.  
  28. var scale = 1;
  29. var translation = {x: 0, y: 0};
  30.  
  31.  
  32. /* FUNCTIONS */
  33.  
  34. function transform(){
  35.    context.translate(translation.x, translation.y);  
  36.    context.scale(scale, scale);
  37. }
  38.  
  39. function draw(){
  40.    if(isImageLoaded){
  41.        for(var i=0; i+image.width<500; i+=image.width+1)
  42.            for(var j=0; j+image.height<500; j+=image.height+1)
  43.                context.drawImage(image, i,j);
  44.        for(var i=image.width+1; i<500; i+=image.width+1)
  45.            line(i,0, i,500, 0,0,0);
  46.        for(var i=image.height+1; i<500; i+=image.height+1)
  47.            line(0,i, 500,i, 0,0,0);
  48.    }
  49. }
  50.  
  51. /* IMAGE LOADING */
  52.  
  53. image.onload = function(){
  54.    isImageLoaded = true;
  55.  
  56.    clear();
  57.    transform();
  58.    draw();
  59. }
  60.  
  61. image.src = "https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcQzdkT4Kr18U9B9TUUaszth60IPWc2BnmkvDi_bgW9QiSDDkLG5EyobT8U";
  62.  
  63.  
  64. /* EVENTS */
  65.  
  66. canvas.addEventListener("wheel", function(event){
  67.    var x = event.clientX - canvas.offsetLeft,
  68.        y = event.clientY - canvas.offsetTop;
  69.  
  70.    var imageMousePosition = { /* Esta es la posición del ratón con respecto a la imagen sin escalar. */
  71.        x: (x - translation.x)/scale,
  72.     y: (y - translation.y)/scale
  73.    };
  74.  
  75.    if(event.deltaY < 0){ /* Aquí simplemente calculamos el nuevo zoom */
  76.        scale *= 1.1;
  77.    }else{
  78.        scale *= 0.9;
  79.    }
  80.  
  81.    translation.x = x - imageMousePosition.x*scale; /* Aquí ponemos la nueva translación como ya comenté, */
  82.    translation.y = y - imageMousePosition.y*scale; /* la diferencia entre la posición del ratón real y la posición en la imagen escalada */
  83.  
  84.    clear();
  85.    transform();
  86.    draw();
  87. });
  88.  
  89. canvas.addEventListener("mousemove", function(event){
  90.    if(mousePosition !== false){
  91.        var x = event.clientX - canvas.offsetLeft,
  92.            y = event.clientY - canvas.offsetTop;
  93.  
  94.        translation.x += x - mousePosition.x;
  95.        translation.y += y - mousePosition.y;
  96.  
  97.        mousePosition.x = x;
  98.        mousePosition.y = y;
  99.  
  100.        clear();
  101.        transform();
  102.        draw();
  103.    }
  104. });
  105.  
  106. canvas.addEventListener("mousedown", function(event){
  107.    if(event.button == 0){
  108.        mousePosition = {
  109.            x: event.clientX - canvas.offsetLeft,
  110.            y: event.clientY - canvas.offsetTop
  111.        };
  112.    }
  113. });
  114.  
  115. canvas.addEventListener("mouseup", function(event){
  116.    if(event.button == 0){
  117.        mousePosition = false;
  118.    }
  119. });

Probablemente no sea igual a lo que buscas para C#, pero la lógica es la misma. Y bueno, como ves, apenas son 2 líneas para X y 2 para Y. No es muy complicado, pero el tema es entenderlo.
« Última modificación: 4 Julio 2017, 01:14 por ivancea96 » En línea

Harold23

Desconectado Desconectado

Mensajes: 7


Ver Perfil
Re: GDI+. Hacer zoom respecto a la posición del Mouse en evento MouseWheel de un Pic
« Respuesta #6 en: 4 Julio 2017, 04:05 »

Hola compañero. De antemano muchas gracias por el código, pero la verdad nunca he trabajado con javascript, y por más que he tratado de buscar convertidores de código, no lo he encontrado, entiendo la idea más sin embargo con código no puedo lograrlo traspasar.

¿Es mucho pedirle, abusando de su amabilidad, pasarlo en sintaxis C# o VB.Net?. Preferiblemente VB.Net.

Mientras, trataré de seguir convertir ese código.

Dios me lo bendiga.
En línea

NEBIRE


Desconectado Desconectado

Mensajes: 2.327


Ver Perfil
Re: GDI+. Hacer zoom respecto a la posición del Mouse en evento MouseWheel de un Pic
« Respuesta #7 en: 4 Julio 2017, 05:58 »

Ya te lo ha explicado bien en el primer mensaje...
si eres capaz de escalar una imagen y eres capaz de desplazarla (pegarla) en otra posición, consigues lo que quieres.

Un sencillo ejemplo (yo en pseudocódigo, así cualquier que lea lo puede trasladar al lenguaje que precise...)

Código:
// Da igual si es una imagen o una captura de la pantalla, ventana, control, etc...
Funcion ZoomEnXY( entero X, entero Y, fraccion Zoom, grafico Imagen)
    fraccion dX, fraccion dY
    grafico ImgZoom
    
    // 0º Es realmente necesario?
    si zoom=1.0 luego Devolver //nada que cambiar.

     // 1º primero obtienes una imagen escalada al zoom indicado.
    ImgZoom = ZoomImg(Zoom, Imagen)

    // 2º Ahora toca cordenar la imagen en el mismo punto que se pulsó.
        // 2.1 X e Y deben ser cordenadas relativas en la imagen (si ya lo son, se puede omitir).
    X = (X - Imagen.Left)
    Y = (Y - Imagen.Top)
      
        //2.2 Escalamos las cordenadas relativas (x,y).
        // Esto es, dónde está el pixel en la imagen escalada, donde se pinchó en la original?
    dX = (Zoom * X)
    dY = (Zoom * Y)
        // Esto quiere decir que una vez la imagen se coloque en el mismo punto, dX y dY
        //sería la cordenada relativa de la imagen coincidente con x,y relativa de la imagen original.
        // 2.3 ahora solo queda traducir la cordenada relativa de la imagen escalada a la cordenada absoluta.
        // O lo que es lo mismo, obtener el origen de la imagen, poscionado como 'eje' en dX,dY.
    X = ((Imagen.left + X) - dX)  // la absoluta (previa) - la relativa actual, no da el origen de la imagen escalada.
    Y = ((Imagen.Top + Y) - dY)  // Es una regla de tres. X= ... es lo mismo que decir ImgZoom.Left = ...
    
    // 3º Finalmente pegar la imagen en la nueva posicion.
    GraficoDibujar(X, Y, ImgZoom)  
Fin Funcion


Un código más limpio podría relativizar el asunto de las cordenadas derivándolo a otra función...
Código:
Funcion ZoomEnXY( entero X, entero Y, fraccion Zoom, grafico Imagen)
    grafico ImgZoom
    
    // 0º Es realmente necesario?
    si zoom=1.0 luego Devolver //nada que cambiar.

     // 1º primero obtienes una imagen escalada al zoom indicado.
    ImgZoom = ZoomImg(Zoom, Imagen)

    // 2º Ahora toca cordenar la imagen en el mismo punto que se pulsó.
    X = TrasladarOrigen(X , Imagen.Left, Zoom)
    Y = TrasladarOrigen(Y , Imagen.Top, Zoom)
    
    // 3º Finalmente pegar la imagen en la nueva posicion.
    GraficoDibujar(X, Y, ImgZoom)  
Fin Funcion

La función que calcula la nueva posición en un solo paso
Pero mejor entenderlo bien más arriba, paso a paso, no usarlo sin entenderlo.
Con copiar y pegar no se aprende...
Código:
entero = Funcion TrasladarOrigen(entero Distancia, entero Posicion, fraccion Zoom)
    Devolver = (Distancia - ((distancia - Posicion) * Zoom))
Fin Funcion
« Última modificación: 4 Julio 2017, 06:19 por NEBIRE » En línea

Harold23

Desconectado Desconectado

Mensajes: 7


Ver Perfil
Re: GDI+. Hacer zoom respecto a la posición del Mouse en evento MouseWheel de un Pic
« Respuesta #8 en: 4 Julio 2017, 17:09 »

Muy buenos días compañero;

Es que una imagen tiene sus propiedades de location, cuestion que no tiene un Graphics, creame que yo le entiendo el procedimiento, de lo cual le estoy enteramente agradecido, pero eso no lo he podido trasladar a código con un Graphics.Todos los ejemplos que he visto por la internet todo lo hacen trabajando con BitMap, que es más sencillo, pero con un PictureBox, donde lo qu hago es obtener su e.Graphics, no he podido lograrlo. Por fa, ayudenme con un ejemplo de este tipo, se los ruego, hoy por mi mañana por ti.

Dios me lo bendiga.
En línea

ivancea96


Desconectado Desconectado

Mensajes: 3.410


ASMático


Ver Perfil WWW
Re: GDI+. Hacer zoom respecto a la posición del Mouse en evento MouseWheel de un Pic
« Respuesta #9 en: 4 Julio 2017, 19:14 »

Esque es lo mismo. La "location" es exactamente lo mismo que dibujarla transladada. Es lo mismo. Com ote digo, ve por pasos. Primero, transládalo. Todo. Sea bitmap, o vectorial. Transládalo. Hecho eso, nuevamente, es prácticamente lo mismo.
En línea

Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines