Calculations used to rotate an image on canvas

11

I have the following code below to be able to rotate an image through canvas .

        function qs(selector) {
            return document.querySelector(selector);
        }

        function rotacionar(canvas, image, angle)
        {
            canvas.height = image.height;
            canvas.width = image.width;

            var context = canvas.getContext('2d');

            context.translate(image.width / 2, image.height / 2);

            context.rotate(angle * Math.PI / 180)

            context.drawImage(image, -image.width / 2, -image.height / 2);

        }

        function onLoad()
        {
            var canvas    = qs('#canvas');
            var image     = qs('#image');
            var btnRotate = qs('#rotate');

            var angle = 0;

            btnRotate.addEventListener('click', function () {
                rotacionar(canvas, image, angle += 90);
            });

        }

        window.addEventListener('load', onLoad)
<img id="image" src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4QAqRXhpZgAASUkqAAgAAAABADEBAgAHAAAAGgAAAAAAAABHb29nbGUAAP/bAIQAAwICCg0KCg0LCgsKCgsKDQoQCgoLCAoKCgoKCggICAoKCAgNCggKDQgJCggKCggKCgoKCgoKCg0NCggNCAgKCAEDBAQGBQYKBgYKDw0LDg4PDxANDw0NDg0NDQ8NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0N/8AAEQgAZABkAwERAAIRAQMRAf/EAB0AAAIDAQEBAQEAAAAAAAAAAAYHBAUIAwIBCQD/xAA6EAACAQIEAwYEAwgBBQAAAAABAhEDIQAEEjEFBkEHEyJRYXGBkaGxCDLwFEJSYsHR4fGCFRgjM3L/xAAbAQACAwEBAQAAAAAAAAAAAAAEBQIDBgcBAP/EADARAAICAgIBBAECBQMFAAAAAAECAAMEERIhMQUTQVEiMnEGFCNhkVKBoWKxweHw/9oADAMBAAIRAxEAPwBH8H4FTqHXUIAB6/M45wzWVdCMA7HoQoDIW0ZdCLXY29N9sF4+O9w2/gT3ZHRl7yz2DVahJdl0TfxKT57YA9VuTHp2ixr6fiDJcgtCvO9nSUaL91UAfpt5Yo9JSzOIbj4hGdhV4o1y7iOy3OBSutOu5EuNjvcbf7xscuyxayuviJEUN3vuTvxA5gM8KkqQNJgyR77fXA3plwFID+ZG2o/M8dgvKxSoHcRAmI2wJ6naWTiJ4Ko3M7zdTqVGD77Yyf8AKvWvufE+KcZAz9LTOkSP6YKVutrII8Ds3n4U6Rfyw1Q2WDuFL+XcpeBc9PTroTYTf2P9sfZGCLUO/MvXoyw7XeCp3gendao1ezdfn5Yl6c54eyfiTWLCvRM4bE6koS5s0e4D6o6wDvHphqyUuuorr5KdiC3KnamwrrqB7oOsqCQSmoagG6EiYPnGBxUK10nj5l9pJGx5jy7cfxFUqbU6nDaRpUe7CsjSNTX8RWWI0iATPiN/U+5/p+PkVqPqe4OU+Mxb7iSp/iFrMTMkt0vAnEMbHWgBKviW5F/uks8EebqlepWpVGlbi6+sffDC2qwptvmKxaqt+M0VSq16qUg1Mmmii7AapA898ZoYTIdiMmv5Abltw/mtKSsr0yCbC31wDmVltbnxgzmc+t26n6emLxj2OoUeJTaR8yrq86VVnqptffEx6aU/IyhQp/TP7lXiXeMdVpxF7OHUIXkPM+8W4fpO0jz+P0xfXaD2fqEqwaX3Dq4q5ZqdtS3BO9un+MKWU1XbX5l8X2YycEg2IOHY2e59E7wDm0s2lydI6GYn2w7rRdxSW6lpxbiyiIAAnp74ucD4kQZfUuaFalDRgT5ly+IFtmpqqqAAsYBgmD7DBQbgNiVOvKNPJcIqU9JrEN1EbAj0/vfHlmXY6gfEoWlRNC9nfO9CsqqzeLaxi4GBzeq/qEKCddTlz/nkOpVUMw/cM6vp98C5dVF9ZPLRHxBWsFbDkRr+51Es3D853nioVETeXR1WPciLYqxMuqqsITsyFt9DN+Lj9t7hU/BpS8W8pxbf6nWV18yysd7EgcO4eisTqv8ALGYtf3IyJLDQhOnMdJVIdZm0wcUIT4EH4MDIVDhxDo1NbFv3Z9enXDClg503mX8z8yNzFw5O8bVCm0j4C/x+84Z8WHUIBiK7ROWVgtTEQfn1wVVbxiVN/MXPjdSBsNzg4PxP7y6Rl48RaZjEvb33PuWptDsF7P8AIUeEUs4zM/FatcxSYTSo5cGFMGxLKNRaZ1NpAASSRjKCeR8Qayxj+IkPtF4BVzLBaImoxiBCqAN2LGyqBMk/UkDE8/Jopr5HxALLTR+Vh6+od9ln4dKVAh6hfMOIgS6UFbqbQ1Uz1chSLGkOnMc31p23x8RLleq32rxp/Aff3HrR4uadjNJSRZRoEkwNKrCkk7KIJxkxl3XvxQEn6HmZ4Yb5DbYnf7y95Z5vy7u1JcwjV4ZjRarTavCT3unL6jVbQASwElQCWCgThtf6b6nRV77rpR3CH9Hs1yB0f+ZTc1dluWrg6QtGqdnQKFY+VSmIDSTOsANJ3YCCHjZ62EcvMjieoZPp7Hm3NPo+R+0zfx7swKValNxoq02g3mdiCD1DCGU9VIsMaQZBXqdUxMxL6lsSdOY+XlOXIsTEeoOB6L/6mjCAeUEuznmUo4p1J0naQfvhraANWLPnXY3LztA5aU1yR1UH5ycOK7NqDICK7imQDLpi5Ez6YV++OQDeYFuKalw9e9KG18aWvTKCJ9y11OfNXIIUgre4ODF6WeE7jc7EamZzNUUKC+FFBeoZ7uipsC5E3Y2SmJdzsAquyCXZAoXcW5mbXiqWbz9fc2FyhyZSpsEEmQJqMYeoRP5tO19kBAX+YyxxGdkNkbmDbMszH5vGzlnRbBFv0GMZlOVXuNa1UjcveHFlKsB+UgxIG17Gwn22xnMfNtxL1vpOtHv+4hlekIImV+UPw01MrxRMz+3astRrvmKdBMvprs7Ozha9UE0zo1Q1YeOoJ1Bdb6utN/GlOTiOjqeTDX/sR21qkaMfXLXB3dgqXfVqvMXLRfcRbYR0m2MFg44vZU1rZiQ4HvNseItvxecn16Ry1YBgxotTay37pyy6u7d1mH8JDGUiQp8I6ddhKiov11NZ6bi+yvtnxM/ctczs8hrxhNk4xVtiM7U4nqfVztLvY6qZ8h1thni0O6ag1jFV6kbmLmZnqEqJUDTb0/3h3j4L8BBltIHcB+McwkOBHQdJtt0wmOL7n5/M8A1BDmvlFmPeIIbf4/r6YZYdrJ+LSpm7ln2SdmGf4hW7tEK00/8AZmGA7ukPIAkF3YflpLfYsUXxYbXZFap57inO9SqxEJPbfU3VyN2M0spQSjRSEFyxA11ahjVUqkBdTGFt+VVsoACgZHKyeZM51dk2Zb+5Yf2ELqPLnUiYnptttb188Ji+twykalzT4kQskQB6YzWbpxqOKpJp8cBUf69r4zpqWM0XYlRxzPKFLdBczsB8II9P8TgrGqVnCQmtORCn7nTgfM65SolYMWo5gqrmAf2d2nRV17imxK06h2TwvZRUI31VQqKhPgTrGB6XUmPph2e5L/ELzqtXIMWIbSA6mRF4EztDK1vn5Y0eNme6CpkczASqoukxbwXgYpl2kGbwCOuHQ9OS9A2+5jzm6OoCc5VXBLAQCcF1Y3sDUi9vOceA8yQgv1wQLddSnhK7j/ERRIUA1axIQKoLOzNYBUFyWNgoEzEYz9RLAk9AdwZn0Nt4j37Mvw25ioUqZ9u6Uif2SkVNUjyrVBIp/wAyJLfz0zbGTzv4hprJSgcj/q+JnM31IKClPn7+psLkvl2hSpLTp00pU1sEQKqibkkL/F1Jkk7knGNt9bv3vcy38u1jcnbZhJV4ckE6hE/LFVfrLue4bXg6HU4otIbFZFrxPsJt/jB75fNdqe54aHQ6+JScYoI11Ye4gj3HQ/1wpNrkkN3GlaAQc4pS0pMiB1/xgIAk/wB4zq461FTzZz5T7t7+EA31QNj4iTYARJY2GNB6VhvZd3DagFYEeREZxf8AE3XpqBTphkIgVASENoHgcbbAgiG3iIJ6MnpPuHQfU6Fj/wAQAVhCm/ifeee2TXw8hFFJqtWe5VtWmmmgBi0KA1RhdVRVkGFjaeN6Wa7SobY15ksr1NWo1x0SfHmBvDeaGGVNQzq28/QYcU3hG9sGZVlG96lDxTjLVaR6dcHWZHIaaTrqJi+o8UdbEbHFY0ZI1Nuak7E+DUkzdTNGk1asTppvuKWoQe6TfvKkkd4bqshY1sThPWctrEFCtx35+DEGSA6/kdKPmaw4VlW3aAd4keH0JFm8rW9TjnFv9EcVmDB5Hr/4QnyNGwhus9PjthMd/MOrXjLB88gMNBnp+vrilgV1xEOR9Tj+2U3Nxtab/wBcXDkf1dS4n7kDiOUAjTbr1i3SRhnjjoyiy0CCXGXBVpJ0eQkGZ+fyw8xsYuVKjZMH/muB3MR9snaQlSo9KnCZVT3YAt3hUwWYxJGqYGxiblrdj9J9LTHTk/majFVuHNvMC+EVU/ZnpvsDKn09MEWoqWbBjRELHepTDMKWhZ0x+95/qMSNoB2PqG10sT3GP2Z5dHFSm/5YxlspjXaGEvtr46g9mqQDMoFgYt1wb7pbsxpWgCjc5jgIa+gn/j/jEve18yRCza3ZfyRSp2Wp3qUfAjlQkuSwqFQCQQplVYkmdV5EnleZkjItNpE5P6nkHQqX/cRmpmRHqNh0j1A3wncknR8RFWmvE8niO3SPhJ9sDmrkSBDR0O56eoZBI+v3G18Q4qF1Pl3JDVASSTB39MW8xrxC99SLmc6JgNf+8xc7YIx/MX3H5gRz5xnRSrHVcUWMbkEIxFrix22G+Np6WCHBAgCK1tyAeNz85aXAWaNTSBG/1necdHOYeOp2tcED/EOaWSXRpFzG2F5ZnO59WoRtSoqZODt9sTUmMjofEKOzmiO+AJgNbywu9RVuAYRffo9xnU+zijRFWvW8YH5KX8ROAhazIBvRlfvFgFEpKfaUt5RKd40xsOmClpJHbSB663/zNFcPzC00SmskKouTBaNiY3k+I+845tcm/wAh4nK32W5S1yHGDIk+/T5eflb6YparrciqaMuM1xRYU9RgZtqOhLp7pcUJHxnC9gAdmTAkXiGfI+0X2x8utz07EHuMc0BQxgk2AEbkmBE+cmPXDnGrDQN6zYQBFTzpx2s9bu3RqeljSZCQfFHWLEQTHxxusakUgEH4heNSKXG/IO4meLcgsslLjyGHq3BvM6njZq2L+Uu+UuXNCCrUSZ8IHU7ed+vyxW9velg99m2/GQeYM1SfV4ND9I64IxgzPo+JUuQydHucOVuHqtRGedIbYdY9cFZi7TgvcJ5c/wBfQ+4eczc5B3XVdWAC7hYAj6Yx1uHkctEGCllU6UyJn+W1JkBSCAZt/bHgFg62f8zzz3Gi/GiC0SQrlCSD4HAUlD/CwBHgMEAbYVXYF1K8ip0JhLsV08roS5y/MMgfr3woAY+ZVx6kzLcZ1T5z8Bil9qPEqA7hBw6qfb+uEt5DQgCWuTGpoawnfz2MYCJ9vuQbs6ldzpwIJQp1GWE7+l4jcaRXpajPSB9sN8FjY/EfI/8AEitZWxT/AHiu7Zs8v/Us0bBe9BnYHTTpyf8Alpn3OOjYJDBEffgdyzJbeR0PmJ7kvj/fsqK926Hy39xbHQMnCxKaOQ/URHtRflDrmjLk/wAIWmNMDqRuY6emBcb0Znq9wHvzC/57g4BETfE8+desKCFMR0wka+ytvZHnfmarExldfdPcY3IWeosyGtpuJVbR1m46jyxr/TKK0O7+4j9Vuewca+v2nrtDNPuz3I1bkCdr3wwzqqrE3V0Yow+Y/XFvwvnasq6Z2PqfhOMRfiEOepotD4jx4XxClT4MtdK9WqeI55nAr6JIypNOrVUaVY66rFQ2oQqtaoGDBl6mdYTcot9SAA6kHJcZtvjkzA7mVhJwXjMRgK5j8TziDDjI8XJgDf0+uEttexuT0ITZZSIPWdvI/wCv15qrdt4nnHc/u2PiRbheYp7t3TOB/wDCM59tjttvhr6P+WTWP9v8yxByYD6mZaWfbNvY+LMKFDm92QUFaMdVrJobQHe5ToPkqO/Msf8Ask4nwonN94tegKRMr+YWtI9jjWZbu9aiwDX9ptxjKGIT6mcuI9rtRixm5Jt5ST0w3pc1oAp+IsNAJ/ISLm+1P/wBdE1Os2t54TvhK93umNqctqV4fEkclc0OWSJDSbdATufrhmrcO5W359wnzPMGlHDTqWbySL74uW1XOmlZQAEGOnsj/DxSq5SnUr1SKlSXhTYKY0i3Xcn3xgc31x0uZEHQ67mzw/SkalWJ3uCPaPxMtWoIFVKdCklJKVMaURUp0xMXJZySz1GJZid4gDQern+lqYH1PpV1PeUrm2Oc2ATNgdwt4VVNsKrZ6QIdcrZoyfQAfOSftGF1gHCSI6EaHAKIbSD5/YDCqtAdyY8zn2qZUDLZoxdcrWI91ovH3v54j6USM1AP9Q/7yQ6fYmSOz7OGnRyzIYZKNNgfJlVCD8xOOw5HdhH/AFSGD3mDf3NdUe1jN18jWWq4Ze7IiOmnbHmJfYxKknW/E6pkVqq8lGjPzs5j5apJLKl97zvc40y2MAO5j3J5GAAp65LEz6R/bB471ufbnzvSr+EkWnfF9g6lyHqX+XzLGiWJMlz9IwPSdNK2JPmF3LXarnKdJVSu6qNhNh6DFGR6ZjWvzdASY0x8y5E4qx1P/9k=";">

    
    <canvas id="canvas"></canvas>

    <button id="rotate" style="display:block">
        Rotate
    </button>

