How do I dynamically stretch an image in Phaser 3? - javascript

I'm trying to stretch an image dynamically so it expands in one direction in my Phaser 3 game. I've tried using a Tween with scaleX but there's a problem.
The first one is what I have. An image object in Phaser that I want to stretch. The second bar is what happens when I use scaleX. I guess it's what normally should happen, but not what I need. I need it like bar three. The left side of the image should stay aligned and only the right side should stretch. ALso I want to do this in an animation, so it should be something I can use with tweens or similar solutions. It needs to be possible to do it on any angle, so I can't just change the x-position. It has to be possible at any angle, when I don't know what the angle is going to be.
Does anyone know how to do that?

I'm not sure how your code looks like, but here is how I would solve it:
(If I would have to use scaleX and tween)
Although I don't know: what you want/need/mean with the "...on any angle..., here to know/see your code would be good.
just set the origin of the gameObject to 0 since the default is center
adjust the x position to compensate for the new origin position.
Here a runnable example:
(Tween starts a scaleX = 0 to better illustrate, where the origin is)
var config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 800,
height: 600,
backgroundColor: '#ffffff',
scene: {
create: create
}
};
var game = new Phaser.Game(config);
function create ()
{
var original = this.add.rectangle(225, 75, 200, 50, 0x0);
var defaultOrigin = this.add.rectangle(225, 150, 200, 50, 0x0);
// calculate the offset -100 = half width
var setOrigin = this.add.rectangle(225 - 100, 200, 200, 50, 0x0).setOrigin(0);
var setOriginAtAnAngle = this.add.rectangle(225 - 100, 275, 200, 50, 0x0)
.setOrigin(0)
.setAngle(25);
var setOriginAtAnAngle2 = this.add.rectangle(225 - 100, 375, 200, 50, 0x0)
.setOrigin(0, .5)
.setAngle(25);
// rotation in degrees
//setOriginAtAnAngle.angle = 25;
/* origin point */
this.add.rectangle(225, 75, 5, 5, 0xFFA701).setOrigin(0.5);
this.add.rectangle(225, 150, 5, 5, 0xFFA701).setOrigin(0.5);
this.add.rectangle(225 - 100, 200, 5, 5, 0xFFA701).setOrigin(0.5);
this.add.rectangle(225 - 100, 275, 5, 5, 0xFFA701).setOrigin(0.5);
this.add.rectangle(225 - 100, 375, 5, 5, 0xFFA701).setOrigin(0.5, 1);
/* Just code to improve the display */
this.add.line(0, 0, 150, 25, 150, 400, 0x0000ff).setOrigin(0);
this.add.text(150, 75, ' Base Box', { fontFamily: 'Arial', fontSize: '20px', color: '#fff' }).setOrigin(0, .5);
this.add.text(150, 150, ' Origin: default (Center)', { fontFamily: 'Arial', fontSize: '20px', color: '#f00' }).setOrigin(0, .5);
this.add.text(150, 200, ' Origin: 0 (TopLeft)', { fontFamily: 'Arial', fontSize: '20px', color: '#0f0' }).setOrigin(0, -.5);
this.add.text(150, 290, ' Origin: 0 (TopLeft) with angle', { fontFamily: 'Arial', fontSize: '20px', color: '#0f0' })
.setOrigin(0, -.5)
.setAngle(25);
this.add.text(150, 360, ' Origin: 0 (CenterLeft) with angle', { fontFamily: 'Arial', fontSize: '20px', color: '#0f0' })
.setOrigin(0, -.5)
.setAngle(25);
this.text = this.add.text(100, 12, 'Click to replay tween!', { fontFamily: 'Arial', fontSize: '20px', color: '#0000ff', backgroundColor: '#ffffff', fontStyle:'Bold' });
this.tween = this.tweens.add({
targets: [defaultOrigin, setOrigin, setOriginAtAnAngle, setOriginAtAnAngle2],
duration: 3000,
scaleX:{from:0, to:2},
ease: 'Power0',
onStart: _ => this.text.setText('Tween is running!'),
onActive: _ => this.text.setText('Tween is running!'),
onComplete: _=> this.text.setText('Click to replay tween!')
});
this.input.on('pointerdown', _=> {
if(!this.tween.isPlaying()){
this.tween.restart();
}
})
}
canvas {
transform: scale(.5) translate(-50%, -50%)
}
<script src="//cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.min.js"></script>
Update:
Origin's are now marked in the example, with a yellow point, for clarity.

