Can ActionText show gifs?

Action text merrily accepts a gif upload through the trix editor. However when it is actually displayed - it seems to show a variant which has been ‘flattened’ to show only the first frame of the gif.

Is there a way to either show the original gif, or to tweak things so that the variants are not flattened?

thanks

1 Like

There are a couple of issues.

First of all, ActiveStorage hardcodes the image’s first frame when doing a transformation, which breaks animated GIFs. You can solve this by setting the page to nil alongside your other transformations. If you are resizing the GIF, for example:

blob.variant(loader: { page: nil }, resize_to_limit: [nil, 560])

This solves the animation problem, but you’ll still run into weird layering issues if you’re working with optimized GIFs. You’ll need to remove these optimizations before calling resize (or resize_to_limit) when creating the variant. Putting everything together:

blob.variant(loader: { page: nil }, coalesce: true, resize_to_limit: [nil, 560])
2 Likes

Hi @Imansur,

thanks for your response. I can see how this would help if I was taking a gif and transforming it myself - however in this case, the gif is an attachment in ActionText.

the full code isn’t much more than

has_rich_text :description

in my model and a form field to accept it.

Can I ‘tell’ ActionText how it should handle gif attachments?

ActionText is deeply integrated with ActiveStorage. When you attach something to your editor, you’re using AS behind the scenes, including how it renders attachments by default.

You should have a partial in app/views/active_storage/blobs/_blob.html.erb that calls blob.representation(...)—this is where it applies the transformations for the attachment.

2 Likes

Thank you - I was aware that ActionText uses ActiveStorage, but wasn’t aware of how that view handles the transformation.

For anyone coming to this later, the simple change below works for me:

Is there any case where this change would cause problems? Some representable class where setting loader/coalesce might break things?

thanks again :slight_smile:

#app/views/active_storage/blobs/_blob.html.erb

previously:


<figure class="attachment attachment--<%= blob.representable? ? "preview" : "file" %> attachment--<%= blob.filename.extension %>">
  <% if blob.representable? %>
    <%= image_tag url_for(blob.representation(resize_to_limit: local_assigns[:in_gallery] ? [ 800, 600 ] : [ 1024, 768 ])) %>
  <% end %>

  <figcaption class="attachment__caption">
    <% if caption = blob.try(:caption) %>
      <%= caption %>
    <% else %>
      <span class="attachment__name"><%= blob.filename %></span>
      <span class="attachment__size"><%= number_to_human_size blob.byte_size %></span>
    <% end %>
  </figcaption>
</figure>

now:

<figure class="attachment attachment--<%= blob.representable? ? "preview" : "file" %> attachment--<%= blob.filename.extension %>">
  <% if blob.representable? %>
    <%= image_tag url_for(blob.representation(loader: { page: nil }, coalesce: true, resize_to_limit: local_assigns[:in_gallery] ? [ 800, 600 ] : [ 1024, 768 ])) %>
  <% end %>

  <figcaption class="attachment__caption">
    <% if caption = blob.try(:caption) %>
      <%= caption %>
    <% else %>
      <span class="attachment__name"><%= blob.filename %></span>
      <span class="attachment__size"><%= number_to_human_size blob.byte_size %></span>
    <% end %>
  </figcaption>
</figure>
1 Like

I’m not sure, but my advice would be to only apply these transformations on GIF attachments. You can check blob.content_type == Mime[:gif].to_s

Update: Since switching to VIPS, this is broken for me. I get the error Vips::Error: VipsOperation: class "coalesce" not found

have you find any solution for this issue?

I’m just sticking with rmagick for now

For VIPS use:

blob.variant(loader: { n: -1 }, resize_to_limit: [nil, 560])

with loader: { n: -1 } being the important bit that corresponds to the arguments passed to vips_gifload.

1 Like