Slim Image Cropper

Five star rating4.9 out of 5 stars based on 86 reviews

Price
$15
Includes
  • future updates
  • 6 months professional support

Slim Image Cropper is a cross platform JavaScript Image Cropping and Uploading plugin. It's easy to setup and features beautiful graphics and animations.

Your users will be cropping and rotating images in no time.

Feature overview:

Works standalone but ships with handy wrappers for jQuery, React, Angular (one and two), Bootstrap and Foundation.

Buy Slim Image Cropper Now

What Our Customers Say...

One of the best downloads I ever made on CodeCanyon. 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.
Read more testimonials here

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-service="async.php"
     data-ratio="16:9"
     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-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-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 "16:10", "16:9", "5:3", "5:4", "4:3", "3:2" and "1:1"

Custom ratios can also be set, Slim will calculate the correct container size automatically. e.g. "14:2"

Set to "free" to allow the user to pick their own crop size.

Set the value to "input" to force the input image ratio.

The default value is "free"

<div class="slim"
     data-ratio="1:1">
    <img src="/media/sea.jpg" alt=""/>
</div>
data-size

Determine the target size of the resulting image.

For example "320,320" will scale down the image to fit within those dimensions. The aspect ratio of the image will be respected.

By default Slim does not resize the output image.

data-min-size

Determine minimum size of the crop in pixels

For example "900,400" will make sure the cropped image is at least 900 pixels by 400 pixels big.

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 "320,320" will scale the image to fit those dimensions.

Force size will also set the aspect ratio to fit the supplied size, so with force-size set to "320,320" this would be "1:1".

By default Slim does not resize the output image.

<div class="slim"
     data-min-size="900,400">
    <img src="/media/dune.jpg" alt=""/>
</div>
data-service

When set, the cropped image will be sent to the set URL using AJAX. Slim contains an example upload PHP file which is also used on this website.

An upload button will appear unless the data-push property is set to "true".

The server can optionally return a JSON response to indicate a successful upload.

{
    "status":"success",
    "name":"uid_filename.jpg",
    "path":"path/uid_filename.jpg"
}

By default the image information is posted to the server without AJAX.

<div class="slim"
     data-size="640,640"
     data-service="async.php">
    <input type="file" name="slim[]"/>
</div>
data-meta-*

Use this attribute to send additional data to the server.

For example setting data-meta-user-id to "1234" wil send along that user id to the server which can then be accessed on the image object as shown below.

// get the image data
$images = Slim::getImages();
$image = $images[0];

// print metadata
echo $image['meta']->userId; // "1234"

See Sending Additional data to the server for more information.

data-push

When set to "true" will hide the upload button and will automatically upload cropped images to the server.

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 "input, output, actions".

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-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 "true" Slim will save the initially loaded image to the hidden input.

Default is "false"

data-download

When set to "true" shows a button to download the cropped image.

Default is "false"

<div class="slim"
     data-download="true">
    <img src="/media/sea.jpg" alt="">
</div>
data-edit

When set to "false" will disable the edit button, effectively turning Slim into an auto cropping upload tool.

Default is "true"

data-instant-edit

When set to "true" will open the editor immidiately on file drop or load.

Default is "false"

data-crop

Pass initial crop coordinates. The format is a comma separated list of coordinates (x, y, width, height).

Setting "0,0,100,100" will crop a 100 pixel square starting from the top left corner.

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-label

The label shown in the drop area.

"Drop your image here"

<div class="slim"
     data-label="Files please...">
    <input type="file" name="slim[]">
</div>
data-button-*-label

Replace the star with edit, remove, download, upload, cancel or confirm to set the label for the related button.

For example data-button-edit-label.

Note that the label is only shown on the cancel and confirm buttons in the image editor popup. The other buttons feature an icon.

data-button-*-title

Replace the star with edit, remove, download, upload, rotate, cancel or confirm to set the title for the related button.

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 3.5 would limit the images to 3.5 megabytes. Keep in mind that you'll also have to configure your server to accept certain file sizes.

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 $0 will be replaced by Slim with the value of the data-max-file-size attribute.

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 accept attribute on the input element. If it's not set, all generally supported image types are allowed (jpeg, png, gif and bmp).

<input type="file" accept="image/jpeg">

You can also supply multiple mime types by comma separating them: "image/jpeg, image/png"

The default text is as follows: "Invalid file type, expects: $0."

The $0 is replaced with the extensions of the mime types set in the accept property.

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.

  • Firefox
  • Chrome
  • Opera
  • Internet Explorer 10+
  • Safari OSX & iOS (Safari on Windows is no longer supported by Apple)
  • Android (Not all Android devices behave the same, should work on most modern Android devices)

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 data-min-size.

"Image is too small, minimum size is: $0 pixels."

The $0 is replaced with the size defined in the data-min-size attribute.

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.

function slimInitialised(data) {
    console.log(data);
}
<div class="slim"
     data-did-init="slimInitialised">
    <input type="file" name="slim[]"/>
</div>
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.

return true All is fine, and Slim continues with this image.

return 'error message' All is not fine, Slim will halt and display the given error message.

return false All is not fine, the image will not be loaded but Slim will not throw an error.

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.

<div class="slim"
     data-service="async.php"
     data-size="500,500"
     data-did-load="isHotEnough">
    <input type="file" name="slim[]">
</div>

<script>
function isHotEnough(file, image, meta) {

    // average image color
    var averageColor = averagePixelColor(image);

    // color to HSL
    var color = rgbToHsl(averageColor);

    // does the hue part fall in the warm range
    // and is the image not too dark or bright
    if ((color.h > 300 || color.h < 60) &&
            (color.l > 10 && color.l < 90)) {
        return true;
    }

    return 'This image is just not hot enough.';
}
</script>
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-transform

