Explain in detail how to use HTML5 canvas API to control the zoom transformation of pictures

Time:2021-7-27

Scale transform scale (SX, SY) passes in two parameters, which are the scaling multiple of the object in the horizontal and vertical directions. For example, context. Scale (2,2) enlarges the image twice. In fact, it looks simple, but there are still some problems in practical use. Let’s look at a piece of code:

JavaScript CodeCopy contents to clipboard
  1. <!DOCTYPE html>   
  2. <html lang=“zh”>   
  3. <head>   
  4.     <meta charset=“UTF-8”>   
  5. < title > scale transform < / Title >
  6.     <style>   
  7.         body { background: url(“./images/bg3.jpg”) repeat; }  
  8.         #canvas { border: 1px solid #aaaaaa; display: block; margin: 50px auto; }   
  9.     </style>   
  10. </head>   
  11. <body>   
  12. <div id=“canvas-warp”>   
  13.     <canvas id=“canvas”>   
  14. Your browser doesn’t support canvas?! Change one quickly!!
  15.     </canvas>   
  16. </div>   
  17.   
  18. <script>   
  19.     window.onload = function(){   
  20.         var canvas = document.getElementById(“canvas”);   
  21.         canvas.width = 800;   
  22.         canvas.height = 600;   
  23.         var context = canvas.getContext(“2d”);   
  24.         context.fillStyle = “#FFF”;   
  25.         context.fillRect(0,0,800,600);   
  26.   
  27.         context.strokeStyle = “red”;   
  28.         context.lineWidth = 5;   
  29.         for(var i = 1; i < 4; i++){   
  30.             context.save();   
  31.             context.scale(i,i);   
  32.             context.strokeRect(50,50,150,100);   
  33.             context.restore();   
  34.         }   
  35.     };   
  36. </script>   
  37. </body>   
  38. </html>  

Operation results:
2016322115330220.jpg (850×500)

In fact, zooming is very simple. What is slightly more complex is how to make the mouse the center of zooming in or out. If the mathematical geometry is not good, the calculation formula may not be understood.

JavaScript CodeCopy contents to clipboard
  1. canvas.onmousewheel=canvas.onwheel=function(event){//chrome   Firefox browser compatible  
  2.     var pos=windowToCanvas(canvas,event.clientX,event.clientY);   
  3.     event.wheelDelta=event.wheelDelta?event.wheelDelta:(event.deltaY*(-40));   
  4.     if(event.wheelDelta>0){   
  5.         imgScale*=2;   
  6.         imgX=imgX*2-pos.x;   
  7.         imgY=imgY*2-pos.y;   
  8.     }else{   
  9.         imgScale/=2;   
  10.         imgX=imgX*0.5+pos.x*0.5;   
  11.         imgY=imgY*0.5+pos.y*0.5;   
  12.     }   
  13.     drawImage();   
  14. }  

At this time, the basic functions are realized. Loading a picture is similar to loading multiple pictures. Maintain the position and size of each picture. Let’s sort out the code.

JavaScript CodeCopy contents to clipboard
  1. var canvas,context;   
  2. var img,//Picture object  
  3.     imgIsLoaded,//Whether the picture is loaded;  
  4.     imgX=0,   
  5.     imgY=0,   
  6.     imgScale=1;   
  7.     
  8. (function int(){   
  9.     canvas=document.getElementById(‘canvas’);   
  10.     context=canvas.getContext(‘2d’);   
  11.     loadImg();   
  12. })();   
  13.     
  14. function loadImg(){   
  15.     img=new Image();   
  16.     img.onload=function(){   
  17.         imgIsLoaded=true;   
  18.         drawImage();   
  19.     }   
  20.     img.src=“map.jpg”;   
  21. }   
  22.     
  23. function drawImage(){   
  24.     context.clearRect(0,0,canvas.width,canvas.height);   
  25.     context.drawImage(img,0,0,img.width,img.height,imgX,imgY,img.width*imgScale,img.height*imgScale);   
  26. }   
  27.     
  28. canvas.onmousedown=function(event){   
  29.     var pos=windowToCanvas(canvas,event.clientX,event.clientY);   
  30.     canvas.onmousemove=function(event){   
  31.         canvas.style.cursor=“move”;   
  32.         var pos1=windowToCanvas(canvas,event.clientX,event.clientY);   
  33.         var x=pos1.x-pos.x;   
  34.         var y=pos1.y-pos.y;   
  35.         pos=pos1;   
  36.         imgX+=x;   
  37.         imgY+=y;   
  38.         drawImage();   
  39.     }   
  40.     canvas.onmouseup=function(){   
  41.         canvas.onmousemove=null;   
  42.         canvas.onmouseup=null;   
  43.         canvas.style.cursor=“default”;   
  44.     }   
  45. }   
  46. canvas.onmousewheel=canvas.onwheel=function(event){   
  47.     var pos=windowToCanvas(canvas,event.clientX,event.clientY);   
  48.     event.wheelDelta=event.wheelDelta?event.wheelDelta:(event.deltaY*(-40));   
  49.     if(event.wheelDelta>0){   
  50.         imgScale*=2;   
  51.         imgX=imgX*2-pos.x;   
  52.         imgY=imgY*2-pos.y;   
  53.     }else{   
  54.         imgScale/=2;   
  55.         imgX=imgX*0.5+pos.x*0.5;   
  56.         imgY=imgY*0.5+pos.y*0.5;   
  57.     }   
  58.     drawImage();   
  59. }   
  60.     
  61. function windowToCanvas(canvas,x,y){   
  62.     var bbox = canvas.getBoundingClientRect();   
  63.     return {   
  64.         x:x – bbox.left – (bbox.width – canvas.width) / 2,   
  65.         y:y – bbox.top – (bbox.height – canvas.height) / 2   
  66.     };   
  67. }  

Problems needing attention in scaling transformation
After reading the above examples, you must be a little strange about the results. First, the coordinates of the vertices in the upper left corner have changed, but the thickness of the lines has also changed. Therefore, there are two points to note about scaling transformation:

When zooming, the position of the upper left coordinate of the image will also be scaled accordingly.
When zooming, the thickness of the image line will also be scaled accordingly.
For example, for the smallest original rectangle, the coordinates of the upper left corner are (50, 50) and the line width is 5px, but after zooming in twice, the coordinates of the upper left corner become (100100) and the line width becomes 10px. This is the side effect of scaling transforms.

Children’s shoes must be looking forward to my way to solve the side effects. Unfortunately, there is no good way to solve these side effects. If you want to fix the upper left coordinate scaling, you can change the upper left coordinate to (0, 0). In this way, no matter what multiple it is, 0 times it or 0, so it remains the same. If you don’t want the line thickness to change, don’t use lines. Or encapsulate a function by yourself instead of using scale ().

Fundamentally, as we said before, translation transformation, rotation transformation and scaling transformation all belong to coordinate transformation, or canvas transformation. Therefore, scaling is not the image, but the entire coordinate system and the entire canvas! It is like scaling the unit distance of the coordinate system, so the coordinates and lines will be scaled. When you think about it, it all seems magical.

Recommended Today

Implementation example of go operation etcd

etcdIt is an open-source, distributed key value pair data storage system, which provides shared configuration, service registration and discovery. This paper mainly introduces the installation and use of etcd. Etcdetcd introduction etcdIt is an open source and highly available distributed key value storage system developed with go language, which can be used to configure sharing […]