Scale Image and Reposition on Canvas element

Scale image and reposition on canvas element after you select a file with this element.

<input type="file" />  

The HTML

<label class="profileAvatar">  
    <input id="profileAvatar-inputFile" type="file" class="profileAvatar-input" placeholder="Upload je profielfoto" />
    <div class="profileAvatar-wrap u-center">
        <div class="profileAvatar-placeholder"><div class="fa fa-cloud-upload"></div><div>Upload je profielfoto</div></div>
    </div>
    <canvas class="profileAvatar-canvas" id="profileAvatar-canvas" width="280" height="160"></canvas>
    <img class="profileAvatar-image u-center" id="profileAvatar-image" alt="Profielfoto" />
    <button class="profileAvatar-button" id="profileAvatar-button"><i class="fa fa-times"></i></button>
</label>  

The CSS

.profileAvatar {
    display: block;
    position: relative;
    cursor: pointer;

    width: 280px;
    height: 160px;
    background-color: black;

    color: rgb(179,179,179);
}
.profileAvatar-input {
    display: block;

    width: 280px;
    height: 160px;

    background-color: rgb(230,230,230);

}
.profileAvatar-input::-webkit-file-upload-button {
    display: none;

    -webkit-appearance: none;

    border: none;
    width: 280px;
    height: 160px;
}

.profileAvatar-wrap {

}
.profileAvatar-placeholder {

    text-align: center;
    text-transform: lowercase;
    font-variant: small-caps;
    font-weight: 300;
    white-space: nowrap;

}
.profileAvatar-placeholder .fa {
    display: block;
    font-size: 6rem;
}

.profileAvatar-canvas {
    position: absolute;
    top:0;
    bottom: 0;
    left: 0;
    right: 0;
}
.profileAvatar-image {
    display: block;
    position: absolute;
    max-width: 100%;
    max-height: 100%;
}
.profileAvatar-image:not([src]) {
    display: none;
}
.profileAvatar-button {
    display: block;
    right: 4px;
    top: 4px;

    border: none;
    position: absolute;

    width:40px;
    height: 40px;
    background-color: rgba(255,255,255,.5);
    border-radius: 4px;
}
.profileAvatar-button:hover {
    background-color: grey;
    color:white;
}
.u-center {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
}

jQuery and Javascript

<script src="//code.jquery.com/jquery-2.1.1.min.js"></script>  
<script>  
(function ($) {
    var img_url = 'http://www.celebritiesontop.com/wp-content/uploads/2013/09/Doutzen-Kroes-021.jpg';

    var loadImageToCanvasEl,
        loadImageToImageEl,
        resetImage,
        reader,
        canvasImage,
        clearCanvas;

    var avatar_file = $('#profileAvatar-inputFile'),
        avatar_image = $('#profileAvatar-image'),
        avatar_button = $('#profileAvatar-button'),
        avatar_canvas = $('#profileAvatar-canvas');


    loadImageToCanvasEl = function (data) {
        canvasImage.src = data;
    };
    loadImageToImageEl = function (data) {
        avatar_image.attr('src', data);
    };
    resetImage = function () {
        avatar_file.value = "";
        avatar_image.attr('src', null);
        clearCanvas();
    };

    // FileReader
    reader = new FileReader();
    reader.onload = function (event) {
        var data = event.target.result;

        // loadImageToImageEl(data);
        loadImageToCanvasEl(data);
    };

    // Image
    canvasImage = new Image();
    canvasImage.onload = function (event) {
        console.log('imageOnLoad');

        var canvasElement = avatar_canvas[0],
            context = canvasElement.getContext('2d');

        var originalWidth = this.width,
            originalHeight = this.height,
            canvasWidth = avatar_canvas.width(),
            canvasHeight = avatar_canvas.height();

        var canvasDimension = canvasWidth/canvasHeight,
            originalDimension = originalWidth/originalHeight;

        var isHorizontal = (canvasDimension < originalDimension),
            isVertical = (canvasDimension > originalDimension),
            isEqual = (canvasDimension == originalDimension);

        var scaleRatio = 0, cX, cY, cWidth, cHeight;

        // Borderless Math
        if (isHorizontal) {
            // treat as HORIZONTAL
            console.log(["HORIZONTAL", canvasDimension, originalDimension]);
            scaleRatio = originalHeight/canvasHeight,
            cWidth = originalWidth/scaleRatio,
            cHeight = originalHeight/scaleRatio,
            cX = (cWidth-canvasWidth)*-.5,
            cY = 0;
        } else if (isVertical) {
            // treat as VERTICAL
            console.log(["VERTICAL", canvasDimension, originalDimension]);
            scaleRatio = originalWidth/canvasWidth,
            cWidth = originalWidth/scaleRatio,
            cHeight = originalHeight/scaleRatio,
            cX = 0,
            cY = (cHeight-canvasHeight)*-.5;
        } else {
            // treat everything EQUAL
            scaleRatio = originalWidth/canvasWidth,
            cWidth = originalWidth/scaleRatio,
            cHeight = originalHeight/scaleRatio,
            cX = 0,
            cY = 0;
        }

        clearCanvas();
        context.drawImage(canvasImage, cX, cY, cWidth, cHeight);
    }

    clearCanvas = function () {
        var canvas = avatar_canvas[0];
        canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height);
    }


    // element: input
    avatar_file.change(function(event){
        var files = event.target.files,
            file = files[0];

        // set value to empty string if the filetype is not an image
        if (file.type.match('image.*')) {
            //Read in the image file as a data URL.
            reader.readAsDataURL(file);
        } else {
            this.value = "";
        }
    });

    // element: button
    avatar_button.click(function (event) {
        event.preventDefault();
        resetImage();
    })

    canvasImage.src = img_url;
})(jQuery);
</script>  
comments powered by Disqus