Jump to content

[TUT] Scaling DX


IIYAMA

Recommended Posts

  • Moderators
7 hours ago, koragg said:

Nice trick for the scale on :~ty resolutions :D

Also here's a similar topic which @Halemade and I expanded with another method as well: 

 

Cold you explain to me, for which user interfaces/layout that method works well?

I can understand that in case of text+box or gridlayout you want to give it a bit more space, but for a button would you use the X axis as well or rather the scaling method? (Both from that topic)

 

 

 

  • Like 1
Link to comment
14 hours ago, IIYAMA said:

Cold you explain to me, for which user interfaces/layout that method works well?

I can understand that in case of text+box or gridlayout you want to give it a bit more space, but for a button would you use the X axis as well or rather the scaling method? (Both from that topic)

 

 

 

I haven't really made DX buttons so can't say for sure. My buttons and menus at my server are the default MTA ones (non-DX). I used my method to scale all DX rectangles & texts on the screen and it works quite well with those. :)

  • Like 2
Link to comment
  • 2 weeks later...
  • Scripting Moderators

Thanks for scaling part. Seems like it worked.

Quote

Note: This part is ABOUT SCALING and not positioning.

I would like to see positioning tut also. I'm confused because, I've readed lots of tutorial, but still i can't get it to work. This thing is correct?

-- left screen side
--x = coords -- from left to half of screen


-- half of screen 
--x = screenX/2 -- to center elements

-- right screen side
--x = screenX - coords -- from right side

 

Edited by DNL291
removed big quote
Link to comment
  • Moderators
9 hours ago, majqq said:

Thanks for scaling part. Seems like it worked.

I would like to see positioning tut also. I'm confused because, I've readed lots of tutorial, but still i can't get it to work. This thing is correct?


-- left screen side
--x = coords -- from left to half of screen


-- half of screen 
--x = screenX/2 -- to center elements

-- right screen side
--x = screenX - coords -- from right side

 

Yes those are correct.

 

If you have trouble with them. Then you could think of building utility stuff.

 

 

local devScreenX = 1920 
local devScreenY = 1080

local screenX, screenY = guiGetScreenSize()

local scaleValue = screenY / devScreenY

scaleValue = math.max(scaleValue, 0.65)

 

 

function getScreenStartPositionFromBox (width, height, offsetX, offsetY, startIndicationX, startIndicationY)
	local startX = offsetX 
	local startY = offsetY
	
	if startIndicationX == "right" then
		startX = screenX - (width + offsetX)
	elseif startIndicationX == "center" then
		startX = screenX / 2 - width / 2 + offsetX
	end
	
	if startIndicationY == "bottom" then
		startY = screenY - (height + offsetY)
	elseif startIndicationY == "center" then
		startY = screenY / 2 - height / 2 + offsetY
	end
	
	return startX, startY
end

 just for the `could`

 

float width, float height, float offsetX, float offsetY [, string startIndicationX, string startIndicationY ]

 


print(getScreenStartPositionFromBox(400, 400, 100, 0, "right", "center"))

print(getScreenStartPositionFromBox(400, 400, 0, 0, "center", "center"))

print(getScreenStartPositionFromBox(400, 400, 0, 100, "center", "top"))

print(getScreenStartPositionFromBox(400, 400, 100, 100, "left", "top"))

print(getScreenStartPositionFromBox(400, 400, 100, 100, "right", "top"))

 

  • Like 1
Link to comment
  • Scripting Moderators

Honestly, i don't understand why this is happening. My res: 1280x960, second res: 1280x1024, i don't know why button pos is incorrect. On other resolutions same.

1.

kgCS5gc.png

2.

YpGXrxo.png

Code:

local centerX = screenX/2
local centerY = screenY/2

--

function scaleSize(size, devY)
	if not size or not devY then
		outputChatBox("scaleSize: Missing arguments.")
		return
	end
	if size and devY then
		local scaleValue = screenY/devY
		scaleValue = math.max(scaleValue, 0.85)
		local scaledSize = scaleValue * size
		return scaledSize
	end
end

--

function getScreenStartPositionFromBox(width, height, offsetX, offsetY, startIndicationX, startIndicationY)
	local startX = offsetX 
	local startY = offsetY
	
	if startIndicationX == "right" then
		startX = screenX - (width + offsetX)
	elseif startIndicationX == "center" then
		startX = screenX / 2 - width / 2 + offsetX
	end
	
	if startIndicationY == "bottom" then
		startY = screenY - (height + offsetY)
	elseif startIndicationY == "center" then
		startY = screenY / 2 - height / 2 + offsetY
	end
	
	return startX, startY
end

--

local position_gui = {inventory_window = {}, loot_gridlist = {}, loot_button = {}}
position_gui.inventory_window[1], position_gui.inventory_window[2] = getScreenStartPositionFromBox(750, 480, 0, 0, "center", "center")
position_gui.loot_gridlist[1], position_gui.loot_gridlist[2] = getScreenStartPositionFromBox(350, 385, 15, 60, "left", "top")
position_gui.loot_button[1], position_gui.loot_button[2] = getScreenStartPositionFromBox(30, 320, 364, 60, "left", "top")

--

local inventory_window = guiCreateWindow(position_gui.inventory_window[1], position_gui.inventory_window[2], scaleSize(750, 960), scaleSize(480, 960), "", false)
local inventory_gridlist = guiCreateGridList(position_gui.loot_gridlist[1], position_gui.loot_gridlist[2], scaleSize(350, 960), scaleSize(385, 960), false, inventory_window)
local inventory_button = guiCreateButton(position_gui.loot_button[1], position_gui.loot_button[2], scaleSize(30, 960), scaleSize(320, 960), "->", false, inventory_window)

 

Edited by majqq
Link to comment
  • Scripting Moderators
2 hours ago, IIYAMA said:

These are absolute values. Shouldn't you scale some of them as well?

You mean width and height? I will try.

EDIT: I should do it for everything?

Edited by majqq
  • Like 1
Link to comment
  • Moderators
11 minutes ago, majqq said:

You mean width and height? I will try.

EDIT: I should do it for everything?

Including offset, unless you have a custom X axis position in mind which is located at for example

1/4 of the screen.

  • Like 1
Link to comment
  • Scripting Moderators
37 minutes ago, IIYAMA said:

Including offset, unless you have a custom X axis position in mind which is located at for example

1/4 of the screen.

Yes, probably works, i'm very grateful, your tutorial and help solved my biggest nightmare, thanks mate. 

  • Like 1
Link to comment
  • 9 months later...

I was trying to use this method, but after all this pain i've been through, it still looks different on each resolution, it works perfectly on 800x600.

Here is the photo of 1280x1024:
https://imgur.com/nYswa5d

The text should be in the right corner

local devSX = 1920
local devSY = 1080
local sx, sy = guiGetScreenSize()
local scaleV = sy / devSY
scaleV = math.max(scaleV, 0.65)

function statsShow ()
local text = "Ping: " ..getPlayerPing(localPlayer) .. " | FPS: " .. getElementData(localPlayer, "FPS")
local textWidth = dxGetTextWidth(text)
local centerX = sx/2
local centerY = sy/2
local textX = centerX - ((scaleV*-840)/2)
local textY = centerY - ((scaleV*-830)/2)
    dxDrawText( text, textX-2, textY, textWidth, sy, tocolor(0, 0, 0, 255), scaleV*2, "arial")
    dxDrawText( text, textX+2, textY, textWidth, sy, tocolor(0, 0, 0, 255), scaleV*2, "arial")
    dxDrawText( text, textX, textY-2, textWidth, sy, tocolor(0, 0, 0, 255), scaleV*2, "arial")
    dxDrawText( text, textX, textY+2, textWidth, sy, tocolor(0, 0, 0, 255), scaleV*2, "arial")
    dxDrawText( text, textX, textY, textWidth, sy, tocolor(255, 255, 255, 255), scaleV*2, "arial")
end
addEventHandler("onClientRender", root, statsShow)
Edited by Mefisto_PL
Link to comment
  • Moderators
9 hours ago, Mefisto_PL said:

The text should be in the right corner

This tutorial is about scaling, not about positioning.

 

  • If you are going to place it in the right + bottom corner, you have to start from that corner, not from the center.
  • textWidth  DOES NOT EXIST  with the dxDrawText function. This function is making use of a text bounding box, which has a START (x,y) and an END (x,y).
    In this box you can align the the text: left, right, top, bottom. center(x), center(y).

 


The following bounding box

> starts at 0,0 which is the left + top corner

and

> ends on the right + bottom corner with some offset from the sides.

 

The text is aligned to the right and to the bottom.

 

local offsetFromSides = scaleV * 10
local textEndX = sx - offsetFromSides
local textEndY = sy - offsetFromSides

dxDrawText( text, 0, 0, textEndX, textEndY, tocolor(255, 255, 255, 255), scaleV*2, "arial", "right", "bottom")

 

 

Edited by IIYAMA
  • Like 1
Link to comment
  • 7 months later...

p.s If you play MTA on a vertical screen, then we developers do not like you at all, sorry.

U killed me xDD

Question:

-Why the scale works only with Y  

 

local scaleValueY = screenY / devScreenY

local scaleValueX = screenX / devScreenX

Why not like this???

and what About this scale trick??

local sx_, sy_ = guiGetScreenSize()
local sx, sy = sx_/1440, sy_/900
dxDrawText("$123456789", 140*sx, 648*sy, 0*sx, 0*sy, tocolor(0,0,0,255), 0.8*sy,"bankgothic")
Link to comment
  • Scripting Moderators
On 25/11/2020 at 22:20, DiGiTal said:

-Why the scale works only with Y  

 

On 13/06/2019 at 21:21, IIYAMA said:

I have cut out of the wide-screen format a square.

 

