white space appear after call phonegap camera function - javascript

In my app, everytime when I call the camera ( either take a picture or scan barcode), there will be a white space added to the bottom(tested on ios 7). It can grow by how many times I used the camera. Looks like the same height of the status bar.
The camera is just using native SDK, nothing else in the code.
CameraHelper.prototype.takeCameraImage = function(callback){
console.log("takeCameraImage");
navigator.camera.getPicture(onSuccess, onFail, { quality: 49,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: navigator.camera.PictureSourceType.CAMERA,
correctOrientation: true,
targetWidth: 266,
targetHeight: 266
});
function onSuccess(imageURI) {
callback({imageURI: imageURI});
}
function onFail(message) {
callback({message: message});
}
};
what's the possible reason for it?

try this one, put this code in your MainViewController.m class
- (void)viewDidLayoutSubviews{
if ([self respondsToSelector:#selector(topLayoutGuide)]) // iOS 7 or above
{
CGFloat top = self.topLayoutGuide.length;
if(self.webView.frame.origin.y == 0){
// We only want to do this once, or if the view has somehow been "restored" by other code.
self.webView.frame = CGRectMake(self.webView.frame.origin.x, self.webView.frame.origin.y + top, self.webView.frame.size.width, self.webView.frame.size.height - top);
}
}
}

For the height try using self.view.frame.size.height - 20 (or what the status bar height is).

I had exactly the same problem on a cordorva app running on an iPhone on OS 7.1. It happens on calls to inAppBrowser, as well. None of the solutions suggested here worked for me.
However, what did work was to find this in MainViewController.m (starting on line 78 for me):
- (void)viewWillAppear:(BOOL)animated
{
// View defaults to full size. If you want to customize the view's size, or its subviews (e.g. webView),
// you can do so here.
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
CGRect viewBounds = [self.webView bounds];
viewBounds.origin.y = 20;
viewBounds.size.height = viewBounds.size.height - 20;
self.webView.frame = viewBounds;
}
[super viewWillAppear:animated];
}
Comment out the following line:
viewBounds.size.height = viewBounds.size.height - 20;
That fixed the compounding white space issue for me completely and I found no negative consequences.

use this code
static int score = 0;
- (void)viewWillAppear:(BOOL)animated
{
// View defaults to full size. If you want to customize the view's size, or its subviews (e.g. webView),
// you can do so here.
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
CGRect viewBounds = [self.webView bounds];
viewBounds.origin.y = 10;
//viewBounds.size.height = viewBounds.size.height - 18;
if (score==0) {
viewBounds.size.height = viewBounds.size.height - 18;
score=1;
}
self.webView.frame = viewBounds;
}
[super viewWillAppear:animated];
}

Related

Dialog position changes on orientation change in Ext JS

I want to display Ext.Dialog in the center of screen which i achieved by using showBy method as below.
dialog.showBy(view.lookupReference('btn'), 'c-c');
It works fine. But when i change the orientation in android device dialog's position gets changed and only half of the dialog is visible.
I tried below steps.
Provided config centered: true
Used center method dynamically
orientationchange event seems to be removed in Ext 6.7
dialog.showBy(Ext.getBody(), 'c-c');
dialog.showBy(Ext.Viewport, 'c-c');
Couldn't make it with any of the above, Any hints to achieve this. I am using Ext JS 6.7
I will give you advice from ExtJS 6.6, be careful it can be updated from 6.7.
I have face the same probleme not so long ago and I found this event : https://docs.sencha.com/extjs/6.6.0/modern/Ext.viewport.Default.html#event-orientationchange
Ok it's only on viewport but i don't found any other solution.
Actually I do something like that :
At the end of my main view initialize function :
Ext.Viewport.on('orientationchange', this.getController().OnOrientationChange, this.getController());
On my main view controller :
OnOrientationChange: function(viewport, orientation) {
viewport.mask();
var actualWidth = window.innerWidth;
var actualHeight = window.innerHeight;
// Orientation check due to latence can fake orientation result
if (orientation === "landscape") {
if (actualWidth < actualHeight) {
Ext.defer(this.OnOrientationChange, 100, this, [viewport, orientation]);
return;
}
}
else if (orientation === "portrait") {
if (actualWidth > actualHeight) {
Ext.defer(this.OnOrientationChange, 100, this, [viewport, orientation]);
return;
}
}
viewport.unmask();
// Xtype liste of object would by notified
var objXtypeList = ['dataview', 'carousel', 'signingarea'];
for (var i = 0, max = objXtypeList.length; i < max; i++) {
var objXtype = objXtypeList[i];
var objList = viewport.query(objXtype);
for (var j = 0, maxJ = objList.length; j < maxJ; j++) {
var obj = objList[j];
if (Ext.isFunction(obj.OnOrientationChange)) {
Ext.defer(obj.OnOrientationChange, 50, obj, [orientation]);
}
}
}
}
Every object's controller that has to react :
OnOrientationChange: function(orientation) {
// The way the object should react
}
I don't know if that was the most correct way to to it, but it's worked for me.

