How do I get the dimensions of the window in a windows 8 metro app?
I want to fill the screen with a canvas element, and currently my default.js file looks something like this
// ... some autogenerated code ...
app.onactivated = function (args) {
if (args.detail.kind === activation.ActivationKind.launch) {
// ... some autogenerated code ...
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
canvas.width = 600; // I want to set width and height here so that
canvas.height = 800; // canvas fills the entire screen/window.
};
// ... more autogenerated code ...
To get the size, you need:
window.outerWidth
window.outerHeight
This will return the logical size with scale factors already applied.
Note that you also want to listen for View State Changes, and when you enter/leave snapped, fill, full modes to make sure that your UI adjusts to the new window sizes.
Specifically, you need to either use CSS media query matching:
var snappedNotification = matchMedia("all and (-ms-view-state: snapped)");
snappedNotification.addEventListener(mySnappedFunction);
Or listen for window.resize, and use the current view state to look at the current view:
var currentViewState = Windows.UI.ViewManagement.ApplicationView.value;
http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.viewmanagement.applicationviewstate.aspx
Physical dimensions can be obtained this way:
var displayInformation = Windows.Graphics.Display.DisplayInformation.getForCurrentView();
var scale = displayInformation.resolutionScale;
var height = Math.ceil(window.outerHeight * scale / 100);
var width = Math.ceil(window.outerWidth * scale / 100);
var physicalWidth = width / displayInformation.rawDpiX; // in inches
var physicalHeight = height / displayInformation.rawDpiY; // in inches
var physicalSize = Math.floor(Math.sqrt(Math.pow(physicalWidth, 2) + Math.pow(physicalHeight, 2)) * 10) / 10; // in inches
I have tried this on several screen sizes and the physicalSize will be accurate in most cases, sometimes with 0.1" error.
I hope it can be helpful.
The following JavaScript code should work:
var height = $('#bodyTag').outerHeight(true);
var width = $('#bodyTag').outerWidth(true);
You can also use the resolutionScale enum if you want to size your canvas based on scale:
var resolutionScale = Windows.Graphics.Display.DisplayProperties.resolutionScale;
Related
CSS
I have a database with a table plan, each table has a property of geometry, with the x and y values.
These values when presented in a web browser get rendered like so:
getStyles() {
const { x, y } = this.props.geometry || {};
return {
left: `${x}%`,
top: `${y}%`,
};
}
So obviously the x and y are percentage values out of 100.
iOS
I've created a UIScrollView and a subclass for the view of each table (TableView).
When the view is added to the scrollView, a method inside TableView gets called to update the table position which looks like this:
- (void)updateTablePosition:(Table *)table {
if (self.superview) {
float x_position = (self.superview.frame.size.width / 100) * table.position.x;
float y_position = (self.superview.frame.size.height / 100) * table.position.y;
[self setFrame:CGRectMake(x_position, y_position, self.frame.size.width, self.frame.size.height)];
}
}
The positions are perfect! However, I have a pan gesture for each TableView which allows me to move them and change the position, the only problem is I can't figure out how to translate this value back to what it would be in CSS (a percentage).
Edit: Removed code to change position because it was completely wrong.
- (void)tablePanAction:(UIPanGestureRecognizer *)sender {
UIScrollView *scrollView = (UIScrollView *)self.superview;
if (sender.state == UIGestureRecognizerStateBegan) {
[scrollView setScrollEnabled:NO];
}
CGPoint updatedLocation = [sender locationInView:scrollView];
self.center = updatedLocation;
if (sender.state == UIGestureRecognizerStateEnded) {
// from here, we should convert the updated location
// back to a relative percentage of the scrollView
}
}
And it turns out.. the answer was ridiculously simple, just took a little bit of thinking. Anyway, i'm answering this question just in case anyones not completely clued up on maths.
The new Table.geometry positions can be calculated like so:
float new_css_x = (self.frame.origin.x / scrollView.frame.size.width) * 100;
float new_css_y = (self.frame.origin.y / scrollView.frame.size.height) * 100;
I'd like to generate custom mip maps for a rendered frame for an effect in THREE.js, but it's not clear how to achieve that. I'll want to regenerate the mip maps again after every frame.
This example shows how to generate mipmaps for a texture, but it looks like the mipmaps array requires a handle to an image or canvas tag, which a renderTarget texture does not have. Ideally I'd like to be able to do something like this:
var rt = new THREE.WebGLRenderTarget()
// initialize and render to the target
var mipmaps = [];
var width = rt.width / 2;
var height = rt.height / 2;
while( width > 2 && height > 2) {
var mip = new THREE.WebGLRenderTarget({ width, height });
mipmaps.push(mip.texture); // mip.texture.image === undefined
// render to the new mipmap with a custom downsample shader
width /= 2;
height /= 2;
}
rt.texture.mipmaps = mipmaps;
// render using the original render target as a texture map and using
// the new mip maps as needed
Is this possible? How would I achieve this?
Thank you!
In Firefox, the default new tab page contains a list of web page recommendations with the page domain name as well as a thumbnail. The thumbnail can be either be a favicon if it is large enough, or a preview image of the web page. Such as this example.
I am trying to create my own version of new tab page with thumbnails similar to Firefox's. Most of the solutions in the Internet suggest to deploy a server (e.g. via node.js) or use a service (e.g. URL2PNG).
Therefore, I am curious how Firefox generate the thumbnails client-side (please correct me if it is actually server-side). Are there any recommended libraries/frameworks (e.g. html2canvas although it cannot screenshot other websites)?
Not sure how useful this is for your case but it renders a snapshot of a window to an intermediate canvas using the (non-standard, internal) CanvasRenderingContext2D.drawWindow() API, then copies that to a target downscaled canvas element.
You can see the code that does this in toolkit/components/thumbnails/PageThumbUtils.jsm:
/** *
* Given a browser window, this creates a snapshot of the content
* and returns a canvas with the resulting snapshot of the content
* at the thumbnail size. It has to do this through a two step process:
*
* 1) Render the content at the window size to a canvas that is 2x the thumbnail size
* 2) Downscale the canvas from (1) down to the thumbnail size
*
* This is because the thumbnail size is too small to render at directly,
* causing pages to believe the browser is a small resolution. Also,
* at that resolution, graphical artifacts / text become very jagged.
* It's actually better to the eye to have small blurry text than sharp
* jagged pixels to represent text.
*
* #params aWindow - the window to create a snapshot of.
* #params aDestCanvas destination canvas to draw the final
* snapshot to. Can be null.
* #param aArgs (optional) Additional named parameters:
* fullScale - request that a non-downscaled image be returned.
* #return Canvas with a scaled thumbnail of the window.
*/
createSnapshotThumbnail(aWindow, aDestCanvas, aArgs) {
if (Cu.isCrossProcessWrapper(aWindow)) {
throw new Error("Do not pass cpows here.");
}
let fullScale = aArgs ? aArgs.fullScale : false;
let [contentWidth, contentHeight] = this.getContentSize(aWindow);
let [thumbnailWidth, thumbnailHeight] = aDestCanvas ?
[aDestCanvas.width, aDestCanvas.height] :
this.getThumbnailSize(aWindow);
// If the caller wants a fullscale image, set the desired thumbnail dims
// to the dims of content and (if provided) size the incoming canvas to
// support our results.
if (fullScale) {
thumbnailWidth = contentWidth;
thumbnailHeight = contentHeight;
if (aDestCanvas) {
aDestCanvas.width = contentWidth;
aDestCanvas.height = contentHeight;
}
}
let intermediateWidth = thumbnailWidth * 2;
let intermediateHeight = thumbnailHeight * 2;
let skipDownscale = false;
// If the intermediate thumbnail is larger than content dims (hiDPI
// devices can experience this) or a full preview is requested render
// at the final thumbnail size.
if ((intermediateWidth >= contentWidth ||
intermediateHeight >= contentHeight) || fullScale) {
intermediateWidth = thumbnailWidth;
intermediateHeight = thumbnailHeight;
skipDownscale = true;
}
// Create an intermediate surface
let snapshotCanvas = this.createCanvas(aWindow, intermediateWidth,
intermediateHeight);
// Step 1: capture the image at the intermediate dims. For thumbnails
// this is twice the thumbnail size, for fullScale images this is at
// content dims.
// Also by default, canvas does not draw the scrollbars, so no need to
// remove the scrollbar sizes.
let scale = Math.min(Math.max(intermediateWidth / contentWidth,
intermediateHeight / contentHeight), 1);
let snapshotCtx = snapshotCanvas.getContext("2d");
snapshotCtx.save();
snapshotCtx.scale(scale, scale);
snapshotCtx.drawWindow(aWindow, 0, 0, contentWidth, contentHeight,
PageThumbUtils.THUMBNAIL_BG_COLOR,
snapshotCtx.DRAWWINDOW_DO_NOT_FLUSH);
snapshotCtx.restore();
// Part 2: Downscale from our intermediate dims to the final thumbnail
// dims and copy the result to aDestCanvas. If the caller didn't
// provide a target canvas, create a new canvas and return it.
let finalCanvas = aDestCanvas ||
this.createCanvas(aWindow, thumbnailWidth, thumbnailHeight);
let finalCtx = finalCanvas.getContext("2d");
finalCtx.save();
if (!skipDownscale) {
finalCtx.scale(0.5, 0.5);
}
finalCtx.drawImage(snapshotCanvas, 0, 0);
finalCtx.restore();
return finalCanvas;
},
I would like to know wether it is possible to get the dimensions of a texture ?
I used this line to set my texture :
const texture = THREE.ImageUtils.loadTexture(src)
Maybe it is necessary to load the image to get its dimensions (but is it possible only with javascript, not html and its div ?) ?
I would like the material I create afterwards to fit the texture dimensions.
First, THREE.ImageUtils.loadTexture is deprecated in the latest THREE.js (r90). Take a look at THREE.TextureLoader instead.
That said, you can get to the image and its properties from a loaded texture.
texture.image
Depending on the image format, you should be able to access the width/height properties, which will be your texture's dimensions.
Just a note: Loading a texture is asynchronous, so you'll need to define the onLoad callback.
var loader = new THREE.TextureLoader();
var texture = loader.load( "./img.png", function ( tex ) {
// tex and texture are the same in this example, but that might not always be the case
console.log( tex.image.width, tex.image.height );
console.log( texture.image.width, texture.image.height );
} );
If you turn off sizeAttenuation, and you have a function that scales the Sprite according to the desired width, then this function will be like:
scaleWidth(width) {
const tex = sprite.material.map;
const scaleY = tex.image.height / tex.image.width;
sprite.scale.setX(width).setY(width * scaleY);
}
So, at this point, you can set the scale according to the desired width, maintaining the aspectRatio of the image.
Then you must have a function that receives the camera, and depending on the type of camera, updates the sprite's width:
updateScale(cam) {
let cw = 1;
if(cam.isOrthographicCamera) {
cw = cam.right - cam.left;
}
else if(cam.isPerspectiveCamera) {
cw = 2 * cam.aspect * Math.tan(cam.fov * 0.5 * 0.01745329);
}
scaleWidth(cw * desiredScaleFactor);
}
This question already has an answer here:
HTML5 canvas zoom where mouse coordinates
(1 answer)
Closed 8 years ago.
I make program like a paint with HTML5 canvas and javascript. Drawing takes place on the background image. How to zoom my drawing on the background together.
Before zoom it:
After zoom it (need this result):
Note: zoom should be where clicked with the mouse on the background image
I've done this before!
First of all, I set a zoom level attribute on my canvas.
Main.canvas.zoomX = 1;
Main.canvas.zoomY = 1;
I also retain the original size of the canvas for reference.
Main.canvas.originW = Main.canvas.width;
Main.canvas.originH = Main.canvas.height;
I also retain the original left and top of the canvas for reference.
Main.canvas.gLeftStart = 0;
Main.canvas.gTopStart = 0;
I then set a zoom percentage. The zoom level will be adjusted by this amount every time that the zoom event occurs.
Main.canvas.zoomPerc = 0.05;
Next, I set an event listener on my canvas to watch for mousewheel.
Main.canvas.addEventListener('wheel', zoom, true);
Now, I'm going to write a quick function to retrieve the zoom, then I'll explain it.
function zoom(evt)
{
var x;
var y;
Main.canvas.xLayerS = (evt.layerX + (Main.canvas.gLeftStart * -1)) / (Main.canvas.originW * Main.canvas.zoomX);
Main.canvas.yLayerS = (evt.layerY + (Main.canvas.gTopStart * -1)) / (Main.canvas.originH * Main.canvas.zoomY);
Main.canvas.leftPerc = Main.canvas.gLeftStart / (Main.canvas.originW * Main.canvas.zoomX);
Main.canvas.topPerc = Main.canvas.gTopStart / (Main.canvas.originH * Main.canvas.zoomY);
if(evt.deltaY > 1)
{
Main.canvas.zoomX *= 1 + Main.canvas.zoomPerc;
Main.canvas.zoomY *= 1 + Main.canvas.zoomPerc;
}
else
{
Main.canvas.zoomX *= 1 - Main.canvas.zoomPerc;
Main.canvas.zoomY *= 1 - Main.canvas.zoomPerc;
}
var iiDS;
var cmd;
Main.canvas.xLayer = Main.canvas.xLayerS * (Main.canvas.originW * Main.canvas.zoomX);
Main.canvas.yLayer = Main.canvas.yLayerS * (Main.canvas.originH * Main.canvas.zoomY);
Main.context.clearRect(0, 0, Main.canvas.width, Main.canvas.height);
Main.context.beginPath();
Main.canvas.gLeftStart = (evt.layerX - Main.canvas.xLayer);
Main.canvas.gTopStart = (evt.layerY - Main.canvas.yLayer);
for(iiDS = 0; iiDS < Main.dataPoints.length; iiDS++)
{
if(iiDS === 0)
{
cmd = 'moveTo';
}
else
{
cmd = 'lineTo';
}
Main.dataPoints[iiDS].xPerc = Main.dataPoints[iiDS].x / Main.range.x;
Main.dataPoints[iiDS].yPerc = Main.dataPoints[iiDS].y / Main.range.y;
x = Main.canvas.gLeftStart + (Main.dataPoints[iiDS].xPerc * (Main.canvas.originW * Main.canvas.zoomX));
y = Main.canvas.gTopStart + (Main.dataPoints[iiDS].yPerc * (Main.canvas.originH * Main.canvas.zoomY));
Main.context[cmd](x, y);
}
Main.context.stroke();
}
Now that your canvas has been re-sized, you will need to redraw whatever was in it. Remember, any time that you re-size a canvas, you clear the canvas. If your canvas was holding an image, then that's simple, redraw that image at that size. If you canvas was holding data points (like a chart) then I would suggest that you make your data points have percentage like (probably a word for that) positions along your chart, not pixel positions.
More importantly though, I do not suggest that you ever re-size and re-position your canvas on zoom. Your page can get jumbled up and sloppy that way. Instead, use the percentages for size (like I showed you) and use the values for left and top positioning as starting points in your drawing. If a data point was a certain percentage of a way across a chart, it can be drawn at any size. Plus, you can draw outside of your canvas, it just won't be visible. Your canvas would then be more like a view-port.
You can do some really impressive charting this way, which a lot of companies pay a lot of money for. Have fun!
Did you try Context2d.scale(x, y)? You could do the following
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
context.scale(2, 2);
paintBackGround(context);
paintForeGround(context);
scale(factorWidth, factorHeight) Scales all coordinates in the canvas by the factors, so it will scale the background and the drawing. The example would double the size. You don't have to scale your coordinates by yourself, just let canvas do that for you.
Here is an example :
http://www.html5canvastutorials.com/advanced/html5-canvas-transform-scale-tutorial/
The only problem here: you need to scale before you draw, so you need a model that contains the original drawing in original unscaled coordinates, that can be drawn after scaling (paintForeGround() in my example)
Scale() is part of so called Transformations. You can Translate (move along a vector) rotate and scale the content of a canvas by using buildin functions of canvas. Just take a look at the html5canvastutorials. This works with matrix-mutliplications in the background, but it is really simple to use.