html canvas font scaling problem , text is flickering without reason - javascript

I readed many forums, but never found some analogue case.
Javascript canvas font displays in a flickering fashion. The conditions appears to be:
scale of the canvas is not an integer (for example setScale(0.1,0.3))
setTransform(1,0,0,1,0,0); and setScale are used widely to restore setting at every draw of new objects.
Windows. In linux this effect is barely visible (only in some single chars of the text !?).
If the scale is too little (0.5 or less) the effect cannot be seen.
Using save() and restore() seems to have different effect other than setTransform(1,0,0,1,0,0); ans setScale(sx,sy); so i never use them.

I solved the question opting for using only saves and restores : no more flickering. This seems to avoid direct using of setTransoform, and for some reason there should no difference in it.
Sorry for the lack of code, it's a very complicated set of instructions to extract from my coded game.
I hope this is the definitive solution to flickering. Thanks.

Related

Javascript retrieve linebreaks from dom [duplicate]

I need to add line breaks in the positions that the browser naturally adds a newline in a paragraph of text.
For example:
<p>This is some very long text \n that spans a number of lines in the paragraph.</p>
This is a paragraph that the browser chose to break at the position of the \n
I need to find this position and insert a <br />
Does anyone know of any JS libraries or functions that are able to do this?
The only solutuion that I have found so far is to remove tokens from the paragraph and observe the clientHeight property to detect a change in element height. I don't have time to finish this and would like to find something that's already tested.
Edit:
The reason I need to do this is that I need to accurately convert HTML to PDF. Acrobat renders text narrower than the browser does. This results in text that breaks in different positions. I need an identical ragged edge and the same number of lines in the converted PDF.
Edit:
#dtsazza: Thanks for your considered answer. It's not impossible to produce a layout editor that almost exactly replciates HTML I've written 99% of one ;)
The app I'm working on allows a user to create a product catalogue by dragging on 'tiles' The tiles are fixed width, absolutely positioned divs that contain images and text. All elemets are styled so font size is fixed. My solution for finding \n in paragraph is ok 80% of the time and when it works with a given paragrah the resulting PDF is so close to the on-screen version that the differences do not matter. Paragraphs are the same height (to the pixel), images are replaced with high res versions and all bitmap artwork is replaced with SVGs generated server side.
The only slight difference between my HTML and PDF is that Acrobat renderes text slightly more narrowly which results in line slightly shorter line length.
Diodeus's solution of adding span's and finding their coords is a very good one and should give me the location of the BRs. Please remember that the user will never see the HTML with the inserted BRs - these are added so that the PDF conversion produces a paragraph that is exactly the same size.
There are lots of people that seem to think this is impossible. I already have a working app that created extremely accurate HTML->PDF conversion of our docs - I just need a better solution of adding BRs because my solution sometimes misses a BR. BTW when it does work my paragraphs are the same height as the HTML equivalents which is the result we are after.
If anyone is interested in the type of doc i'm converting then you can check ou this screen cast:
http://www.localsa.com.au/brochure/brochure.html
Edit: Many thanks to Diodeus - your suggestion was spot on.
Solution:
for my situation it made more sense to wrap the words in spans instead of the spaces.
var text = paragraphElement.innerHTML.replace(/ /g, '</span> <span>');
text = "<span>"+text+"</span>"; //wrap first and last words.
This wraps each word in a span. I can now query the document to get all the words, iterate and compare y position. When y pos changes add a br.
This works flawlessly and gives me the results I need - Thank you!
I would suggest wrapping all spaces in a span tag and finding the coordinates of each tag. When the Y-value changes, you're on a new line.
I don't think there's going to be a very clean solution to this one, if any at all. The browser will flow a paragraph to fit the available space, linebreaking where needed. Consider that if a user resizes the browser window, all the paragraphs will be rerendered and almost certainly will change their break positions. If the user changes the size of the text on the page, the paragraphs will be rerendered with different line break points. If you (or some script on your page) changes the size of another element on the page, this will change the amount of space available to a floating paragraph and again - different line break points.
Besides, changing the actual markup of your page to mimic something that the browser does for you (and does very well) seems like the wrong approach to whatever you're doing. What's the actual problem you're trying to solve here? There's probably a better way to achieve it.
Edit: OK, so you want to render to PDF the same as "the screen version". Do you have a specific definitive screen version nominated - in terms of browser window dimensions, user stylesheets, font preferences and adjusted font size? The critical thing about HTML is that it deliberately does not specify a specific layout. It simply describes what is on the page, what they are and where they are in relation to one another.
I've seen several misguided attempts before to produce some HTML that will exactly replicate a printed creative, designed in something like a DTP application where a definitive absolute layout is essential. Those efforts were doomed to failure because of the nature of HTML, and doing it the other way round (as you're trying to) will be even worse because you don't even have a definitive starting point to work from.
On the assumption that this is all out of your hands and you'll have to do it anyway, my suggestion would be to give up on the idea of mangling the HTML. Look at the PDF conversion software - if it's any good it should give you some options for font kerning and similar settings. Playing around with the details here should get you something that approximates the font rendering in the browser and thus breaks lines at the same places.
Failing that, all I can suggest is taking screenshots of the browser and parsing these with OCR to work out where the lines break (it shouldn't require a very accurate OCR since you know what the raw text is anyway, it essentially just has to count spaces). Or perhaps just embed the screenshot in the PDF if text search/selection isn't a big deal.
Finally doing it by hand is likely the only way to make this work definitively and reliably.
But really, this is still just wrong and any attempts to revise the requirements would be better. Keep going up one step in the chain - why does the PDF have to have the exact same ragged edge as some arbitrary browser rendering? Can you achieve that purpose in another (better) way?
Sounds like a bad idea when you account for user set font sizes, MS Windows accessibility mode, and the hundreds of different mobile devices. Let the browser do it's thing - trying to have exact control over the rendering will only cause you hours of frustration.
I don't think you'll be able to do this with any kind of accuracy without embedding Gecko/WebKit/Trident or essentially recreating them.
Maybe an alternative: do all line-breaks yourself, instead of relying on the browser. Place all text in pre tags, and add your own linebreaks. Now at least you don't have to figure out where the browser put them.

Animating opacity of 1400 Raphael.js objects hurts animating performance

First off, thank you for any help. :)
JSFiddle code.
JSFiddle full screen
As you can see by the fiddle link above I am animating 1400 objects trying to create a 'twinkling effect'. As the user moves the mouse faster more hexagon shapes pop into full opacity and have varying fade out rates. The version in the fiddle fills the space with enough color but feels jerky and clumpy. If I lessen the fade_time variable amounts it is smoother but does not have enough hexagons with full opacity. The end goal is to spell words with the hexagons.
The performance in Chrome is best, less so in FireFox and IE. I tested (using Raphael's element.touchmove) in mobile safari on an iPad and it was even worse.
I'm looking for any advice on what pieces of the code could be done differently for performance gains.
I saw this answer somebody else gave that was supposed to help with performance, but I'm trying to base the amount of animating hexagons on cursor movement and I'm not sure I could do that with a timer.
This answer mentioned using canvas:
A good alternative would be using Canvas to draw the elements. From my experiments it will be faster than SVG at drawing this many although if you are using some animations, they will be harder to implement than with the RaphaelJS library.
Does that seem like a better route to people, even with the animations the code is using?
This is my first use of Raphael.js. I'm not very experienced in JS in general, so any help is wunderbar!
Edit: Edit: Also, seeing this answer about .resize being called more times than the questioner might have thought got me wondering if the .mousemove function may be called more times (more than I would need) than I would expect.
I think it chokes on "overlapped" animations, i.e. for example:
hexagon number #6 starts its fade
at a half of its fade, another fade is started
I added a stop() instruction to avoid unexpected results.
Besides, the for() cycle doesn't check if another animation is in progress, nor if some hex has been randomly selected twice or more inside the cycle.
As a workaround for this, I added a vector to cache the indexes of the hexagons being animated, although it does not seem to be of great help.
To see how many (useless) animations it saved, uncomment the last console.log().
Besides, your getRandomInt() function generated some undefined index errors (since your array indexes go from 0 to 1399 and it returned integers between 0 and 1400... I changed it.
See my add-ons here: http://jsfiddle.net/rz4yY/46/

Most efficient way to draw particles in HTML5 on iPad 2

I'm trying to create moving lights with trails for an HTML5 website/app targeted at iPad 2.
I wonder what the best way to do this is and whether using HTML5 is viable at all. I chose HTML5 because it's easier and cheaper to develop and deploy than native iOS apps with Objective C. Of course if it turns out that HTML5 simply doesn't offer enough performance I might have to swallow the bitter pill.
Anyway to give you an impression what I'm talking about, this is what I got so far:
screenshot http://devdali.no-ip.org/mathias/test-lights/screenshots/1.jpg
Or you can see it in action here (only works in webkit based browsers).
At first I tried using HTML5 canvas and drawing radial gradients as particles in similar manner you see above. It worked but the framerate was horrible even on my desktop computer!
So after a bit of reading I found out that CSS3 transforms may be hardware accelerated, so I build the version you see above. Every "particle" is a 64x64 png image. For each light there is the "head" light (one img) followed by a trail consisting of 115 img elements. Each img element is transformed using "translate3d" (as well as scale and rotation). Also the opacity of each element is adjusted dynamically.
Doing it this way provided much better framerates on my computer, but I doubt the iPad 2 will handle it.
I'd be grateful if anyone could give me some hints on how to improve the performance of this in general and considering the target platform.
Thanks for any help in advance!
If you accept small changes to the effect, some other procedure may work fast:
Instead of drawing the light's trails by the means of many particles, just draw the lights in their current positions in a Canvas element.
You can then darken the whole image at the beginning of a frame by filling a black rectangle with a very low opacity on top. This way the trails fade into dark, but would not alter their color like they do now.
The amount of drawing operations however will reduce vastly. The most costly operation would be filling the fading rectangle for every frame.
This should be built in the canvas. Check out EaselJS and this demo.
http://easeljs.com/
http://easeljs.com/demos/MusicVisualizer/index.html
You could optimize performances a LOT by using WebGL(, which is supported on the iPad2.)... which is not supported for basic html pages on ios safari as stated Nison Maƫl...
For the time being you only have canvas as a solution. Which will still give you better performances...
(You can check this blog for more info:
http://learningwebgl.com/blog/
With a little faith and time you'll be amazed!)

HTML Canvas Tracing

I'm trying to build something in HTML5/Canvas to allow tracing over an image and alert if deviating from a predefined path.
I've figured out how to load an external image into the canvas, and allow mousedown/mousemovement events over it to draw over the image, but what I'm having trouble getting my head around is comparing the two.
Images are all simple black on white outlines, so from what I can tell a getPixel style event can tell if there is black underneath where has been drawn upon or underneath where the mouse is on.
I could do it with just the mouse position, but that would require defining the paths of every image outline (and there are a fair number, hence ideally wanting to do it by analyzing the underlying image)..
I've been told that its possible with Flash, but would like to avoid that if possible so that compatability with non-flash platforms (namely the ipad) can be maintained as they are the primary target for the page to run.
Any insight or assistance would be appreciated!
I think you already touched upon the most straight-forward approach to solving this.
Given a black and white image on a canvas, you can attach a mousemove event handler to the element to track where the cursor is. If the user is holding left-mouse down, you want to determine whether or not they are currently tracing the pre-defined path. To make things less annoying for the user, I would approach this part of the problem by sampling a small window of pixels. Something around 9x9 pixels would probably be a good size. Note that you want your window size to be odd in both dimensions so that you have a symmetric sampling in both directions.
Using the location of the cursor, call getImageData() on the canvas. Your function call would look something like this: getImageData(center_x - Math.floor(window_size / 2), center_y - Math.floor(window_size / 2), window_size, window_size) so that you get a sample window of pixels with the center right over the cursor. From there, you could do a simple check to see if any non-white pixels are within the window, or you could be more strict and require a certain number of non-white pixels to declare the user on the path.
The key to making this work well, I think, is making sure the user doesn't receive negative feedback when they deviate the tiniest bit from the path (unless that's what you want). At that point you run the risk of making the user annoyed and frustrated.
Ultimately it comes down to one of two approaches. Either you load the actual vector path for the application to compare the user's cursor to (ie. do point-in-path checks), or you sample pixel data from the image. If you don't require the perfect accuracy of point-in-path checking, I think pixel sampling should work fine.
Edit: I just re-read your question and realized that, based on your reference to getPixel(), you might be using WebGL for this. The approach for WebGL would be the same, except you would of course be using different functions. I don't think you need to require WebGL, however, as a 2D context should give you enough flexibility (unless the app is more involved than it seems).

HTML5 canvas performance on small vs. large files

I seem to be experiencing varying performance using an HTML5 canvas based on the memory size of the page... perhaps the number of images (off-screen canvases) that are loaded. How to I best locate the source of the performance problem? Or does anyone know if in fact there is a performance issue when there's a lot of data loaded, even if it isn't all being used at once?
Here's an example of good performance. I have a relatively simple map. It's between 700 and 800 KB. You can drag to scroll around this map relatively smoothly.
There's another file (which you may not want to look at due to its large size).
It's about 16 MB and contains dozens, maybe on the order of a hundred images/canvases. It draws a smaller view so it should go faster. But it doesn't. Many of the maps lag quite severely compared to the simpler demo.
I could try to instrument the code to start timing things, but I have not done this in JavaScript before, and could use some help. If there are easier ways to locate the source of performance problems, I'd be interested.
In Google Chrome and Chromium, you can open the developer tools (tools->developer tools) and then click on "Profiles". Press the circle at the bottom, let the canvas redraw and then click on the circle again. This gives you a profile that shows how much time was spent where.
I've been working on some complex canvas stuff where rendering performance mattered to me.
I wrote some test cases in jsperf and came to the conclusion that a rule of thumb is that a source offscreen canvas should never be more than 65536 pixels.
I haven't yet come to a conclusion about why this is, but likely a data structure or data type has to be changed when dealing with large source canvases.
putImageData showed similar results.
destination canvas size didn't seem to matter.
Here are some tests I wrote that explore this performance limitation:
http://jsperf.com/magic-canvas/2
http://jsperf.com/pixel-count-matters/2

Categories

Resources