Add listener to a group - javascript

How i can do something like this? all the shapes in the group should not listen to the event, but the group should operate on the event, but do not work. I gave the example of the two groups, and they are actually very much, and so I have to add a listener to the layer, and listen to the babbling events all internal groups.
var stage = new Kinetic.Stage({
container: 'container',
width: 1000,
height: 800
});
var layer = new Kinetic.Layer();
var group1 = new Kinetic.Group({listening: true});
var group2 = new Kinetic.Group();
var circle = new Kinetic.Circle({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
radius: 70,
listening: false,
fillLinearGradientStartPoint: {x:70, y:-70},
fillLinearGradientEndPoint: {x:70,y:70},
fillLinearGradientColorStops: [0, 'black', 1, 'white'],
stroke: 'black',
strokeWidth: 4
});
var circle2 = new Kinetic.Circle({
x: 100,
y: 100,
radius: 70,
listening: false,
fillLinearGradientStartPoint: {x:70, y:-70},
fillLinearGradientEndPoint: {x:70,y:70},
fillLinearGradientColorStops: [0, 'black', 1, 'white'],
stroke: 'black',
strokeWidth: 4
});
var circle3 = new Kinetic.Circle({
x: 300,
y: 300,
radius: 70,
listening: false,
fillLinearGradientStartPoint: {x:70, y:-70},
fillLinearGradientEndPoint: {x:70,y:70},
fillLinearGradientColorStops: [0, '#678345', 1, '#824444'],
stroke: 'black',
strokeWidth: 4
});
var circle4 = new Kinetic.Circle({
x: 200,
y: 200,
radius: 70,
listening: false,
fillLinearGradientStartPoint: {x:70, y:-70},
fillLinearGradientEndPoint: {x:70,y:70},
fillLinearGradientColorStops: [0, '#678345', 1, '#824444'],
stroke: 'black',
strokeWidth: 4
});
group1.add(circle);
group1.add(circle2);
group2.add(circle3);
group2.add(circle4);
// add the triangle shape to the layer
layer.add(group1);
layer.add(group2);
layer.on("click",onClick);
// add the layer to the stage
stage.add(layer);
function onClick(e){
console.log("click",e.target);
}
Please help!

Only nodes in a group will trigger events
your circles will trigger events
clicking in a non-node area of a group will not trigger any events
A workaround is to add a transparent rect as a background covering the entire group width/height.
var group=new Kinetic.Group({
x:0,y:0,width:100,height:100
})
var groupListener=new Kinetic.Rect({
x:group.x(),
y:group.y(),
width:group.width(),
height:group.height(),
});
group.add(groupListener);
Then you can assign a listener to the "invisible" groupListener rectangle
groupListener.on("click",function(){
console.log("clicked on non-node area of group");
});
A Demo: http://jsfiddle.net/m1erickson/ur6be/

Related

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 correctly apply globalCompositeOperation on canvas's elements?

I have an issue with globalCompositeOperation.
My goal is to make Blue element displayed only inside of Red element and should not be visible outside of Red rectangle at all (kind of Overflow-Hidden effect). Plus, both Red and Blue must have Transformation ability (both editable).
As you can see, if I'll add one more element into the canvas (yellow element), the Blue one become visible on the area where Yellow and Blue overlaps.
http://jsfiddle.net/redlive/q4bvu0tb/1/
var canvas = new fabric.Canvas('c');
var yellow = new fabric.Circle({
top: 200,
left: 0,
radius: 100,
strokeDashArray: [5, 5],
stroke: 'black',
strokeWidth: 5,
fill: 'yellow'
});
canvas.add(yellow);
var red = new fabric.Rect({
top: 0,
left: 0,
width: 300,
height: 300,
strokeDashArray: [5, 5],
stroke: 'black',
strokeWidth: 5,
fill: 'red',
rx: 40
});
canvas.add(red);
var blue = new fabric.Circle({
top: 150,
left: 80,
radius: 100,
strokeDashArray: [5, 5],
stroke: 'black',
strokeWidth: 5,
fill: 'blue',
globalCompositeOperation: 'source-atop'
});
canvas.add(blue);
var green = new fabric.Circle({
top: 0,
left: 0,
radius: 100,
strokeDashArray: [5, 5],
stroke: 'black',
strokeWidth: 5,
fill: 'green'
});
canvas.add(green);
Mandatory Conditions:
Preserve elements appearance on Canvas.
No clipping (since clipping
does not allow to add background color and image in the same time)
It could be accomplish-able using the following steps ...
remove the yellow element before drawing the blue one
after drawing the blue element set the yellow element's globalCompositeOperation to destination-over and add it back
var canvas = new fabric.Canvas('c');
var yellow = new fabric.Circle({
top: 200,
left: 0,
radius: 100,
strokeDashArray: [5, 5],
stroke: 'black',
strokeWidth: 5,
fill: 'yellow'
});
canvas.add(yellow);
var red = new fabric.Rect({
top: 0,
left: 0,
width: 300,
height: 300,
strokeDashArray: [5, 5],
stroke: 'black',
strokeWidth: 5,
fill: 'red',
rx: 40
});
canvas.add(red);
canvas.remove(yellow); //remove yellow
var blue = new fabric.Circle({
top: 150,
left: 80,
radius: 100,
strokeDashArray: [5, 5],
stroke: 'black',
strokeWidth: 5,
fill: 'blue',
globalCompositeOperation: 'source-atop'
});
canvas.add(blue);
yellow.set({globalCompositeOperation: 'destination-over'}); //set gCO for yellow
canvas.add(yellow); //add yellow back
var green = new fabric.Circle({
top: 0,
left: 0,
radius: 100,
strokeDashArray: [5, 5],
stroke: 'black',
strokeWidth: 5,
fill: 'green'
});
canvas.add(green);
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<canvas id="c" width="800" height="800"></canvas>

