Why i have stage.height/width is 0 using PixiJS? - pixi.js

In function setup the value of app.stage.height is 0. Why? There is a text for validator(zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz)
let Application = PIXI.Application,
Container = PIXI.Container,
loader = PIXI.loader,
resources = PIXI.loader.resources,
TextureCache = PIXI.utils.TextureCache,
Sprite = PIXI.Sprite,
Rectangle = PIXI.Rectangle;
let app = new Application({
width: 512,
height: 512,
antialias: true,
transparent: false,
resolution: 1
}
);
document.body.appendChild(app.view);
loader
.add("/img/treasureHunter.json")
.load(setup);
function setup() {
console.log(app.stage.height)
let id = PIXI.loader.resources["/img/treasureHunter.json"].textures;
let dungeon = new Sprite(id["dungeon.png"])
let treasure = new Sprite(id["treasure.png"]);
let explorer = new Sprite(id["explorer.png"]);
explorer.y = app.stage.height / 2 - explorer.height / 2;
console.log(app.stage.height)
explorer.x = 68;
app.stage.addChild(dungeon);
app.stage.addChild(explorer);
app.stage.addChild(treasure);
}

The stage is a Container, whose height is always calculated from its children. Until you don't add any children to the stage, its height will be zero.
Also, the stage's height is not equal to the canvas renderer.view height.

Related

Phaser Scrollable Text Box Tutorial not working on mobile

I recreated the scrolling text box tutorial in my game. However, it is running a bit glitchy on mobile. For example, if I swipe up, the text first goes down for a second and then follows my finger up. You’ll see the problem if you open the tutorial on mobile. Any thoughts? I copied my code below.
var graphics = scene.make.graphics();
graphics.fillRect(x, y + 10, width, height - 20);
var mask = new Phaser.Display.Masks.GeometryMask(scene, graphics);
var text = scene.add.text(x + 20, y + 20, content, {
fontFamily: 'Assistant',
fontSize: '28px',
color: '#000000',
wordWrap: { width: width - 20 }
}).setOrigin(0);
text.setMask(mask);
var minY = height - text.height - 20;
if (text.height <= height - 20) {
minY = y + 20;
}
// The rectangle they can 'drag' within
var zone = scene.add.zone(x, y - 3, width, height + 6).setOrigin(0).setInteractive({useHandCursor: true});
zone.on('pointermove', function (pointer) {
if (pointer.isDown) {
text.y += (pointer.velocity.y / 10);
text.y = Phaser.Math.Clamp(text.y, minY, y + 20);
}
});
I had the same issue. My solution is using "pointer.y" instead of "pointer.velocity.y".
Here is my code:
var previousPointerPositionY;
var currentPointerPositionY;
zone.on('pointerdown', function (pointer) {
previousPointerPositionY = pointer.y;
});
zone.on('pointermove', function (pointer) {
if (pointer.isDown) {
currentPointerPositionY = pointer.y;
if(currentPointerPositionY > previousPointerPositionY){
text.y += 5;
} else if(currentPointerPositionY < previousPointerPositionY){
text.y -= 5;
}
previousPointerPositionY = currentPointerPositionY;
text.y = Phaser.Math.Clamp(text.y, -360, 150);
}
});

How draw plane in three js with two diagonal position vectors known?

