Поворот изображения по степени и кадрированию - PullRequest
3 голосов
/ 17 апреля 2020

Я пытаюсь повернуть изображение по степени и обрезать его часть, а затем показать на холсте, но изображение обрезается больше, чем я. Я использую это https://github.com/BossBele/cropzee

Давайте посмотрим фрагмент (на полной странице) и попробуем загрузить изображение, которое будет вращаться и обрезаться. Результат не связан с модальным.

image

/*!
   light-modal v1.1.0: A new lightweight css modal.
   (c) 2017 
   MIT License
   git+https://github.com/hunzaboy/Light-Modal.git
*/
.button {
  display: block;
  cursor: pointer;
  padding: 10px 20px;
  margin: 10px 0;
  background: #4C7CC4;
  clear: both;
  color: #FFF;
}
.light-modal {
    display: none;
    position: fixed;
    background: transparent;
    top: 0;
    bottom: 0;
    left: 0;
    -ms-flex-align: center;
    align-items: center;
    -ms-flex-pack: center;
    justify-content: center;
    right: 0;
    z-index: 9000;
    transition: background 1s;
    font-size: 16px;
    visibility: hidden;
}

.light-modal-content {
    background: #fff;
    color: #fff;
    width: 30vw;
    border-radius: .2em;
    position: relative;
    max-height: calc(100vh - 150px);
    line-height: 1.4;
    display: -ms-flexbox;
    display: flex;
    -ms-flex-direction: column;
    flex-direction: column;
min-height: 200px;
}

.light-modal-content img {
    max-width: 100%;
    border-radius: .2em;
}

.light-modal-content.large-content {
    width: 50vw;
}

.light-modal-header {
    padding: 20px 20px 20px 20px;
    background: rgba(0, 0, 0, 0.2);
    display: -ms-flexbox;
    display: flex;
    -ms-flex-pack: justify;
    justify-content: space-between;
    -ms-flex-align: center;
    align-items: center;
}

.light-modal-heading {
    margin: 0;
    font-size: 1.5em;
}

.light-modal-heading + .light-modal-close-icon {
    position: static;
}

.light-modal-body {
    padding: 20px;
    overflow: auto;
    max-height: 450px;
}

.light-modal-footer {
    position: relative;
    padding: 20px 20px 20px 20px;
    text-align: right;
    display: -ms-flexbox;
    display: flex;
    -ms-flex-align: center;
    align-items: center;
}

.light-modal-footer .image-rotate-value {
    position: absolute;
    border: 0;
    text-align: center;
    top: 0;
    width: calc(100% - 40px);
}

.light-modal-footer .image-rotate {
    margin: 0 10px;
}

.light-modal-close-icon, .light-modal-close-btn {
    text-decoration: none;
    color: #fff;
    padding: 5px 10px;
    border-radius: .2em;
    background: #4C7CC4;
    font-size: 1.5em;
    line-height: 1;
    transition: background .2s ease-in-out;
}

.light-modal-close-icon:hover, .light-modal-close-btn:hover {
    background: #46BF46;
}

.light-modal-close-icon {
    position: absolute;
    top: -15px;
    right: -15px;
}

.light-modal-close-btn {
    font-size: 1em;
}

.light-modal-caption {
    position: absolute;
    left: 50%;
    -ms-transform: translateX(-50%);
    transform: translateX(-50%);
    top: 100%;
    padding: 10px 0;
    background: rgba(0, 0, 0, 0.2);
    border-radius: .2em;
    width: 100%;
    text-align: center;
    margin-top: 5px;
}

.light-modal:target {
    background: rgba(0, 0, 0, 0.5);
    display: -ms-flexbox;
    display: flex;
    visibility: visible;
}

.light-modal-navigation .navigation-next,
.light-modal-navigation .navigation-prev {
    width: 32px;
    height: 32px;
    border-color: #fff;
    transition: border-color .2s;
}