Animate "fillLinearGradientColorStops" of a shape

How can I animate fillLinearGradientColorStops of a KineticJS Rect? I tried using a tween but surely it doesn't work.
The rectangle:
var rect = new Kinetic.Rect({
x: 20,
y: 20,
width: 100,
height: 100,
fillLinearGradientStartPoint: { x: -50, y: -50 },
fillLinearGradientEndPoint: { x: 50, y: 50 },
fillLinearGradientColorStops: [0, 'red', 1, 'yellow']
});
The tween:
var tween = new Kinetic.Tween({
node: rect,
duration: 2,
easing: Kinetic.Easings.Linear,
fillLinearGradientColorStops: [0, 'black', 1, 'green']
});
tween.play();
Please see the fiddle http://jsfiddle.net/ZdCmS/. Is it not possible?
From there: https://github.com/ericdrowell/KineticJS/issues/901
You can use an external tweening library, like GreenSock (http://www.greensock.com/gsap-js/) with it's ColorProps plugin (http://api.greensock.com/js/com/greensock/plugins/ColorPropsPlugin.html) to tween colors and then apply them to the Kinetic shape on each frame update: http://jsfiddle.net/ZH2AS/2/
No plans for direct support of tweening color stops on a gradient fill.
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var linearGradPentagon = new Kinetic.RegularPolygon({
x: 150,
y: stage.height() / 2,
sides: 5,
radius: 70,
fillLinearGradientStartPoint: {
x: -50,
y: -50
},
fillLinearGradientEndPoint: {
x: 50,
y: 50
},
fillLinearGradientColorStops: [0, 'white', 1, 'black'],
stroke: 'black',
strokeWidth: 4,
draggable: true
});
layer.add(linearGradPentagon);
stage.add(layer);
//activate ColorPropsPlugin
TweenPlugin.activate([ColorPropsPlugin]);
//object to store color values
var tmpColors = {
color0: 'white',
color1: 'black'
};
//tween the color values in tmpColors
TweenMax.to(tmpColors, 5, {
colorProps: {
color0: 'black',
color1: 'red'
},
yoyo: true,
repeat: 5,
ease:Linear.easeNone,
onUpdate: applyProps
});
function applyProps() {
linearGradPentagon.setAttrs({
fillLinearGradientColorStops: [0, tmpColors.color0, 1, tmpColors.color1]
});
layer.batchDraw();
}

KineticJS - Creating a Spline with a Gradient Stroke

I'm trying to stroke my Kinetic Spline object with a gradient instead of a solid color. However, my spline is turning out black. Any ideas?
Here's my code:
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var blueSpline = new Kinetic.Spline({
points: [{
x: 73,
y: 160
}, {
x: 340,
y: 23
}, {
x: 500,
y: 109
}, {
x: 300,
y: 109
}],
strokeWidth: 10,
lineCap: 'round',
tension: 1,
fillLinearGradientStartPoint: [73, 160],
fillLinearGradientEndPoint: [300, 109],
fillLinearGradientColorStops: ['#ff0000', '#00ff00'],
fillPriority: 'linear-gradient'
});
layer.add(blueSpline);
stage.add(layer);
You can try this:
var ctx = layer.getContext();
var grad = ctx.createLinearGradient(73, 160, 300, 109);
grad.addColorStop(0, '#ff0000');
grad.addColorStop(1, '#00ff00');
var blueSpline = new Kinetic.Spline({
...
stroke: grad,
...
});
Here is an example:
http://jsfiddle.net/qK6nq/
KineticJS does not support gradient strokes--only gradient fills.

KineticJS: How to scale the radius of a Group in Tween?

I'm trying to make a tween which makes a ball bigger and disappear from the screen. It's easy if you do it for a circle.
Tween for only circle: http://jsfiddle.net/VrUB6/
Code:(it won't let me paste only the link):
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 500
});
var layer = new Kinetic.Layer();
var circle = new Kinetic.Circle({
x: 100,
y: 100,
radius: 30,
fillRadialGradientStartPoint: 0,
fillRadialGradientStartRadius: 0,
fillRadialGradientEndPoint: 0,
fillRadialGradientEndRadius: 90,
fillRadialGradientColorStops: [0, 'red', 1, 'yellow'],
stroke: 'black',
strokeWidth: 0.4,
opacity: 1
});
layer.add(circle);
stage.add(layer);
circle.on('mousedown', function(){
var tween = new Kinetic.Tween({
node: circle,
duration: 0.8,
radius: 80,
opacity: 0,
});
tween.play();
});
But what I want to do is, same tween like this, but a text in the circle. For this I have to create a group, add circle and text in it and then tween the group(I guess). But if I do this, I can't change the radius in tween. It won't work.
Here is my work for it: http://jsfiddle.net/N2J2u/
Code:
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 500
});
var layer = new Kinetic.Layer();
var circ = new Kinetic.Circle({
x: 100,
y: 100,
radius: 30,
fillRadialGradientStartPoint: 0,
fillRadialGradientStartRadius: 0,
fillRadialGradientEndPoint: 0,
fillRadialGradientEndRadius: 90,
fillRadialGradientColorStops: [0, 'red', 1, 'yellow'],
stroke: 'black',
strokeWidth: 0.4,
opacity: 1
});
var group = new Kinetic.Group({
draggable: true,
});
group.add(circ);
var complexText = new Kinetic.Text({
x: 97,
y: 90,
text: '4',
fontSize: 30,
fontFamily: 'Calibri',
fill: '#555',
padding: -5,
align: 'center'
});
group.add(complexText);
layer.add(group);
stage.add(layer);
group.on('mousedown', function(){
var tween = new Kinetic.Tween({
node: group,
duration: 0.8,
radius: 80,
opacity: 0,
});
// start tween after 20 seconds
setTimeout(function() {
tween.play();
});
});
Thanks for the help.
Set up multiple tweens where the circle expands+fades and the number fades:
group.on('mousedown', function(){
var tweenCirc = new Kinetic.Tween({
node: circ,
duration: 0.8,
width: 80,
opacity: 0,
});
var tweenComplexText = new Kinetic.Tween({
node: complexText,
duration: 0.8,
opacity: 0,
});
// start tween after 20 seconds
setTimeout(function() {
tweenCirc.play();
tweenComplexText.play();
});
});
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/dvfr2/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.4.min.js"></script>
<style>
#container{
border:solid 1px #ccc;
margin-top: 10px;
}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 500
});
var layer = new Kinetic.Layer();
stage.add(layer);
var group = new Kinetic.Group({ draggable: true });
layer.add(group);
var circ = new Kinetic.Circle({
x: 100,
y: 100,
radius: 30,
fillRadialGradientStartPoint: 0,
fillRadialGradientStartRadius: 0,
fillRadialGradientEndPoint: 0,
fillRadialGradientEndRadius: 90,
fillRadialGradientColorStops: [0, 'red', 1, 'yellow'],
stroke: 'black',
strokeWidth: 0.4,
opacity: 1
});
group.add(circ);
var complexText = new Kinetic.Text({
x: 97,
y: 90,
text: '4',
fontSize: 30,
fontFamily: 'Calibri',
fill: '#555',
padding: -5,
align: 'center'
});
group.add(complexText);
group.on('mousedown', function(){
var tweenCirc = new Kinetic.Tween({
node: circ,
duration: 0.8,
width: 80,
opacity: 0,
});
var tweenComplexText = new Kinetic.Tween({
node: complexText,
duration: 0.8,
opacity: 0,
});
// start tween after 20 seconds
setTimeout(function() {
tweenCirc.play();
tweenComplexText.play();
});
});
layer.draw();
}); // end $(function(){});
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>

Categories

Resources