JavaScript + html5canvas implement local screenshot tutorial _ javascript skills

Source: Internet
Author: User
This article mainly introduces the local implementation tutorial of JavaScript + html5canvas. If you are interested in functions, refer to the html5 APIs that you have recently learned, I found that Sina Weibo's profile picture settings were implemented using canvas. In addition, I learned some time ago that the html5 File API uses the File API FileReader to upload files. JavaScript File API File Upload preview,I think html5 is more fun. I want to try writing this function to learn canvas.
Below is a demo I wrote myself. The code is rarely written and many details are not processed. If you have any questions, please kindly advise. Thank you! ^_^
Function implementation step:

  • 1. Get the file, read the file and generate a url
  • 2. Use canvas to draw images based on the container size
  • 3. Use canvas to draw a Mask Layer
  • 4. Use canvas to draw the cropped Image
  • 5. Drag the cropping box and crop the image again.

PS: Because the demo is first written and then written in this article, the code for multipart pasting is copied directly from the segment in the Code. Pay attention to this object.
Step 1: Get the file, read the file, and generate a url
Here, I use the file api in html5 to process local file uploads, because it does not need to upload images to the server, and then the server returns the image address for preview. For details, see: use FileReader of File API to upload files

Document. getElementById ('Post _ file '). onchange = function () {var fileList = this. files [0]; var oFReader = new FileReader (); oFReader. readAsDataURL (fileList); oFReader. onload = function (oFREvent) {// called when the read operation is completed successfully. postFile.paintImage(oFREvent.tar get. result); // pass the url of the preview image to the function };}

Step 2: Use canvas to draw images based on the container size

The FileReader using the File API in the previous step has obtained the address of the image to be uploaded. Next, you need to use canvas to draw the image. Why isn't I just inserting img and re-drawing it with canvas? Actually not. If you use img to insert a page directly, the image cannot be automatically centered. If you use canvas to draw an image, the image can be automatically centered and scaled proportionally, and the coordinates of the image can be easily adjusted, the size is passed to the subsequent mask layer, so that the mask layer can be drawn based on the coordinates of the image and the size of the image.
Pay attention to the drawImage method of canvas.

PaintImage: function (url) {var t = this; var createCanvas = t. getImage. getContext ("2d"); var img = new Image (); img. src = url; img. onload = function () {// proportional scaling image (if the image width and height are smaller than the container, the image width and height are equal to the width and height of the original image .) // If the image width or height is greater than that of the container, the width or height is equal to the width or height of the container, and the other height or width is proportional. // t. imgWidth: the width of the image after painting; t. imgHeight: the height of the image after painting; t. px: X axis of the image after painting; t. py: if (img. width <t. regional. offsetWidth & img. height <t. regional. offsetHeight) {t. imgWidth = img. width; t. imgHeight = img. height;} else {var pWidth = img. width/(img. height/t. regional. offsetHeight); var pHeight = img. height/(img. width/t. regional. offsetWidth); t. im GWidth = img. width> img. height? T. regional. offsetWidth: pWidth; t. imgHeight = img. height> img. width? T. regional. offsetHeight: pHeight;} // coordinate t of the image. px = (t. regional. offsetWidth-t. imgWidth)/2 + 'px '; t. py = (t. regional. offsetHeight-t. imgHeight)/2 + 'px '; t. getImage. height = t. imgHeight; t. getImage. width = t. imgWidth; t. getImage. style. left = t. px; t. getImage. style. top = t. py; createCanvas. drawImage (img, 0, 0, t. imgWidth, t. imgHeight); // you can use a canvas to draw an image without directly inserting a background image to adjust the size of the image t in the required frame. imgUrl = t. getImage. toDataURL (); // store the image address t drawn by the canvas. cutImage (); t. drag ();};},

The result is as follows:

Step 3: Use canvas to draw a Mask Layer
The background image to be cropped has been drawn in the previous step. Now we need to draw a mask layer covering the background based on the coordinates and sizes of the background image, in addition, use the clearRect method of canvas to clear a cropping area and compare the area with the area without cropping.
(Here, the mask layer is only used to display the effect, and does not crop the image. I wonder if this step can be removed directly? Tell me if you have any children's shoes .)

// Draw the mask layer: t. editBox. height = t. imgHeight; t. editBox. width = t. imgWidth; t. editBox. style. display = 'block'; t. editBox. style. left = t. px; t. editBox. style. top = t. py; var cover = t. editBox. getContext ("2d"); cover. fillStyle = "rgba (0, 0, 0, 0.5)"; cover. fillRect (0, 0, t. imgWidth, t. imgHeight); cover. clearRect (t. sx, t. sy, t. sHeight, t. sWidth );

Step 4: Use canvas to draw the cropped Image
In step 3, the mask layer is drawn, but the mask layer is not capable of cropping. It is only used to display the comparison between the cropping area and the non-cropping area, so here we start to crop the image. The drawImage method of the canvas is also used.

// Draw a cut image: t. editPic. height = t. sHeight; t. editPic. width = t. sWidth; var ctx = t. editPic. getContext ('2d '); var images = new Image (); images. src = t. imgUrl; images. onload = function () {ctx. drawImage (images, t. sx, t. sy, t. sHeight, t. sWidth, 0, 0, t. sHeight, t. sWidth); // crop the image document. getElementById ('show _ edit '). getElementsByTagName ('img ') [0]. src = t. editPic. toDataURL (); // use the img label to display the cropped image}

Step 5: drag the cropping box and re-crop the image
When using the upload Avatar function, we hope to crop images that are satisfactory. Therefore, the cropping box must be constantly changed to crop perfect images. The basic functions of cropping images have been implemented in the previous steps. Therefore, you need to follow the mouse movement to crop images in real time.

Drag: function () {var t = this; var draging = false; var startX = 0; var startY = 0; document. getElementById ('Cover _ box '). onmousemove = function (e) {// obtain the distance from the mouse to the background image var pageX = e. pageX-(t. regional. offsetLeft + this. offsetLeft); var pageY = e. pageY-(t. regional. offsetTop + this. offsetTop); // determines whether the mouse is in the cropping area: if (pageX> t. sx & pageX <t. sx + t. sWidth & pageY> t. sy & pageY <t. sy + t. sHeight) {this. style. cursor = 'move '; this. onmousedown = function () {draging = true; // records the last coordinate t. ex = t. sx; t. ey = t. sy; // record the coordinates startX = e when the mouse is pressed. pageX-(t. regional. offsetLeft + this. offsetLeft); startY = e. pageY-(t. regional. offsetTop + this. offsetTop);} window. onmouseup = function () {draging = false;} if (draging) {// coordinates of the cropping area when moving = positioning of the previous record + (current location of the mouse-position of the mouse pressed), the cropping area cannot exceed the region of the mask layer; if (t. ex + (pageX-startX) <0) {t. sx = 0;} else if (t. ex + (pageX-startX) + t. sWidth> t. imgWidth) {t. sx = t. imgWidth-t. sWidth;} else {t. sx = t. ex + (pageX-startX) ;}; if (t. ey + (pageY-startY) <0) {t. sy = 0;} else if (t. ey + (pageY-startY) + t. sHeight> t. imgHeight) {t. sy = t. imgHeight-t. sHeight;} else {t. sy = t. ey + (pageY-startY);} t. cutImage () ;}} else {this. style. cursor = 'auto ';}};}

The success is as follows:


Some children's shoes pointed out that it is not very performance-consuming to crop an image every time you move the mouse. Why don't you use canvas to crop the image when previewing the effect? I think this suggestion makes sense, so I changed the code slightly in step 4. When you move the mouse, the preview effect is to change the background-position of the image. You can crop the image only when you click the Save button. You can generate a new url for the cropped image and send it to the server ~~
The following code is correct. Do you have any other good suggestions?
The complete demo code is as follows:
Note: Because seajs is used, pay attention to file loading.
Css:

body{text-align:center;}#label{border:1px solid #ccc;background-color:#fff;text-align:center;height:300px; width:300px;margin:20px auto;position:relative;}#get_image{position:absolute;}#edit_pic{position:absolute;display:none;background:#000;}#cover_box{position: absolute;z-index: 9999;display:none;top:0px;left:0px;}#show_edit{margin: 0 auto;display:inline-block;}#show_pic{height:100px;width:100px;border:2px solid #000;overflow:hidden;margin:0 auto;display:inline-block; }

Html:

Save

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.