diff options
Diffstat (limited to 'plugins/shotwell-transitions/CrumbleEffect.vala')
-rw-r--r-- | plugins/shotwell-transitions/CrumbleEffect.vala | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/plugins/shotwell-transitions/CrumbleEffect.vala b/plugins/shotwell-transitions/CrumbleEffect.vala new file mode 100644 index 0000000..a458811 --- /dev/null +++ b/plugins/shotwell-transitions/CrumbleEffect.vala @@ -0,0 +1,103 @@ +/* Copyright 2010 Maxim Kartashev + * Copyright 2011-2014 Yorba Foundation + * + * This software is licensed under the GNU Lesser General Public License + * (version 2.1 or later). See the COPYING file in this distribution. + */ + +using Spit; + +private class CrumbleEffectDescriptor : ShotwellTransitionDescriptor { + public CrumbleEffectDescriptor(GLib.File resource_directory) { + base(resource_directory); + } + + public override unowned string get_id() { + return "org.yorba.shotwell.transitions.crumble"; + } + + public override unowned string get_pluggable_name() { + return _("Crumble"); + } + + public override Transitions.Effect create(Spit.HostInterface host) { + return new CrumbleEffect(); + } +} + +private class CrumbleEffect : Object, Transitions.Effect { + private const int DESIRED_FPS = 25; + private const int MIN_FPS = 15; + + private const int STRIPE_WIDTH = 10; + + private Cairo.ImageSurface[] from_stripes; + private double[] accelerations; + private int stripes_count; + + public CrumbleEffect() { + } + + public void get_fps(out int desired_fps, out int min_fps) { + desired_fps = CrumbleEffect.DESIRED_FPS; + min_fps = CrumbleEffect.MIN_FPS; + } + + public bool needs_clear_background() { + return true; + } + + public void start(Transitions.Visuals visuals, Transitions.Motion motion) { + Rand rand = new Rand(); + + // Cut original image into stripes of STRIPE_WIDTH width; also prepare + // acceleration for each stripe. + if (visuals.from_pixbuf != null) { + stripes_count = visuals.from_pixbuf.width / STRIPE_WIDTH; + from_stripes = new Cairo.ImageSurface[stripes_count]; + accelerations = new double[stripes_count]; + for (int i = 0; i < stripes_count; ++i) { + from_stripes[i] = new Cairo.ImageSurface(Cairo.Format.RGB24, STRIPE_WIDTH, + visuals.from_pixbuf.height); + Cairo.Context ctx = new Cairo.Context(from_stripes[i]); + Gdk.cairo_set_source_pixbuf(ctx, visuals.from_pixbuf, - i * STRIPE_WIDTH, 0); + ctx.paint(); + accelerations[i] = rand.next_double(); + } + } + } + + public void paint(Transitions.Visuals visuals, Transitions.Motion motion, Cairo.Context ctx, + int width, int height, int frame_number) { + double alpha = motion.get_alpha(frame_number); + + if (alpha < 0.5) { + // First part: draw stripes that go down with pre-calculated acceleration + alpha = alpha * 2; // stretch alpha to [0, 1] + + // tear down from_pixbuf first + for (int i = 0; i < stripes_count; ++i) { + int x = visuals.from_pos.x + i * STRIPE_WIDTH; + double a = alpha + alpha * accelerations[i]; + int y = visuals.from_pos.y + (int) (visuals.from_pixbuf.height * a * a); + + ctx.set_source_surface(from_stripes[i], x, y); + ctx.paint(); + } + } else if (visuals.to_pixbuf != null) { + // Second part: fade in next image ("to_pixbuf") + alpha = (alpha - 0.5) * 2; // stretch alpha to [0, 1] + Gdk.cairo_set_source_pixbuf(ctx, visuals.to_pixbuf, visuals.to_pos.x, visuals.to_pos.y); + ctx.paint_with_alpha(alpha); + } else { + // TODO: fade in background color + } + } + + public void advance(Transitions.Visuals visuals, Transitions.Motion motion, int frame_number) { + } + + public void cancel() { + } +} + |