renderAll() not working in fabric.js

I have six floors of a building drawn on a canvas with fabric.js. In order to show only one floor, I do this:
building.selectFloor = function(floorId){
for (var i = 0; i < floors.length; i++){
if (floorId == floors[i].name){
floors[i].visible = true;
}else{
floors[i].visible = false;
}
}
canvas.renderAll();
};
But nothing changes - all floors are still visible. The floors set to visible = false don't disappear until renderAll() is called later on a window resize:
$(window).resize(setSize);
setSize();
function setSize(){
viewportWidth = $(window).width();
viewportHeight = $(window).height();
$appContainer.css({ "width": viewportWidth, "height": viewportHeight});
canvas.setDimensions({ width: viewportWidth, height: viewportHeight });
if (canvas.building){
canvas.building.center();
canvas.building.scaleX = canvas.building.scaleY = (viewportWidth + viewportHeight) / (1920 + 1080);
canvas.renderAll();
}
}
but then they do disappear. Why is one renderAll() working, and the other not? I've tried wrapping the non-functioning renderAll() in a window.timeOut to see if a delay helps, but no luck.
Ok - so I figured it out in the end: building is a group which appears to be getting cached by some internal fabric magic, and the cached version is being rendered instead of the updated version. To render the updated version you have to do this
canvas.building.set('dirty', true);
canvas.renderAll();
Hope that helps someone on down the line.
EDIT
Turns out there's an easier solution still:
canvas.building.objectCaching = false
There is a new version that changed the format to:
canvas.requestRenderAll();
This worked for me in later versions:
// for one canvas
myCanvas.objectCaching = false;
// for all canvas
fabric.Object.prototype.objectCaching = false;
// in both case it still needs to be re-rendered
myCanvas.renderAll();
ps: using version 4.2.0
You have to update (at least in the new version) object properties with object.set({...}) or set object.dirty = true in order to make the cache system recognize the change in the object properties. Disabling cache might not be the best idea, it has been included for a reason. canvas.requestRenderAll(); then works as intended.

FabricJS - performance threading

Sorry if the title was misleading, it's the closest approximation I could come up with, haha.
Okay so I'm using FabricJS for a proof-of-concept for a fabric-printing client, and they require 300PPI images (i.e, freaking huge). Now, if you check the JsFiddle I've popped in below you'll see the tiling is done with some while loops which seem to work fine, except for the fact that the whole browser freezes while loading, meaning I can't even stick up a loader icon.
Have I done something horribly wrong, or is that just sorta how it works? The long loading times are fine as long as I can a) put up a loader and b) it doesn't, uh, "He's dead, Jim!" my Chrome. I'm getting the images with base64, if that helps at all.
Cheers everyone!
EDIT For context, here's one of the functions that creates a pattern from an uploaded file:
function renderMirror(){
showLoader();
var isFullRows = false;
var rowIndex = 0;
var totalHeight = 0;
while(isFullRows == false){
// let's start with filling up the row's columns. start the width at zero.
var totalWidth = 0;
var isFullCols = false;
var colIndex = 0;
if(rowIndex % 2){
var isRowMirrored = false;
}else{
var isRowMirrored = true;
}
while(isFullCols == false){
colIndex++
if(rowIndex == 1){
console.log('row');
}
if(totalWidth >= canvas.width){
isFullCols = true;
}
if(colIndex % 2){
var isColMirrored = false;
}else{
var isColMirrored = true;
}
canvas.add(new fabric.Rect({
left: totalWidth,
top: totalHeight,
fill: pattern,
flipX: isColMirrored,
flipY: isRowMirrored,
height: newImgHeight,
width: newImgWidth,
selectable: false
}));
totalWidth+= newImgWidth;
// safeguard
if(colIndex > 100){
isFullCols = true;
}
}
// now instantiate the row.
rowIndex++;
if(totalHeight >= canvas.height){
isFullRows = true;
}
totalHeight+= newImgHeight;
// safeguard
if(rowIndex > 100){
isFullRows = true;
}
}
hideLoader();
}
The whole thing is here, if you'd like to have a proper look?
I've experienced something similar to generate PDF at 300. I tried two different solutions:
Using webWorkers which will do the heavy work on the background and is not going to freeze the browser, however this approach was a little bit slower in my use case.
The second approach I took was create an endpoint where I get just the base 64 image and then with that data of the image I generate a PDF using imagemagick to create the PDF at 300 DPI also I create a virtual canvas with JS to generate the real size of the image from a scaled canvas in order to make it a little bit faster as well.