We can add plane geometry with this code and position in anywhere:
var geometry = new THREE.PlaneGeometry( 5, 20, 32 );
var material = new THREE.MeshBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} );
var plane = new THREE.Mesh( geometry, material );
scene.add( plane );
But how can we add plane when two diagonal positions are known. Is this possible?
The closest to this so far I have is to get center of two positions and it positions the plane correctly but does not size correctly:
var dir = pointB.clone().subtract(pointA);
var length = dir.length();
dir = dir.normalize().scale(length * 50);
center_position = pointA.clone().add(dir);
Direction is not important in my case, can be set by lookat().
Find the subtraction vector of those two, its absolute values are plane size.
Average vector of those two is plane's center.
Example (r120):
body{
overflow: hidden;
margin: 0;
}
<script type="module">
import * as THREE from "https://threejs.org/build/three.module.js";
import { OrbitControls } from "https://threejs.org/examples/jsm/controls/OrbitControls.js";
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 100);
camera.position.set(0, 5, 10);
let renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
let controls = new OrbitControls(camera, renderer.domElement);
scene.add(new THREE.GridHelper());
let vec1 = new THREE.Vector3(0, 2, 0);
let vec2 = new THREE.Vector3(4, 0, 0);
let size = new THREE.Vector3().subVectors(vec2, vec1);
let center = new THREE.Vector3().addVectors(vec1, vec2).multiplyScalar(0.5);
let planeWidth = Math.abs(size.x);
let planeHeight = Math.abs(size.y);
let planeGeom = new THREE.PlaneBufferGeometry(planeWidth, planeHeight, planeWidth, planeHeight);
let planeMat = new THREE.MeshBasicMaterial({color: "aqua", wireframe: true});
let plane = new THREE.Mesh(planeGeom, planeMat);
plane.position.copy(center);
scene.add(plane);
renderer.setAnimationLoop(()=>{
renderer.render(scene, camera);
});
</script>

How can I restrict gestures are working only draw line area itself in Xamarin.Ios

What I have tried is
CAShapeLayer shapeLayer = new CAShapeLayer();
shapeLayer.Path = new CGPath();
shapeLayer.Path.AddLines(new CGPoint [] { startingPoint, endingPoint});
shapeLayer.StrokeColor = UIColor.Blue.CGColor;
shapeLayer.LineWidth = (System.nfloat)3.0;
shapeLayer.FillColor = UIColor.Clear.CGColor;
var width = Math.Abs(latestPoint.X - initioalPoint.X) + initioalPoint.X;
var height = Math.Abs(latestPoint.Y - initioalPoint.Y) + initioalPoint.Y;
var padding = 10;
shapeLayer.Frame = new CGRect(5, 5, width + padding - 2, height + padding - 2);
var view = new UIView();
view.Layer.AddSubLayer(shapeLayer);
CanvasView canvasDrawLine = new CanvasView(subView);
canvasDrawLine.Frame = new CGRect(5, 5, width + padding, height + padding[![enter image description here][1]][1]);
Public Class CanvasView : UIView
{
public CanvasView(drawline)
{
drawLine.ClipsToBounds = true;
var width = Math.Abs(endingPoint.X - initioalPoint.X) + initioalPoint.X;
var height = Math.Abs(endingPoint.Y - initioalPoint.Y) + initioalPoint.Y;
var padding = 10;
drawLine.Frame = new CGRect(5,5, width + padding, height + padding);
this.AddSubview(drawLine);
setUpGestures();
}
}
scrollView.AddSubview(canvasDrawLine );
when I set the width and height of the frame default, my gestures not working properly, for example If I have apply a pan gesture to the draw line even out of the draw line also pan gesture is working.How can I restrict all gestures are working only draw line area.
you can calculate bounds of your area covered by line :
CoreGraphics.CGPoint initialPoint = new CoreGraphics.CGPoint(1, 2);
CoreGraphics.CGPoint latestPoint = new CoreGraphics.CGPoint(1, 2);
var width = Math.Abs(latestPoint.X - initialPoint.X);
var height = Math.Abs(latestPoint.X - initialPoint.X);
var padding = 10;
subView.Frame = new CGRect(0, 0, width+padding, height+padding);
I have created sample code with simple view controller class -- Have assigned red colour to view containing line. And its working perfect. gesture recogniser is working on red part only --where line is.
public partial class ViewController : UIViewController
{
protected ViewController(IntPtr handle) : base(handle)
{
// Note: this .ctor should not contain any initialization logic.
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
CGPoint initioalPoint = new CGPoint(12, 12);
CGPoint latestPoint = new CGPoint(80, 45);
var shapeLayer = new CAShapeLayer();
shapeLayer.Path = new CGPath();
shapeLayer.Path.AddLines(new CGPoint[] { initioalPoint, latestPoint });
shapeLayer.StrokeColor = UIColor.Blue.CGColor;
shapeLayer.LineWidth = (System.nfloat)3.0;
shapeLayer.FillColor = UIColor.Clear.CGColor;
var subView = new UIView();
var width = Math.Abs(latestPoint.X - initioalPoint.X) + initioalPoint.X;
var height = Math.Abs(latestPoint.Y - initioalPoint.Y) + initioalPoint.Y;
var padding = 10;
subView.Frame = new CGRect(5, 5, width + padding, height + padding);
subView.Layer.AddSublayer(shapeLayer);
shapeLayer.Frame = new CGRect(5, 5, width + padding-2, height + padding-2);
subView.BackgroundColor = UIColor.Red;
var mainView = new UIView();
mainView.Frame = new CGRect(40, 40, width + padding+200, height + padding+200);
mainView.AddSubview(subView);
mainView.BackgroundColor = UIColor.Yellow;
this.View.AddSubview(mainView);
UITapGestureRecognizer tap = new UITapGestureRecognizer();
tap.AddTarget((obj) => {new UIAlertView("tapped","",null,"ok",null).Show();});
subView.AddGestureRecognizer(tap);
//UITapGestureRecognizer tap = new UITapGestureRecognizer(() => Console.WriteLine("tap"));
// Perform any additional setup after loading the view, typically from a nib.
}
public override void DidReceiveMemoryWarning()
{
base.DidReceiveMemoryWarning();
// Release any cached data, images, etc that aren't in use.
}
}
///To check if Touch Point is inside Given Polygon::
CGPoint pt1 = new CGPoint(initioalPoint.X - 50, initioalPoint.Y - 50);
CGPoint pt2 = new CGPoint(initioalPoint.X + 50, initioalPoint.Y - 50);
CGPoint pt3 = new CGPoint(latestPoint.X - 50, latestPoint.Y + 50);
CGPoint pt4 = new CGPoint(latestPoint.X + 50, latestPoint.Y + 50);
UIBezierPath path = new UIBezierPath();
path.MoveTo(pt1);
path.AddLineTo(pt2);
path.AddLineTo(pt3);
path.AddLineTo(pt4);
path.AddLineTo(pt1);
if (!path.ContainsPoint(ToucPoint))
return;