Related

how to draw adjustable Right Angle Using Fabric.js

I am trying to Draw a Right Angle using Rectangles.
My Problem is instead of Using two Rectangles to Draw the Adjustable Right Angle,I want to use a Exact Right Angle as in this Image
I am using the Below code to add the Rectangle using fabric.js
addRect = () => {
this.canvas.add(new fabric.Rect({
left: this.canvas.width / 2,
top: this.canvas.height / 2,
fill: '#ffa726',
width: 100,
centeredRotation: true,
height: 100,
originX: 'center',
originY: 'center',
strokeWidth: 0
}));
}
Kindly Help me to solve this issue.
You can't use a Rect to get just a right angle, but you can use a Polyline. Here's an example:
const points = [
{x: 5, y: 15},
{x: 95, y: 15},
{x: 95, y: 85},
]
const options = {
strokeWidth: 20,
stroke: 'orange',
fill: null,
strokeLineJoin: 'miter',
strokeLineCap: 'butt'
}
const rightAngle = new fabric.Polyline(points, options)
canvas.add(rightAngle)
If you want to interactively adjust the points, you could adapt the code from the custom controls example on the Fabric.js site (Polygon and Polyline are similar).

KonvaJS - How to add shape with button trigger?

Sorry for bad grammar-
i have a problem about how to add shape with button trigger.
but isn't working
here my code :
HTML
<button id="btnCreateRectangle" class="btn-primary-blue">Button Text</button>
And here my js :
function addRectangle(layer) {
var scale = 1;
var rectangle = new Konva.Rect({
x: 12,
y: 12,
numPoints: 5,
innerRadius: 30,
outerRadius: 50,
fill: "#89b717",
opacity: 0.8,
draggable: true,
name: 'rect',
width: 128,
height: 50,
scale: {
x: scale,
y: scale
},
shadowColor: "black",
shadowBlur: 4,
shadowOffset: {
x: 5,
y: 5
},
shadowOpacity: 0.6,
// custom attribute
startScale: scale
});
layer.add(rectangle);
}
document
.getElementById('btnCreateRectangle')
.addEventListener('click', function () {
addRectangle(layer)
});
Im very pretty new in javasrcipt language ,
any suggest or answer will be appreciate
thanks
from the documentation of KonvaJS after adding the rect to layer, you should add that layer to stage https://konvajs.org/docs/overview.html
stage.add(layer);

How to add a border radius to a Textbox in FabricJS