A callback method that gets called after each image transform.

Slim sends the following two parameters along: data and ready. The data parameter contains the current crop state. The ready parameter is a function that when called will let Slim continue working with the given data.

When calling the ready method you need to pass the altered (or original) crop state object along like this ready(data).

You could for example use this method to add watermarks to images, like shown in the demo below.

<div class="slim"
     data-service="async.php"
     data-size="500,500"
     data-will-transform="addWatermark">
    <input type="file" name="slim[]">
</div>

<script>
function addWatermark(data, ready) {

    // get the drawing context for the output image
    var ctx = data.output.image.getContext('2d');

    // draw our watermark on the center of the image
    var size = data.output.width / 20
    ctx.font = size + 'px sans-serif';

    var x = data.output.width * .5;
    var y = data.output.height * .5;
    var text = ctx.measureText('Slim is Awesome');
    var w = text.width * 1.15;
    var h = size * 1.75;

    ctx.fillStyle = 'rgba(0,0,0,.75)';
    ctx.fillRect(
        x - (w * .5),
        y - (h * .5),
        w, h
    );
    ctx.fillStyle = 'rgba(255,255,255,.9)';
    ctx.fillText(
        'Slim is Awesome',
        x - (text.width * .5),
        y + (size * .35)
    );

    // continue saving the data
    ready(data);

}
</script>
data-will-save

Similar to the data-will-transform attribute, but data-will-save is only used just before saving the crop information and does not contain the original canvas elements but instead contains base64 formatted information.

Keep in mind that, as with the data-will-transform function, this function also relies on you calling the ready callback and returning the crop state object to Slim.

When adding custom properties to the crop state object, make sure they are all contained in a parent property called meta as other properties will be cleaned up by the Slim PHP script.

data-did-save

Called after the current crop object was saved. Receives the crop state object as it's only parameter.

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 error parameter contains the error information returned from the server. If the request is successful the response parameter contains the server response (if the server returned a JSON string this will be a JSON object).

function imageUpload(error, data, response) {
    console.log(error, data, response);
}
<div class="slim"
     data-did-upload="imageUpload">
    <input type="file" name="slim[]"/>
</div>
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.

function imageWillBeRemoved(slim, remove) {
    if (window.confirm("Are you sure?")) {
        remove();
    }
}

This method will not be called when the API remove() method is used.

data-will-request

A callback method that can be used to add additional request headers to the XMLHttpRequest object. The method will be called each time Slim fires an XMLHttpRequest.

<div class="slim"
     data-service="async.php"
     data-size="400,300"
     data-will-request="handleRequest">
    <input type="file" name="slim[]">
</div>

<script>
function handleRequest(xhr) {
    xhr.setRequestHeader('X-Custom-Header', 'Some value');
}
</script>
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.

function imageRemoved(data) {
    console.log(data);
}
<div class="slim"
     data-did-remove="imageRemoved">
    <input type="file" name="slim[]"/>
</div>

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.

Replace the * in the button properties with one of the following buttons to alter it's properties.

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.

cropper.load(src, options, function(error, data) {
// image load done!
});

Upload currently loaded image

cropper.upload(function(error, response) {
// upload done!
});

Download currently loaded image as file

cropper.download();

Remove currently loaded image

var data = cropper.remove();

Destroy the cropper

cropper.destroy();

Get current data object

var data = cropper.data;

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};

Set new ratio

cropper.ratio = '3:2';

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.

$(selector).slim('load', src, options, function(error, data) {
// image load done!
});

Upload currently loaded image

$(selector).slim('upload', function(error, 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');

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

$(selector).slim('size', {width:640, height:480});

Set new ratio

$(selector).slim('ratio', '3:2');

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;
}

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 'n Angular

Slim ships with React, Angular and Angular 2 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 from 'react';
import ReactDOM from 'react-dom';
import Slim from './slim/slim.react.jsx';

class App extends React.Component {

slimDidInit(data) {
    console.log(data);
}

render() {
    return (
        <div>
            <Slim ratio="1:1"
                  download={ true }
                  didInit={ this.slimDidInit.bind(this) }>
                <img src="stars.jpg" alt=""/>
                <input type="file" name="foo"/>
            </Slim>
        </div>
    );
    }
}

Angular 1.x

The Slim directive binds on the "slim" class name so you can write the exact same HTML as in the other code examples.

<div ng-app="myApp" ng-controller="AppController">

    <div class="slim" data-ratio="1:1" data-download="true" data-did-init="slimDidInit">
        <img src="stars.jpg" alt="">
        <input type="file" name="slim[]">
    </div>

</div>

An example controller with callback method.

var app;
app = angular.module('myApp',['slim']);
app.controller('AppController', function ($rootScope, $scope) {

    $scope.slimDidInit = function(data) {
        console.log(data);
    }

});

Angular 2

Angular 2 is a bit different. Options are passed to the Slim module as an object.

import { NgModule, Component } from '@angular/core';
import { Slim } from './slim/slim.angular2';

@Component({
    selector: 'my-app',
    template: `
        <div>
            <h3>Hello</h3>
            <slim [options]="slimOptions">
                <img src="test.jpg" alt="">
                <input type="file" name="foo">
            </slim>
        </div>
        `
})

@NgModule({
    imports: [ Slim ],
    declarations: [ Slim ],
    bootstrap: [ AppComponent ]
})

export class AppComponent {

    slimOptions = {
        ratio: '1:1',
        download: true,
        didInit: this.slimHandleInit
    };

    slimHandleInit(data) {
        console.log(data);
    };

}

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 and React

What are you waiting for? Buy Slim Now!