In createjs textAlign Center Causing hit area misalignment

When I set up text as a link, set a bounds shape, and set the hit area to the bounds shape, my hit area is off if the textAlign = 'center'. Any ideas?
var linkColor = "#0000ff";
var linkFont = "bold 14px Times";
var presentationLink = new createjs.Text("View Presentation", linkFont, linkColor);
presentationLink.textAlign = "left";
presentationLink.maxWidth = 170;
presentationLink.x = 300;
presentationLink.y = 125;
stage.addChild(presentationLink);
var plBounds = presentationLink.getTransformedBounds();
var s = new createjs.Shape().set({ x: plBounds.x, y: plBounds.y + plBounds.height });
s.graphics.s(linkColor).moveTo(0, 0).lineTo(plBounds.width, 0);
stage.addChild(s);
var hitAreaForPLink = new createjs.Shape(new createjs.Graphics().beginFill("#ffffff").drawRect(-10, -10, plBounds.width + 20, plBounds.height + 10));
presentationLink.hitArea = hitAreaForPLink;
stage.enableMouseOver();
presentationLink.on("mouseover", function () {
presentationLink.cursor = "pointer";
});
The hitArea is positioned according to its owner's coordinate system. That is, all of the owner's transformations are applied to the hitArea. This is so that if you were to animate the owner, the hitArea would track it as expected.
Since the transformation is already applied, you need to use getBounds, not getTransformedBounds. See this example: http://jsfiddle.net/gskinner/uagv5t84/2/

Control z-index in Fabric.js

