2017-06-29 2 views
-1

Ich erstelle eine Chrome-Erweiterung: https://github.com/justaguy84/resizemy.photos.chrome, die beim Zuschneiden und Ändern der Größe von Bildern aus dem Internet hilft.
Ich benutze cropperjs Bibliothek: https://github.com/fengyuanchen/cropperjs
Aus irgendeinem Grund, wenn ich die Crop-Größe ändern, bekomme ich 2 Crop-Container statt nur einer und beide von ihnen haben ein Problem mit ihrer Breite/Höhe.cropperjs> Fehler beim Erstellen des Containers

Was ist seltsam ist, dass es manchmal funktioniert und manchmal nicht, während die einzige Änderung ist Aktualisieren der Seite.

Ich hoffe, jemand kann helfen. Danke.

AKTUALISIERT

Hier ist der HTML-und JS-Code: html

<!doctype html> 
<html lang="en"> 
    <head> 
    <meta charset="utf-8"> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge"> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags --> 
    <title>Resize My Photos Test Page</title> 

    <!-- Latest compiled and minified cropper CSS --> 
    <link rel="stylesheet" type="text/css" href="css/cropper.min.css"> 

    <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous"> 

    <link href="https://fonts.googleapis.com/css?family=Lato:400,700" rel="stylesheet"> 
    <link rel="stylesheet" type="text/css" href="css/general.css"> 

    </head> 
    <body> 
    <div id="wrapper"> 

     <div id="editor"> 

     <h1>Choose your image size</h1> 

     <div id="custom" class="editor-section"> 
      <h2>Custom size</h2> 
      <div id="custom-sizes"> 
      Width <input type="text" name="custom-width" id="dataWidth"> PX 
      <a class="link"> 
       <i class="fa fa-link" aria-hidden="true"></i> 
       <!-- <i class="fa fa-chain-broken" aria-hidden="true"></i> --> 
      </a> 
      Height <input type="text" name="custom-height" id="dataHeight"> PX 
      </div> 
     </div> 
     <div id="preset" data-toggle="buttons"> 
      <div id="standard" class="editor-section"> 
      <h2>Standard</h2> 
      <div> 
       <div> 
       <label class="box btn active desktop" aria-pressed="true"> 
        <input type="radio" class="sr-only" id="Desktop-ratio" name="aspectRatio" value="1.7777777777777777" data-option="{ &quot;width&quot;: 1920, &quot;height&quot;: 1080 }"> 
        <p> 
        Desktop<br> 
        1920 x 1080 
        </p> 
       </label> 
       </div> 
       <div> 
       <label class="box btn laptop" aria-pressed="true"> 
          <input type="radio" class="sr-only" id="Laptop-ratio" name="aspectRatio" value="1.6" data-option="{ &quot;width&quot;: 1440, &quot;height&quot;: 900 }"> 
        <p> 
        Laptop<br> 
        1440 x 900 
        </p> 
       </label> 
       </div> 
       <div> 
       <label class="box btn thumbnail" aria-pressed="true"> 
          <input type="radio" class="sr-only" id="Thumbnail-ratio" name="aspectRatio" value="1" data-option="{ &quot;width&quot;: 200, &quot;height&quot;: 200 }"> 
        <p> 
        Thumbnail<br> 
        200 x 200 
        </p> 
       </label> 
       </div> 
      </div> 
      </div> 
      <div id="social" class="editor-section"> 
      <div class="section-header"> 
       <h2>Social networks</h2> 
       <ul id="social-icons"> 
       <li class="fb"><i class="fa fa-facebook-official" aria-hidden="true"></i></li> 
       <li class="in"><i class="fa fa-linkedin-square" aria-hidden="true"></i></li> 
       <li class="gplus"><i class="fa fa-google-plus-official" aria-hidden="true"></i></li> 
       <li class="pn"><i class="fa fa-pinterest" aria-hidden="true"></i></li> 
       </ul> 
      </div> 
      <div id="social-boxes"> 
       <div id="fb" class="facebook active"> 
       <div class="box cover"> 
        <label class="box btn cover" aria-pressed="true"> 
        <input type="radio" class="sr-only" id="facbook-cover" name="aspectRatio" value="2.6285714286" data-option="{ &quot;width&quot;: 828, &quot;height&quot;: 315 }"> 
        <p> 
        Facebook cover<br> 
        828 x 315 
        </p> 
        </label> 
       </div> 
       <div class="box profile"> 
        <label class="box btn profile" aria-pressed="true"> 
        <input type="radio" class="sr-only" id="facbook-cover" name="aspectRatio" value="2.6285714286" data-option="{ &quot;width&quot;: 828, &quot;height&quot;: 315 }"> 
        <p> 
        Facebook profile<br> 
        180 x 180 
        </p> 
        </label> 

       </div> 
       <div class="box post"> 
       <label class="box btn post" aria-pressed="true"> 
        <input type="radio" class="sr-only" id="facbook-cover" name="aspectRatio" value="2.6285714286" data-option="{ &quot;width&quot;: 828, &quot;height&quot;: 315 }"> 
        <p> 
        Facebook post<br> 
        600 x 600 
        </p> 
        </label> 

       </div> 
       </div> 
       <div id="in" class="linkedin"> 
       <div class="box cover"> 
        <label class="box btn cover" aria-pressed="true"> 
        <input type="radio" class="sr-only" id="facbook-cover" name="aspectRatio" value="2.6285714286" data-option="{ &quot;width&quot;: 828, &quot;height&quot;: 315 }"> 
        <p> 
        linkedin cover<br> 
        828 x 315 
        </p> 
        </label> 
       </div> 
       <div class="box profile"> 
        <label class="box btn profile" aria-pressed="true"> 
        <input type="radio" class="sr-only" id="facbook-cover" name="aspectRatio" value="2.6285714286" data-option="{ &quot;width&quot;: 828, &quot;height&quot;: 315 }"> 
        <p> 
        linkedin profile<br> 
        180 x 180 
        </p> 
        </label> 

       </div> 
       <div class="box post"> 
       <label class="box btn post" aria-pressed="true"> 
        <input type="radio" class="sr-only" id="facbook-cover" name="aspectRatio" value="2.6285714286" data-option="{ &quot;width&quot;: 828, &quot;height&quot;: 315 }"> 
        <p> 
        linkedin post<br> 
        600 x 600 
        </p> 
        </label> 

       </div> 
       </div> 
       <div id="gplus" class="googlePlus"> 
       <div class="box cover"> 
        <label class="box btn cover" aria-pressed="true"> 
        <input type="radio" class="sr-only" id="facbook-cover" name="aspectRatio" value="2.6285714286" data-option="{ &quot;width&quot;: 828, &quot;height&quot;: 315 }"> 
        <p> 
        Gplus cover<br> 
        828 x 315 
        </p> 
        </label> 
       </div> 
       <div class="box profile"> 
        <label class="box btn profile" aria-pressed="true"> 
        <input type="radio" class="sr-only" id="facbook-cover" name="aspectRatio" value="2.6285714286" data-option="{ &quot;width&quot;: 828, &quot;height&quot;: 315 }"> 
        <p> 
        Gplus profile<br> 
        180 x 180 
        </p> 
        </label> 

       </div> 
       <div class="box post"> 
       <label class="box btn post" aria-pressed="true"> 
        <input type="radio" class="sr-only" id="facbook-cover" name="aspectRatio" value="2.6285714286" data-option="{ &quot;width&quot;: 828, &quot;height&quot;: 315 }"> 
        <p> 
        Gplus post<br> 
        600 x 600 
        </p> 
        </label> 

       </div> 
       </div> 
       <div id="pn" class="pinterest"> 
       <div class="box cover"> 
        <label class="box btn cover" aria-pressed="true"> 
        <input type="radio" class="sr-only" id="facbook-cover" name="aspectRatio" value="2.6285714286" data-option="{ &quot;width&quot;: 828, &quot;height&quot;: 315 }"> 
        <p> 
        pinterest cover<br> 
        828 x 315 
        </p> 
        </label> 
       </div> 
       <div class="box profile"> 
        <label class="box btn profile" aria-pressed="true"> 
        <input type="radio" class="sr-only" id="facbook-cover" name="aspectRatio" value="2.6285714286" data-option="{ &quot;width&quot;: 828, &quot;height&quot;: 315 }"> 
        <p> 
        pinterest profile<br> 
        180 x 180 
        </p> 
        </label> 

       </div> 
       <div class="box post"> 
       <label class="box btn post" aria-pressed="true"> 
        <input type="radio" class="sr-only" id="facbook-cover" name="aspectRatio" value="2.6285714286" data-option="{ &quot;width&quot;: 828, &quot;height&quot;: 315 }"> 
        <p> 
        pinterest post<br> 
        600 x 600 
        </p> 
        </label> 

       </div> 
       </div> 
      </div> 
      </div> 
     </div> 
     </div> 
     <div id="the-image"> 
     <div id="img-container"> 
      <img id="image" src="loading.gif" class="img-responsive" alt="Image to crop"> 
     </div> 
     <div id="info"> 
      <p id="file-name"></p> 
      <p id="file-size"></p> 
     </div> 
     <div id="download"> 
      <div id="image-format"> 
      <label class="btn active" aria-pressed="true"> 
      <input type="radio" id="download-jpg" name="fileType" value="image/jpeg" checked="checked"> 
      JPG 
      </label> 
      <label class="btn active" aria-pressed="true"> 
      <input type="radio" id="download-png" name="fileType" value="image/png"> 
      PNG 
      </label> 
      </div> 
      <button id="prepareImage" class="btn btn-primary prepare-button" data-method="getCroppedCanvas" data-option="{ &quot;width&quot;: 1920, &quot;height&quot;: 1080 }">Download Image</button> 
     </div> 
     </div> 
    </div> 
    <!-- Show the cropped image in modal --> 
     <div class="hidden" id="getCroppedCanvasModal" role="dialog" aria-hidden="true" aria-labelledby="getCroppedCanvasTitle" tabindex="-1"> 
      <div class="modal-body"></div> 
     </div><!-- /.modal --> 
    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) --> 
     <script src="js/jquery.min.js"></script> 
    <!-- Latest compiled and minified Cropper JavaScript --> 
    <script type="text/javascript" src="js/cropper.js"></script> 
    <!-- Main javascript file --> 
    <script type="text/javascript" src="js/main.js"></script> 
    </body> 
