{"id":1399,"date":"2020-07-03T17:53:57","date_gmt":"2020-07-03T15:53:57","guid":{"rendered":"https:\/\/hannes.enjoys.it\/blog\/?p=1399"},"modified":"2020-07-03T17:53:57","modified_gmt":"2020-07-03T15:53:57","slug":"eyes-that-follow-the-cursor-in-qgis","status":"publish","type":"post","link":"https:\/\/hannes.enjoys.it\/blog\/2020\/07\/eyes-that-follow-the-cursor-in-qgis\/","title":{"rendered":"Eyes that follow the cursor in QGIS"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">I did this all in some random EPSG:25832 location and scale, this uses several magic numbers that make it work for that. I did not make it work for any CRS or canvas size. If you do, please share. But this is just silly fun so &#8230;..<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Have two polygons for the eyes.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"790\" height=\"783\" src=\"https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-5.png\" alt=\"\" class=\"wp-image-1400\" srcset=\"https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-5.png 790w, https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-5-300x297.png 300w, https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-5-150x150.png 150w, https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-5-768x761.png 768w, https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-5-624x618.png 624w\" sizes=\"auto, (max-width: 790px) 100vw, 790px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Set their Symbol Layer Type to Geometry Generator and smooth them:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">smooth($geometry, 3)<\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"790\" height=\"783\" src=\"https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-6.png\" alt=\"\" class=\"wp-image-1401\" srcset=\"https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-6.png 790w, https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-6-300x297.png 300w, https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-6-150x150.png 150w, https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-6-768x761.png 768w, https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-6-624x618.png 624w\" sizes=\"auto, (max-width: 790px) 100vw, 790px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Add another Geometry Generator symbol layer to it and throw in the following magic expression to build the pupils. It calculates the distance from your cursor to the centroids of the polygons and it prepares a line from each centroid to the cursor. Then it places a point geometry onto that line at a fraction of the distance. Use the Geometry Type &#8220;Point \/ MultiPoint&#8221; for this Geometry Generator.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">with_variable(\n  'distance',\n  distance(@canvas_cursor_point, centroid($geometry)),\n  with_variable(\n    'line',\n    make_line(centroid($geometry), @canvas_cursor_point),\n    line_interpolate_point(@line, @distance\/5)\n  )\n)<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Set the layer itself to automatically refresh its rendering in the layer&#8217;s properties:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-7-1024x827.png\" alt=\"\" class=\"wp-image-1402\" width=\"652\" height=\"525\" srcset=\"https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-7-300x242.png 300w, https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-7-768x620.png 768w\" sizes=\"auto, (max-width: 652px) 100vw, 652px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Now the eyes will follow your cursor as it moves across the map canvas!<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"714\" height=\"359\" src=\"https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-9.png\" alt=\"\" class=\"wp-image-1404\" srcset=\"https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-9.png 714w, https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-9-300x151.png 300w, https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-9-624x314.png 624w\" sizes=\"auto, (max-width: 714px) 100vw, 714px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Task for you: The pupils are not clipped and can exit the eyes. Oops! Head over to Topi&#8217;s for a hint how to solve this: https:\/\/twitter.com\/tjukanov\/status\/1278689814288760837<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And then you paint the <a href=\"https:\/\/i.imgur.com\/rCr9A.png\">rest of the fucking owl<\/a>:<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video height=\"1080\" style=\"aspect-ratio: 1920 \/ 1080;\" width=\"1920\" controls src=\"https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/qgis-animated-eyes.mp4\"><\/video><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Those are lines with 3 vertices each:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"790\" height=\"783\" src=\"https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-10.png\" alt=\"\" class=\"wp-image-1406\" srcset=\"https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-10.png 790w, https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-10-300x297.png 300w, https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-10-150x150.png 150w, https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-10-768x761.png 768w, https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/image-10-624x618.png 624w\" sizes=\"auto, (max-width: 790px) 100vw, 790px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">And the middle vertex is moved vertically using the expression below. Basically the line is reconstructed.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">smooth(\n  make_line(\n    start_point($geometry),  -- first point is kept\n    translate(\n      point_n($geometry, 2),  -- second point is translated\n      0,\n      distance(\n        @canvas_cursor_point, centroid($geometry)\n      )\/10  -- move according the cursor distance to centroid\n    ),\n    end_point($geometry)  -- last point is kept\n  ),\n  4\n)<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Here is my project file including the temporary scratch layers (use the awesome Memory Layer Saver plugin to have them loaded automatically):<\/p>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/qgis-animated-eyes.zip\">qgis-animated-eyes<\/a><a href=\"https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/qgis-animated-eyes.zip\" class=\"wp-block-file__button\" download>Download<\/a><\/div>\n","protected":false},"excerpt":{"rendered":"<p>I did this all in some random EPSG:25832 location and scale, this uses several magic numbers that make it work for that. I did not make it work for any CRS or canvas size. If you do, please share. But this is just silly fun so &#8230;.. Have two polygons for the eyes. Set their [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1399","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/posts\/1399","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/comments?post=1399"}],"version-history":[{"count":2,"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/posts\/1399\/revisions"}],"predecessor-version":[{"id":1409,"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/posts\/1399\/revisions\/1409"}],"wp:attachment":[{"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/media?parent=1399"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/categories?post=1399"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/tags?post=1399"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}