My question is regarding this section:

// A
canvas.height = image.height;

canvas.width = image.width;

var context = canvas.getContext('2d');

// B
context.translate(image.width / 2, image.height / 2);

// C
context.rotate(angle * Math.PI / 180)

// D
context.drawImage(image, -image.width / 2, -image.height / 2);

A) The canvas is defined with the same image dimensions (height and width).

B) The translate of canvas.getContext('2d') method is called in then set the first parameter with the width of the image divided by 2, and the second, the height divided by 2.

C) A degree conversion is made to some other unit that I do not know what it is. This snippet is angle * Math.PI / 180 . This is the moment that rotate is called.

D) The drawImage method is then called by setting the parameters x and y to have the values of the width and height of the image divided by two and negative respectively.

About the steps listed above:

  • Why in A, does the canvas need to have the same dimensions as the image?
asked by anonymous 07.04.2017 / 19:08

1 answer

14
  

Why in A, does the canvas need to have the same dimensions as the image?

This action creates a buffer - a temporary workspace - with the same size as the target image.

  

Why in B, does the canvas need to have the translate values need to have the geometric measurements of the image divided by 2 (height and width)?

Because the 'cursor' for the action is default , located at [0,0] :

translate()movesthecursortothemiddleoftheimage:

  

ThisconversionthatisdoneinC,whichscaleofmeasureofrotationforwhich?

Accordingto documentation , the angle of rotation is expressed in radians - so the need for conversion:

180 graus = π radianos
  

Why does the method that draws the image in D need to have the values divided by two and denied?

Negative values are called offset - the image will be rotated by reference to the medium, but it must be drawn in the original coordinates.

    
07.04.2017 / 19:25