At example uses Bootstrap. You cannot use it at your projects.

Extension can be uses without Bootstrap.

js-cropbox

A lightweight and simple js extension to crop your image.

GitHub page Integration with Yii2

Browse

Result of cropping

Info of cropping

Source code of example

JS

var cropbox = new Cropbox('#plugin', {
    variants: [
        {
            width: 200,
            height: 200,
            minWidth: 180,
            minHeight: 200,
            maxWidth: 350,
            maxHeight: 350
        },
        {
            width: 150,
            height: 200
        }
    ]
});
// scaling
var scaleInBtn = document.querySelector('.btn-scale-in');
scaleInBtn.addEventListener('click', function(){
    cropbox.scale(1.05);
});
var scaleOutBtn = document.querySelector('.btn-scale-out');
scaleOutBtn.addEventListener('click', function(){
    cropbox.scale(0.95);
});
cropbox.getMembrane().addEventListener('wheel', function(event){
    if (event.deltaY < 0) {
        cropbox.scale(1.01);
    } else {
        cropbox.scale(0.99);
    }
    event.preventDefault();
});
// image loading from a file
var fileInput = document.querySelector('input[type="file"]'),
    startBtn = document.querySelector('.btn-start');
startBtn.addEventListener('click', function(){
    var fileReader = new FileReader();
    fileReader.readAsDataURL(fileInput.files[0]);
    fileReader.addEventListener('load', function(event){
        cropbox.load(event.target.result);
    });
});
// reset
var resetBtn = document.querySelector('.btn-reset');
resetBtn.addEventListener('click', function(){
    cropbox.reset();
});
// crop
var cropBtn = document.querySelector('.btn-crop');
cropBtn.addEventListener('click', function(){
    cropbox.crop();
});
// the cropped event
cropbox.getCb().addEventListener('cb:cropped', function(event){
    // add image to the container
    var img = document.createElement('img');
    img.src = event.detail.data.image;
    img.setAttribute('style', 'margin-right: 5px; margin-bottom: 5px');
    img.className = 'img-thumbnail';
    document.querySelector('#cropped-container .panel-body').appendChild(img);
    // update inforamtion about crop
    document.querySelector('#data').value = JSON.stringify(cropbox.getData());
});
// the reset event
function resetHandler(){
    // clear the container
    document.querySelector('#cropped-container .panel-body').innerHTML = '';
    // clear information about crop
    document.querySelector('#data').value = '';
};
cropbox.getCb().addEventListener('cb:reset', resetHandler);
// the ready event
cropbox.getCb().addEventListener('cb:ready', resetHandler);
// the disabled/enabled event
function disabledHandler(){
    scaleInBtn.setAttribute('disabled', 'disabled');
    scaleOutBtn.setAttribute('disabled', 'disabled');
    cropBtn.setAttribute('disabled', 'disabled');
};
disabledHandler();
cropbox.getCb().addEventListener('cb:disabledCtrls', disabledHandler);
cropbox.getCb().addEventListener('cb:enabledCtrls', function(){
    scaleInBtn.removeAttribute('disabled');
    scaleOutBtn.removeAttribute('disabled');
    cropBtn.removeAttribute('disabled');
});

HTML

<div id="plugin"></div>
<div class="form-inline">
    <div class="form-group">
        <div class="btn-group">
            <span class="btn btn-info btn-file">
                <i class="glyphicon glyphicon-folder-open"></i>
                Browse <input type="file" accept="image/*">
            </span>
            <button type="button" class="btn btn-primary btn-start">
                <i class="glyphicon glyphicon-play"></i> Start
            </button>
        </div>
    </div>
    <div class="form-group">
        <div class="btn-group">
            <button type="button" class="btn btn-success btn-crop">
                <i class="glyphicon glyphicon-scissors"></i> Crop
            </button>
            <button type="button" class="btn btn-warning btn-reset">
                <i class="glyphicon glyphicon-repeat"></i> Reset
            </button>
            <button type="button" class="btn btn-default btn-scale-out">
                <i class="glyphicon glyphicon-minus"></i>
            </button>
            <button type="button" class="btn btn-default btn-scale-in">
                <i class="glyphicon glyphicon-plus"></i>
            </button>
        </div>
    </div>
</div>
<br>
<div id="cropped-container" class="panel panel-success">
    <div class="panel-heading"><h3 class="panel-title">Result of cropping</h3></div>
    <div class="panel-body"></div>
</div>
<div class="panel panel-info">
    <div class="panel-heading"><h3 class="panel-title">Info of cropping</h3></div>
    <div class="panel-body">
        <textarea id="data" class="form-control" rows="5"></textarea>
    </div>
</div>

CSS

.btn-file {
    position: relative;
    overflow: hidden;
}
.btn-file input[type=file] {
    position: absolute;
    top: 0;
    right: 0;
    min-width: 100%;
    min-height: 100%;
    font-size: 100px;
    text-align: right;
    filter: alpha(opacity=0);
    opacity: 0;
    outline: none;
    background: white;
    cursor: inherit;
    display: block;
}
#plugin .workarea-cropbox,
#plugin .bg-cropbox {
    height: 500px;
    min-height: 500px;
    width: 500px;
    min-width: 500px;
}