.light-modal-navigation .navigation-next:hover,
.light-modal-navigation .navigation-prev:hover {
    border-color: rgba(255, 255, 255, 0.7);
}

.light-modal-navigation .navigation-next {
    position: absolute;
    right: -50px;
    top: 50%;
    border-bottom: 1px solid;
    border-left: 1px solid;
    -ms-transform: rotate(-135deg);
    transform: rotate(-135deg);
}

.light-modal-navigation .navigation-prev {
    position: absolute;
    left: -50px;
    top: 50%;
    border-bottom: 1px solid;
    border-left: 1px solid;
    -ms-transform: rotate(45deg);
    transform: rotate(45deg);
}

.image-previewer {
    min-height: 10px;
    width: 270px;
}

@media (max-width: 480px) {
    .light-modal-navigation .navigation-next {
        right: 5px;
    }
    .light-modal-navigation .navigation-prev {
        left: 5px;
    }
}

@keyframes basic {
    0% {
        opacity: 0;
    }
    100% {
        opacity: 1;
    }
}

.basic {
    animation-name: basic;
}

@media (max-width: 767px) {
    .light-modal {
        font-size: 14px;
    }
    .light-modal:target .light-modal-content {
        width: 70vw;
    }
}

@supports (display: flex) {
    @media (max-width: 767px) {
        .light-modal:target .light-modal-content {
            width: 70vw;
        }
    }
}
<html>
<head>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/gh/daneden/animate.css@latest/animate.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/gh/eligrey/canvas-toBlob.js@latest/canvas-toBlob.min.js" defer></script>
<script src="https://cdn.jsdelivr.net/gh/eligrey/FileSaver.js@latest/dist/FileSaver.min.js" defer></script>
<link href="https://cdn.jsdelivr.net/gh/jamesssooi/Croppr.js@latest/dist/croppr.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/gh/jamesssooi/Croppr.js@latest/dist/croppr.min.js"></script>
</head>
<body>
<form action="" method="post">
<div id="cropzee-hidden-canvas" class="image-previewer" data-cropzee="crop"></div>
<input id="crop" type="file" name="filename">
<input type="submit" name="upload" value="upload">
</form>
</body>
</html>

Это сработало, но изображение обрезано (снизу и справа) больше, чем должно быть.