</html> 

Javascript - main.js

window.onload = function() { 

    'use strict'; 

    //set vars for common elements 
    var Cropper = window.Cropper; 
    var container = document.querySelector('#img-container'); 
    var prepareImage = document.getElementById('prepareImage'); 
    var actions = document.getElementById('editor'); 
    var download = document.getElementById('download'); 
    var dataHeight = document.getElementById('dataHeight'); 
    var dataWidth = document.getElementById('dataWidth'); 

    //prepare cropper options 
    var options = { 
    aspectRatio: 16/9, 
    zoomable: false, 
    checkCrossOrigin: true, 
    ready: function (e) { 
     console.log(e.type); 
     }, 
    cropstart: function (e) { 
     console.log(e.type, e.detail.action); 
    }, 
    cropmove: function (e) { 
     console.log(e.type, e.detail.action); 
    }, 
    cropend: function (e) { 
     console.log(e.type, e.detail.action); 
    }, 
    crop: function (e) { 
     var data = e.detail; 
     console.log(e.type); 
    }, 
    zoom: function (e) { 
     console.log(e.type, e.detail.ratio); 
    } 
    }; 

    // prepare image 
    var imageUrl = window.location.hash.substring(1); 
    if (imageUrl !==""){ 
    var image = container.getElementsByTagName('img').item(0); 
    image.src = imageUrl; 
    var xhr = new XMLHttpRequest(); 
    xhr.open("GET", imageUrl, true); 
    xhr.onreadystatechange = function() { 
     if (xhr.readyState == 4) { 
     cropper['replace'](imageUrl); 
     } 
    } 
    xhr.send(); 
    } 
    else{ 
    var image = container.getElementsByTagName('img').item(0); 
    } 
    image.onload = function(){ 
    var imageName = image.getAttribute('src'); 
    var imageWidth = image.naturalWidth; 
    var imageHeight = image.naturalHeight; 

    // preset info on page 
    document.getElementById('file-name').innerHTML = imageName; 
    document.getElementById('file-size').innerHTML = 'Original size: ' + imageWidth + 'x' + imageHeight; 
    dataHeight.value = Math.round(imageHeight); 
    dataWidth.value = Math.round(imageWidth); 
    } 

    //create cropper 
    var cropper = new Cropper(image, options); 

    var originalImageURL = image.src; 

    //socail tabs 
    actions.querySelector('#social-icons').onclick = function (event){ 
    var e = event || window.event; 
    var target = e.target || e.srcElement; 
    if (target.type !== ''){ 
     var socialTarget = '#'+target.parentElement.className; 
     var boxes = document.getElementById('social-boxes'); 
     $("#social-boxes >div.active").removeClass("active"); 
     boxes.querySelector(socialTarget).classList.add("active"); 
    } 
    } 

    // set image/cropper size 
    actions.onchange = function (event) { 
    var e = event || window.event; 
    var target = e.target || e.srcElement; 
    var isRadio; 
    var isText; 
    var data; 
    var imageData; 

    data = { 
     method: target.getAttribute('data-method'), 
     target: target.getAttribute('data-target'), 
     option: target.getAttribute('data-option'), 
     secondOption: target.getAttribute('data-second-option') 
    }; 

    if (!cropper || (target.type === undefined)) { 
     return; 
    } 

    if (target.tagName.toLowerCase() === 'label') { 
     target = target.querySelector('input'); 
    } 

    isRadio = target.type === 'radio'; 
    isText = target.type === 'text'; 

    //set preset sizes 
    if (isRadio) { 
     options[target.name] = target.value; 
     $('.box.btn.active').removeClass('active'); 
     $('#custom-sizes input').removeClass('active'); 
     target.parentNode.classList.add("active"); 
     prepareImage.setAttribute('data-option', data.option); 
     options.ready = function() { 
     console.log('ready'); 
     }; 
    } 

    //set custom size 
    if(isText){ 
     if (target.id === 'dataWidth'){ 
     dataHeight.value = Math.round(target.value * (image.naturalHeight/image.naturalWidth)); 
     } 
     else if (target.id === 'dataHeight') { 
     dataWidth.value = Math.round(target.value * (image.naturalWidth/image.naturalHeight)); 
     } 
     $('.box.btn.active').removeClass('active'); 
     $('#custom-sizes input').addClass('active'); 
     prepareImage.setAttribute('data-option', '{ "width": '+dataWidth.value+', "height": '+dataHeight.value+' }'); 
     imageData = cropper['getImageData'](); 
     options['aspectRatio'] = imageData.aspectRatio; 
     options['top'] = 0; 
     options['left'] = 0; 
     options['autoCropArea'] = 1; 
    } 

    // Restart 
    cropper.destroy(); 
    cropper = new Cropper(image, options); 
    }; 

    // set download button 
    download.onclick = function (event) { 
    var e = event || window.event; 
    var target = e.target || e.srcElement; 
    var result; 
    var input; 
    var data; 
    var cropedImageName = "cropped."; 
    var cropedImageType; 

    if (!cropper) { 
     return; 
    } 

    data = { 
     method: target.getAttribute('data-method'), 
     target: target.getAttribute('data-target'), 
     option: target.getAttribute('data-option'), 
     secondOption: target.getAttribute('data-second-option') 
    }; 

    if (data.method === 'getCroppedCanvas') { 
     data.option = JSON.parse(data.option); 
     result = cropper[data.method](data.option, data.secondOption); 
     if (result) { 
     // prepare image and auto download 

     // get filetype and set download name 
     cropedImageType = $('input[name="fileType"]:checked').val(); 
     if (cropedImageType === 'image/jpeg'){ 
      cropedImageName = cropedImageName + 'jpg'; 
     } 
     else{ 
      cropedImageName = cropedImageName + 'png'; 
     } 

     //draw image 
     //$('#getCroppedCanvasModal').find('.modal-body').html(result); 

     // start auto download of image 
     var a = $("<a>").attr("href", result.toDataURL(cropedImageType)).attr("download", cropedImageName).appendTo("body"); 
     a[0].click(); 
     a.remove(); 
     } 
    } 
    }; 

}; 

