[Home] [Downloads] [Search] [Help/forum]

Gammon Forum

See www.mushclient.com/spam for dealing with forum spam. Please read the MUSHclient FAQ!

[Folder]  Entire forum
-> [Folder]  MUSHclient
. -> [Folder]  Miniwindows
. . -> [Subject]  Zoom in and out an image.
Home  |  Users  |  Search  |  FAQ
Username:
Register forum user name
Password:
Forgotten password?

Zoom in and out an image.

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page


Pages: 1 2  

Posted by Wuggly   USA  (112 posts)  [Biography] bio
Date Fri 12 Feb 2016 10:03 AM (UTC)

Amended on Fri 12 Feb 2016 11:22 AM (UTC) by Wuggly

Message
Hi again,

I've started working on a mini-window that will show an image of a map. I want to be able to zoom in and zoom out the image using the mouse. Being able to drag it around would be neat too.

I've searched around and couldn't find any information on how to accomplish something like this, besides with text maps.

Could someone point me into the right direction how I would go about doing something like this?

Here's what I've managed to piece together from various forum posts. Right now I'm just trying it with one image to see if I could get it working before getting more complicated with it. The Hotspot part of the code... is just a bad attempt for zooming in that I took out of some post reply here.

Window creates fine, and shows the map image.


function show_map ()

  map_window = GetPluginID()
  map_width = 500
  map_height = 500

  check (WindowCreate (map_window,   -- window ID
                0,   -- left
                0,   -- top
                map_width, -- width
                map_height, -- depth
                0,  -- center it 
                2,          
                0))  -- background colour

  -- load the map image
  check (WindowLoadImage (map_window, "map", GetInfo (66) .. "Maps/Woods_Map.png"))


  -- draw it
  check (WindowDrawImage (map_window, "map", 0, 0, 0, 0, 2))  -- draw it

  check (WindowAddHotspot(map_window, "map", 0, 0, map_width,map_height, "", "", "", "", "mouseup", "Zoom", 10, 0))

  -- show the window
  WindowShow (map_window, true)

end -- show_map


Assuming you would have to redraw the window every time you zoomed in or out, but being able to drag it around? How could that work?
[Go to top] top

Posted by Fiendish   USA  (1,641 posts)  [Biography] bio   Global Moderator
Date Reply #1 on Fri 12 Feb 2016 09:54 PM (UTC)

Amended on Fri 12 Feb 2016 09:59 PM (UTC) by Fiendish

Message
Ok, so you're talking about making what we call a "slippy map" in digital cartography.

To be able to drag it around, you'll need make a big hotspot that covers the entire miniwindow and then do something like this...

a) first make some variables to store the map's current display offsets call them offset_x and offset_y and set them both to 0 for now. These, combined with the dimensions of your miniwindow and your zoom ratio will determine what we'll call your view window, which is the chunk of your map that gets displayed at any moment.
b) on mousedown store the mouse position via GetInfo.
c) on mousemove get the current mouse position via GetInfo and subtract the original mouse position found during onmousedown to get the position delta (current_x-original_x, current_y-original_y). Draw your scaled image using the display offsets plus the position delta as the image location. I'd probably use WindowTransformImage for my initial prototype of this, because it doesn't require caching the scaled image.
d) on mouseup replace the saved display offsets with what you were just using as your image location (previous display offsets plus mouse position delta).

e) once you get that working, give yourself bonus points by rate-limit your attempts to redraw the map so that you don't do any of this more than like 15 times per second. More is just wildly unnecessary.

https://github.com/fiendish/aardwolfclientpackage
[Go to top] top

Posted by Wuggly   USA  (112 posts)  [Biography] bio
Date Reply #2 on Sat 13 Feb 2016 12:45 AM (UTC)

Amended on Sat 13 Feb 2016 05:41 AM (UTC) by Wuggly

Message
Thanks for the information! That'll for sure help me get started to figuring this out.
[Go to top] top