Новый фрагмент с кадрирующим элементом:

        
            window.addEventListener('DOMContentLoaded', function () {
                    $("#crop").change(function () {
                        readURL(this);
                    });
            });
        
            function readURL(input) {
                if (input.files && input.files[0]) {
                    var reader = new FileReader();
        
                    reader.onload = function (e) {
                        $('.cropper-container').remove();
                        $('#upload-photo-image-rotate').val(0);
                        $('#upload-photo-image-rotate-value').val(0);
                        $('#upload-photo-image-rotate-value-text').val('0°');
                        
                        var cropContainer = $('#crop-container');
                        var button = $('#done');
        
                        var image = new Image();
                        image.id = 'upload-preview-image';
                        image.src = e.target.result;
                        image.onload = function () {
                            $(cropContainer).html(image);
                        };
        
                        var cropBoxData;
                        var canvasData;
                        var cropper;
        
                        var modalImage = document.getElementById('modal-upload-preview-image');
                        modalImage.src = image.src;
                        cropper = new Cropper(modalImage, {
                            autoCropArea: 1,
                            minCropBoxHeight: $(cropContainer).data('min-height'),
                            minCropBoxWidth: $(cropContainer).data('min-width'),
                            scalable: false,
                            ready: function () {                               cropper.setCropBoxData(cropBoxData).setCanvasData(canvasData);
                            }
                        });
        
                        $('#modal-upload-preview').on('shown.bs.modal', function () {
                            modalImage.onload = function () {
                                $(document).on("input", "#upload-photo-image-rotate", function () {
                                    rotate(cropper, $(this).val());
                                });
        
                                $(document).on("change", "#upload-photo-image-rotate", function () {
                                    rotate(cropper, $(this).val());
                                });
        
                                $(button).on('click', function () {
                                    var canvas = cropper.getCroppedCanvas();
                                    var data = cropper.getData();
                                    $(cropContainer).html(canvas);
        
                                    $('#photoX').val(data.x);
                                    $('#photoY').val(data.y);
                                    $('#photoWidth').val(data.width);
                                    $('#photoHeight').val(data.height);
                                    $('#photoDegree').val(data.rotate);
                                    $('#modal-upload-preview').modal('hide');
    $('#data-viewer').text(JSON.stringify(cropper.getData()));
                                });
                            };
                        }).on('hidden.bs.modal', function () {
                            cropBoxData = cropper.getCropBoxData();
                            canvasData = cropper.getCanvasData();
                            cropper.destroy();
                        }).modal('show');
                    };
        
                    reader.readAsDataURL(input.files[0]);
                }
            }
        
            function rotate(cropper, degree) {
                var rotateValue = document.getElementById('upload-photo-image-rotate-value');
                var rotateValueText = document.getElementById('upload-photo-image-rotate-value-text');
                rotateValue.value = degree;
                rotateValueText.value = degree.replace('.', ',') + '°';
                cropper.rotateTo(degree);
            }
        
        
        
            #upload-preview-image {
                max-width: 100%;
            }
            #modal-upload-preview .cropper-bg {
                background: #000;
            }
            #modal-upload-preview .image-rotate-value {
                border: 0;
                text-align: center;
                width: 100%;
            }
            #modal-upload-preview .image-rotate {
        
            }
        
        
        
            <html>
            <head>
            <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
            <script type="text/javascript" defer="defer" src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script>
            <script type="text/javascript" defer="defer" src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.6/cropper.min.js"></script>
            <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" media="screen" rel="stylesheet" type="text/css" >
        <link href="https://fengyuanchen.github.io/cropperjs/css/cropper.css" media="screen" rel="stylesheet" type="text/css" >
            </head>
            <body>
            <div id="crop-container" data-min-height="185" data-min-width="210">
            </div>
            <form action="" method="post">
            <input id="crop" type="file" name="filename">
<input type="hidden" name="photoX" value="0" id="photoX">
<input type="hidden" name="photoY" value="0" id="photoY">
<input type="hidden" name="photoWidth" value="0" id="photoWidth">
<input type="hidden" name="photoHeight" value="0" id="photoHeight">
<input type="hidden" name="photoDegree" value="0" id="photoDegree">
<div id="data-viewer"></div>
            <input type="submit" name="upload" value="upload">
            </form>
            <div class="modal" id="modal-upload-preview" tabindex="-1" role="dialog" aria-labelledby="modalLabel" aria-hidden="true">
                <div class="modal-dialog" role="document">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h5 class="modal-title" id="modalLabel">Oříznout a natočit obrázek</h5>
                            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                                <span aria-hidden="true">&times;</span>
                            </button>
                        </div>
                        <div class="modal-body">
                            <div class="img-container" style="max-width: 100%;">
                                <img id="modal-upload-preview-image" src="">
                                <div style="position:relative;">
                                    <input id="upload-photo-image-rotate-value" type="hidden" name="rangeInputValue" value="0">
                                    <input id="upload-photo-image-rotate-value-text" class="image-rotate-value" type="text" name="rangeInputValueText" value="0°" readonly>
                                    <input id="upload-photo-image-rotate" class="image-rotate" type="range" name="rangeInput" step="0.1" min="-2" max="2" value="0">
                                </div>
                            </div>
                        </div>
                        <div class="modal-footer">
                            <button id="done" class="button btn pull-right" type="button">Oříznout</button>
                        </div>
                    </div>
                </div>
            </div>
            </body>
            </html>

Before rotate After rotate In canvas

...