Showing posts with label easeljs. Show all posts
Showing posts with label easeljs. Show all posts

Friday, 6 January 2023

Getting the position of a character in a text object in CreateJS

 For those of us who are accustomed to Flash, if we wanted to know the exact x,y coordinates of a character in a textbox, using AS3, we could use the getCharBoundaries function, which if I remember correctly, would return a Rectangle object with the x, y, width and height... I think? The point is, there was a built-in method to do it.

Such a function does not exist in CreateJS (or I couldn't find one).

I was trying to make a little missing-words-type activity, and I wanted users to select the word they were dealing with (could this have been done in HTML with less bother? Probably, I dunno) - so I needed to make a button that would go behind the part of the textbox where the specific word was created.

When I saw that CreateJS did not have an equivalent of the getCharBoundaries function in AS3, I was ready to give up and try an alternative approach. But then I remembered that there are monospaced fonts such as Courier New, that we use in biosciences so that DNA and protein sequences are easy to read. If I used one of those (please skip to the code excerpt(s) below if you aren't interested in the evolution of this, I just really enjoyed this little problem-solving journey, personally), I reasoned, then as long as I knew where the text started, I might be able to figure out the location of each letter, though working out where the line breaks were would be a pain.

On the stage, I manually measured the width of each letter (I realised later a better way of doing this, see below) at 21.6px in the font and size I was using. I used this letter width and the index of the character in the text to position a movieclip relative to the text area.

There were two empty movieclips on stage, the one on top (loadIt) was for loading the dynamic text, the one underneath (loadItBtn) was for loading the buttons.

It went something like this (just focusing on how to deal with a single line first):

tx = new createjs.Text('Hello _____.''36px Courier New','black');
this.loadIt.addChild(tx);

this.letterWidth = 21.6;//I measured this on the stage manually...blech
for(i=6; i<11; i++) {
	btn = new lib.btnMC();//this is just a rectangle made to match the height of the line, and the width of the letters.
	btn.x = i * this.letterWidth;
	this.loadItBtn.addChild(btn);
}

So, some useful functions: tx.getMeasuredWidth() could tell me how wide the text area was, as I was using short paragraphs. I would then use tx.lineWidth, to set how wide I wanted the text area to be, which would cause word wrapping. I would then use tx.getMeasuredHeight() to find out the height of the text area so I could position it on the canvas (you can use a function to get or set your lineHeight).

However, what if the text ends up with multiple lines? Enter (drumroll) getMetrics()!

This function will give you an array, called 'lines', which tells you what text is in each line! So I wrote a loop to check whether the index of the character in the text could be found in the line of the array. Then adjusted the y coordinate of the buttons I was adding based on that. Then I had to remember to figure out what the index of my character was in the line of the text, and use that as the x coordinate.

I won't go into all the details, but if you use console.log(text_name.getMetrics());, you can see the output for yourself in the console.


ISSUES:

1) Using scaleX to size an mc to match the word width did not work for me, it doesn't seem to be very accurate. I dealt with this by making a movieclip that was the perfect size and adding it multiple times, but a better solution would have been to draw a rectangle of the correct size.

2) Measuring the letter width manually is a pain, but manageable because you only need to do it once, but then you have to stick to that font size. I realised later that you could write a function to create a text area, add some text and measure the width to calculate the width of a single letter. Then I realised that actually, you could do this for any font! You'd have to make sure you measured every type of letter you were planning to use, and punctuation, but you could easily create an object that stores the widths of the characters you are using. Easily-ish. But basically, it means that you could work out the position of letters in text areas, and such a function would require some alteration if the text was left-, centre- or right-justified, and it would probably only shorten your life-span by a few years... But, yeah, doable.

You can see an example of what I was aiming for here: Missing words exercise

Have a nice day!

Thursday, 6 June 2013

EaselJS: Spritesheets

Still figuring this out myself, but here is what I have so far...

A sprite sheet is an image of all the frames of an animation, I'm not sure if it has to be a .png, but that will work.


In the example file, there were loads of scripts added, but I replaced it with the one script and it still worked for me...


Line 24: Create a 'spritesheet' - seems to be a way of telling the page which sections of the spritesheet are what, etc.
"animations" is, I think, used if you want to use your spritesheet as an animation? I don't know.

Lines 26 and 27: These two lines both define certain frames as part of a sequence. Sort of like if you had frames in Flash, and a frame had a name, and then when it reached a certain frame, it would loop back to the beginning, or go to another named frame.
On line 26, it's saying that the run sequence is to start from section 0 of the sprite sheet, and go through to section 25, and then, though I have commented this out, to go to the sequence of frames called 'jump', which is defined on the next line.

Line 28: Defines the source file for the image that is the spritesheet.

