Search code examples
yuicrop

yui How to make in tag image does not necessarily will been to specify its size?


Good day.

I use script Imagecropper

Script:

<img src="http://test.com/img/1362244329.jpg" id="yui_img" height="768" width="1024">

<script>
(function() {
    var Dom = YAHOO.util.Dom,
        Event = YAHOO.util.Event;

    var crop = new YAHOO.widget.ImageCropper('yui_img');
})();
</script>

result: 1

But if i do not specify the image size, then i get next(see image):

<img src="http://test.com/img/1362244329.jpg" id="yui_img">

result: 2

And if i specify the wrong picture size, the window will increase the portion of the image:

<img src="http://test.com/img/1362244329.jpg" id="yui_img" height="333" width="500">

result:

3

How to make in tag image does not necessarily will been to specify its size?


Solution

  • First of all I'd like to point you to YUI 3 since YUI 2 is no longer supported. You shouldn't write new code using YUI 2. There's an ImageCropper component I wrote for YUI 3 that works just like the YUI 2 version in the YUI Gallery: http://yuilibrary.com/gallery/show/imagecropper. Since it copies what the YUI 2 ImageCropper did, it shares these issues with the older version.

    What to do when the size of the image isn't specified

    The reason why you're getting a small ImageCropper is that you're creating the widget before the image has been fetched and so the browser doesn't know its size yet. What you can do is wait for the image's onload event. You can listen to that event and create the ImageCropper after it fires:

    (function() {
      var Dom = YAHOO.util.Dom,
          Event = YAHOO.util.Event;
    
      var yui_img = Dom.get('yui_img');
    
      Event.addListener(yui_img, 'load', function () {
        var crop = new YAHOO.widget.ImageCropper(yui_img);
      });
    
    })();
    

    Why the ImageCropper doesn't work with images with the wrong size

    Neither the YUI 2 ImageCropper nor my YUI 3 version work with images when they don't have the right size. The reason is that both use the background: url() CSS style for showing the image inside the crop area (the non-darkened part of the widget). CSS backgrounds don't let you use a resized/zoomed image.

    I plan on using another strategy at some point for the YUI 3 version that will fix the issue. However, you need to keep in mind that the ImageCropper component is designed so that you send the crop coordinates to the server for it to actually crop the image. That means that if you have the wrong size set to the image, the coordinates that the image cropper returns with its getCropCoords method wouldn't be the coordinates that match with the full sized image. Instead you'd also have to send the server the size of the image you've been using and do extra math to crop the image correctly.

    In conclusion, you shouldn't use the image with the wrong size. You can fix the size of the image in two ways:

    1. Use the HTML5 naturalWidth and naturalHeight attributes of the image. Those return the real size of the image even if it's resized. Unfortunately these attributes are not yet supported by all browsers.
    2. Create a new image with JS, set it the same src as the image you're using, listen to its load event and get that image's size.

    Something like this:

     (function () {
      var Dom = YAHOO.util.Dom;
    
      var yui_img = Dom.get('yui_img'),
          new_img = new Image();
    
      new_img.onload = function () {
        yui_img.width = new_img.width;
        yui_img.height = new_img.height;
    
        // create the ImageCropper
      };
      new_img.src = yui_img.src;
    }());
    

    A YUI3 version

    You can easily do all this with YUI3:

    YUI().use('gallery-imagecropper', function (Y) {
    
      var img = Y.one('#yui_img');
    
      img.on('load', function () {
        var cropper = new Y.ImageCroper({
          srcNode: img,
          width: img.get('width'),
          height: img.get('height')
        });
        cropper.render();
      });
    
    });