{"id":1,"date":"2019-03-19T19:44:03","date_gmt":"2019-03-19T19:44:03","guid":{"rendered":"http:\/\/www.januszcimek.com\/blog\/?p=1"},"modified":"2019-11-11T18:58:38","modified_gmt":"2019-11-11T18:58:38","slug":"tilting-images-with-phone-position-html5","status":"publish","type":"post","link":"https:\/\/www.januszcimek.com\/blog\/2019\/03\/19\/tilting-images-with-phone-position-html5\/","title":{"rendered":"Tilting images with phone&#8217;s gyroscope the javascript way"},"content":{"rendered":"\n<p>Have you ever seen website UI reacting to device&#8217;s orientation? If not then maybe it is time to browse a little, there are some really cool effects that you can achieve by triggering visual changes with device motion. Let&#8217;s dive into a case of making images tilt while we angle our phone. <\/p>\n\n\n\n<h2>Detecting mobile device orientation<\/h2>\n\n\n\n<p>These days increasing number of mobile browsers support  <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/DeviceOrientationEvent\">DeviceOrientationEvent<\/a> which gives us the data we need about current device orientation. For the purpose of this task we need only one property that this event object &#8211;  DeviceOrientationEvent.gamma. It is a number that represents the device&#8217;s motion around the y axis so simply speaking its left to right rotation. Its value ranges from -90 to 90. We can listen to that event on the window object like this:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\" data-enlighter-theme=\"atomic\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">window.addEventListener(\"deviceorientation\", function(event) {\nconsole.log(event.gamma);\n});<\/pre>\n\n\n\n<p>If you look at the returned value you will notice that it is super accurate, covering lot of decimal spaces and reacting to even slightest device movements. We do not need this to be so precise (actually we do not want it) so we can use the Math.round method to round it to the nearest integer which will be handy when we will use this data to animate the image. <br><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">window.addEventListener(\"deviceorientation\", function(event) {\nlet position = Math.round(event.gamma);\n});<\/pre>\n\n\n\n<h2>Setting up image tilt CSS transformation<br><\/h2>\n\n\n\n<p>OK, so we receive our client&#8217;s Y-axis angle, now it&#8217;s time to set up some initial css and html. We will have our image wrapped to set some perspective and we need to set the transition property to achieve smoother transform animations, which we will use to animate our element with.  The basic HTML\/CSS setup would look like this:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"html\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;body>\n  &lt;div class=\"wrapper\">\n      &lt;img id=\"tiltable\" src=\"http:\/\/i64.tinypic.com\/2cpte9f.jpg\"\/>\n  &lt;\/div>\n&lt;\/body>\n<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"css\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">body {\n  width:100%;\n  height:100vh;\n  display:flex;\n  justify-content:center;\n  align-items:center;\n  background-color:black;\n } \n\n.wrapper {\n  perspective: 15px;\n}\n\n#tiltable {\n  height:400px;\n  transition: transform 0.5s;\n  backface-visibility: hidden;\n}\n<\/pre>\n\n\n\n<h2>Triggering animation when device orientation changes<\/h2>\n\n\n\n<p>Now it&#8217;s time to connect the dots and make sure our event triggers the animation. Let&#8217;s go back to our event handler and throw in some code.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">const inner = document.getElementById(\"inner\");\nconst limit = 45;\n\nwindow.addEventListener(\"deviceorientation\", function(event) {\nlet position = Math.round(event.gamma);\n if (Math.abs(position) > limit) {\n       if (position > limit) {\n            position = limit;\n        } else {\n            position = -limit;\n            }\n        }\nposition = position \/ -100;\nlet style = \"rotateY(\" + position + \"deg)\";\ninner.style.transform = style;\n});<\/pre>\n\n\n\n<p>As you can see I included some additional stuff, first there is this if else statement which limits the position value for both positive and negative number scenario.  This is to set out limits to element css rotation degree which we will use to animate the image.  Next we transform the position variable by dividing it by -100 to rotate by fractions of deg only and in opposite direction than the device angle to achieve desired visual effect. Finally we assign value to our style variable which uses the position variable to construct the css property value for transform property of the element we want to rotate which we then use to set this property via element.style property of our selected HTML element. <\/p>\n\n\n\n<h2>Making things smoother<\/h2>\n\n\n\n<p>Well we are almost there but things are still a bit rough on the edges. We would like our animation not to be triggered every single time the device changes its orientation. We can achieve this by implementing simple counter function which will limit the animation to be triggered every n-th time the event fires only, every 10th time in our case.  You can find complete, working example below on the embeded codepen. <br><\/p>\n\n\n<p class=\"codepen\" style=\"height: 358px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;\" data-height=\"358\" data-theme-id=\"0\" data-default-tab=\"js,result\" data-user=\"codeVerses\" data-slug-hash=\"xBBoQK\" data-pen-title=\"Tilting images with device orientation\">See the Pen <a href=\"https:\/\/codepen.io\/codeVerses\/pen\/xBBoQK\/\"><br>Tilting images with device orientation<\/a> by codeVerses (<a href=\"https:\/\/codepen.io\/codeVerses\">@codeVerses<\/a>)<br>on <a href=\"https:\/\/codepen.io\">CodePen<\/a>.<\/p>\n<p><script async=\"\" src=\"https:\/\/static.codepen.io\/assets\/embed\/ei.js\"><\/script><\/p>\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Have you ever seen website UI reacting to device&#8217;s orientation? If not then maybe it is time to browse a little, there are some really cool effects that you can achieve by triggering visual changes with device motion. Let&#8217;s dive into a case of making images tilt while we angle our phone. Detecting mobile device [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":9,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[4,3,2],"tags":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v15.6.2 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Tilting images with phone&#039;s gyroscope the javascript way - The Code Verses<\/title>\n<meta name=\"description\" content=\"Learn how your web app could interact with smartphone&#039;s gyroscope data using JavaScript Apis that modern web browsers provide.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.januszcimek.com\/blog\/2019\/03\/19\/tilting-images-with-phone-position-html5\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Tilting images with phone&#039;s gyroscope the javascript way - The Code Verses\" \/>\n<meta property=\"og:description\" content=\"Learn how your web app could interact with smartphone&#039;s gyroscope data using JavaScript Apis that modern web browsers provide.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.januszcimek.com\/blog\/2019\/03\/19\/tilting-images-with-phone-position-html5\/\" \/>\n<meta property=\"og:site_name\" content=\"The Code Verses\" \/>\n<meta property=\"article:published_time\" content=\"2019-03-19T19:44:03+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-11-11T18:58:38+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.januszcimek.com\/blog\/wp-content\/uploads\/2019\/03\/mobile.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"800\" \/>\n\t<meta property=\"og:image:height\" content=\"533\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\">\n\t<meta name=\"twitter:data1\" content=\"3 minutes\">\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.januszcimek.com\/blog\/#website\",\"url\":\"https:\/\/www.januszcimek.com\/blog\/\",\"name\":\"The Code Verses\",\"description\":\"Just another front end blog\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https:\/\/www.januszcimek.com\/blog\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/www.januszcimek.com\/blog\/2019\/03\/19\/tilting-images-with-phone-position-html5\/#primaryimage\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/www.januszcimek.com\/blog\/wp-content\/uploads\/2019\/03\/mobile.jpg\",\"width\":800,\"height\":533},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.januszcimek.com\/blog\/2019\/03\/19\/tilting-images-with-phone-position-html5\/#webpage\",\"url\":\"https:\/\/www.januszcimek.com\/blog\/2019\/03\/19\/tilting-images-with-phone-position-html5\/\",\"name\":\"Tilting images with phone's gyroscope the javascript way - The Code Verses\",\"isPartOf\":{\"@id\":\"https:\/\/www.januszcimek.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.januszcimek.com\/blog\/2019\/03\/19\/tilting-images-with-phone-position-html5\/#primaryimage\"},\"datePublished\":\"2019-03-19T19:44:03+00:00\",\"dateModified\":\"2019-11-11T18:58:38+00:00\",\"author\":{\"@id\":\"https:\/\/www.januszcimek.com\/blog\/#\/schema\/person\/80e429555c65a9c976839288342ae906\"},\"description\":\"Learn how your web app could interact with smartphone's gyroscope data using JavaScript Apis that modern web browsers provide.\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.januszcimek.com\/blog\/2019\/03\/19\/tilting-images-with-phone-position-html5\/\"]}]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.januszcimek.com\/blog\/#\/schema\/person\/80e429555c65a9c976839288342ae906\",\"name\":\"Janusz Cimek\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/www.januszcimek.com\/blog\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/78902c04acb4f0fc7634ec30637984c1?s=96&d=mm&r=g\",\"caption\":\"Janusz Cimek\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","_links":{"self":[{"href":"https:\/\/www.januszcimek.com\/blog\/wp-json\/wp\/v2\/posts\/1"}],"collection":[{"href":"https:\/\/www.januszcimek.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.januszcimek.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.januszcimek.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.januszcimek.com\/blog\/wp-json\/wp\/v2\/comments?post=1"}],"version-history":[{"count":33,"href":"https:\/\/www.januszcimek.com\/blog\/wp-json\/wp\/v2\/posts\/1\/revisions"}],"predecessor-version":[{"id":81,"href":"https:\/\/www.januszcimek.com\/blog\/wp-json\/wp\/v2\/posts\/1\/revisions\/81"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.januszcimek.com\/blog\/wp-json\/wp\/v2\/media\/9"}],"wp:attachment":[{"href":"https:\/\/www.januszcimek.com\/blog\/wp-json\/wp\/v2\/media?parent=1"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.januszcimek.com\/blog\/wp-json\/wp\/v2\/categories?post=1"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.januszcimek.com\/blog\/wp-json\/wp\/v2\/tags?post=1"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}