简体   繁体   中英

Why is my script to resize a clipped image not working?

Firstly, my apologies for my somewhat pathetic knowledge of javascript.

I will explain briefly what I am trying to do - I am trying to set up a set of SIMPLE functions, to allow users to upload an image, crop, rotate and resize the result.

I am not 100% sure that this is the best way to do this, but it is the only way I can think to do it at the moment, so please bear with me. I am using the (perhaps somewhat clumsy) method of clipping using a div with overflow:hidden , and a clip:(rect...) property on the image.

My resize function is as follows:

function ResizeClip(factor) {
    var CropImg = document.getElementById('CroppedPreview');
    var CropContainer = document.getElementById('hiddenCropInner');

    var newHeight = CropImg.offsetHeight * factor;
    var newWidth = CropImg.offsetWidth * factor;
    var newwrapHeight = CropContainer.offsetHeight * factor;
    var newwrapWidth = CropContainer.offsetWidth * factor;

    var cX1 = document.getElementById('qx1').value * factor;
    var cX2 = document.getElementById('qx2').value * factor;
    var cY1 = document.getElementById('qy1').value * factor;
    var cY2 = document.getElementById('qy2').value * factor;

    document.getElementById('qx2').value = cX2;
    document.getElementById('qx1').value = cX1;
    document.getElementById('qy1').value = cY1;
    document.getElementById('qy2').value = cY2;


    CropImg.style.height = newHeight + 'px';
    CropImg.style.width = newWidth + 'px';
    CropImg.style.marginTop = '-' + cY1 + 'px';
    CropImg.style.clip = 'rect(' + cX1 + 'px, ' + cX2 + 'px, ' + cY1 + 'px, ' + cY2 + 'px)';

    CropContainer.style.height = newwrapHeight + 'px';
    CropContainer.style.width = newwrapWidth + 'px';
}

CroppedPreview is the image, hiddenCropInner is the container div which has overflow:hidden defined in CSS.

Perhaps I am just an idiot, but I cannot for the life of me figure out why this isn't working properly. Depending on what parts of the image I clip, the image shifts around, the width and height enlarge at different rates causing the crop region to change...

What I would like to be able to do is resize (and, ideally, manipulate otherwise) this cropped image as if it were a real image. Is there a better way to do it? Otherwise, how can I fix that function?

I would be forever grateful for any help at all but please keep in mind I am a total novice and really don't know what I'm doing so I need things explained somewhat lucidly for me. I'm not asking anyone to do it for me but I have tried to come up with some method of doing what I want to do (easily resizing the clipped image) for days with no result. So, thank you in advance for any help anyone can offer!


EDIT I have now created a fiddle but embarassingly enough I can't even get that to work. Nonetheless it can be found here: http://jsfiddle.net/Xenthide/x62L3/9/

I have arbitrarily defined the initial clipping using values pulled from a crop function that I have not included as that seems to be working fine for the most part (well, that and it would just overcomplicate the fiddle massively). Locally that code does seem to cause changes in the size of the image but for reasons unknown and immutable to me, the fiddle doesn't... but hopefully it makes things a bit clearer...

Provided that this fiddle is a good representation of your work, there are some problems indeed.

First of all, you've put your input and button elements inside a form element:

<form>
    <input type="text" name="qx1" id="qx1" value="74">
    <input type="text" name="qy1" id="qy1" value="63">
    <input type="text" name="qx2" id="qx2" value="367">
    <input type="text" name="qy2" id="qy2" value="220">

    <button id="enlarge" onclick="ResizeClip(1.10)">Enlarge Clip</button>
    <button id="shrink" onclick="ResizeClip(0.9)">Shrink Clip</button>
</form>

Now, if you don't specify a type attribute on those buttons, they default to type="submit" button. This implies that when you click on them, the form is submitted and, in short, reloads the page (this explains the white blinking when you click on the buttons). Whether your function works or not, the result will be thrashed by the page reload.

This can be avoided with these methods:

  1. Don't wrap the elements in a form - you don't need it in this case.
  2. Call the .preventDefault (or other legacy IE method) function on the submit event on the form.
  3. Define type="button" on the buttons (without a submit button, this should prevent form submission when pressing Enter on the form fields too).

I'll use the last one.

We're almost there. Now, your fiddle won't work because the buttons' click event listeners can't resolve the ResizeClip function. This is because ResizeClip isn't a globally defined function, even if it looks so (JSFiddle doesn't help here - but it depends on the choice "onLoad" in the left menu). So you either:

  1. Expose the function globally, doing something like window.ResizeClip = ResizeClip after you defined it. (Hint: defining global variables and functions is considered bad practice.)
  2. Remove the traditional event registering from the DOM (ie, the onclick attributes on the buttons) and use a more modern approach attaching the event listeners in your script, thus separating the presentation (the HTML part) and the logic (the Javascript).

Of course I'll use the last one:

<button type="button" id="enlarge">Enlarge Clip</button>
<button type="button" id="shrink">Shrink Clip</button>

And at the end of the script:

document.getElementById("enlarge").onclick = function() {ResizeClip(1.1);};
document.getElementById("shrink").onclick = function() {ResizeClip(.9);};

There, it works! Updated live demo .

Well, not exactly. It doesn't really clip the image because, as I told you, you must set position: absolute for it. And I guess the rect parameters need some working. It just zooms it in and out. But now you're in the good path.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM