WoWInterface (
-   Lua/XML Help (
-   -   Pixel Perfect 1px borders (

gempir 12-27-20 04:19 AM

Pixel Perfect 1px borders
I'm trying to create a pixel perfect border that is 1px. My method was working perfectly in Legion, but seems broken now in Shadowlands.

Here you can see an example of what works and what doesn't. The buffs and Unitframes are a custom oUF Layout.
And in the screenshot you can see they have 2px of Border on the bottom.

The Panel in the middle (behind the actionbars) uses the same function to create borders and is doing just fine with borders, no 2px thickness anywhere.

Lua Code:
  1. function F.createBorder(self, anchor, extend)
  2.     spacing = 0
  3.     if extend then
  4.         spacing = 1
  5.     end
  7.     if not anchor then
  8.         anchor = parent
  9.     end
  11.     if self:GetObjectType() == "StatusBar" then
  12.         self = CreateFrame("Frame", nil, self)
  13.         self:SetPoint("TOPLEFT", anchor, "TOPLEFT", 0, 0)
  14.         self:SetPoint("BOTTOMRIGHT", anchor, "BOTTOMRIGHT", 0, 0)
  15.     end
  17.     if not self.borders then
  18.         self.borders = {}
  19.         for i=1, 4 do
  20.             self.borders[i] = self:CreateLine(nil, "LOW", nil, 0)  
  21.             local l = self.borders[i]
  22.             l:SetThickness(1)
  23.             l:SetColorTexture(unpack(G.colors.border))
  24.             if i==1 then
  25.                 l:SetStartPoint("TOPLEFT", -spacing, spacing)
  26.                 l:SetEndPoint("TOPRIGHT", spacing, spacing)
  27.             elseif i==2 then
  28.                 l:SetStartPoint("TOPRIGHT", spacing, spacing)
  29.                 l:SetEndPoint("BOTTOMRIGHT", spacing, -spacing)
  30.             elseif i==3 then
  31.                 l:SetStartPoint("BOTTOMRIGHT", spacing, -spacing)
  32.                 l:SetEndPoint("BOTTOMLEFT", -spacing, -spacing)
  33.             else
  34.                 l:SetStartPoint("BOTTOMLEFT", -spacing, -spacing)
  35.                 l:SetEndPoint("TOPLEFT", -spacing, spacing)
  36.             end
  37.         end
  38.     end
  40.     return self
  41. end

This is the function to create borders for my frames. When hardcoding spacing to like 5 or so to play around with the position, I noticed the border of 2px sometimes being on top. Other UI Elements like my Tooltip have it on 2 sides.
(Although I don't use the same border function for that on the tooltip)

Here is the code for the tooltip (and rest of my code) if it helps giving any context.

I have read several older threads about this on here, but can't find one that helps me with my problem.
I have played around with UI scaling with stuff like this

Lua Code:
  1. SetCVar('useuiscale', 1)
  2. SetCVar('uiscale', 1)
  3. local _, height = GetPhysicalScreenSize()
  4. UIParent:SetScale(768 / height)

This seems to work but generally just makes everything too big on my 1440p screen. Preffered Solution would be with the UI Scaling option off, that looks best to me.

Setting the UI scale to the minimum possible via the UI seems to make it a bit better, but there are still some vertical borders that are too big.

d87 12-27-20 06:43 AM

Getting length of 1px for 100% scale region would be PixelUtil.GetNearestPixelSize(1, UIParent:GetEffectiveScale(), 1)

gempir 12-27-20 07:21 AM

That's helpful, never seen that before!

Now it looks even better, but some vertical borders are just non existant now. Is there something I'm missing?

(Right side of Castbar)

Edit: Hmm. Changing the width of the castbar, will fix that on some widths. I'm confused why this doesn't work for every width though.

d87 12-27-20 08:08 AM

Well it's not a perfect solution, at the end of the day units will still be rounded up to pixels, you can only try to make so that it happens at the same time from both ends. Try sizing your bar in whole pixels too

gempir 01-02-21 04:21 AM

I fiddled with this a lot and still haven't found a good solution to this.

Positioning Elements with calculated Pixels didn't really help.

I read an old thread about a technique of having a frame that you parent everything to instead of UIParent. And then scale that frame correctly so everything is 1px.

Lua Code:
  1. G.frame = CreateFrame("Frame", nil, self)
  2. local _, height = GetPhysicalScreenSize()
  3. G.frame:SetAllPoints(UIParent)
  4. G.frame:SetScale(768 / height)

Sadly it doesn't seem to fix many of my issues.

I tried out ElvUI and actually noticed they have the same issue on some UI scales. When I click like on Medium or whatever the names of their scales were they actually had some 2px Borders.

Is there maybe just no good fix to this?

runamonk 01-02-21 04:27 AM

I have the same issue with my bag addon. I spent a lot of time trying to figure out how to resolve it and eventually gave up. Notice the grid between icons sometimes has 2 pixels rather than a single pixel. Even though the math checks out and it should be a single pixel. :/

gempir 01-02-21 04:40 AM

Are you also on 2560x1440 ? I feel like that resolution has the most problems.

runamonk 01-02-21 04:41 AM

Yep, if down to 1080p the issue goes away.


Originally Posted by gempir (Post 338147)
Are you also on 2560x1440p ? I feel like that resolution has the most problems.

Lybrial 01-02-21 06:08 AM

Same for my addons.

on 2560 x 1440 I get weird borders sometimes. On 1080p everything is fine.

All times are GMT -6. The time now is 07:50 AM.

vBulletin © 2021, Jelsoft Enterprises Ltd
© 2004 - 2020 MMOUI