Lines 29 to 36: Tells it how to recognise what frames are on the sprite sheet.
"hieght" and "width" are how many pixels each section of the image is that should be taken as a frame. I'm not sure how you are supposed to know this, I made a sprite sheet using zoe, and it gave me a file that was 2048 by 512 pixels, with two rows of 7 frames. So I divided 2048 by 7 to get "width", and 512 by 2 to get "height". It worked for me. I suggest you try altering these values so you can see what goes wrong.
"regX" and "regY" are the registration co-ordinates for the animation that will result from the sprite sheet.
"count" is how many frames you have in total, I think.

Line 38: Assign your animation to a variable (a BitmapAnimation) that you can then position etc, and generally treat like a movie clip.

Line 61: If you use gotoAndPlay without any parameters, it will just play everything that the spritesheet is capable of. Or you can tell it which 'frame' to go to.

Line 64: You need the Ticker to get it to work, but strangely, it won't pause in the way a Tween will. So...

Monday, 29 April 2013

EaselJS: Hit Areas

Hit Areas are areas that allow will respond for an object, for mouse events, such as clicks or mouseovers. This is especially useful for text, which will otherwise only respond if you directly hit the pixels that make up the letters.

1) Mouseovers are expensive for the CPU, so are diabled by default. The lower the parameter, the less responsive the mouseover will be.
2) This is how to create a text label.
3) This is the shape that will act as the hit area.
4) getMeasured... is used to see how big the text is. I imagine the parameters are x, y, width, height.
5) When hit is used as a hitarea, it doesn't need to be added to the stage, it will still work. It also doesn't need to be given x and y coordinates, it is assumed to start off wherever the label does. If you give it x and y co-ordinates, they are relative to the position of the label the hitarea has been attached to. If you attach it to the stage, it will be visible, but it will still work.
6) The label doesn't need to be made a global variable, because it is a parameter of the evnt.
7) This changes the alpha dependent on what kind of mouseevent triggered it.
8) In the tutorial, the stage.update was attached to a tick event, but this works too.

Friday, 15 March 2013

EaselJS: Stagemouse events

This script makes your average drawing type thing, where dragging on the screen draws, and releasing the mouse stops the drawing.

1) I think this is needed to make the stage mouse events work.
2) This shape will contain the drawing.
3) Make sure you add it to the stage!
4) This will be the colour of the pen.
5) This will be the thickness of the line.
6) Ensures that the drawing only starts when the person presses down on the stage.
7) Gives a starting point for the drawing, so it doesn't pick up from where the last one finished.
8) See 6.
9 and 10) Makes sure the drawing stops when the mouse is released.
11) I gave the function a proper name so it would be easy to remove. Technically, this function could have been declared outside the init function, but it still works.
12) I guess the if statement isn't really necessary with this version because oldX should always exist... sorry.
13) Draws a line from 'moveTo' to 'lineTo'.
14) Make sure to update the stage after each line.
15) Gives a new starting point for the next line.

(That last stage.update() isn't needed either, sorry.)

EaselJS: EASY Drag Method


I have seen an example of a drag method, which used an offset object that constantly calculated the difference between the position of the mouse and the position of the initial click, I think. But this is way easier.

1) The mousemove event listener has to be added to the mousedown event in order to work.

2) Position the object using the stageX and Y properties of the mousemove event.

3) Be sure to update the stage!

A mouse up event occurs when you release the mouse, so if you need something to occur then, add a mouseup event listener to the mousedown event.

EDIT: I came across this method somewhere else later - oh well, I guess I'm not a programming genius...

Thursday, 14 March 2013

EaselJS: Mouseover and Mouseout

1) Because it would slow your computer down to be checking for mouse movements all the time, you have to enable hte ability of the stage to check for these events.

2) The mouseover event, note the use of stage update so that the change is visible.

3) Ditto for the mouse out event.

EaselJS: How to use the mouseup event



The mouseup event isn't as straight forward to use as the other click type events.

It has to be an event listener of a mousedown event, as shown above.

I believe the mousemove event is used in the same way (in fact, I figured out how to attach a mousedown event by looking at a mousemove event from the tutorials).

EaselJS: Simple Mouse Events

Basic Clicks

In the example above, if you double click on the circle, you will see an alert that gives you information about where the mouse was (relative to the whole stage) when the clicking was done.

These can be accessed by using event.stageX, and event.stageY.

This also works with click, and mousedown.

Friday, 8 March 2013

EaselJS: The Tick Event

(Click the image to see a larger version.)

You can attach 'tick' event handlers to individual shapes, but there has to be a master tick event, of sorts, that tells them all when to go. It can also pass them information about the tick event, in this example I have used the delta event.