Laser Animation with TweenJS and EaselJS

So, I'm trying to create a laser effect, similar to the one located at http://map.norsecorp.com/
For this example, I have a 500x500 canvas. The current javascript part of the solution is located below:
function shootLaser(x, y) {
var beam = new createjs.Shape();
beam.graphics.beginFill("red");
beam.graphics.moveTo(0,1.5).lineTo(70,0).lineTo(70,3).closePath();
beam.x = 80;
beam.y = 50;
stage.addChild(beam);
beam.setBounds(0,0,70,3);
createjs.Tween.get(beam,{ loop: true, onChange: beamUpdate })
.to({ x: 400 }, 1000, createjs.Ease.linear());
}
function beamUpdate(e) {
var beam = e.currentTarget.target;
var targetX = e.currentTarget._curQueueProps.x;
if( targetX - beam.x < beam.getBounds().width ) {
beam.scaleX = (targetX - beam.x) / targetX;
} else {
beam.scaleX = 1;
}
}
This draws the line the way that I want to. However the scaleX method doesn't quite work (not even close really, it just gets extremely small very fast).
The problem is that I can't find a way to shrink the "laser" once it hits it's target. If I shoot it from 0px to 250px. It should hit 250px and begin shrinking until the 250th pixel has "consumed" it for lack of a better term. Any help is greatly appreciated.
P.S. I'm also open to doing this with other libraries or tools. I just haven't found them yet.

Phantom JS - clipRect - Javascript Help

i'm using phantom js to screen shot a page
http://code.google.com/p/phantomjs/wiki/QuickStart#Rendering
it has a feature called clipRect
http://code.google.com/p/phantomjs/wiki/Interface#clipRect_(object)
can someone show me how i would modify the following code to us clipRect so i only get a partial screenshot and not the whole thing?
if (phantom.state.length === 0) {
if (phantom.args.length !== 2) {
console.log('Usage: rasterize.js URL filename');
phantom.exit();
} else {
var address = phantom.args[0];
phantom.state = 'rasterize';
phantom.viewportSize = { width: 600, height: 600 };
phantom.open(address);
}
} else {
var output = phantom.args[1];
phantom.sleep(200);
phantom.render(output);
phantom.exit();
}
If you are trying to get a screenshot of a particular element, you could get the necessary information for clipRect from getBoundingClientRect as per the bottom of this article:
page.clipRect = page.evaluate(function() {
return document.getElementById(THE_ELEMENT_YOU_WANT).getBoundingClientRect();
});
From the fine manual:
clipRect (object)
This property defines the rectangular area of the web page to be rasterized when render() is invoked. If no clipping rectangle is set, render() will process the entire web page.
Example: phantom.clipRect = { top: 14, left: 3, width: 400, height: 300 }
So try setting clipRect right before you call render:
var output = phantom.args[1];
phantom.sleep(200);
phantom.clipRect = { top: 14, left: 3, width: 400, height: 300 }
phantom.render(output);
phantom.exit();
You'd have to figure out where the upper left corner (top and left) is and how big (width and height) you want the clipping rectangle to be.
You can probably set the clipRect any time before render() is called but start with that and see what happens.
What was happening is i was using brew and it was installing v 1.0.0 where clipRect and almost every other function wasn't supported as v 1.0.0 is the oldest version.
If you follow these instructions: http://code.google.com/p/phantomjs/wiki/BuildInstructions#Mac_OS_X
then right click on the complied file and click show/view contents (on mac) then copy the executable bin/phantomjs.app/Contents/MacOS/phantomjs to some directory in your PATH.
Feel free to post on here i'm monitoring this and i can help if needed.

Categories

Resources