Html5 canvas element pixel grid ( pageX and pageY) - html

Hey I'm trying to make a drawing app using html canvas and I'll trace the coordinates of canvas using mouse events and everything went fine. I set my canvas to scr.width and scr.height to make it full screen board..
I'll store all the mouse events in an array for making drawing on canvas
Now the problem is,
Say suppose I used 1920*1080 resolution screen, as mentioned above my canvas will be 1920*1080 (full screen)
And I started storing all my mouse events and pushed it to back-end.
Now I opened my site in 1440 resolution. I cannot see few drawing.
Reason: in 1920*1080 , I traced points above 1440 and stored it in back-end.
When I get it back , from back-end to front in different resolution, I cannot draw all the points which are above 1440 because my screen size max is 1440.
Can anyone tell me a solution for this?
Thanks in advance.
Framework used: angular 6

Sounds like you need to introduce a scale factor.
You should store the original height and width of the canvas when you save it i.e. 1920 x 1080.
For new drawings.
let scale = 1;
For existing drawings calculate a scale factor. This assumes the new screen resolution is proportional to the old.
let scale = currentWidth / originalWidth; // 1440 / 1920 = 0.75
Now use the scale factor for all drawing. e.g.
context.arc(x * scale, y * scale, radius, 0, Math.PI*2, false);

Related

Proper positioning (Screen width & height)

