Re: scale operations



Thanks Lionel,

i tried your implementation. It works nice, except if you change your mouse pointer position, shift appears.

Making the translation, did you mean just actor.translation_x -= x * sx ? as you just want the diff between before and after scaling ?

Stephane


2015-05-14 0:11 GMT+02:00 Lionel Landwerlin <llandwerlin gmail com>:
Yeah touching the pivot is not the right solution, it's only going to
generate jumps because you kind of move the referential at the same time
you move the coordinates within that referential.

The solution is to keep the pivot point a given known position (easier
is 0,0) and then adjust the translation of the object based on the
scaling you apply and where the pointer is.

Here a Gjs example (to launch like this : gjs file.js picture.jpg) :

======================================================================

const Gio = imports.gi.Gio;
const Clutter = imports.gi.Clutter;
const Cogl = imports.gi.Cogl;
const GdkPixbuf = imports.gi.GdkPixbuf;

Clutter.init(null, null);

// Yeah \o/, We love Java so much we had to copy it into Gio...
let imageFromFile = function(filename) {
    let file = Gio.File.new_for_path(filename);
    let fileinfo = file.query_info('*', Gio.FileQueryInfoFlags.NONE, null);
    let stream = file.read(null);
    let loader = new GdkPixbuf.PixbufLoader();
    loader.write_bytes(stream.read_bytes(fileinfo.get_size(), null));
    loader.close();
    let pixbuf = loader.get_pixbuf();
    let image = new Clutter.Image();
    image.set_data(pixbuf.get_pixels(), Cogl.PixelFormat.RGB_888,
                   pixbuf.get_width(), pixbuf.get_height(),
                   pixbuf.get_width() * 3);
    return image;
};

let stage = new Clutter.Stage({ width: 800, height: 600 });
stage.show();

let actor = new Clutter.Actor({width: 800, height: 600, reactive: true });
actor.set_content(imageFromFile(ARGV[0]));
stage.add_child(actor);

actor.connect('scroll-event', function(a, event) {
    let sx = 0, sy = 0;
    switch (event.get_scroll_direction()) {
    case Clutter.ScrollDirection.UP:
        [sx, sy] = [0.1, 0.1];
        break;
    case Clutter.ScrollDirection.DOWN:
        [sx, sy] = [-0.1, -0.1];
        break;
    }
    let [x, y] = event.get_coords();
    actor.translation_x -= (x / actor.width) * sx * actor.width;
    actor.translation_y -= (y / actor.height) * sy * actor.height;
    actor.scale_x += sx;
    actor.scale_y += sy;
});

Clutter.main();

======================================================================

It's not perfect. I don't have multitouch device to play with the ZoomAction, but you can adapt it to deal with only a single (non multitouch) point.

Cheers,

-
Lionel