Hope this mit der helfen debuggen. Danke

+0

Sie müssen genaue Schritte zum Reproduzieren hinzufügen. Ich habe versucht, Ihre Erweiterung auf einem zufälligen Web-Bild und es funktioniert ohne Probleme, außer es unterstützt nicht WebP Bildformat. – wOxxOm

+0

Danke @wOxxOm für den Versuch, aber ich habe es bereits gelöst. Das Problem war, dass cropper nicht bereit war, bevor die URL gesetzt wurde, so dass es bei langsameren Verbindungen oder großen Dateien, die ich vermute, nicht funktionierte und nach der Aktualisierung funktionierte (vielleicht aus dem Cache ???) – justaguy

Antwort

0

OK, das Problem gefunden. Wenn Sie eine neue URL für die cropper Laden, müssen wir sicherstellen, dass er bereit ist:

xhr.onreadystatechange = function() { 
     if (xhr.readyState == 4) { 
     new Cropper(image, { 
      ready: function() { 
      cropper['replace'](imageUrl); 
      } 
     }); 
     } 
} 

und nicht nur für die Bildanforderung warten zu laden:

xhr.onreadystatechange = function() { 
     if (xhr.readyState == 4) { 
      cropper['replace'](imageUrl); 
     } 
    } 

Hoffe, dass es jemand helfen. ..

Verwandte Themen