Posted by Nick Gammon   Australia  (21,322 posts)  [Biography] bio   Forum Administrator
Date Reply #3 on Sat 13 Feb 2016 10:34 AM (UTC)
Message
The supplied mapper module (mapper.lua) implements zooming and dragging, if that helps.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Wuggly   USA  (112 posts)  [Biography] bio
Date Reply #4 on Sat 13 Feb 2016 11:22 AM (UTC)

Amended on Sat 13 Feb 2016 11:36 AM (UTC) by Wuggly

Message
Ok so I figured out how to keep it from positioning back up after going back to drag it again. I simply took out where it adds up the current with the delta in the MouseUp function.

function MouseUp(flags, hotspot_id)
 offset_x, offset_y = delta_xa, delta_ya
end -- function MouseUp


Now when you drag it and the image goes offscreen in the miniwindow, you can see a bunch of old copies of it.

Any idea how I would go about cleaning this up? I tried simple things like adding ReDraw into the mouseup function, but it made no difference.

Here's a screenshot below of what I mean.
http://i.imgur.com/laYztcK.png

I understand it's making a new copy of the image every time the mouse is moved when dragging it, but I can't seem to find any other way to do this with the WindowTransformImage function.
[Go to top] top

Posted by Fiendish   USA  (1,641 posts)  [Biography] bio   Global Moderator
Date Reply #5 on Sat 13 Feb 2016 11:45 AM (UTC)
Message
You have to manually blank out the space where you're not drawing the image. The simplest way is to blank the whole miniwindow before drawing your image.

https://github.com/fiendish/aardwolfclientpackage
[Go to top] top

Posted by Fiendish   USA  (1,641 posts)  [Biography] bio   Global Moderator
Date Reply #6 on Sat 13 Feb 2016 11:47 AM (UTC)
Message
Nick Gammon said:

The supplied mapper module (mapper.lua) implements...dragging, if that helps.

Does it? I wonder if that's a part I edited out of mine.

https://github.com/fiendish/aardwolfclientpackage
[Go to top] top

Posted by Wuggly   USA  (112 posts)  [Biography] bio
Date Reply #7 on Sat 13 Feb 2016 12:14 PM (UTC)

Amended on Sat 13 Feb 2016 12:43 PM (UTC) by Wuggly

Message
Could you give me a hint how I would go about blanking it out? I have no clue where to start on something like that or what to use.
How do I blank the whole miniwindow? Wouldn't ReDraw be doing that? I'm quite lost on this.

And what about limiting the redraws like you mentioned? I have no clue about that one either.


Sorry for these newb questions, but I've never coded anything before getting mushclient and have only been at it for a month and a half now, with most of that just being simple things like triggers and aliases then slowly moving on into making plugins up to where I am now trying to make this crazy thing lol.

I don't think the mapper.lua helps any when it comes to dealing with an image.

function zoom_in ()
  if last_drawn and ROOM_SIZE < 40 then
    ROOM_SIZE = ROOM_SIZE + 2
    DISTANCE_TO_NEXT_ROOM = DISTANCE_TO_NEXT_ROOM + 2
    build_room_info ()
    draw (last_drawn)
  end -- if
end -- zoom_in


I deleted one of my posts here as it was just taking up room and irrelevant now. Here's the code so far.


function show_map ()

  map_window = GetPluginID()
  map_width, map_height = 500, 500

  check (WindowCreate (map_window,   -- window ID
                0,   -- left
                0,   -- top
                map_width, -- width
                map_height, -- depth
                0,  -- center it (ignored anyway) 
                2,          
                0))  -- background colour

  -- load the map image
  check (WindowLoadImage (map_window, "map", GetInfo (66) .. "Maps/Woods_Map.png"))


  -- draw it
if offset_x == nil and offset_y == nil then 
 offset_x, offset_y = 0, 0
else
end -- offset check
  check (WindowDrawImage (map_window, "map", offset_x, offset_y, 0, 0, 2))  -- draw it

  -- drag hotspot
check (WindowAddHotspot(map_window, "map1", 0, 0, map_width,map_height, "", "", "MouseDown", "", "MouseUp", "Drag", 10, 0))
check (WindowDragHandler (map_window, "map1", "dragmove", "", 0))

  -- show the window
  WindowShow (map_window, true)