1) After adding the circle to the stage, I have not updated the stage, because that will get done by the tick event.
2) Having set the frames per second to 40, this means that there are 25ms between each tick.
3) This is what I am referring to as the master tick event. Without it, none of the others will occur.
4) This is function that the tick event initially calls.You'll note that I have made the event (and therefore its properties) available to the function.
5) 'delta' is a property of the tick event - it tells you how many milliseconds have passed since the last tick. Since the frame rate is meant to be 40 per second, it should be approximately 25ms.
6) The update has to be called here, if you try to call it in the other ticks, everything won't work. Also, the stage.update can be used to pass info to other tick events.
7) Now you can add a tick event to other objects, that will be called by stage.update.
8) This contains the info sent by stage.update
9) This is how you access that info.

Monday, 4 March 2013

EaselJS: Animation 2 (Pausing)

So apparently, you can tell Tick to pause, and it just keeps on going... But it will tell any animation that cares to know, that they should pause if they wish. Seems a bit odd, but maybe it will make sense later.

9) Adds a button below the canvas that will tell the Ticker it should/should not be paused.
5) The function that does the pausing/unpausing.
6) A variable that sets itself to be the opposite of Ticker's paused status.
7) Changes Ticker's paused status.
8) Changes the text on the button to say pause/unpause, accordingly.
1) Animates the normal circle.
2) Checks the pause status of the Ticker
3) Animates the pauseable circle, but only if the Ticker is not paused
4) Updates the image on the canvas - needs to be outside of the pausable code, or normal circle will keep going round, but you won't see it happening.

EaselJS: Animation 1

A simple animation of a circle looping across the stage.

1) I have declared 'circle' outside of the init function so that other functions can access it.
2) Likewise with 'circleRadius' - I will need to use it in the looping code.
5) Ticker is a class that exists (you don't need to create it, it exists to handle framerate etc), and to use it, you add an event listener to it.
4) You have to say "tick" as the type of event it will listen for.
3) The name of the function that will be called at every 'tick'.
6) Allows you to determine the frame rate, an alternative method is commented out below.
8) Gives you the width of your canvas, so you can check if the circle has moved across it.
7) Adding the circleRadius makes sure the circle is completely off-stage before it goes back to the beginning.
9) This positions the circle just off stage, before it moves on.
10) Call the update in the ticking function so that you can see the change with every tick.

Monday, 25 February 2013

EaselJS: How to add a script and a circle to the stage

1) This is the doctype declaration for an html5 page.

2) This is how you tell the html page to access the library of EaselJS, and use it's functions. The filepath is relative to the location of the htmlfile itself, so make sure you know how to find a file, relative to your file.

3) You then add another script tag that contains your code. This will contain the initial function that is called when the page loads.

4) The body tag has an onLoad event, you use this to call your initial function.

5) The canvas tag is where you can actually draw stuff. The id attribute is used by the script to identify the tag. Multiple canvases can be added to the document, just give them each a unique id. I'm told that you can even overlap canvases on top of each other and use them as layers!

6) I have declared the stage variable (which will hold the canvas tag) oustide of any functions, so that all functions can access the stage.

7) This connects the stage variable to the canvas tag.

8) Adds the circle object to the stage, so it exists on stage, but it will not be visible until you update the stage.

9) Updates the stage, so you can see what it really looks like. If you don't update the stage, it is possible for things to be moving around, but you can't see it happening.

Thursday, 20 December 2012

Create JS: EaselJS: Getting Started

What is CreateJS?
For me, CreateJS will be a way to take my Flash skills and use them in a way that will work with HTML5, and on more devices than the Flash Player is currently running on.

First things first - You need to know HTML and JavaScript. A great place to learn this is at W3Schools, don't worry, it's free!

I'd start with learning HTML, then HTML5, then JavaScript.

CreateJS appears to be a JavaScript 'library' (a collection of JavaScript functions that someone has written, that makes really complex things a lot easier), which also writes a lot like actionscript 3 (Flash programming language). So if you know JavaScript, or ActionScript 3, then a lot of the logic behind what you are doing comes very quickly.

Second things second - You need to download the library.
It looks like you can actually use the online versions of the libraries in your scripts, but I think your fields would have to be online too for that to work.

For writing and testing script on your hard-drive, the files need to be on your hard-drive too (I tried accessing the online one, it wouldn't work. I'm sure some people knew this was obvious, but I had to check.).

The website for downloading them is here. And you will have to unzip the folder to access the files inside.

Once inside, open the 'tutorials' folder, then the 'Getting Started' folder, and then the 'index.html' file. This will take you through the basics of how to use the library as a script source, making a canvas tag, and if I remember correctly, drawing a red circle.

For now, I will be going through these tutorials, so anything I post will just be a re-organisation of what I learnt there, into a format that makes more sense to me.

But I just thought I'd post this, because I spent a long time trying to find free tutorials on line, only to find that they were available within the download itself!

Warning: The tutorial may have typos in the code (e.g. Window, instead of window), but the source code for the examples works, so use that as a guide.