On Wed, 2015-05-13 at 20:00 +0200, Stephane Pion wrote:
> I thank i have sent a short code to describe my problem but i'm wrong.
>
> Following a little C code :
>
>
> This is my plan to do scaling
>
>
> Stephane
>
> #include <stdlib.h>
>
> #include <clutter/clutter.h>
> #include <gdk/gdk.h>
>
> gboolean on_event_cb (ClutterActor *actor, ClutterEvent *event,
> gpointer user_data)
> {
>     switch (event->type)
>     {
>     case CLUTTER_SCROLL:
>     {
>         ClutterScrollDirection
> scroll_direction=clutter_event_get_scroll_direction (event);
>
>         if (scroll_direction == CLUTTER_SCROLL_SMOOTH)
>         {
>             gdouble delta, x_scale, y_scale;
>             gfloat x_event,y_event,width,height;
>             gfloat x_pivot,y_pivot;
>             clutter_event_get_scroll_delta (event,NULL,&delta);
>             clutter_actor_get_scale (actor,&x_scale,&y_scale);
>             x_scale = x_scale * (1 - delta*.01);
>             y_scale = y_scale * (1 - delta*.01);
>
>             // set the focal point and rescale
>             clutter_event_get_coords (event,&x_event,&y_event);
>             clutter_actor_get_size (actor,&width,&height);
>             clutter_actor_transform_stage_point
> (actor,x_event,y_event,&x_pivot,&y_pivot);
>             x_pivot=x_pivot/width;
>             y_pivot=y_pivot/height;
>             clutter_actor_set_pivot_point (actor,x_pivot,y_pivot);
>             clutter_actor_set_scale (actor,x_scale,y_scale);
>         }
>     }
>     break;
>     default:
>         break;
>     }
>     return FALSE;
> }
>
> void set_image (ClutterActor *image_actor,const char *path)
> {
>     GdkPixbuf *image=gdk_pixbuf_new_from_file (path, NULL);
>     ClutterContent *image_content=clutter_image_new ();
>     clutter_image_set_data (CLUTTER_IMAGE (image_content),
>             gdk_pixbuf_get_pixels (image),
>             gdk_pixbuf_get_has_alpha (image)
>             ? COGL_PIXEL_FORMAT_RGBA_8888
>                     : COGL_PIXEL_FORMAT_RGB_888,
>                       gdk_pixbuf_get_width (image),
>                       gdk_pixbuf_get_height (image),
>                       gdk_pixbuf_get_rowstride (image),
>                       NULL);
>     g_object_unref (image);
>
>     clutter_actor_set_content (image_actor,image_content);
>     g_object_unref (image_content);
> }
>
> int main(int argc,char **argv)
> {
>     ClutterActor *stage;
>     ClutterActor *image_actor;
>     ClutterContent *image_content;
>
>     if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
>         return EXIT_FAILURE;
>
>     stage = clutter_stage_new ();
>     clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE);
>     image_actor = clutter_actor_new ();
>     clutter_actor_set_reactive (image_actor,TRUE);
>     clutter_actor_add_constraint
> (image_actor,clutter_bind_constraint_new (stage,CLUTTER_BIND_SIZE,0));
>
>     // drag image
>     clutter_actor_add_action (image_actor, clutter_drag_action_new
> ());
>
>     // zoom event
>     g_signal_connect(image_actor, "captured-event", G_CALLBACK
> (on_event_cb), NULL );
>
>     clutter_actor_add_child (stage, image_actor);
>     image_content = clutter_image_new ();
>     clutter_actor_set_content (image_actor, image_content);
>     g_object_unref (image_content);
>
>     set_image (image_actor,"put your image here.jpg");
>
>     clutter_actor_show (stage);
>
>     clutter_main ();
> }
>
>
>
> 2015-05-13 18:35 GMT+02:00 Lionel Landwerlin <llandwerlin gmail com>:
>         Yes, the Zoom action only reacts to touch points (only way it
>         can detect scaling).
>         How did plan to do scaling?
>
>         On 13/05/15 16:56, Stephane Pion wrote:
>
>         > Yes, but it seems inoperative. It seems to be relative to
>         > Gestures, and it doesn't react to mouse action.
>         >
>         > Did i miss something about zoom action ?
>         >
>         > 2015-05-13 17:55 GMT+02:00 Stephane Pion
>         > <stephane pion gmail com>:
>         >         Yes, but it seems inoperative. It seems to be
>         >         relative to Gestures, and it doesn't react to mouse
>         >         action.
>         >
>         >         Did i miss something about zoom action ?
>         >
>         >
>         >         2015-05-13 17:43 GMT+02:00 Lionel Landwerlin
>         >         <llandwerlin gmail com>:
>         >                 Have you tried the ClutterZoomAction? :
>         >                 https://developer.gnome.org/clutter/stable/ClutterZoomAction.html
>         >
>         >
>         >                 On 13/05/15 16:40, Stephane Pion wrote:
>         >
>         >                 > Hi All,
>         >                 >
>         >                 >
>         >                 > I'm working on an application which use
>         >                 > clutter (1.20, debian jessie).
>         >                 >
>         >                 >
>         >                 > I have to display an image and be able to
>         >                 > zoom / pan it. I have some troubles to set
>         >                 > the pivot point.
>         >                 >
>         >                 >
>         >                 > As i scale, some shifts appears.
>         >                 >
>         >                 >
>         >                 > I tried to use
>         >                 > clutter_actor_transform_stage_point
>         >                 > without any success.
>         >                 >
>         >                 >
>         >                 > I think it's an obvious problem, but i
>         >                 > didn't find the solution
>         >                 >
>         >                 > Is somebody know the right way to do
>         >                 > that ?
>         >                 >
>         >                 >
>         >                 > See attached a source which demonstrate my
>         >                 > problem
>         >                 >
>         >                 >
>         >                 > Regards
>         >                 >
>         >                 > Stephane
>         >                 >
>         >                 >
>         >                 >
>         >                 >
>         >                 > _______________________________________________
>         >                 > clutter-list mailing list
>         >                 > clutter-list gnome org
>         >                 > https://mail.gnome.org/mailman/listinfo/clutter-list
>         >
>         >
>         >
>         >                 _______________________________________________
>         >                 clutter-list mailing list
>         >                 clutter-list gnome org
>         >                 https://mail.gnome.org/mailman/listinfo/clutter-list
>         >
>         >
>         >
>         >
>         >
>         >
>         >
>         > _______________________________________________
>         > clutter-list mailing list
>         > clutter-list gnome org
>         > https://mail.gnome.org/mailman/listinfo/clutter-list
>
>
>
>         _______________________________________________
>         clutter-list mailing list
>         clutter-list gnome org
>         https://mail.gnome.org/mailman/listinfo/clutter-list
>
>
>
> _______________________________________________
> clutter-list mailing list
> clutter-list gnome org
> https://mail.gnome.org/mailman/listinfo/clutter-list


_______________________________________________
clutter-list mailing list
clutter-list gnome org
https://mail.gnome.org/mailman/listinfo/clutter-list



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]