end -- show_map


function MouseDown(flags, hotspot_id)
  original_x, original_y = GetInfo(283), GetInfo(284)
end  -- function MouseDown

function MouseUp(flags, hotspot_id)
 offset_x, offset_y = delta_xa, delta_ya
end -- function MouseUp

function dragmove(flags, hotspot_id)
 current_x, current_y = GetInfo(283), GetInfo(284)
 delta_x, delta_y = current_x-original_x, current_y-original_y
 delta_xa, delta_ya = offset_x+delta_x, offset_y+delta_y
 WindowTransformImage (map_window, "map", delta_xa, delta_ya, miniwin.image_copy, 1, 0, 0, 1) 

 Redraw ()
end  -- function dragmove
[Go to top] top

Posted by Fiendish   USA  (1,641 posts)  [Biography] bio   Global Moderator
Date Reply #8 on Sat 13 Feb 2016 01:41 PM (UTC)

Amended on Sat 13 Feb 2016 01:53 PM (UTC) by Fiendish

Message
Quote:

Could you give me a hint how I would go about blanking it out?

Draw the background color over the whole thing.

Quote:
And what about limiting the redraws like you mentioned? I have no clue about that one either.

During mousemove, check the high precision time with utils.timer() and see how much time has elapsed since the last time you redrew everything. If not enough time has elapsed, do nothing. Then do one final draw in mouseup.


Quote:
Wouldn't ReDraw be doing that? I'm quite lost on this.

I find Redraw to be actually quite useless. See this page for my thoughts:
https://github.com/fiendish/aardwolfclientpackage/wiki/Repaint-Buffer

Which corresponds to this plugin file
https://raw.githubusercontent.com/fiendish/aardwolfclientpackage/MUSHclient/MUSHclient/worlds/plugins/aard_repaint_buffer.xml

https://github.com/fiendish/aardwolfclientpackage
[Go to top] top

Posted by Wuggly   USA  (112 posts)  [Biography] bio
Date Reply #9 on Sat 13 Feb 2016 02:37 PM (UTC)

Amended on Sat 13 Feb 2016 02:54 PM (UTC) by Wuggly

Message
I guess I just don't understand what to draw the background color with. Would I use something like WindowImageOp or WindowRectOp and just put that right before the WindowTransformImage or WindowDrawImage?

EDIT: Ok so I tried it using the RectOp putting it right before the WindowTransformImage.

WindowRectOp (map_window, 2, 500, 500, 1, 1, ColourNameToRGB("green"))


This did the trick, but, I can't seem to set the position to 0, 0. When I do that, it doesn't show at all, and with 1, 1 you can see that tiny 1 line on the top and left.. Any idea how to get it to fit perfectly?
[Go to top] top

Posted by Fiendish   USA  (1,641 posts)  [Biography] bio   Global Moderator
Date Reply #10 on Sat 13 Feb 2016 02:57 PM (UTC)

Amended on Sat 13 Feb 2016 03:02 PM (UTC) by Fiendish

Message
You have your coordinates reversed. 0,0 should come before 500,500 not after. Remember, the top left corner is 0,0 and numbers increase as you go down and right.

0,0 and lower (negative) when given for the lower right corner coordinates evaluate as "size of miniwindow plus this value". So 0,0 is the lower right corner and negative coordinates moves in from there. So when you do 500,500,0,0 you're actually doing 500,500,500,500, which is nothing. If you did 0,0,0,0 it would work as you want. And 0,0,-1,-1 would leave the bottom and right edges exposed. And so on.

https://github.com/fiendish/aardwolfclientpackage
[Go to top] top

Posted by Wuggly   USA  (112 posts)  [Biography] bio
Date Reply #11 on Sat 13 Feb 2016 03:20 PM (UTC)

Amended on Sat 13 Feb 2016 03:31 PM (UTC) by Wuggly

Message
Thank you thank you thank you! Feels like I just became debt-free! lol.

