Animating height of fabricjs rect object decreasing from top instead of bottom - javascript

I've mocked up an MCVE that demonstrates the problem. If you click on the red square then it'll gradually decrease in size (over roughly ~10 seconds) to nothing and then get removed.
However, the animation is bottom up rather than the desired top down.
Is there a way to do this using the standard fabricjs .animate method?
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.2/fabric.min.js"></script>
<script>
$(function() {
canvas = new fabric.Canvas('test');
canvas.observe('mouse:down', function(e) {
e.target.animate('height', 0, {
onChange: canvas.renderAll.bind(canvas),
duration: 10000,
onComplete: function() {
e.target.remove();
canvas.renderAll();
}
});
});
var rect = new fabric.Rect({
top : 100,
left : 100,
width : 200,
height : 200,
fill : 'red',
lockUniScaling: true,
lockRotation: true,
hasControls: false
});
canvas.add(rect);
canvas.renderAll();
});
</script>
<title>Test Test</title>
</head>
<body>
<canvas id="test" height="1000" width="1000"></canvas>
</body>
</html>

Try it:
canvas.observe('mouse:down', function (e) {
if (!e.target)
return;
e.target.animate('height', 0, {
onChange : canvas.renderAll.bind(canvas),
duration : 10000,
onComplete : function () {
e.target.remove();
canvas.renderAll();
}
});
//It is suitable if you know initial height...
e.target.animate('top', 300, {// initialHeight(100) + initialTop(200)
duration : 10000,
onChange : canvas.renderAll.bind(canvas),
});
});
example
example 2
This method is not optimal, but it works!
Need to do custom animate that will change height and top.

Related

jCanvas - setPixels()

Everything works great with jCanvas except for one thing. I can't get setPixels () to work, when I run the code in Chrome and Safari, nothing happens.
I have copied the example code from the Sandbox on jCanvas website (where everything works when I look in the browser).
Anyone have a suggestion on what I may have done wrong?
<canvas id="canvas" width="520" height="520"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>
<script src="http://projects.calebevans.me/jcanvas/resources/jcanvas/jcanvas.js"></script>
<script type="text/javascript">
function invert() {
$(this).setPixels({
x: 150, y: 100,
width: 220, height: 138,
// loop through each pixel
each: function(px) {
px.r = 255 - px.r;
px.g = 255 - px.g;
px.b = 255 - px.b;
}
});
}
$('canvas').drawImage({
source: 'images/fish.jpg',
x: 150, y: 100,
// Invert image color when image loads
load: invert
});
</script>

How to change color of a set of nodes in kinetic js?

SO I have a lot of Kinetic polygons, and I collect them and store in a variable like this:
var midr = layer.find('.midr');
I want to change their colors, so I want to delete them and draw them with different colour:
midr.on('mouseover',function(){
midr.destroy();
Boxes.MidR(color.R,color.G,color.B,1,'midr');
midr = layer.find('.midr');
});
midr.on('mouseout',function(){
midr.destroy();
Boxes.MidR(color.R,color.G,color.B,0,'midr');
midr = layer.find('.midr');
});
where:
var Boxes={
.....
MidR:function(R,G,B,A,group){
var C = shade(R,G,B,25,"+");
Mid_right.left(C.r,C.g,C.b,A,group);
var C = shade(R,G,B,20,"-");
Mid_right.back(C.r,C.g,C.b,A,group);
Mid_right.right(R,G,B,A,group);
Mid_right.bottom(R,G,B,A,group);
Mid_right.shelf(R,G,B,A,group);
}, ....
}
and
var Mid_right={
left:function(R,G,B,A,group){
frame([89,192,120,192,120,309,89,315],150,150,150,A,group);
frame([75,311,89,315,89,192,75,192],R,G,B,A,group)
},
right:function(R,G,B,A,group){
frame([99,193.5,99,306,118.5,309,118.5,193.5],R,G,B,A,group)
},
back:function(R,G,B,A,group){
frame([90.5,308,99,306,99,193.5,90.5,193.5],R,G,B,A,group);
},
shelf:function(R,G,B,A,group){
frame([90.5,270,118.5,266,99,264,90.5,265],R,G,B,A,group)
},
bottom:function(R,G,B,A,group){
frame([120,309,99,306,90.5,308,90.5,315],R,G,B,A,group)
}
};
and
function frame(array,R,G,B,A,group){
poly = new Kinetic.Polygon({
points: array,
stroke: 'white',
strokeWidth: 1,
name: group
});
if(R!=null||G!=null||B!=null){
poly.setFill('rgba('+R+','+G+','+B+','+A+')');
} else {
poly.setFill('rgba(0,0,0,0)');
};
layer.add(poly);
};
maybe it is kind of stupid and I could do it much easier, but there are other things I have to think about, which are not included here and I thought this should be a good way.
so what I want is to delete a set of polygons then redraw them with different colour, when the mouse hovers them and when it leaves, it should change back to original. but using destroy, redraw, and then collecting them again does not seem to work, dont know why. any ideas?
Instead of removing/recreating the poly, just use myPoly.setFill inside the mouseover and mouseleave events:
Add 2 additional properties to your poly: hoverColor and blurColor,
On mouseover: this.setFill(this.hoverColor);
On mouseleave: this.setFill(this.blurColor);
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/GTe9j/
<!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.7.2.min.js"></script>
<style>
body{padding:20px;}
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:350px;
height:350px;
}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 350,
height: 350
});
var layer = new Kinetic.Layer();
stage.add(layer);
newPoly("red","green",[50,50, 100,50, 50,100]);
newPoly("blue","green",[100,50, 150,50, 150,100]);
newPoly("orange","green",[150,100, 150,150, 100,150]);
newPoly("purple","green",[100,150, 50,150, 50,100]);
function newPoly(hovercolor,blurcolor,array){
var poly = new Kinetic.Polygon({
points: array,
stroke: 'gray',
strokeWidth: 1,
fill:blurcolor
});
poly.hoverColor=hovercolor;
poly.blurColor=blurcolor;
poly.on("mouseover",function(){
this.setFill(this.hoverColor);
this.draw();
});
poly.on("mouseleave",function(){
this.setFill(this.blurColor);
this.draw();
});
layer.add(poly);
layer.draw();
}
}); // end $(function(){});
</script>
</head>
<body>
<h4>Hover over a triangle to change its hover-color</h4>
<div id="container"></div>
</body>
</html>

