We are facing issues in Xamarin grid layout, the sizes are defined in the OnAppearing method. every time if we call OnAppearing method, the size of grid is reducing continuously, not getting exact issue
here is the code
gridLayout.RowDefinitions.Add(new RowDefinition(){
Height = new GridLength(5, GridUnitType.Star),
});
gridLayout.RowDefinitions.Add(new RowDefinition(){
Height = new GridLength(5, GridUnitType.Star),
});
gridLayout.ColumnDefinitions.Add(new ColumnDefinition()
{
Width = new GridLength(2, GridUnitType.Star),
});
gridLayout.ColumnDefinitions.Add(new ColumnDefinition(){
Width = new GridLength(2, GridUnitType.Star),
});
gridLayout.ColumnDefinitions.Add(new ColumnDefinition(){
Width = new GridLength(2, GridUnitType.Star),
});
gridLayout.ColumnDefinitions.Add(new ColumnDefinition(){
Width = new GridLength(2, GridUnitType.Star),
});
gridLayout.ColumnDefinitions.Add(new ColumnDefinition(){
Width = new GridLength(2, GridUnitType.Star),
});
var productIndex = 0;
for (int rowIndex = 0; rowIndex < 2; rowIndex++)
{
for (int columnIndex = 0; columnIndex < 5; columnIndex++)
{
if (productIndex >= CategoryArray.Count)
{
break;
}
var category = CategoryArray[productIndex];
productIndex += 1;
var categoriesView = new CategoriesView
{
BackgroundColor = Color.White
};
if(category.Image == null){
categoriesView.CategoriesImage.Source = "category_logo";
}else{
categoriesView.CategoriesImage.Source = category.Image;
}
//categoriesView.BackgroundColor = Color.Olive;
categoriesView.TextLabel.Text = category.Name;
categoriesView.CategoryId = category.Id.ToString();
gridLayout.Children.Add(categoriesView, columnIndex, rowIndex);
//gridLayout.BackgroundColor = Color.Beige;
}
}
when ever OnAppearing is calling the page is reloading (the is the feature) and the grid size is reducing continuously.
You should declare the Grid structure only once, ideally in Constructor (or in XAML which is called in the constructor). Whenever OnAppearing is called, you are adding 2 new rows and 5 new columns to the existing Grid hence its size is reducing.
Also, by looking at the elements adding logic you've written, you should probably be using ListView with a Grid ViewCell and set the ItemsSource to an ObservableCollection so that it will update automatically
Related
I am trying to draw a straight line making x fix using freeDrawingBrush.
For example:
canvas.isDrawingMode = 1;
canvas.freeDrawingBrush.color = "purple";
canvas.freeDrawingBrush.width = 10;
canvas._onMouseMoveInDrawingMode = function (e) {
var pointer = canvas.getPointer(e);
pointer.x = 100;
this.freeDrawingBrush.onMouseMove(pointer);
}
this doing the work but it is drawing continuously on mousemove. I want user to be able to draw multiple lines at a fix (for e.g.) x=100 at distances on y-axis.
Update:
I added following code :
canvas._onMouseUpInDrawingMode = function (e) {
this._isCurrentlyDrawing = false;
//canvas.selection = true;
canvas.isDrawingMode = 0;
this.freeDrawingBrush.onMouseUp();
this._handleEvent(e, 'up');
}
This stops drawing continuously but new problem raised. When I enable drawing mode again and try to draw new line it also add previous line to new line
After a lot of research I found the way:
var brush = new fabric.PencilBrush(canvas);
canvas.isDrawingMode = 1;
brush.width = 10;
canvas._onMouseMoveInDrawingMode = function (e) {
var pointer = canvas.getPointer(e);
pointer.x = 100;
brush.onMouseDown({x:pointer.x, y:pointer.y});
}
i am trying to making zoomin images slideshow using pixijs on canvas from three images like this
I tried but not succeed. My question in how to add zoomin or zoomout image in pixijs for specific width and height, then second image and so on.
I am writing this code
var pixiapp;
var pixiloader = PIXI.Loader.shared;
initpixiapp();
function initpixiapp() {
pixiapp = new PIXI.Application({ width: 1280, height: 720 });
document.getElementById('canvas-container').appendChild(pixiapp.view);
pixiloader.add('images/img1.png').add('images/img2.png').add('images/img3.png').load(handleimagesload);
}
function handleimagesload() {
var imagessprites=[]
var img1 = new PIXI.Sprite(pixiloader.resources['images/img1.png'].texture);
var img2 = new PIXI.Sprite(pixiloader.resources['images/img2.png'].texture);
var img3 = new PIXI.Sprite(pixiloader.resources['images/img3.png'].texture);
imagessprites.push(img1)
imagessprites.push(img2)
imagessprites.push(img3);
for (let index = 0; index < imagessprites.length; index++) {
const element = imagessprites[index];
pixiapp.stage.addChild(element);
// here will the the code to run zoom image to specific width and heigth and then move to next image,
// here is my code, its only display zooming third image
var ticker = new PIXI.Ticker();
ticker.add(() => {
console.log('ticker called')
element.width += 1;
element.height += 1;
if(element.width==1500)
{
ticker.stop()
}
})
ticker.start()
}
}
One more things, how to display a box with text for three seconds before slideshow start.
Try something like this:
var pixiapp;
var pixiloader = PIXI.Loader.shared;
initpixiapp();
function initpixiapp() {
pixiapp = new PIXI.Application({ width: 1280, height: 720 });
document.getElementById('canvas-container').appendChild(pixiapp.view);
pixiloader
.add('images/img1.png')
.add('images/img2.png')
.add('images/img3.png')
.load(handleimagesload);
}
function handleimagesload() {
var imagessprites = [];
var img1 = new PIXI.Sprite(pixiloader.resources['images/img1.png'].texture);
var img2 = new PIXI.Sprite(pixiloader.resources['images/img2.png'].texture);
var img3 = new PIXI.Sprite(pixiloader.resources['images/img3.png'].texture);
imagessprites.push(img1);
imagessprites.push(img2);
imagessprites.push(img3);
// Put first image on stage:
var currentImageIndex = 0;
var currentImage = imagessprites[currentImageIndex];
pixiapp.stage.addChild(currentImage);
var ticker = new PIXI.Ticker();
// Start "main animation loop":
ticker.add(() => {
currentImage.width += 1;
currentImage.height += 1;
if (currentImage.width >= 1500) {
// remove current image from stage:
pixiapp.stage.removeChild(currentImage);
// Move to next image:
// Increase index - but if it reached maximum then go back to 0 (to first image)
currentImageIndex++;
if (currentImageIndex >= imagessprites.length) {
currentImageIndex = 0;
}
currentImage = imagessprites[currentImageIndex];
// Set initial width and height of image (TODO: adjust this)
currentImage.width = 1000;
currentImage.height = 1000;
// put image on stage:
pixiapp.stage.addChild(currentImage);
}
});
ticker.start()
}
I'm trying to create a text input on top of a fabric canvas using either IText or Textbox objects. This seems to be accomplished pretty well on http://impretty.me, which is using Fabric, but I can't seem to replicate what they're doing here. I'd either like to be able to set a max width/max character count on IText or limit the Textbox object to a single line.
My issue is that setting a width on IText is ineffective, and even though the width parameter works on Textbox, I need to keep the text to a single line. Scaling text, as is seen on http://impretty.me would be nice but isn't necessary. Any help would be greatly appreciated.
Code for the text box and the interaction I've worked out at this point is below.
const text = new fabric.IText('Type Your Message', {
originY: 'center',
hoverCursor: 'text',
left: 210,
top: 825,
width: 300,
fontFamily: 'Permanent Marker',
fontSize: 50,
hasBorders: false,
hasControls: false,
lockMovementX: true,
lockMovementY: true,
id: 'text'
})
canvas.add(text)
text.on('changed', function (options) {
if (this.width >= 635) {
const newText = this.text.slice(0, -1)
this.text = newText
this.hiddenTextarea.value = newText
console.log(this)
}
})
you can resize down the text to fit inside the bounding box
sizeDownTextNew = function(canvasObj, limit_height, limit_width )
{
if(typeof (canvasObj) == "undefined" || canvasObj == null)
return;
var counter = 250; //Maximum of 250iterations to size down
var initial_height = limit_height;
var max = canvasObj.get('fontSize');
var min = 6; //This is our minimum size
var foundmin=0; //Flag if minimum is met
var ratio = max;
//Now reduce the size of actual text font size property
while(canvasObj.height+2<canvasObj._getTextHeight()) //While the height of text is larger then actual text, try reducing the lineHeight
{
var fontSize = parseFloat(canvasObj.get('fontSize'));
fontSize=fontSize - fontSize/max; //reduce the size with a set ratio
if(fontSize > min) //If main font is greater then min font, we will now reduce
{
canvasObj.set('fontSize', fontSize);
canvasObj.height = initial_height
canvasObj.canvas.renderAll();
canvasObj.height = initial_height;
canvasObj.setCoords();
canvasObj.canvas.renderAll();
if(counter == 0) //Failsafe to exit the while loop if no condition is met
break;
}
counter = 300;
while(limit_width<canvasObj._getTextWidth()) //While the width of text is larger then actual text, try reducing it
{
var fontSize = parseFloat(canvasObj.get('fontSize'));
fontSize=fontSize - fontSize/ratio; //reduce the size with a set ratio
canvasObj.setCoords();
canvasObj.canvas.renderAll();
}
else
{
break;
}
canvasObj.width = limit_width;
counter -- ;
if(counter == 0)
{
break;
}
}
}
and then call this function like
text.on('changed', function (options) {
sizeDownTextNew(this,500,60);
})
you can add 'maxLength' to textarea.
this.on("editing:entered", () => {
if (this.hiddenTextarea) {
// limit textarea length
this.hiddenTextarea.maxLength = 40;
}
});
To limit text for fabric js Version 2+,
We need to override the onInput function as follows
onInput: function(e) {
if(this.width > this.maxWidth) {
return;
}
if(this._textLines.length > this.maxLines) {
return;
}
// Call parent class method
this.callSuper('onInput', e);
}
Note: maxWidth - to limit width
and maxLines - to limit height / lines in text box.
Edit: Fixed Syntax.
I am getting the values of the properties of an object(top,width...) as an object is being scaled/moved by using this function :
canvas.on('object:scaling', onObjectModification);
canvas.on('object:moving', onObjectModification);
canvas.on('object:rotating', onObjectModification);
function onObjectModification(e) {
var activeObject = e.target;
var reachedLimit = false;
objectLeft = activeObject.left,
objectTop = activeObject.top,
objectWidth = activeObject.width,
objectHeight = activeObject.height,
canvasWidth = canvas.width,
canvasHeight = canvas.height;
}
How can I get the same for each object that are being moved as a group? I need the values to be constantly changing as the object:scaling event provide.
I know of the event selection:created but I am lost how to use that to attain what I want. Any help from you guys would be highly appreciated.
Thanks
during object scaling width and height will not change. They will be the same all the time, just scaleX and scaleY will change.
You have to write a function that will iterate on possibile group sub objects.
canvas.on('object:scaling', onObjectModification);
canvas.on('object:moving', onObjectModification);
canvas.on('object:rotating', onObjectModification);
function onObjectModification(e) {
var activeObject = e.target;
if (!activeObject) {
return;
}
var canvasWidth = canvas.width;
var canvasHeight = canvas.height;
var reachedLimit = false;
var objectLeft = activeObject.left;
var objectTop = activeObject.top;
// this provide scaled height and width
var objectWidth = activeObject.getWidth();
var objectHeight = activeObject.getHeight();
if (activeObject._objects) {
objs = activeObject._objects;
for (var i= 0; i < objs.length; i++) {
var obj = objs[i];
var objWidth = activeObject.getWidth() * activeObject.scaleX;
var objHeight = activeObject.getHeight() * activeObject.scaleY;
}
}
}
I am using YUI and need to get the true width of the element. The width of an element can be determined as follows.
width + border-left + border-right + padding-left + padding-right + margin-left + margin-right.
Below is what I have come up with. It appears to be working. I was just wondering if this is the best way to go about determining this or is there there a more efficient way?
YUI().use('node', function(Y) {
var node = Y.one('#nav');
var nodeWidth = trueElementWidth(node);
alert(nodeWidth);
});
function trueElementWidth(el) {
var width = 0;
var attributes = ['border-left', 'border-right', 'padding-left', 'padding-right', 'width', 'margin-right', 'margin-left'];
for(var i=0; i < attributes.length; i++) {
width = width + removePx(el.getComputedStyle(attributes[i]));
}
return width;
}
function removePx(el) {
el = el.toString();
length = el.length - 2;
elDimension = parseInt(el.substring(0, length));
return isNaN(elDimension) ? 0 : elDimension;
}
There is an offsetWidth property that returns exactly what you want.