Croppie - element plugin to crop and zoom images before upload

The change I put in is “Upload Original Image”, only half the solution you are looking for. To load it back into Croppie is a feature still pending on fixing the CORS issue.

I like the UI you have there.

Hi @mishav

This is the Croppie Set up (0.4.0)

With the latest release …

  1. Original Image is no longer saved on my “Save” action. I have not changed that logic other than to remove the “Upload Original image from Browser” option. This upload of the original image now seems to be dependant on this check box (have tested it, tick the box and the Original Image is saved).

  2. Even with the option unticked, when I create a completely new thing, Croppie is still loading the last browsed image. Unless you refresh the Browser. So it looks like it is trying to be helpful and load images when it can. But that makes the UI pretty poor when previous images appear randomly. (This is not even a new thing for storeage - I am creating a new Question thing, then creating a new Answer Thing which is linked to Question and when Croppie loads on this brand new set of data … up comes the last Image Browsed.

Whilst I appreciate all the hard work you have put in, I think we need to come to a landing on how this should work going forward. Can’t keep testing it for much longer before I need to look for another solution. And anyone who comes after me to use the Plugin in anything more complex than an “image gallery” is going to hit the same issues. I don’t think it is my lack of understanding on how it is working, I just think it is trying to be too clever on this image load. Can we work on getting the load behaviour predictable ?

PM me if you want adding to the app so you can see what if going on.

Thanks, as always, for creating this. It is so useful, but we just need to get those final few kinks ironed out now.

Hi @NigelG, thanks for sharing the properties, it makes it easier to see what is happening.

Unfortunately there isn’t a way for the plugin element to group related properties together, or hide them if not needed, so I’ve tried to make it clear by the labelling. I’ve also tried sticking to the convention that Bubble has on its Picture Uploader, for private file etc.

Make this file private means the next two properties are used, attaching the cropped file to a database record.

Upload original image from browse activates the “original image” function. If turned on, it only uploads an image from Browse, not from Default image or Load image, because in both those cases you already have the original image.

Make original image private is only relevant if uploading the original image, so in your case this entire section is unused.

Source image you have set to Answer’s OrigImage, I see this as a problem if you no longer upload the originals. Possibly there are some prior saved original images which this setting will show.

This is interesting behaviour. When you create a new thing, do the repeating group cells move around in position? I need to test more with Croppie in a repeating group.

Yes I’d like to see your app and the workflow.

Part of the problem is that in a repeating group:

When a new row is added at the top so the current one is supposed to “move down” in the list, what Bubble does is:

  • Give the properties of the element to a new one (or existing invisible one) in the next row.
  • Alter the top element properties according to a new row, i.e. a blank source image.
  • The internal instance.data stays with the top element instead of moving to the element in the next row.

This makes the element partly a new one and internally still the original one.

@emmanuel what do you do with internal state for standard elements moving position in a repeating group? And what can we do with plugin elements?

I tested with Picture Uploader, it doesn’t remember the image it just uploaded when moving to a new row.

Edit: if there is no property changes, the top element doesn’t even receive an update() event, so there is no chance of clearing out what is shown!

Thanks, that now makes sense ! I had not realised that the “Load Browsed” option was the parent of the ones below. All is much clearer now.

My bad on the layout of the properties, we have limited options there, but I’ll try to make it look better.

My bad for not reading it properly ! It makes sense now. It is a complex Plugin :slight_smile:

When we have it sorted I will do a post about using Croppie so we don’t lose what we have learned.

#New version v0.5.1

  • Revised logic about when to draw the image.
  • New workflow action “clear”, to clear the displayed image.
  • New published state “is loaded”, sets to true when an image is displayed.
  • New property “Instance timestamp”. Setting this to a new value will cause Croppie to clear its image.

Best way to use the instance timestamp is:

  1. in a workflow, set current date/time in a custom state
  2. set the instance timestamp to have a dynamic value from the custom state.

This is a workaround for repeating-group weirdness. Leave it blank if you don’t need to use it.

@mishav Fantastic Plugin.

I’m Still testing it and trying to figure it out.
Huge potential to be a primary plugin for every bubble App.

Thanks.

I’ve been putting in the field documentation but they don’t show anywhere, so here goes:

#Fields
Viewport width
Width of viewport in pixels. Viewport is the crop area.
Viewport height
Height of viewport in pixels.
Viewport type
Square includes rectanglar, circle includes oval. Circle shape looks better with an output format of png to make the corners transparent.
Show zoomer
Croppie’s zoom control slider.
Set boundary
Boundary defines how much of the container to use for the image.
Boundary width
Width of the boundary, in pixels or percentage of the container.
Boundary height
Height of the boundary, in pixels or percentage of the container.
Enable EXIF
Use EXIF of source image to determine initial orientation.
Enable zoom
Allow user to zoom in and out.
Enable mouse wheel zoom
Interpret mouse wheel movement as zoom control.
Custom class
Apply a class to the croppie container, to pick up your own styles added in page html header.
Output format
Auto attempts to match the stored format with the input format, jpeg or png.
Make this file private
Check this box if you want to protect the file that is uploaded.
Attach file to thing type
When the file is uploaded in private mode, you define here who / which thing owns the file. For a file to be private, it must be attached to a thing/user that already exists.
Attach this file to
When the file is uploaded in private mode, you define here who / which thing owns the file. For a file to be private, it must be attached to a thing/user that already exists.
[Original] Upload original image from browse
Upload the original image, as well as the cropped image.
[Original] Maximum file size in bytes
Limit the size of the selected file. Useful if uploading the original selected file. Triggers “image too large” event if too large.
[Original] Make original image private
Check this box if you want to protect the original image that is uploaded.
[Original] Attach original image to thing type
When the file is uploaded in private mode, you define here who / which thing owns the file. For a file to be private, it must be attached to a thing/user that already exists.
[Original] Attach original image to
When the file is uploaded in private mode, you define here who / which thing owns the file. For a file to be private, it must be attached to a thing/user that already exists.
Source image
If set, loads this image by default.
Instance timestamp (optional)
Set this timestamp to ensure all further instances of the element are cleared from previous image. This is used if inside a repeating group.

#Exposed states
Result image
Url of cropped image uploaded to storage.
is loading
Croppie is loading image from url or file.
is saving
Croppie is saving the cropped image to storage.
Browser supported
True if browser does support FileReader method.
Original image
Url of original selected image uploaded to storage.
is loaded
Croppie has loaded an image from url or file.

#Events
is saved
Croppie has saved the cropped image to storage.
is loaded
Croppie has loaded the image from url or file.
image too large
Selected image exceeds maximum file size.

#Actions
Browse
Open the browser’s file dialog to choose an input file.
Save
Start uploading the cropped image to storage.
Rotate
Rotate the image about its center by specified degrees.
Zoom
Zoom the image in or out.
The amount of zoom, minimum is zero, maximum is 1.5 if zoom restricted to image size.
Load
Load an image from url.
Clear
Clear the image.

3 Likes

This is awesome !

@mishav Seeding the idea for your next plugin - Copy / paste from clipboard. That would help a lot of people building chat related apps as well as users reporting bugs.

2 Likes

Haha thanks for the tip. Copy/paste is soooo browser specific, unless picking the right library.

Just to confirm that v0.5.1 is working well in a repeating group.

The “Is Loaded” state is very handy for making the “Save” button appear at the right time - so your have “Browse” then as long as the user selects an image then “Save” appears. Makes the UX more obvious.

I set the timestamp to be the creation date of the thing that my gallery of images hang off. Which is the current date/time for this particular workflow anyway.

Not that there is still an underlying timing issue that is Bubble related, not Croppie related, in that a repeating group can flash up with previously saved data before clearing itself.

Will post up some instructions and a demo of our Crop gallery.

Actually an even better way to use this in a repeating group is set it to the current cell’s record Creation Date, to tie it in with the record, and clear/redisplay from storage if belonging to a different record.

Especially for @NigelG, haha!

Love it @mishav!! Thank you for this awesome contribution to Bubble :slight_smile:

1 Like

Great plugin @mishav. When using a popup, Croppie still has a few bugs. I’ve made a sample application to demo the issue:

Runtime

App Editor

In this example, we are just updating the user image using Croppie. The Croppie on the main page works fine, but the one inside the Popup does not. If you use the Browse button inside of the popup and then click save…functionally, it works (i.e. updates the user image), but Croppie never displays the image after Browse is ran in a workflow so the functionality is blind to the user.

1 Like

@supernaturally thanks for the detailed problem report.

The problem is in the workflow, the popup’s browse button is triggering the action to browse the croppie on the page instead of the croppie in the popup.

Good luck!

Right you are! Sorry about that, it works now. I’m trying to figure out why my application doesn’t work but the exact same issue I just re-created now works. I’m wondering if custom HTML/JS on the page is breaking Croppie.

Its possible. To confirm this, see if Croppie works when the extra javascript is removed.

Keep me posted about what interferes, there may be an easy fix my end or your end.

1 Like

Hi Misha,

Congratulations on the great work with this plugin. I think you have solved a big problem by introducing this plugin. Thank you.

Hi @supernaturally,
On a separate note, can I ask a question, please? While going through one of your recent posts I visited the link to your test app, which you set-up to test Croppie, and I could not believe how quickly the images were uploading there. The images were uploading in a snap. The same image that takes about 10-15 seconds to upload on my app didn’t even take a second on your’s. Just wanted to check with you if you are on a dedicated server plan (if you prefer answering that) or if you have done something differently there?