-1

我正在构建一个 chrome 扩展:https ://github.com/justaguy84/resizemy.photos.chrome这将有助于从网络上裁剪和调整图像大小。
我正在使用cropperjs 库:https
://github.com/fengyuanchen/cropperjs 出于某种原因,当更改裁剪尺寸时,我得到了 2 个裁剪容器,而不仅仅是一个,而且它们的宽度/高度都有一些问题。

奇怪的是,它有时工作,有时不工作,而唯一的变化是刷新页面。

希望有人可以提供帮助。谢谢。

更新

这是html和js代码: 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();
      }
    }
  };

};

希望这将有助于调试。谢谢

4

1 回答 1

0

好的,找到问题了。当为cropper加载一个新的url时,我们需要确保他已经准备好了:

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

而不仅仅是等待图像请求加载:

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

希望它会帮助某人...

于 2017-06-30T07:27:17.487 回答