Squares have the ratio 1:1, which means that we have removed our ratio difference from this screen resolution.

It is very easy to do, as our Y * Y resolution makes exactly that beautiful square!

 

On 25/11/2020 at 22:20, DiGiTal said:

and what About this scale trick??

This is a trick which i do not recommend. Due of thing mentioned above. Personally i'm using a IIYAMA's way for everything, and it works perfectly.

  • Like 2
Link to comment
  • Moderators
On 25/11/2020 at 22:20, DiGiTal said:

drawText("$123456789", 140*sx, 648*sy, 0*sx, 0*sy, tocolor(0,0,0,255), 0.8*sy,"bankgothic")

 

Hey DiGiTal
 

Summary:

Y axis: Y axis position & compute pixel density(scale)

X axis: X axis position

 


 

drawText("$123456789", 140*sx, 648*sy, 0*sx, 0*sy, tocolor(0,0,0,255), 0.8*sy,"bankgothic")

drawText("$123456789", <start position>, <start position>, <end position>, <end position>, tocolor(0,0,0,255), <scale>,"bankgothic")

Take a look at your code. There are 3 types of arguments.

  • start position (boundingbox)
    • x
    • y
  • end position (boundingbox)
    • x
    • y
  • scale (text)

And an `invisible` one, which is the boundingbox size:

  • boundingbox width  = (end position x) - (start position x)
  • boundingbox height = (end position y) - (start position y)

You are currently not using the boundingbox. But that is something you could scale as well.

 


 

When scaling and positioning, there is 1 important thing to keep in mind and that is to look at both of them differently. Because for some cases you want to scale position over the X and Y axis at the same time.

X axis is used for the raw position.

Y axis is used for the offset.

local scaleValueY = sy_/900

local startPositionX = x_ -- right side of the screen
local offsetX = scaleValueY * 30 -- calculate an scaled offset value

local positionX = startPositionX - offsetX

 


Your code

drawText("$123456789", 140*sx, 648*sy, 0*sx, 0*sy, tocolor(0,0,0,255), 0.8*sy,"bankgothic")

=

drawText("$123456789", <10.2%>, <72%>, <0%>, <0%>, tocolor(0,0,0,255), <80% * 100%>,"bankgothic")

I assume this is text placed above the radar.

 


 

Now how to figure out the difference in methods?

The only way is actually to see it for yourself.

 

I made the following changes to reproduce your situation:

  • Argument 2: Scaling the left offset over the Y axis.
  • Argument 3: Starting from bottom to top, to improves `value` readability. (but doesn't change the outcome)
  • Changed the text color to red.
local scaleValueY = sy_/900

drawText("$123456789", scaleValueY * 140, sy_ - (scaleValueY * 252), 0, 0, tocolor(255,0,0,255), 0.8 * scaleValueY,"bankgothic")

 

  1. Your development resolution is: 1440 x 900
  2. Check if both of them are aligned properly.
    If yes, then:
  3. Run both of examples at the same time with different resolutions and ratio aspects.
  4. Check the X position of both methods and see how those behave.
  5. Make some screenshots, which we can discus here.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Edited by IIYAMA
  • Like 2
Link to comment
  • Tut pinned this topic
  • 4 months later...
  • Scripting Moderators
On 14/07/2021 at 18:02, MohammedX said:

I have a question @IIYAMA do i have to work on resolution of 1920x1080? or on any resolution. cuz i prefer 1280x720 most of it and some people say that u should work on 1920x1080 resolution that is better?

 maybe my question is stupid....or idk i just asking

Not really. I am using this method on 1360x768.

  • Like 1
Link to comment
  • Moderators
On 14/07/2021 at 18:02, MohammedX said:

most of it and some people say that u should work on 1920x1080 resolution that is better?

You should work with the resolution you have yourself. Since that is the only absolute measure you have when building your interface.

If you have your monitor on 1280x720 and you use 1920x1080. You can't calculate width/height exactly with your own pixels. So if you want 100% of the height of your screen and you fill in 720, the output is  720 / 1080 = 0.666666666667 = ~67% height!

If you did use 1280x720: 720 / 720 = 1 = 100% height! That is what we want to see.

 

 

 

Link to comment

This method works for me perfect:

local scrX, scrY = guiGetScreenSize()
local devScreenY = 1024
local scale = math.min(math.max(scrY / devScreenY, 0.65), 2)

local parent_w = 600
local parent_h = 360
local parent_x = scrX / 2 - parent_w * scale / 2
local parent_y = scrY /2 - parent_h * scale / 2

addEventHandler("onClientRender", root, function()
 dxDrawRectangle(parent_x, parent_y, parent_w * scale, parent_h * scale, tocolor(23, 23, 25))
 dxDrawCircle(parent_x + (50) * scale, parent_y + (50) * scale, 50 * scale, 0, 360, tocolor(60, 80, 150))
end)
Edited by UndR
  • Like 1
Link to comment
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...