I wish to have a line going across my canvas element in a similar fashion to the one I have managed to produce below after I had read up a little about the tween function:
http://jsfiddle.net/MjLdT/17/
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var line = new Kinetic.Line({
x: 100,
y: 100,
points: [0, 0, 0, 0],
stroke: '#000000'
});
layer.add(line);
stage.add(layer);
var tween = new Kinetic.Tween({
node: line,
duration: 3,
x: 800,
y: 100,
points: [-700, 0, 800, 0]
});
setTimeout(function () {
tween.play();
}, 2000);
Eventually I wish to have users be able to manipulate the line by clicking the left mouse button and the line goes up and to the right diagonally, right clicking and the line goes down diagonally (horizontal speed towards the right of the screen remains the same). Letting go of the mouse button will result in it returning to it's normal horizontal motion at whatever 'height' it is on the screen at that time.
This is one of my first attempts at using JavaScript and was wondering if the method I have chosen is appropriate for what I wish to achieve.
Also, any tips on how to get started on the mouse effects would be much appreciated.
The method is appropriate and it works, you should look into Kinetic.Animation which may give you slightly cleaner code. With an animation you can put more logic into the code that is being re-run. I believe tweens may be limited for what you are trying to do, it is possible but Animations are probably what you are looking for if you are aiming for a good design.
I would read through this documentation.
http://kineticjs.com/docs/Kinetic.Animation.html
Related
The Raphael Js website is down so I can't find any documentation or anything on how to do this. I want to create a rectangle with initial vertical size of 0 and make it animate so that it gets vertically larger and larger when I click another object. Thanks!
so i've got a rectangle
var water = paper.rect( 0, 300, 600, 0).attr({fill:"blue"});
how do I make it animate?
In particular, check out the documentation for
Element.attribute(),
Element.animate(),
Element.click(), and
Raphael.animation().
The following snippet demonstrates a simple animation like the one you are looking for. Click the red square to make the water "fill". It may not work in some browsers (e.g. Chrome) possibly because the snippet is trying to access an external third-party library, i.e. Raphael.js. So, to run it, either go to this SO question/answer page on Firefox or copy the code and run it on your own computer.
Note that, to make the water "fill" in the up direction, you can't just increase the height of the water rectangle...that would make the rectangle grow downwards. You also have to simultaneously raise the top of the rectangle by the identical amount. Thus you have to animate height and y simultaneously, as shown in the code.
UPDATE: provided an up-to-date link for the Raphael minified library
var paper = Raphael(0, 0, 500, 120);
var button = paper.rect( 10, 10, 40, 20).attr({fill:"red"});
var water = paper.rect( 10, 100, 400, 0).attr({fill:"blue"});
var anim = Raphael.animation({
height: 60,
y: (100 - 60)
}, 2000);
button.click(function() {water.animate(anim);});
<script src="https://raw.githubusercontent.com/DmitryBaranovskiy/raphael/master/raphael.min.js"></script>
To get the animation to start, click on the red rectangle.
I am using KineticJS and to this point it has been a great experience. One question I have though is about dragging. I have the image in this example set to 'draggable: true', but after I drag it the first time, it cannot be moved again.
var stage = new Kinetic.Stage({
container: 'container',
width: 2754,
height: 1836
});
var layer = new Kinetic.Layer();
var scale = '0.16339869281045751633986928104575';
var imageObj = new Image();
imageObj.onload = function () {
var img = new Kinetic.Image({
x: 0,
y: 0,
height:612,
width:612,
image: imageObj,
draggable: true,
dragBoundFunc: function (pos) {
console.log(img.getAttrs());
return {
x: Math.floor((pos.x/scale)/306)*306,
y: Math.floor((pos.y/scale)/306)*306
};
}
});
// add the shape to the layer
layer.add(img);
// add the layer to the stage
stage.add(layer);
};
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/yoda.jpg';
http://jsfiddle.net/7UEC6/
Any help is appreciated. For extra credit you can suggest ways to make the dragging smoother in general.
Thanks!
edit: I have noticed that after the image is dragged the initial time, the dragBoundFunc is no longer called when the user tries to drag the image
it also works if i drag the image back to 0,0 but no other time
This is not possible with current KineticJS.
Let me try to explain why.
When you use transform:scale, which is CSS3 element(not standard yet), the visual position of actual elements gets also scaled. However the relative mouse position of MouseEvent only passes visual position(not scaled position).
The mouse click event for dragging, which KineticJS uses, only reads MouseEvent position, which is visual one(not scaled one), and it does not consider transformation of canvas element.
When you set your image x/y to following, you cannot even do the first drag
x: 612,
y: 612,
However when you set it as 0 and 0, it respond to it because the scaled and unscaled position is the same.
For the above example x/y 612 and 612, you cannot click to drag,
because KineticJS understand it as you are not clicking 612 and 612,
but it think it as 100 and 100
The reason is simple as I explained.
MouseEvent does not pass scaled X/Y, but visual position of X/Y.
Who knows when CSS3 become standard, it might be well supported :)
Meanwhile, I would not recommend to use transformation with canvas. Unless you build your own framework, it is pretty hard to make all things correctly with canvas transformed.
I am with a little problem here but I don't know if it is a bug or a new feature since in the KineticJS change logs there is the following change:
"drag and drop operations now automatically dynamically create a temporary top layer, and place nodes there for groups and shapes to greatly improve drag and drop performance..."
I was used to use the version 4.0.0 in my test projects and I must use explicity moveToTop() when I want to move some shape to the top (I think that this is the correct way). Now (version 4.3.2) if I just click over some pic, it is automatically moved to the top against my wish. This temporary layer should be something internal, nothing visual. So is this really a bug or there is someway to turn this thing off.
Even the labs changed I think, before I think that the objects keeps the space order if you don't call the moveUp, moveToTop, etc, functions. For example in the following link there are no moveToTop() function calls, even this way if you click on the shapes, they are moved to the top.
http://www.html5canvastutorials.com/kineticjs/html5-canvas-move-shape-to-another-container-with-kineticjs/
Thanks for the attention
While I dont think you can completely disable the layer, you can turn off moving the shapes into it. Say you have some shape like:
var shape1 = new Kinetic.Rect({
x: 100,
y: 100,
width: 100,
height: 100,
fill: 'blue',
draggable: true
});
you need to add one parameter to this to disable moving your shape to the temporary layer on drag: 'dragOnTop' which needs to be false, so make your shapes something like:
var shape1 = new Kinetic.Rect({
x: 100,
y: 100,
width: 100,
height: 100,
fill: 'blue',
draggable: true,
dragOnTop: false //<-- add this line so that this shape doesn't use the drag layer.
});
Alright, I'm at my wits end and I can't get CraftyJS to do a tween.
So what I wanna do is, everytime a Mushroom gets hit, I want to check if that mushroom has the component "Answer". If it exists, I will do nothing. Otherwise, I wanna display a big red box that fades away.
Crafty.c("Mushroom", {
init: function() {
this.addComponent("collision");
this.collision();
this.onhit("bullet",function(e) {
this.destroy();
e[0].obj.destroy();
if(!this.has("Answer")) {
Crafty.e("2D, Tween, color, canvas")
.attr({alpha: 1.0, x: 170, y: 100, w:300, h:100})
.color("red")
.bind("enterframe", function() { //How do i actually get the box to fade?
this.tween({alpha: 0.5, x: 170, y: 100}, 30);
});
}
});
}
You are binding the tween code execution to the EnterFrame event, which will cause the tween to start with each frame. Instead, you want to simply call the tween function on the entity you created, like so
Crafty.e("2D, Tween, color, canvas")
.attr({alpha: 1.0, x: 170, y: 100, w:300, h:100})
.color("red")
.tween({alpha: 0.5, x: 170, y: 100}, 600);
And the tween function will manage its own EnterFrame over the next 600 ms (30 frames), after which it will fire the TweenEnd event.
(In old versions of Crafty, you specified the duration in frames instead of ms.)
This is more like a meta answer :-)
First, i would encourage you to upgrade to the latest version as it has a lot of bugfixes. Some of the changes you will have to do to get your code to run under the new release is to change all components and events to Pascal casing. That is enterframe => EnterFrame, canvas => Canvas etc.
Second, i think you should bring these questions to the Crafty forum to get the right audience. The only way i discovered this question was through a google alert.
The best way to get help is to create a jsfiddle from this template http://jsfiddle.net/mCdUX/62/ with a small running example demonstrating the part that you can not get to work.
Oh, and welcome to the Crafty community :-)
I need to create a wheel which will be dragged around 360 degrees by the user (in order to have a specific segment of the wheel placed at the top).
I've found examples of a roulette wheel using HTML5 canvas which just spin an image of a wheel for a random amount of time. However, when it comes to allowing a user to drag a wheel as they wish, I'm stumped.
I'd also rather make the wheel from HTML/CSS rather than use an image, because it needs to be dynamically updated.
mmm this looks like a math problem...
so define a center point and then use trigonometry to define the angle of the line (from the center point to the mouse) from the horizon
http://en.wikipedia.org/wiki/Trigonometry
now draw in a canvas on the center point inside the cnavas the weel, get the angle and redraw the weel as needed
The Sencha drawing framework allows you to just about do anything that you might have seen done in flash - but without flash. It works in just about all browsers without plugins. It uses SVG or VML depending on the browser. Have a look at the draggable tiger example here
Edit:
Documentation for the drawing framework which is part of the larger ExtJS framework is found at: http://docs.sencha.com/ext-js/4-0/#!/api/Ext.draw.Component
This is the code I knocked up for a draggable circle/wheel. Didn't put any spinning action in as I think you've got that worked out.
<script src="ext-all-debug.js" type="text/javascript"></script>
<script type="text/javascript">
Ext.onReady( function() {
//create the drawing surface
var drawComponent = Ext.create('Ext.draw.Component', {
width: 400,
height: 400,
draggable: {
constrain: true,
constrainTo: Ext.getBody()
},
autoShow:true,
floating: true,
renderTo: Ext.getBody(),
items:[{
//add the circle sprite to the
//drawing surface
type: 'circle',
fill: '#79BB3F',
"stroke-width": "1",
stroke: "#000",
radius: 100,
x: 100,
y: 100
}]
});
});
</script>
You will want to use probably Canvas to draw: http://diveintohtml5.info/canvas.html
For dragging the wheel you will need to handle mouse down, mouse move and mouse up events.