Raphael animation

I am new to Raphael and am trying to do something very simple, but failing miserably.
I am trying to replicate the animation at this link This is the code I have so far:
<html>
<head><title></title>
<script src="raphael-min.js"></script>
<script src=" src="jquery-1.7.2.js"></script>
</head>
<body>
<div id="draw-here-raphael" style="height: 200px; width: 400px; background: #666;">
</div>
<script type="text/javascript">
//all your javascript goes here
var r = new Raphael("draw-here-raphael", 400, 200),
// Store where the box is
position = 'left',
// Make our pink rectangle
rect = r.rect(20, 20, 50, 50).attr({"fill": "#fbb"});
// Note JQuery is adding the mouseover. SVG == html nodes
$(rect.node).mouseover(function () {
if (position === 'left') {
rect.animate({x: 300, y: 100}, 400, "<>");
position = 'right';
} else {
rect.animate({x: 20, y: 20 }, 800, "bounce");
position = 'left';
}
});
// Make that sucker rotate
setInterval(function () {
rect.rotate(1);
}, 10);
</script>
</body>
</html>
I have downloaded jquery and have it in the same folder as the Raphael. The code that isn't working is the commented code talking about jquery adding the mouseover. When I add that code the rectangle doesn't rotate anymore. It is just stationary. If someone can please help me with this animation I would appreciate it.
Thanks
You have an error in your code:
<script src=" src="jquery-1.7.2.js"></script>
Change it to:
<script src="jquery-1.7.2.js"></script>
That should correct your problem with jQuery.

Canvas draggable with kineticJS and Clip function

I've a problem which deals with canvas.
I would like to use kinetic to use mobile events (most particularly for draggable) and I would also like to use the clip() function at the same time.
Here is my code :
<!DOCTYPE HTML>
<html>
<head>
<style>
canvas {
border: 1px solid #9C9898;
}
</style>
<script src="kinetic-v3.9.4.js"></script>
<script>
window.onload = function() {
var stage = new Kinetic.Stage({
container: "container",
width: 708,
height: 500
});
var layer = new Kinetic.Layer();
var circle1 = new Kinetic.Circle({
x: 150,
y: 150,
radius: 75,
fill: "red",
draggable: true
});
var circle2 = new Kinetic.Circle({
x: 350,
y: 150,
radius: 75,
fill: "blue",
});
layer.add(circle2);
layer.add(circle1);
stage.add(layer);
};
</script>
</head>
<body onmousedown="return false;">
<div id="container"></div>
</body>
</html>
I've the first circle draggable but I would like to use it and the clip function but I don't really know how to do it. In addition, I tried to get the 2d context like this:
var context = this.getContext();
But it didn't work. If there's someone that can help me thanks.
I also saw this example but it doesn't work with mobile devices.
The reason why the example you mentioned doesn't work on mobile is because its only using mouse event handlers:
stage.on("mousemove", function(){})
But you'll need to add touch events like this:
stage.on("mousemove touchmove", function(){})
touchstart, touchmove, touchend
Good luck!

how to call raphael methods on jquery objects?

I'm creating some circles using Raphael. When a user clicks a button, I want to animate these circles (by growing their radius). How do I do this?
For example, here's my example code:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="raphael.js"></script>
<script type="text/javascript">
$(function() {
var paper = new Raphael("canvas_container", 300, 150);
paper.circle(50, 75, 30);
paper.circle(150, 75, 30);
$("button").click(function() {
$("circle").each(function(i) {
this.animate({ r: 100 }, 500); // Doesn't work.
});
});
});
</script>
</head>
<body>
<div id="canvas_container"></div>
<button>Click me to animate the circles</button>
</body>
</html>
[In general, I'm not clear what is the difference between the following two variables:
var c = paper.circle(50, 75, 30); // Raphael circle
$("circle").first(); // using jQuery to grab that Raphael circle
Is the jQuery object a wrapper around the Raphael circle?]
Reading through the Raphaël Reference, it seems that you can do this using Raphaël's own Event methods
circle.click(function (event) {
this.animate({ r: 100 }, 500);
});
The same part of the documentation also notes that you can use libraries like jQuery, but you have to pass in the node, like this:
$(circle.node)
Where circle is the object returned from the paper.circle call.
In your case, however, I think the following code will work:
var paper = new Raphael("canvas_container", 300, 150),
circles = [];
circles.push(paper.circle(50, 75, 30));
circles.push(paper.circle(150, 75, 30));
$("button").click(function() {
$.each(circles, function(i, c){
c.animate({ r: 100 }, 500);
});
});
Your selector "circle" isn't targeting anything - there's no circle element for you to target. However, you could do this:
circle1 = paper.circle(50, 75, 30);
circle2 = paper.circle(150, 75, 30);
$("button").click(function() {
circle1.animate({ r: 100 }, 500);
circle2.animate({ r: 100 }, 500);
});
I couldn't tell you if you can animate() the circles based on the radius, but at the very least this gives you a jQuery object to work with.

Categories

Resources