Phaser 3: Text displayed using TrueType (.ttf) font renders distorted/blurred - html5-canvas

I'm loading a .ttf file via CSS and definition of font-face.
However, in the game the text renders blurry.
This is what I tried first (the font name is truetypetest):
this.sampleText = this.scene.add.text(0, 0, 'Almost clear text', { fontFamily: 'truetypetest' });
This actually renders almost clearly:
Almost clear text
There is still some sort of lighter 'shadow' if you look carefully. Setting the resolution arbitrarily high via the below gives what I want:
this.sampleText = this.scene.add.text(0, 0, 'Clear text', { fontFamily: 'truetypetest' }).setResolution(10);
This renders clearly:
Clear text
However, I don't want to be setting resolution this way as it's expensive memory-wise.
Furthermore, if I avoid setting the resolution AND specify a specific fontSize, via:
this.sampleText = this.scene.add.text(0, 0, 'Blurry text', { fontFamily: 'truetypetest', fontSize: '20px' });
This renders as blurry text:
Blurry text
I should mention that I'm rendering the text inside a container (GameObjects.Container). Also, and I suspect this is the key problem - I'm zooming the canvas using:
scale: {
parent: 'game-canvas',
zoom: 2,
autoCenter: Phaser.Scale.CENTER_BOTH,
}
I can't avoid using the zoom at this stage as the art is based off of this requirement. I've also tried using Bitmap font with no luck.
So my question is how do I use my custom font in my game that can render clear text for a wide range of different fontSize?
Thanks!
UPDATE
I've tried all of the following but with no luck:
Used Bitmap Fonts (including adding png font-sheets for different sizes
Tried rex WebFont Loader plugin: https://rexrainbow.github.io/phaser3-rex-notes/docs/site/webfontloader/#test-string (loads font but still blurry)
Used a normal font like Roboto from the Google Font API. So the problem is not isolated to my particular font style (pixel-style font)
Tried following the method described here: https://phaser.io/examples/v3/view/game-objects/text/custom-webfont (CSS injection and custom webfont loading)
Tried multiples of font sizes
Tried autoRound=true
I find it difficult to believe what I'm trying to do is not possible. Its only text being rendered within a container. I would have thought there's a way of ensuring a single font can be used across a general range of sizes within the game? Failing that, I wouldn't mind using a more exhaustive strategy (multiple different font files at different sizes) if that is needed. There MUST be a way of rendering crisp text within a game? :(

Related

Scaling in MathJax with respect to text direction

I'm working on a site which is in Arabic (default text direction is "right to left") and I'm using "Noto Naskh Arabic" font for arabic text and Latin-Modern for latin text which I'm definig by the following css code:
*[dir="ltr"] {
font-size: 20px !important;
font-family:"Latin-Modern";
}
Users may need to enter mathematical equations and I'm using 'Mathjax' for this purpose, the problem is that:
Fractions are displayed without the horizontal line
Equations are displayed with different sizes between arabic and latin paragraph as when I write
some text in english here $\int f(x)dx $
I have come to a slution to the first problem using css
span:lang(ar).MathJax {
direction: ltr !important;
font-family:"Latin-Modern";
}
For the second problem, I need to know if there is a way to automatically specify scale separately for equation which are embedded in Arabic paragraph end those embedded in English paragraph.
It seems like the main issue is that you have to scale in the first place. I'm guessing you did that because MathJax is rendering too large in RTL contexts.
It looks like MathJax is having issues detecting the correct ex-height of the surrounding font. That can be caused by various problems, from fonts not having a correct ex-height to bad CSS interactions; from a quick test it's not the fonts.
As a workaround you can disable font matching in the MathJax configuration
MathJax.Hub.Config({
"HTML-CSS": {matchFontHeight: false},
SVG: {matchFontHeight: false},
CommonHTML: {matchFontHeight: false}
});
You should then also disable the scaling you applied.

What is the best aproach to display images in different devices: CSS3 or jQuery resizing?

I have a webpage with different images of different proportions. I want to display in the best format for different devices: desktop, tablet, smartphone, etc.
Is it best to use CSS3 #media (mx-width: ** px ) or jQuery $( window ).resize(function() and $( document ).ready(function() { with a change in the size of the image?
The last step works very well and does not require to set a lot of different media sizes as in the case of CSS3, but if Javascript is disabled it will not work.
Basically, I want the images to be responsive, but not with re-scaling of the screen of the device, which is what I get with the Javascript code, but offering the full width of the container div when the page and images are displayed in a smartphone. I think that the approach would involve PHP code to get the Client data ( $_SERVER['USER_AGENT'] ) because don't want images to be too big to go outside the screen, and when using a smartphone I don't want the images to be too small to be seen, and here I have the problem of screen resolutio: the pixels of the image can be 1200 px, but it is shown very small because of screen pixel density or resolution.
The best approach these days is using a technique called "responsive image sizes" along with good old CSS to handle image scaling on devices with similar screen sizes.
Using 'resize' event to manipulate the DOM with jQuery is a staging way to bad performance and bad user experience.
The core idea is to load smaller images on smaller screens and down-scale them in browser if image is bigger than required, using:
img {
display: block;
/* You should never upscale raster images in browser */
max-width: 100%;
height: auto;
}
Here is a good article, that covers the concept in details: Responsive Images in Practice
I would recommend checking out lazysizes, it implements lazy-loading as a bonus.
This is how you use it in your markup:
<img
data-sizes="auto"
data-src="image2.jpg"
data-srcset="image1.jpg 300w,
image2.jpg 600w,
image3.jpg 900w" class="lazyload" />

Delphi PNGImage - Image transparency is not pure

I am using PNG images as main image resource in my application. Since im using Delphi 7, i downloaded PNGImage lib and included it in project. I load images like this:
Form.image.Picture.LoadFromFile(PAnsiChar('\background.png'));
Image has transparent and semi transparent pixels on its border. The problem i get is that transparent pixels are filled with random zoomed part of my desktop with currently opened windows, while i expected to see what is actually located beneath form.
Additionally, form has this properties:
BorderStyle: bsNone;
TransparentColor: true;
Visible: false;
Here is a picture of current state (above black line) and desired:
Can this be fixed somehow or it is how delphi deals with transparency?
To have the form "shade" what's beneath it, use the forms AlphaBlend and AlphaBlendValue properties. The .png image doesn't have to be partially (alpha blended) transparent, but it can be.
If you want the form to be semi-transparent you use Alphablending, that's a limitation of Windows. In addition you can have a certain color fully transparent. In the following sample the forms color is clGray, which is also defined as the Transparent color property in addition to the Transparent property set to True. The image, aligned alClient, is 50% transparent, placed on a TImage which is set as transparent, but even so, it doesn't show up as semi-transparent unless you have AlphaBlending on. Again, this is a limitation of Windows. The best you can do is try with a fairly high value for AlphaBlendingValue (240..250) and a rather light image to find the right compromise.

TinyMCE prevent image resizing

I am adding an image to a TinyMCE editor using:
var params = {
src: filename,
title: "Attached image: " + filename,
width: 500
};
ed.execCommand("mceInsertContent", false, ed.dom.createHTML("img", params));
This insert the image correctly in the editor. However, when the user clicks on the image he has the ability of resizing it.
I would like to know if there is a way to:
Prevent the user to resize only in one direction (i.e. how do I keep a fixed aspect ratio for the image)
Completely prevent the user to resize the image
I found a (partial) answer, so I thought I will share it here.
Adding
'object_resizing' : false
In the editor config prevents the resizing.
Note that this is a feature of Mozilla only (e.g. Google Chrome does not allow you to resize the image).
I am still looking for a way of keeping aspect ratio in real time, but I do not know if that is really possible.
You can simply add this little plugin to tinyMCE, I used it and it works very well!
Here's the documentation: Link
You would need to implement a resize handler (for example a jQuery handler).
It might be helpfull to add attributes to your images to save its dimensions or to use one single setting holding the aspect ratio. For this you will adjust the tinymce configuration setting valid_elements to allow those attributes for images - otherwise tinymce would strip them out.
When resize gets fired you grab the new dimensions and adjust the dimensions according to the aspect ratio - eigther adjust using the new width or new heigth (the other value is needs to get corrected).
Example: images have an attribute aspectratio holding the aspect ration
You may place this code in thetinymce setup configuration parameter
setup : function(ed) {
ed.onInit.add(function(ed) {
$(ed.getBody()).find('img').resize( function(event){
$(event.target).css('width', parseInt ( event.target.width * this.aspectratio) );
});
});
}
Update:
I have created a tinymce fiddle to show an example to use with IE.

Safari changing font weights when unrelated animations are running

I'm using css animations on my page and Safari seems to change unrelated font weights elsewhere on the page when animations are running. Any idea why this happens? All other browsers work fine, include webkit ones like Chrome.
I've detailed the bug in a video here - http://www.screenr.com/gZN8
The site is also here - http://airport-r7.appspot.com/ but it might keep changing rapidly.
I'm using compass (#transition-property, #transition-duration) on the arrow icons. No transitions applied on the heading that's flashing. On a Mac - so it might be the hardware acceleration, but I'm still trying to figure it out.
When you trigger GPU compositing (eg, through CSS animation), the browser sends that element to the GPU, but also anything that would appear on top of that element if its top/left properties were changed. This includes any position:relative elements that appear after the animating one.
The solution is to give the animating element position:relative and a z-index that puts it above everything else. That way you get your animation but keep the (superior IMO) sub-pixel font rendering on unrelated elements.
Here's a demo of the problem and solution http://www.youtube.com/watch?v=9Woaz-cKPCE&hd=1
Update: Newer versions of Chrome retain sub-pixel antialiasing on GPU composited elements as long as the element has no transparency, eg has a background with no transparent or semi-transparent pixels. Note that things like border-radius introduce semi-transparent pixels.
Apparently, that's the price you pay for hardware acceleration: all text momentarily turns into images, which causes the drop in render quality.
However, applying html {-webkit-font-smoothing: antialiased} to turn off the sub-pixel anti-aliasing makes this problem go away. That's what I'm doing for now.
UPDATE: Since then, I've also come to learn that this happens only when the browser can't be sure if the section being animated is going to affect the text. This can usually be handled by having the text above (higher z-index than) the elements being animated, and/or making sure the text has a fully opaque background.
I've faced this issue numerous times and have had success adding the following css to the animated element:
z-index: 60000;
position: relative;
It seems it needs both z-index and position to be effective. In my case I was using it with Font Awesome animated spinners.

Resources