Slim Image Cropper
- Price
- $89
- Includes
-
- future updates
- 6 months professional support
Slim is a cross platform JavaScript Image Cropper. It's easy to setup and features beautiful graphics and animations.
Your users will be cropping and rotating images in no time.
Feature overview:
- Responsive and Mobile Friendly
- Fast and Beautifully Animations
- Crop, Rotate and Upload images
- Drag and Drop Images and URLs
- Works on all Major Browser
- JavaScript and jQuery API
Works standalone but ships with handy wrappers for jQuery, React, Angular (1.x and newer versions), VueJS, Bootstrap and Foundation.
Slim image cropper is no longer available for purchase.
Slim image cropper has been discontinued in favor of Pintura Image Editor and CropGuide Image Cropper.
Pintura is a JavaScript Image Editor SDK similar to Slim, it offers cropping functionality and much more.
Learn more about Pintura
CropGuide is a NoCode Image Cropper, it is the easiest way to add image cropping to a file upload field, it doesn't require any code changes.
Learn more about CropGuide
What Our Customers Say...
One of the best downloads I ever made. Design is top notch. The customer support is excellent.
Great, easy to use plugin for image upload and cropping. Sleek design that will fit the look and feel of any modern website. Had some issues with implementing into a complicated AJAX form and the customer support was superb!
Worth every cent. Does the job as promised. Had some server-side problems setting it up, but the support was pure gold. Even got some extra coding help.
Let's take a look and see why Slim Image Cropper is super awesome!
Drag, Drop 'n Crop
Let's give Slim a test run, drop an image in the Slim drop area below.
If you're old school, clicking the drop area will work just as well.
<div class="slim"
data-ratio="16:9"
data-service="async.php"
data-fetcher="fetch.php"
data-size="640,640">
<input type="file" name="slim[]"/>
</div>
Edit Server Images
Got images on your server that are in need of some cropping? Put an img
within the Slim element and it will automatically be made ready for cropping.
<div class="slim"
data-service="async.php"
data-fetcher="fetch.php"
data-ratio="3:2"
data-size="600,400"
data-max-file-size="2">
<img src="./media/stars.jpg" alt=""/>
<input type="file" name="slim[]"/>
</div>
Form Post
In the first demo the content was posted using AJAX, in this one, well use the good old form
to post our cropped image.
Note that we prevent form submission with the required
attribute on the input file tag.
<form action="post.php" method="post" enctype="multipart/form-data" class="avatar">
<div class="slim"
data-label="Drop your avatar here"
data-fetcher="fetch.php"
data-size="240,240"
data-ratio="1:1">
<input type="file" name="slim[]" required />
</div>
<button type="submit">Upload now!</button>
</form>
Easy Configuration
Slim can be setup using only HTML. See the attribute overview below for an outline of Slims configuration options.
Attribute | Description |
---|---|
data-ratio |
What ratio should the crop be in, default ratios are all supported Custom ratios can also be set, Slim will calculate the correct container size automatically. e.g. Set to Set the value to The default value is "free" |
|
|
data-size |
Determine the target size of the resulting image. For example By default Slim does not resize the output image. |
|
|
data-min-size |
Determine minimum size of the crop in pixels For example If the minimum width defined is bigger than the height of the image the rotation button will only rotate the image by 180 degrees instead of 90. By default Slims minimum size is 100 by 100 pixels this prevents the controls of the cropper from overlapping. |
|
|
data-force-size |
Determine the forced output size of the resulting image. For example Force size will also set the aspect ratio to fit the supplied size, so with force-size set to By default Slim does not resize the output image. |
data-force-min-size |
Set to Default is "true" |
data-filter-sharpen |
Slim can sharpen images after they've been resized, this can be used to highlight colors and high contrast edges. This can lead to a slight improvement in image clarity. Takes a value between By default Slim does not sharpen images. |
data-service |
When set, the cropped image will be sent to the set URL using AJAX. Slim ships with an example upload PHP file which is also used on this website (async.php). An upload button will appear unless the The server can optionally return a JSON response to indicate a successful upload.
You can also set a function reference, in that case Slim will call the function passing the following parameters.
By default the image information is posted to the server without AJAX. |
data-service-format |
If the By default Slim will send data as a FormData Object. Set this attribute to |
data-fetcher |
By default Slim will not load dropped URLs as it needs a server script to do so. The Configuring Slim like shown below will enable the URL drop feature.
By default no remote fetch service is defined. |
data-upload-base64 |
Determines if the asynchronous upload method (data-service) sends base64 data or sends a file object. "false" |
data-upload-method |
The default request method used to asynchronously send data to the server. "POST" |
data-meta-* |
Use this attribute to send additional data to the server. For example setting
See Sending Additional data to the server for more information. |
data-push |
When set to Default is "false" |
data-post |
What information to send to the server. The original input image, the cropped output image and/or the actions (crop position and size). Can be set as a comma separated list Note that when sending the input image along the resulting upload size can potentially get two times as big as the original image (input + output). Input and output metadata like filename, size, width and height will always be sent. By default only the "output" and the user "actions" are sent. |
data-jpeg-compression |
The amount of JPEG compression to apply to cropped JPEG images. Ranges from 0 (for high compression) to 100 (no compression). By default Slim uses the browser JPEG compression value which is around 90%. |
data-internal-canvas-size |
Some devices have limited memory and therefor cannot load super high resolution images. To cope with big amounts of data you can set the maximum internal canvas size Slim uses to load data, images that are bigger are scaled down to this size. By default the value is set to By default Slim uses a maximum of 4096 by 4096 pixels. |
data-force-type |
Force output type, set to either "png", or "jpg" and Slim will replace the extension and save file in the given format. By default Slim tries to detect the file type, if it cannot be determined it falls back to "png". Default is "false" |
data-default-input-name |
The name of the default input field. The default value is in array format so multiple Slim croppers can post to the same input name. This is only used if there's no hidden input to write to and no service url has been set. By default this is set to "slim[]" |
data-save-initial-image |
When set to Default is "false" |
data-download |
When set to Default is "false" |
|
|
data-rotate-button |
When set to Default is "true" |
data-edit |
When set to Default is "true" |
data-instant-edit |
When set to Default is "false" |
data-crop |
Pass initial crop coordinates. The format is a comma separated list of coordinates (x, y, width, height). Setting Please not that this only crops the initial image. Subsequent images will not be cropped with these settings but will use auto crop. Use case could be an avatar upload form. Where you might want to allow the user to edit the previously uploaded original image instead of the cropped version but do want to show the cropped preview. |
data-rotation |
Pass rotation for initial image. When set, has to be either "90", "180" or "270". Please not that this only rotates the initial image. |
data-copy-image-head |
Set to Default is "false" |
data-device-pixel-ratio |
The device pixel ratio used to render the images. Set to Default is "1" |
data-popover-class-name |
Add custom class name to popover editor. |
data-label |
The label shown in the drop area. "Drop your image here" |
|
|
data-label-loading |
The label shown in the drop area while loading. "Image loading..." |
data-button-*-label |
Replace the star with For example Note that the label is only shown on the |
data-button-*-title |
Replace the star with By default the title contains the same value as the label |
data-button-*-class-name |
Useful for when you want to add additional class names to on of the action buttons. |
data-max-file-size |
The maximum file size the user is allowed to upload in megabytes. A value of By default no limit is set on file size |
data-status-file-size |
The status text shown when a user tries to upload a file that's too big. The default is: "File is too big, maximum file size: $0 MB." The |
data-status-file-type |
The status text shown when a user tries to upload an invalid file. You can set the allowed file types using the
You can also supply multiple mime types by comma separating them: The default text is as follows: "Invalid file type, expects: $0." The |
data-status-no-support |
The status text shown when the user is not running a modern web browser. The following browsers and devices are supported.
On very old browsers (older than Internet Explorer 8), Slim won't load due to lack of JavaScript functionality. The default text reads as follows: "Your browser does not support image cropping." |
data-status-image-too-small |
The status text shown when the user is trying to load an image that is smaller than the value set in "Image is too small, minimum size is: $0 pixels." The |
data-status-content-length |
The status text shown when the user uploads a file that is too big for the server to handle. Slim tries to interpret the error page the server returns if it contains the term "Content-Length" it will assume it's because the image is too big. Keep in mind that while the input file may fall below the limit of your server, the total uploaded bytes could possibly be higher (if you for example send both "input" and "output" to the server). The default text reads as follows: "The file is probably too big" |
data-status-unknown-response |
The error text shown when the server returns an unknown response. Default: "An unknown error occurred" |
data-status-upload-success |
The status text shown when the image is uploaded correctly. Default: "Saved" |
data-did-init |
A callback method that gets called when Slim has initialised. The function arguments consist of a single object reflecting the current crop state.
|
data-did-load |
This callback method is called when an image was loaded and passed the default input validation methods. The return value of the did-load callback determines what Slim does next.
This setup makes it possible to do custom validation. For instance, the validation rule below checks if the dropped image contains "warm" enough colors. Dropping images with mostly blue, green or purple tones will result in an error. |
|
|
data-did-transform |
This callback method is called after the image has just been transformed (cropped or otherwise updated). The only passed parameter contains the current crop state. |
data-will-crop-initial |
This callback method is called before the initial crop is made. It receives the image file as only parameter and expects an initial crop rectangle as result.
|
data-will-transform |
A callback method that gets called after each image transform. Slim sends the following two parameters along: When calling the You could for example use this method to add watermarks to images, or mask images, like shown in the demo below. |
|
|
Here we apply a mask to the image in the will-transform callback |
|
|
|
In this example we add a watermark to the image. |
|
|
|
data-will-save |
Similar to the Keep in mind that, as with the When adding custom properties to the crop state object, make sure they are all contained in a parent property called |
data-did-save |
Called after the current crop object was saved. Receives the crop state object as it's only parameter. |
data-did-confirm |
Called after the user pressed the image editor confirm button. |
data-did-cancel |
Called after the user pressed the image editor cancel button. |
data-did-upload |
Callback function that gets called when Slim uploads a file and the server returns with a success or failure. If something went wrong the
|
data-did-receive-server-error |
By default Slim will render the "unknown error" response if the server triggers an error (if the status property in the response object equals The error returned in the callback is the error message Slim will show in the visual status message.
|
data-will-remove |
A callback method that can be used to block the actual removal of the image. This allows you to setup a "please confirm image removal" message.
This method will not be called when the API |
data-will-request |
A callback method that can be used to add additional request headers to the upload XMLHttpRequest object. |
data-will-fetch |
A callback method that can be used to add additional request headers to the fetch XMLHttpRequest object. |
data-will-load |
A callback method that can be used to add additional request headers to the load local image XMLHttpRequest object. |
|
|
data-did-remove |
A callback method that allows you to detect when the user has removed an image. Slim returns the previous crop state object that would have otherwise been send to the server.
|
data-did-throw-error |
A callback method that receives all visual errors thrown by Slim. Receives the error as only parameter.
|
JavaScript API
If you're using jQuery, Slim automatically sets up the jQuery API for your convenience. Want to go Vanilla? No problem at all.
Creating a new cropper
Here's how you'd turn the following HTML into a Slim cropper.
<input type="file" id="myCropper"/>
Using good ol' JavaScript.
new Slim(document.getElementById('myCropper'));
And this is how you'd do that with the jQuery API.
$('#myCropper').slim();
Setting custom options
The JavaScript/jQuery API unlocks the same set of options as the HTML API.
- edit
- ratio
- size
- rotation
- post
- service
- serviceFormat
- uploadBase64
- push
- crop
- instantEdit
- jpegCompression
- filterSharpen
- forceType
- forceSize
- forceMinSize
- defaultInputName
- minSize
- maxFileSize
- download
- fetcher
- saveInitialImage
- internalCanvasSize
- rotateButton
- label
- labelLoading
- statusFileType
- statusFileSize
- statusNoSupport
- statusImageTooSmall
- statusContentLength
- statusUnknownResponse
- statusUploadSuccess
- button*Label
- button*ClassName
- button*Title
- uploadMethod
- willTransform
- willSave
- willRemove
- willRequest
- willFetch
- willLoad
- didInit
- didLoad
- didTransform
- didCancel
- didConfirm
- didSave
- didRemove
- didUpload
- didReceiveServerError
Replace the * in the button properties with one of the following buttons to alter it's properties.
- Confirm
- Cancel
- Rotate
- Remove
- Edit
- Download
- Upload
An example code snippet passing custom options
in JavaScript.
new Slim(element, {
ratio: '4:3',
minSize: {
width: 640,
height: 480,
},
crop: {
x: 0,
y: 0,
width: 100,
height: 100
},
service: 'upload-async.php',
download: false,
willSave: function(data, ready) {
alert('saving!');
ready(data);
},
label: 'Drop your image here.',
buttonConfirmLabel: 'Ok',
meta: {
userId:'1234'
}
});
The options
object is identical.
$(selector).slim({
ratio: '4:3',
minSize: {
width: 640,
height: 480,
},
crop: {
x: 0,
y: 0,
width: 100,
height: 100
},
service: 'upload-async.php',
download: false,
willSave: function(data, ready) {
alert('saving!');
ready(data);
},
label: 'Drop your image here.',
buttonConfirmLabel: 'Ok',
meta: {
userId:'1234'
}
});
Initialising Slim within a HTML snippet
<div id="my-snippet">
<!-- my first cropper -->
<input type="file" class="slim"/>
<!-- my second cropper -->
<input type="file" class="slim"/>
</div>
Below two examples on how to turn the elements with class slim
into Slim croppers.
Using JavaScript with we select the parent element using the getElementById
method.
Slim.parse(document.getElementById('my-snippet'));
In jQuery we can just pass the parent selector to the jQuery method.
$('#my-snippet').slim('parse');
Destroying a Slim image cropper
If you've manually created a Slim image cropper using the JavaScript/jQuery API you can destroy it using the destroy function.
The API exposes a destroy
method.
// Create a new cropper
var cropper = new Slim(document.getElementById('my-cropper'));
// Destroy the cropper
cropper.destroy();
If you want to destroy a cropper that was initialised automatically (or by using the parse
method) you can use the destroy method on the Slim Class itself.
// Destroy cropper on element
Slim.destroy(document.getElementById('my-cropper'));
If you're using jQuery creating and destroying croppers can be done with a single destroy call.
// Create cropper(s)
var croppers = $('#my-cropper').slim(options);
// Destroy cropper(s)
croppers.slim('destroy');
Manual loading and uploading of images
// Create a new cropper
var cropper = new Slim(document.getElementById('my-cropper'));
// Load image by url or pass a File object
// - The error parameter contains error messages
cropper.load('path/to/image.jpg', function(error, data){
// Done loading the image!
// Upload a selected image to the server
cropper.upload(function(error, data, response){
// Done uploading!
});
});
Summary of instance API methods
Create a new Slim Cropper.
var cropper = new Slim(document.getElementById('my-cropper'));
Test if Slim is bound to given element.
var state = cropper.isAttachedTo(element);
Test if Slim is still bound to DOM.
var state = cropper.isDetached();
Upload an image by url or data-uri.
// basic implementation
cropper.load(src);
// if you need to know when the image has loaded, pass a function
// as the second parameter
cropper.load(src, function(error, data) {
// image load done!
});
// you can also pass an options object
// this options object also accepts a rotation and crop parameter
// these options reflect the functionality of the rotation and
// crop options on the slim options object
cropper.load(src, { rotation:90, crop: {} }, function(error, data) {
// image load done!
});
// if 'push' is set to true, you can pass the blockPush
// property to prevent immediate upload on image load
cropper.load(src, { blockPush:true }, function(error, data) {
// image load done!
});
Upload currently loaded image
cropper.upload(function(error, data, response) {
// upload done!
});
Download currently loaded image as file
cropper.download();
Request current output data
cropper.requestOutput(function(fileData, formData) {
// fileData files
// formData files wrapped in FormData object ready for submit
});
Remove currently loaded image
var data = cropper.remove();
Destroy the cropper
cropper.destroy();
Get current data object
var data = cropper.data;
// format of data object
{
// server response object after async upload
server: null,
// meta data set with data-meta-*
meta: {},
// the source file
input:{
// input field id
field: null,
// name of file
name: null,
// mime type of image
type: null,
// file loaded
file: null,
// file size in bytes
size: null,
// image base64 data or canvas
image: null,
// original dimensions of image
width: 0,
height: 0
},
// the result of the crop
output:{
// name of file
name: null,
// mime type of image
type: null,
// image base64 data or canvas
image: null,
// output image dimensions
width: 0,
height: 0
},
// user actions
actions:{
// angle of rotation in degrees
rotation: null,
// crop coordinates and type
crop: {
// coordinates
x: 0,
y: 0,
width: 0,
height: 0,
// type of crop
// - 'auto'
// - 'initial'
// - 'manual'
type: null
},
// output size
size: {
width: 0,
height: 0
},
// applied filters
filters: {
sharpen: 0
}
}
}
Get current data object in base64 format
var data = cropper.dataBase64;
Get root element
var element = cropper.element;
Do manual crop, please keep in mind that this method does not check if the input matches the required ratio or image size.
cropper.crop({x:0, y:0, width:100, height:100}, function(result) {
// crop done!
});
Open the editor
cropper.edit();
Set new output size
cropper.size = { width:640, height:480 };
// directly apply with set method
cropper.setSize({ width:640, height:480 }, function(data) {
// done!
});
set new forced size
cropper.forceSize = { width:640, height:480 };
// directly apply with set method
cropper.setForceSize({ width:640, height:480 }, function(data) {
// done!
});
Set new ratio
cropper.ratio = '3:2';
// directly apply with set method
cropper.setRatio('3:2', function(data) {
// done!
});
Set new rotation
cropper.rotation = 90;
// directly apply with set method
cropper.setRotation(90, function(data) {
// done!
});
Summary of Static API methods
Tests if slims can be used on this browser.
var supported = Slim.supported;
Parses the given DOM context for Slim croppers.
var croppers = Slim.parse(context);
Finds a previously initialised cropper by element.
var cropper = Slim.find(context);
Creates a cropper on the given element.
var cropper = Slim.create(element, options);
Destroys cropper attached to element
var success = Slim.destroy(element);
Create a new Slim Cropper.
var $cropper = $('#my-cropper').slim();
Test if Slim is bound to given element.
var state = $(selector).slim('isAttachedTo', element);
Test if Slim is still bound to DOM.
var state = $(selector).slim('isDetached');
Upload an image by url or data-uri.
// basic implementation
$(selector).slim('load', src);
// if you need to know when the image has loaded, pass a function
// as the second parameter
$(selector).slim('load', src, function(error, data) {
// image load done!
});
// you can also pass an options object
// this options object also accepts a rotation and crop parameter
// these options reflect the functionality of the rotation and
// crop options on the slim options object
$(selector).slim('load', src, { rotation:90, crop: {} }, function(error, data) {
// image load done!
});
// if 'push' is set to true, you can pass the blockPush
// property to prevent immediate upload on image load
$(selector).slim('load', src, { blockPush:true }, function(error, data) {
// image load done!
});
Upload currently loaded image
$(selector).slim('upload', function(error, data, response) {
// upload done!
});
Download currently loaded image as file
$(selector).slim('download');
Remove currently loaded image
$(selector).slim('remove');
Destroy the cropper
$(selector).slim('destroy');
Get current data object
$(selector).slim('data');
// format of data object
{
// server response object after async upload
server: null,
// meta data set with data-meta-*
meta: {},
// the source file
input:{
// input field id
field: null,
// name of file
name: null,
// mime type of image
type: null,
// file loaded
file: null,
// file size in bytes
size: null,
// image base64 data or canvas
image: null,
// original dimensions of image
width: 0,
height: 0
},
// the result of the crop
output:{
// name of file
name: null,
// mime type of image
type: null,
// image base64 data or canvas
image: null,
// output image dimensions
width: 0,
height: 0
},
// user actions
actions:{
// angle of rotation in degrees
rotation: null,
// crop coordinates and type
crop: {
// coordinates
x: 0,
y: 0,
width: 0,
height: 0,
// type of crop
// - 'auto'
// - 'initial'
// - 'manual'
type: null
},
// output size
size: {
width: 0,
height: 0
},
// applied filters
filters: {
sharpen: 0
}
}
}
Get current data object in base64 format
$(selector).slim('dataBase64');
Get root element
$(selector).slim('element');
Do manual crop, please keep in mind that this method does not check if the input matches the required ratio or image size.
$(selector).slim('crop', {x:0, y:0, width:100, height:100}, function(result) {
// crop done!
});
Open the editor
$(selector).slim('edit');
Set new output size
// only set the size
$(selector).slim('size', { width:640, height:480 });
// directly apply, callback method is called on completion
$(selector).slim('setSize', { width:640, height:480 }, function(data) {
});
Set new ratio
// only set a new ratio
$(selector).slim('ratio', '3:2');
// directly apply the ratio
$(selector).slim('setRatio', '3:2', function(data) {
});
Set new ratio
// only set a new rotation
$(selector).slim('rotation', 90);
// directly apply the rotation
$(selector).slim('setRotation', 90, function(data) {
});
Summary of Static API methods
Tests if slims can be used on this browser.
var supported = $().slim('supported');
Parses the given DOM context for Slim croppers.
// Return value is not croppers but nodes parsed as
// it's possible to supply multiple nodes using a
// single selector.
var $elements = $(selector).slim('parse');
Creates a cropper on the given element.
var cropper = $(selector).slim(options);
Destroys cropper attached to element
var success = $(selector).slim('destroy');
PHP API
Slim ships with a static PHP Class which you can use to access the posted data.
Use the getImages()
method to quickly get the posted image(s).
$images = Slim::getImages();
If you've setup to use a different name than "slim" pass it along.
$images = Slim::getImages('myFieldName');
If only one image was posted it can be found at index 0
.
As the default slim field name ("Slim[]") allows to upload multiple images under the same name the PHP script assumes it receives an array of images.
$images = Slim::getImages();
$image = $images[0];
Store the image on your server with the saveFile()
method (ready to use examples of this are included in the package). All the information of the original image can be accessed through the image object returned by the getImages()
method.
// let's create some shortcuts
$name = $image['output']['name'];
$data = $image['output']['data'];
// store the file
$file = Slim::saveFile($data, $name);
By default the saveFile method stores the image in the "tmp" folder. If you want to store images in a different folder you can pass the folder name along as the third parameter to the store method.
$file = Slim::saveFile($data, $name, 'myFolder/');
The saveFile()
method returns a file object. This object contains the name of the file and the file path. The name of the file will be different from the name of the image as the original image name is prepended with a unique id before saving.
$file = Slim::saveFile($data, $name);
echo $file['name'];
// 573f60ddd630f_imagename.jpg
echo $file['path'];
// tmp/573f60ddd630f_imagename.jpg
If you don't want a unique id call the saveFile()
method like shown below.
$file = Slim::saveFile($data, $name, 'myFolder/', false);
Sending Additional Data to the Server
If you want to add custom data to the Slim object you have to use the meta
property. The Slim.php script will clean up the data sent to the server but will leave the meta
property alone.
Using the data-meta
attribute (or option property) you can set static values in String format only. For example setting data-meta-user-id
to 1234
wil result in the following additional object being sent to the server.
{
"meta":{
"userId":"1234"
}
}
You can now access the metadata on the server as you would any other object, see the code snippet below.
// get the image data
$images = Slim::getImages();
$image = $images[0];
// print metadata
echo $image['meta']->userId; // "1234"
If you need to add metadata in a certain format (say Number or Boolean) you can add it in the willSave phase. See the example below where we send a timestamp to the server in Number format.
By submitting the form below you can view the metadata in the table rendered by the post.php
page.
<script>
function addTime(data, ready) {
// add additional data
data.meta.now = Date.now();
// continue saving the data
ready(data);
}
</script>
<form action="post.php" method="post" enctype="multipart/form-data">
<div class="slim"
data-meta-user-id="1234"
data-ratio="16:9"
data-size="600,300"
data-will-save="addTime">
<input type="file" name="slim[]">
</div>
<button type="submit">Send!</button>
</form>
Form Post or AJAX Upload
If you're planning to send the cropped data to your server using AJAX, add the data-service
attribute and supply it with the url to the API endpoint.
If you don't set the data-service
attribute Slim will store the data in a automatically created hidden input field named "slim[]". If you add a hidden input field yourself, Slim will use that field. When using AJAX Slim will store the server response in the hidden input field so after a form submit you know which file was uploaded last.
You can change the default name of the automatically created input using the defaultInputName
property or the data-default-input-name
attribute.
In both situations Slim will prevent the original file input from posting so data is not sent to the server twice.
Look 'n Feel
A large part of Slim can be restyled with basic CSS rules.
Rounded Corners
By default the Slim landing areas do not have rounded corners. Adding the following CSS rule will make them nice and round immidiately.
.slim {
border-radius: 0.5rem;
}
Create a circular drop area with the following snippet.
.slim {
border-radius: 50%;
}
Square Buttons
If circular buttons are not your thing, you can turn the Slim edit buttons into squares using the following snippet.
.slim-btn {
border-radius: 0;
}
Show Buttons on Hover
If you only want to show buttons when the mouse hovers over the drop area.
.slim .slim-btn-group {
opacity:0;
transition:.25s opacity;
}
.slim:hover .slim-btn-group {
opacity:1;
}
White Overlay
The default overlay is dark, you can turn it around to the bright side using the following CSS snippet.
.slim-popover {
background-color: #efefef;
}
.slim-image-editor-btn {
color:#999;
}
.slim-image-editor-btn:focus,
.slim-image-editor-btn:hover {
color:#777;
}
.slim-image-editor-preview::after {
background-color: rgba(0, 0, 0, 0.25);
}
FontAwesome Icons
By default Slim features SVG icons. If you want to use an icon font use the following snippet.
This example replaces the icon of the edit button with the Font Awesome Cog icon.
<div class="slim"
data-button-edit-label="<i class='fa fa-cog'></i>"
data-button-edit-title="Edit">
...
</div>
We have to hide the original icon and restore the font-size.
.slim-btn {
font-size: 1em;
background-image: none;
}
Text Buttons
If icons are just not your thing, hide the icons with the following CSS snippet.
.slim-btn {
width:auto;
font-size:1em;
padding: 0 1em;
border-radius: 1em;
background-image: none;
}
White Buttons
The default buttons are black with a white icon. You can quickly make this white with a black icon by using the invert filter.
.slim-btn {
filter: invert(100%);
}
Note that this does not work on Internet Explorer 11 and below.
React, Angular 'n Vue
Slim ships with React, Angular 1.x, Angular, and Vue wrappers. These wrappers function as a basic gateway with the single purpose of binding Slim to the supplied node and handling callbacks.
React
React has a custom component syntax. We use the Slim element instead of a class and instead of the data attributes we pass the JavaScript options directly like shown in the example below.
import React, { Component } from 'react';
import Slim from './slim/slim.react';
class App extends Component {
// called when slim has initialized
slimInit(data, slim) {
// slim instance reference
console.log(slim);
// current slim data object and slim reference
console.log(data);
}
// called when upload button is pressed or automatically if push is enabled
slimService(formdata, progress, success, failure, slim) {
// slim instance reference
console.log(slim)
// form data to post to server
// set serviceFormat to "file" to receive an array of files
console.log(formdata)
// call these methods to handle upload state
console.log(progress, success, failure)
}
render() {
return (
<div className="App">
<Slim ratio="1:1"
initialImage="test.jpg"
minSize={ { width:600, height:400 } }
service={ this.slimService.bind(this) }
didInit={ this.slimInit.bind(this) }>
<input type="file" name="foo"/>
</Slim>
</div>
);
}
}
Angular 1.x
The Slim directive binds on the "slim"
tag, you can add the exact same HTML attributes as in the other code examples.
<div ng-app="myApp" ng-controller="AppController">
<slim data-size="200,200"
data-download="true"
data-initial-image="test.jpg"
data-service="slim.service"
data-did-init="slim.init">
<input type="file" name="slim[]"/>
</slim>
</div>
An example controller with callback method.
(function(angular){
var app;
app = angular.module('myApp', ['slim']);
app.controller('AppController', function($scope) {
$scope.slim = {
// called when slim has initialized
init: function (data, slim) {
// slim instance reference
console.log(slim);
// current slim data object and slim reference
console.log(data);
},
// called when upload button is pressed or automatically if push is enabled
service: function (formdata, progress, success, failure, slim) {
// form data to post to server
// set data-service-format to "file" to receive an array of files
console.log(formdata);
// call these methods to handle upload state
console.log(progress, success, failure);
// reference to Slim instance
console.log(slim);
}
}
});
}(angular));
Angular
Angular is a tiny bit different. Options are passed to the Slim module as an object.
This code is compatible with Angular 2 and up.
When using Angular CLI you'll have to make some changes to the configuration files.
add to /tconfig.js
"allowJs": true,
"allowUnreachableCode": true,
add to /.angular-cli.json "styles" array
"app/slim/slim.css"
For Angular version 7 and lower:
You need the slim.angular2.ts
file and the slim.commonjs.js
file.
/**
* app.module.ts
*/
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { Slim } from './slim/slim.angular2'; // import from slim.angular2 file
@NgModule({
imports: [ BrowserModule ],
declarations: [ AppComponent, Slim ], // add declaration
bootstrap: [ AppComponent ]
})
export class AppModule { }
For Angular version 8 and up:
You need the slim.angular.component.ts
, slim.angular.module.ts
and the slim.commonjs.js
file.
/**
* app.module.ts
*/
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { SlimModule } from './slim/slim.module'; // import from slim.module file
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, SlimModule], // add imports
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Usage is the same for all modern Angular versions.
/**
* app.component.ts
*/
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `
<slim [options]="slimOptions">
<input type="file" name="foo">
</slim>
`
})
export class AppComponent {
slimOptions = {
ratio: '1:1',
download: true,
initialImage: './test.jpg',
service: this.slimService.bind(this),
didInit: this.slimInit.bind(this)
};
// called when slim has initialized
slimInit(data:any, slim:any) {
// slim instance reference
console.log(slim);
// current slim data object and slim reference
console.log(data);
};
// called when upload button is pressed or automatically if push is enabled
slimService(formdata:any, progress:any, success:any, failure:any, slim:any) {
// form data to post to server
// set serviceFormat to "file" to receive an array of files
console.log(formdata);
// call these methods to handle upload state
console.log(progress, success, failure);
// reference to Slim instance
console.log(slim);
};
}
Vue
Options are passed to the Slim module as an object and we use the `slim-cropper` tag.
<template>
<div>
<slim-cropper :options="slimOptions">
<input type="file" name="slim"/>
</slim-cropper>
</div>
</template>
<script>
import Slim from './slim/slim.vue'
// called when slim has initialized
function slimInit (data, slim) {
// slim instance reference
console.log(slim)
// current slim data object and slim reference
console.log(data)
}
// called when upload button is pressed or automatically if push is enabled
function slimService (formdata, progress, success, failure, slim) {
// slim instance reference
console.log(slim)
// form data to post to server
// set serviceFormat to "file" to receive an array of files
console.log(formdata)
// call these methods to handle upload state
console.log(progress, success, failure)
}
export default {
name: 'hello',
components: {
'slim-cropper': Slim
},
data () {
return {
slimOptions: {
ratio: '1:1',
initialImage: require('../assets/test.jpg'),
service: slimService,
didInit: slimInit
}
}
}
}
</script>
Bootrap 'n Foundation
A snippet showing how to use Slim with Bootstrap.
<form>
<fieldset class="form-group">
<label for="email">E-mail</label>
<input type="email" class="form-control" id="email">
</fieldset>
<fieldset class="form-group">
<label for="avatar">Avatar</label>
<input type="file"
class="form-control slim"
data-ratio="1:1"
id="avatar">
</fieldset>
</form>
An example of Slim being used in a Foundation form.
<form>
<label>E-mail
<input type="email">
</label>
<label>Avatar
<input type="file" class="slim" data-ratio="1:1">
</label>
</form>
Feature Summary
- Beautiful Animations
- Correctly handles Device Orientation
- Very Fast
- Includes PHP sample files for both sync and async posting
- Compatible with both Bootstrap and Foundation
- Easy to Configure
- High Quality User Experience
- Edit Server Images
- Responsive
- Vanilla JavaScript and jQuery
- Contains wrappers for Angular, React and Vue
Slim image cropper is no longer available for purchase and has been discontinued in favour of Pintura image editor.