A little lost here. I've got two movieclips. I want one on the far left (out of reach until the user hovers over their left side of the screen) and one on the far right. I've tried playing with Screen, Capabilities, and stage.
I don't know why, but apparently my resolution 1536 by 864?
trace("Screen x = " + Capabilities.screenResolutionX); //Screen x = 1536
trace("Screen y = " + Capabilities.screenResolutionY); //Screen y = 864
I don't want to set the position of the native window to what the difference of the stage's with and height is to screenResoltionX and Y just because that number seems so off to me. I'm on a monitor with it's current resolution at 1920 x 1080. The only thing I can think of is that I have my laptop set to display only on the monitor at this time with it's main screen inactive, yet the window appears on my monitor, so i'm assuming its picking up the values from my monitor .. and my laptop's screen has no where near that weird of a resolution. Anyone know where this is coming from? I've never seen this before. The same numbers return from stage.fullScreenWidth and stage.fullScreenHeight..
I'm using Adobe AIR 17.0 to build this. Building it with an opaque window. The current size of the stage is set to 1024 x 786.
Edit: I want these objects on the edges of the user's screen. I'm trying to get a grid that represents the entire bounds of the user's screen.
When using Capabilities.screenResolutionX & Capabilities.screenResolutionY, it is reporting for the primary display (so if you have more than one monitor, regardless of which monitor your app is on, it will report back the primary monitor's resolution), and only at the time your application starts (so if you change resolution after the app starts Capabilities.screenResolutionX will not reflect the new screen resolution).
Here is a quote from the documentation: (emphasis mine)
This property does not update with a user's screen resolution and instead only indicates the resolution at the time Flash Player or an Adobe AIR application started. Also, the value only specifies the primary screen.
For your purposes, it seems like it shouldn't matter what the screen resolution is. Just use the stage.stageWidth & stage.stageHeight values since they reflect the boundaries of your actual app, regardless of which monitor it's on or if it's full screen, windowed, or scaled etc.
if(stage.mouseX < stage.stageWidth * 0.5){
//mouse is on the left hand side of the application.
}
EDIT
Based off your comment, sounds like you need to do this:
When your app first runs, do this to make it responsive/liquid:
stage.align = StageAlign.TOP_LEFT
stage.scaleMode = StageScaleMode.NO_SCALE
Then the stage.stageWidth and stage.stageHeight properties will reflect the actual window size.
You can maximize it through code with:
stage.nativeWindow.maximize();
You can listen for window sizing changes with:
stage.addEventListener(Event.RESIZE, myResizeHandler);
function myResizeHandler(e:Event):void {
//stage.stageWidth & stage.stageHeight have changed
}

Why would I want to use unit scale? (Libgdx)

I have looked into the SuperKaolio example on Libgdx github repo. It is basically a test for integrating Tiled maps with Libgdx. They are using the unit scale 1/16 and if I have understood it correctly it means that the world no longer is based on a grid of pixels but on a grid of units (each 16 pixels wide). This is the code and comment in the example:
// load the map, set the unit scale to 1/16 (1 unit == 16 pixels)
map = new TmxMapLoader().load("data/maps/tiled/super-koalio/level1.tmx");
renderer = new OrthogonalTiledMapRenderer(map, 1 / 16f);
I am basically wondering why you would want to do that. I only got problems doing it and can't see any obvious advantages.
For example, one problem I had was adding a BitMap font. It didn't scale at all with the background and one pixel in the font occupied an entire unit. Image here.
I'm using this code for drawing the font. It's a standard 14 points arial font included in libgdx
BitmapFont font = new BitmapFont();
font.setColor(Color.YELLOW);
public void draw(){
spriteBatch.begin();
font.draw(batch, "Score: " + thescore, camera.position.x, 10f);
spriteBatch.end();
}
I assume there is a handy reason to have a 1/16th scale for tiled maps (perhaps for doing computations on which tile is being hit or changing tiles (they're at handy whole-number indices).
Anyway, regardless of what transformation (and thus what "camera" and thus what projection matrix) is used for rendering your tiles, you can use a different camera for your UI.
Look at the Superjumper demo, and see it uses a separate "guiCam" to render the "GUI" elements (pause button, game over text, etc). The WorldRenderer has its own camera that uses world-space coordinates to update and display the world.
This way you can use the appropriate coordinates for each aspect of your display.

Flickering during resizing of HTML5 canvas

I'm observing some flickering during the resizing of an animated canvas control.
You can see it in action at this page. Drag the 'width' slider left and right to try it for yourself. I see this flickering in Chrome 26.0.1410.43 running on Linux. Currently this page won't work in Firefox until it supports HTML5's <input type="range">.
I've tried to reproduce the issue on a smaller scale in this jsFiddle. It's not as noticeable, but occurs for me when the canvas is around 90% of the available width wide.
The code traps requestAnimationFrame, and resizing wipes the canvas. I would hope that the render callback would be called before the browser's frame was painted. This doesn't seem to be the case, as the white background shows through occasionally during resizing.
Is there anything that can be done to avoid this?
When you set canvas.width or canvas.height it clears the canvas, combined with the redrawing this causes the flicker you see.
You can mitigate this to a reasonable extent by saving the canvas to a temporary canvas before resizing and then drawing it back again afterwards.
Here's my resize function:
function resize(width, height) {
//Create temp canvas and context
var tempContext = Utils.Canvas.Create2DContext(context.canvas.width, context.canvas.height);
//Draw current canvas to temp canvas
tempContext.drawImage(context.canvas, 0, 0);
//Resize current canvas
context.canvas.height = height;
context.canvas.width = width;
//Draw temp canvas back to the current canvas
context.drawImage(tempContext.canvas, 0, 0);
}
If you resize to a smaller size then the temp canvas is "overdrawn" so it'll completely fill the current canvas. However if you resize to a larger size then your temp canvas will only fill part of the current canvas. The part it doesn't fill will still flicker as it's redrawn.
If you wanted to get a bit more fancy you could try drawing a temp canvas of the correct (final) size rather than simply copying the current canvas. This would be slower but could well eliminate all flicker.
In my case I'm resizing to fill a div, so having a little flicker along the bottom and right edges is tolerable, and certainly much better than the whole thing flickering.
EDIT:
Here's an update of your jsFiddle with my changes applied:
jsfiddle.net/Uz5Pt/13
It seems to work better than where I'm using it in my app! You can hardly see any flashing on any newly created bits of canvas.

How do I rotate StageVideo 90 degrees

I have a mobile application that I am going to allow for landscape mode when you are playing stagevideo.
I'm farmiliar with creating a veiwport and getting stagevideo to play on ios. I am detecting when the device orientation changes and I would then like to rotate stagevideo object when the orientation changes. I'm not finding any examples or documentation on how to do this.
I notice that the Rectangle object has topLeft and bottomRight values that can be set. I'm wondering if changing the values will do the trick, or will creating a new view port setting X, Y and width and height will rotate the video if I set the X and Y to the corner that is now "0, 0" after rotation ? In other words if I rotate my phone clockwise in landscape then the new view port would be something like this.
sv.viewPort = new Rectangle(0, view.stage.stageHeight, view.stage.stageHeight, view.stage.stageWidth);
You can rotate the video played by the StageVideo class by encoding it rotated!
For example, in After Effects, just rotate the composition containing the video after nesting it into a new composition. Then render. Then pick it up with StageVideo. Voila.

ActionScript Screen Measurements

i'm attempting to use the Capabilities class to draw an accurately sized sprite on screen at exactly (2.5" x 5") regardless of the screen's resolution, but while i believe the code is correct, the size of the sprite is not accurate - when actually measuring it with a ruler.
function inchesToPixels(inches:Number):uint
{
return Math.round(Capabilities.screenDPI * inches);
}
var mySprite:Sprite = new Sprite();
mySprite.graphics.beginFill(0x000000, 0.5);
mySprite.graphics.drawRect(0, 0, inchesToPixels(2.5), inchesToPixels(5));
mySprite.graphics.endFill();
addChild(mySprite);
I'm not entirely sure about this, but my feeling is that the screenDPI value being returned by the Capabilities class would be the same value for two monitors running the same resolution, even if the monitors had different physical dimensions.
To illustrate, if you have two monitors, one which is 14" and the other which is 28", both displaying the same resolution of 800 x 600 pixels, that screenDPI property will return the same thing because they're both using the same resolution.
However, the number of dots in a literal, real-world inch on each screen will be different because of the physical dimensions of the monitor. So when you're running your code and measuring the on-screen Sprite you create with a ruler, it's not going to match up to real-world inches. I'm not sure how you could get around this problem (if I'm right about what's causing it), it seems like it'd be difficult.
Debu
I suggest at the start of your app telling the user "I detected your monitor is XX inches" (where XX is calculated from screenDPI), and allow the user to type in a correct monitor size.