In fabricjs, I want to create a scene in which the object under the mouse rises to the top of the scene in z-index, then once the mouse leaves that object, it goes back to the z-index where it came from. One cannot set object.zindex (which would be nice). Instead, I'm using a placeholder object which is put into the object list at the old position, and then the old object is put back in the position where it was in the list using canvas.insertAt. However this is not working.
See http://jsfiddle.net/rFSEV/ for the status of this.
var canvasS = new fabric.Canvas('canvasS', { renderOnAddition: false, hoverCursor: 'pointer', selection: false });
var bars = {}; //storage for bars (bar number indexed by group object)
var selectedBar = null; //selected bar (group object)
var placeholder = new fabric.Text("XXXXX", { fontSize: 12 });
//pass null or a bar
function selectBar(bar) {
if (selectedBar) {
//remove the old topmost bar and put it back in the right zindex
//PROBLEM: It doesn't go back; it stays at the same zindex
selectedBar.remove();
canvasS.insertAt(selectedBar, selectedBar.XZIndex, true);
selectedBar = null;
}
if (bar) {
//put a placeholder object ("XXX" for now) in the position
//where the bar was, and put the bar in the top position
//so it shows topmost
selectedBar = bar;
canvasS.insertAt(placeholder, selectedBar.XZIndex, true);
canvasS.add(bar);
canvasS.renderAll();
}
}
canvasS.on({
'mouse:move': function(e) {
//hook up dynamic zorder
if (!e.target) return;
if (bars[e.target])
selectBar(e.target);
else
selectBar(null);
},
});
var objcount = canvasS.getObjects().length;
//create bars
for (var i = 0; i < 20; ++i) {
var rect = new fabric.Rect({
left: 0,
top: 0,
rx: 3,
ry: 3,
stroke: 'red',
width: 200,
height: 25
});
rect.setGradientFill({
x1: 0,
y1: 0,
x2: 0,
y2: rect.height,
colorStops: {
0: '#080',
1: '#fff'
}
});
var text = new fabric.Text("Bar number " + (i+1), {
fontSize: 12
});
var group = new fabric.Group([ rect, text ], {
left: i + 101,
top: i * 4 + 26
});
group.hasControls = group.hasBorders = false;
//our properties (not part of fabric)
group.XBar = rect;
group.XZIndex = objcount++;
canvasS.add(group);
bars[group] = i;
}
canvasS.renderAll();
Since fabric.js version 1.1.4 a new method for zIndex manipulation is available:
canvas.moveTo(object, index);
object.moveTo(index);
I think this is helpful for your use case. I've updated your jsfiddle - i hope this is what you want:
jsfiddle
Also make sure you change z-index AFTER adding object to canvas.
So code will looks like:
canvas.add(object);
canvas.moveTo(object, index);
Otherwise fabricjs don`t care about z-indexes you setup.
After I added a line object, I was make the line appear under the object using:
canvas.add(line);
canvas.sendToBack(line);
Other options are
canvas.sendBackwards
canvas.sendToBack
canvas.bringForward
canvas.bringToFront
see: https://github.com/fabricjs/fabric.js/issues/135
You can modify your _chooseObjectsToRender method to have the following change at the end of it, and you'll be able to achieve css-style zIndexing.
objsToRender = objsToRender.sort(function(a, b) {
var sortValue = 0, az = a.zIndex || 0, bz = b.zIndex || 0;
if (az < bz) {
sortValue = -1;
}
else if (az > bz) {
sortValue = 1;
}
return sortValue;
});
https://github.com/fabricjs/fabric.js/pull/5088/files
You can use these two functions to get z-index of a fabric object and modify an object's z-index, since there is not specific method to modify z-index by object index :
fabric.Object.prototype.getZIndex = function() {
return this.canvas.getObjects().indexOf(this);
}
fabric.Canvas.prototype.moveToLayer = function(object,position) {
while(object.getZIndex() > position) {
this.sendBackwards(object);
}
}

Resources