I can't add border radius to Textbox using FabricJS and make it working with edit text.
I Added a Textbox into FabricJS, i used a snippet to add background color to padding.
The only way it worked, i added a rect and grouped it with Textbox, when i did it, the edit was gone.
I created a fiddle for it:
canvas = new fabric.Canvas('main-canvas', {
allowTouchScrolling: true
});
context = canvas.getContext("2d");
var textbox = new fabric.Textbox('Test', {
left: (canvas.width - 150) / 2, // 150 is width of text box
top: (canvas.height - 25) / 2, // 25 is height of text box
width: 150,
fontSize: 20,
fontFamily: 'rubik',
originX: 'center',
originY: 'center',
rx: 10,
ry: 10,
textAlign: 'center',
fill: "#ffffff",
backgroundColor: '#ffffff',
textBackgroundColor: '#ffffff',
padding: 10
});
textbox.setGradient('fill', {
x1: -textbox.width / 2,
y1: 0,
x2: textbox.width / 2,
y2: 0,
colorStops: {
0: "black",
0.5: "red",
1: "blue"
}
});
textbox.setControlsVisibility({
mt: false,
mb: false,
ml: false,
mr: false,
bl: false,
br: false,
tl: false,
tr: false,
mtr: false
});
textbox.set({ // enable padding background color
_getNonTransformedDimensions(){ // Object dimensions
return new fabric.Point(this.width, this.height).scalarAdd(this.padding);
},
_calculateCurrentDimensions(){ // Controls dimensions
return fabric.util.transformPoint(this._getTransformedDimensions(), this.getViewportTransform(), true);
}
});
textbox.borderColor = "#fff";
canvas.add(textbox).setActiveObject(textbox);
canvas.renderAll();
body{
background: #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.4.0/fabric.js"></script>
<div id="canvas-container">
<canvas id="main-canvas" width="300" height="300"></canvas>
</div>
I want the text to have a border radius and able to edit the text.

Angularjs + Kineticjs mouse events

I want to use Angularjs with Kineticjs. The problem is that, it seems angular is overriding mouse events on my stage object.
The following html works fine as stand alone file, you can test it. But if you put this as an Angularjs template, the mouse events stop working.
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
#container {
background-color: black;
background-image: url("http://www.html5canvastutorials.com/demos/assets/line-building.png");
background-position: 1px 0px;
background-repeat: no-repeat;
width: 580px;
height: 327px;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.1.min.js"></script>
<script defer="defer">
function getData() {
return {
'1st Floor': {
color: 'blue',
points: [366, 298, 500, 284, 499, 204, 352, 183, 72, 228, 74, 274]
},
'2nd Floor': {
color: 'red',
points: [72, 228, 73, 193, 340, 96, 498, 154, 498, 191, 341, 171]
},
'3rd Floor': {
color: 'yellow',
points: [73, 192, 73, 160, 340, 23, 500, 109, 499, 139, 342, 93]
},
'Gym': {
color: 'green',
points: [498, 283, 503, 146, 560, 136, 576, 144, 576, 278, 500, 283]
}
}
}
function updateTooltip(tooltip, x, y, text) {
tooltip.getText().setText(text);
tooltip.setPosition(x, y);
tooltip.show();
}
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 325
});
var shapesLayer = new Kinetic.Layer();
var tooltipLayer = new Kinetic.Layer();
var tooltip = new Kinetic.Label({
opacity: 0.75,
visible: false,
listening: false,
text: {
text: '',
fontFamily: 'Calibri',
fontSize: 18,
padding: 5,
fill: 'white'
},
rect: {
fill: 'black',
pointerDirection: 'down',
pointerWidth: 10,
pointerHeight: 10,
lineJoin: 'round',
shadowColor: 'black',
shadowBlur: 10,
shadowOffset: 10,
shadowOpacity: 0.5
}
});
tooltipLayer.add(tooltip);
// get areas data
var areas = getData();
// draw areas
for(var key in areas) {
var area = areas[key];
var points = area.points;
var shape = new Kinetic.Polygon({
points: points,
fill: area.color,
opacity: 0,
// custom attr
key: key
});
shapesLayer.add(shape);
}
stage.add(shapesLayer);
stage.add(tooltipLayer);
stage.on('mouseover', function(evt) {
var shape = evt.targetNode;
shape.setOpacity(0.5);
shapesLayer.draw();
});
stage.on('mouseout', function(evt) {
var shape = evt.targetNode;
shape.setOpacity(0);
shapesLayer.draw();
tooltip.hide();
tooltipLayer.draw();
});
stage.on('mousemove', function(evt) {
var shape = evt.targetNode;
var mousePos = stage.getMousePosition();
var x = mousePos.x;
var y = mousePos.y - 5;
updateTooltip(tooltip, x, y, shape.attrs.key);
tooltipLayer.batchDraw();
});
</script>
How does event handling work on angular? And how could I prevent from overriding events like:
stage.on('mouseover', function(evt) {
var shape = evt.targetNode;
shape.setOpacity(0.5);
shapesLayer.draw();
});
Thanks!
Ok, it seems Angular was capturing all DOM events.
The solution is to put Kineticjs tag before angular.js(and probably before jQuery too), and be sure you don't declare the tag again elsewhere in any view.

KineticJS change property after object creation (NOOB)

Hello guys I am a noob in KineticJS and I want to know how to change property values. For example for a rectangle after its creation:
var rect = new Kinetic.Rect({
x: 239,
y: 75,
width: 100,
height: 50,
fill: "#00D2FF",
stroke: "black",
strokeWidth: 4
});
How would I do something like this:
rect.NewProperty({
x: 100,
y: 30,
width: 100,
height: 50,
fill: "#cccccc",
});
and leave the other properties the same?
Like this:
var rect = new Kinetic.Rect({
x: 239,
y: 75,
width: 100,
height: 50,
fill: "#00D2FF",
stroke: "black",
strokeWidth: 4
});
rect.setFill("#D200FF");
rect.setStrokeWidth(1);
thanks for the info..
i also tried
rect.setWidth(100);
and
rect.setHeight(100);
it works :)

Categories

Resources