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.
Related
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.
I want to draw a polyline:
With arrows
With endpoint control, you can drag and drop, and you will be able to connect with other objects in the future (I don’t know whether to use fabric.js Control or draw a circle by myself)
My current implementation is like this: The line consists of 5 parts:
Two endpoints + two arrows + line body.
When dragging the end point, the arrow position, the arrow angle, and the coordinates of the line body are synchronously modified.
this is demo fabric.PolygonalLine is the key to the problem
var canvas = new fabric.Canvas(document.getElementById("c"))
fabric.PolygonalLine = fabric.util.createClass(fabric.Object, {
// hasControls: false,
// hasBorders: false,
// selectable: true,
points: [],
sControl: null,
eControl: null,
centerControl: null,
// 垂直方向或者水平方向
controlMoveDirection: "",
sArrow: null,
eArrow: null,
initialize: function (points, options = {}) {
this.points = points || []
this.callSuper("initialize", options)
let len = this.points.length
let defaultOpt = {
hasBorders: false,
hasControls: false,
originX: "center",
originY: "center",
}
this.sControl = new fabric.Circle({
fill: null,
radius: 4,
strokeWidth: 1,
stroke: "rgba(57, 87, 239, 0.8)",
left: this.points[0].x,
top: this.points[0].y - 8,
...defaultOpt,
})
this.eControl = new fabric.Circle({
fill: null,
radius: 4,
strokeWidth: 1,
stroke: "rgba(57, 87, 239, 0.8)",
left: this.points[len - 1].x,
top: this.points[len - 1].y + 8,
...defaultOpt,
})
this.sArrow = new fabric.Triangle({
left: this.points[0].x,
top: this.points[0].y,
width: 10,
height: 10,
// selectable: false,
lockMovementX: true,
lockMovementY: true,
...defaultOpt,
})
this.eArrow = new fabric.Triangle({
left: this.points[len - 1].x,
top: this.points[len - 1].y,
width: 10,
height: 10,
angle: 180,
// selectable: false,
lockMovementX: true,
lockMovementY: true,
...defaultOpt,
})
canvas.add(this.sArrow, this.eArrow, this.sControl, this.eControl)
this._bindEvents()
},
_bindEvents() {
this.sControl.on("moving", (e) => {
this.sArrow.set({
left: e.pointer.x,
top: e.pointer.y + 8,
})
this.points[0].x = e.pointer.x
this.points[0].y = e.pointer.y
this.points[1].x = e.pointer.x
canvas.requestRenderAll()
})
this.eControl.on("moving", (e) => {
this.eArrow.set({
left: e.pointer.x,
top: e.pointer.y - 8,
})
this.points[3].x = e.pointer.x
this.points[3].y = e.pointer.y
this.points[2].x = e.pointer.x
canvas.requestRenderAll()
})
this.sControl.on("selected", (e) => {
console.log("---106-11-selected---", this)
})
this.on("selected", (e) => {
console.log("---106---selected--", e)
})
this.on("moving", (e) => {
console.log("---110--moving---", e)
})
},
render(ctx) {
ctx.save()
ctx.beginPath()
ctx.moveTo(this.points[0].x, this.points[0].y)
for (let i = 0; i < this.points.length - 1; i++) {
let point = this.points[i]
ctx.lineTo(point.x, point.y)
}
ctx.lineTo(this.points[3].x, this.points[3].y)
ctx.stroke()
ctx.restore()
},
})
// ---------------------------content---------------------
let rect = new fabric.Rect({
width: 50,
height: 50,
left: 10,
top: 5,
fill: "rgba(255,0,0,0.5)",
})
let circle = new fabric.Circle({
width: 50,
height: 50,
radius: 25,
left: 200,
top: 205,
fill: "#aac",
})
let line = new fabric.PolygonalLine(
[
{
x: 35,
y: 70,
},
{
x: 35,
y: 120,
},
{
x: 225,
y: 120,
},
{
x: 225,
y: 190,
},
],
{
text: "",
stroke: "red",
strokeWidth: 2,
strokeLineCap: "butt",
strokeDashArray: [10, 5],
}
)
canvas.add(rect, circle, line)
canvas.zoomToPoint({ x: 0, y: 0 }, 2)
canvas.renderAll()
canvas {
border: 1px solid #999;
display:inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/460/fabric.js"></script>
<canvas id="c" width="600" height="600"></canvas>
But it feels awkward to do so. Does any friend have a better way? Or provide an idea. Grateful.
I'm facing an issue where the hover label of multiple traces overlaps with the x-axis's hover label when all the trace values are close to 0.
In the example below, you can see the overlap when you mouseover x=1000
const data = []
const x = [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000];
data.push({
x: x,
y: [100, 105, 132, 150, 130, 103, 2, 200, 301, 1],
});
data.push({
x: x,
y: [200, 205, 232, 250, 230, 193, 1, 100, 201, 0],
})
data.push({
x: x,
y: [0, 205, 232, 250, 230, 193, 10, 100, 0, 0],
})
const layout = {
height: 350,
xaxis: {
// tickformat: ',.2r',
},
hoverlabel: {
font: {
family: 'Helvetica Neue',
size: 11,
}
}
}
Plotly.plot('graph', data, layout);
<head>
<!-- Plotly.js -->
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
<div id="graph"></div>
</body>
https://codepen.io/anon/pen/RBpQPg
Any workarounds would be appreciated. For example, would it be possible to combine all the hover labels into 1 label somehow?
I am working on fabric js app & i trying to apply shadow to imported SVG without stroke shadow
when i apply shadow to SVG then shadow is also applied to stroke of svg but i don't want this
Thanks in advance for help
My tried code is
canvas = new fabric.Canvas('canvas');
var shadow = {
color: 'rgba(0,0,0,0.6)',
blur: 20,
offsetX: 10,
offsetY: 10,
opacity: 0.6,
fillShadow: true,
strokeShadow: false
}
var s = '<svg width="100" height="100"><polygon points="30 0, 70 0, 99 33, 99 66, 70 99, 30 99, 0 66, 0 33" fill="#bbb"/></svg>'
fabric.loadSVGFromString(s, function(objects, options) {
var shape = fabric.util.groupSVGElements(objects, options);
//shape.setShadow("10px 10px 5px rgba(94, 128, 191, 0.5)");
if (shape.isSameColor && shape.isSameColor() || !shape.paths) {
console.log('shape');
shape.set({
strokeWidth: 3,
stroke: '#000'
});
}
if (shape.paths) {
console.log('shape path');
/*for (i in shape.paths) {
shape.paths[i].set({
strokeWidth: strokewidth,
stroke: strokecolor
});
}*/
allObjects = shape.paths;
$.each(allObjects, function(key, value) {
value.set({
strokeWidth: 3,
stroke: '#000'
});
});
}
//shape.setShadow("10px 10px 5px rgba(94, 128, 191, 0.5)");
shape.setShadow(shadow);
canvas.add(shape).renderAll();
});
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id='canvas' width="500" height="400" style="border:#000 1px solid;"></canvas>
canvas = new fabric.Canvas('canvas');
var shadow = {
color: 'rgba(0,0,0,0.6)',
blur: 20,
offsetX: 10,
offsetY: 10,
opacity: 0.6,
affectStroke: false
}
var s = '<svg width="100" height="100"><polygon points="30 0, 70 0, 99 33, 99 66, 70 99, 30 99, 0 66, 0 33" fill="#bbb"/></svg>'
fabric.loadSVGFromString(s, function(objects, options) {
var shape = fabric.util.groupSVGElements(objects, options);
if (shape.paths) {
allObjects = shape.paths;
$.each(allObjects, function(key, value) {
value.set({
shadow: shadow,
strokeWidth: 3,
stroke: '#000',
});
value.shadow.affectStroke = false;
});
}
canvas.add(shape).renderAll();
});
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id='canvas' width="500" height="400" style="border:#000 1px solid;"></canvas>
I refined your code to apply the shadow just on paths instead of pathGroup. For what concerns shadow.affectStroke = false not working on pathGroups, this may be a bug, or simply fabric.PathGroup shadow feature is poorly implemented.
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 :)