So about the timer.. still a bit lost on that one. Would it be something like this?

if (utils.timer() < 16) then
  Redraw ()
end


Then on the mouseup just throw in a Redraw? I tried it out like that, but it wouldn't redraw until after you let go of the mouse. So I could drag it, but not see it while it was dragging, which isn't really much of an issue, it just looks and feels better when it's.. live like that.
[Go to top] top

Posted by Fiendish   USA  (1,641 posts)  [Biography] bio   Global Moderator
Date Reply #12 on Sat 13 Feb 2016 03:31 PM (UTC)

Amended on Sat 13 Feb 2016 03:47 PM (UTC) by Fiendish

Message
Something like this


local last_time

function MouseDown(flags, hotspot_id)
  last_time = utils.timer()
  ...


function dragmove(flags, hotspot_id, force_update)
  local new_time = utils.timer()
  if new_time - last_time < 0.1 and not force_update then return end
  last_time = new_time
  ...

function MouseUp(flags, hotspot_id)
  dragmove(nil, nil, true)
  ...



I also almost never directly use Redraw or Repaint when I care about the interface actually following the user. The first has too much flexibility to do absolutely nothing until "later", and the second stops the world for long enough that it might cause the next iterations of processing to fall behind.

https://github.com/fiendish/aardwolfclientpackage
[Go to top] top

Posted by Wuggly   USA  (112 posts)  [Biography] bio
Date Reply #13 on Sat 13 Feb 2016 03:41 PM (UTC)

Amended on Sat 13 Feb 2016 04:12 PM (UTC) by Wuggly

Message
Ok, edited, had to wait 8 minutes.

local last_time

function MouseDown(flags, hotspot_id)
  original_x, original_y = GetInfo(283), GetInfo(284)
  last_time = utils.timer()
end  -- function MouseDown

function dragmove(flags, hotspot_id, force_update)
  local new_time = utils.timer()
  if new_time - last_time < 0.1 and not force_update then return end
  last_time = new_time
 current_x, current_y = GetInfo(283), GetInfo(284)
 delta_x, delta_y = current_x-original_x, current_y-original_y
 delta_xa, delta_ya = offset_x+delta_x, offset_y+delta_y
WindowRectOp (map_window, 2, 0, 0, 0, 0, ColourNameToRGB("green"))
 WindowTransformImage (map_window, "map", delta_xa, delta_ya, miniwin.image_copy, 1, 0, 0, 1) 
  Redraw ()
end  -- function dragmove

function MouseUp(flags, hotspot_id)
 offset_x, offset_y = delta_xa, delta_ya
dragmove(nil, nil, true)

end -- function MouseUp


This is working, but it's funky. When I let go of the mouse depending on which way I was dragging, the map image jumps that direction a little bit than where I left off. I'm guessing I need to add something to the delta_xa and ya in the mouseup part? It didn't do this before adding in the timer.
[Go to top] top

Posted by Fiendish   USA  (1,641 posts)  [Biography] bio   Global Moderator
Date Reply #14 on Sat 13 Feb 2016 03:45 PM (UTC)

Amended on Sat 13 Feb 2016 03:56 PM (UTC) by Fiendish

Message
First, it looks like that Redraw in MouseUp does nothing since you always call it right after WindowTransformImage anyway.
Second, maybe that 15 needs to be 0.1 or something. Let me check my notes.

Yeah it does. It's a measure of seconds, not milliseconds, sorry. So make it 0.1 or 0.09 or 0.08 or something on that order. I'll update the above post to reflect this.

https://github.com/fiendish/aardwolfclientpackage
[Go to top] top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


6,852 views.

This is page 1, subject is 2 pages long: 1 2  [Next page]

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page

Go to topic:           Search the forum


[Go to top] top

Quick links: MUSHclient. MUSHclient help. Forum shortcuts. Posting templates. Lua modules. Lua documentation.

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.

[Home]


Written by Nick Gammon - 5K   profile for Nick Gammon on Stack Exchange, a network of free, community-driven Q&A sites   Marriage equality

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( https://gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Hosted at FutureQuest]