Flash CC Canvas HTML5 Element adding interactivity in Timeline - javascript

I've been trying to solve this for several time, but I'm now pointless with this situation. I'm creating a HTML5 canvas project in Flash CC, I'm kinda new in JS (not difficult BTW), the point is, I have around 10 keyframes inside my main timeline, and some classic buttons, all I need to do is to navigate inside every frame when a button is pressed (pretty easy uh!) the trouble is, the first frame works perfectly, but from 2 to the others, I can't be able to use buttons, interactivity is being programmed as follows:
var self = this;
this.stop();
this.btn4.addEventListener("click", clickUno);
function clickUno() {
self.gotoAndPlay(1);
}
Any help will be really appreciated, I just don't know why 1st frame works great, but others doesn't!

I had similar issues with canvas with flash.
I needed to created completed new buttons on every instance you need a button to get code to work. (ODD I know.)
Button code.
this.getinsideIt.addEventListener("click", fl_ClickToGoToAndPlayFromFrame_9.bind(this));
function fl_ClickToGoToAndPlayFromFrame_9()
{
this.Mygreatmovie.gotoAndPlay(350);
}

As I understand, you need a button, clicking on which proceeds your animation 1 frame at a time. Correct?
You should make use of the currentFrame and totalFrames properties of the main stage for this. Query the current frame and move on to next!
var self = this;
this.stop();
if(!this.btn4.hasEventListener("click", clickUno))
this.btn4.addEventListener("click", clickUno);
function clickUno(e) {
var curr = self.currentFrame;
var total = self.totalFrames;
self.gotoAndStop((curr + 1)%total);
}

Related

Find out when the Youtube HUD fades out, and fade out an element with it

I am creating a chrome extension that adds a button to the youtube player HUD (to the left of the watch later button). This works fine, but the only problem is that when the HUD autofades after a few seconds of inactivity, this button element doesn't.
I've added the button to the following div using javascript:
<div class="ytp-chrome-top-buttons"> </div>
and my button looks like this:
<button class="customClass" id="customID" title="custom title"><svg class="customClass"></svg></button>
I've looked through the source of the page to try and see how exactly youtube makes the other icons disappear, and whether I can copy a class to my svg to make it disappear, but I haven't been able to find it.
I've looked at using a timer and javascript to make the element disappear, but I figured if the functionality is already there, why complicate it.
As a last resort I will be resorting to using the timer method, but I'd much prefer using CSS classes.
I have had a cursory glance into the Youtube Player API, but to be frank, I'm having a hard time understanding how it works (While I have a few years of programming experience, I only started learning javascript, HTML, and CSS yesterday). I also understand that this API is only for embedded youtube videos?
To clarify, I DO know how to use API's in javascript, just not this particular one. I have used the youtube data API to implement the button's functionality successfully.
Any help is appreciated.
Thanks.
If you examine the element changes, you can see that the class list of the video has changed with the change of the bottom bar. When the bottom bar is hidden, the ytp-autohide class is added. Keeping this in mind, after scanning the class changes with the mutation observer, you will reach the desired result when the ytp-autohide class's existence status changes.
var video = document.querySelector("#movie_player");
var lastState = video.classList.contains('ytp-autohide');
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if(mutation.attributeName == "class"){
var currentState = mutation.target.classList.contains('ytp-autohide');
if(lastState !== currentState) {
lastState = currentState;
if(currentState)
console.log("Hided");
else
console.log("Shown");
}
}
});
});
observer.observe(video, {attributes: true});

Flash HTML5 canvas fl_MouseOverHandler

I'm quite new to Flash Actionscript & Javascript but I'm hoping to get some help here if possible. I'm creating a website using the canvas element, there is an image on the canvas and when you scroll over a part of that image, a movie clip plays, when you click on it, it takes you to another page.
I'm using flash to create it, but I'm having difficulty figuring out what's going wrong. I'm using code snippets to add in event handlers but I'm not getting the movie clip to play. The link to the page works but the mouse over event does not.
Also, my movie clip contains many layers, will this make a difference?
Any help would be greatly appreciated.
/* Stop a Movie Clip*/
this.movieClip_11.stop();
/* Mouse Over Event*/
var frequency = 3;
stage.enableMouseOver(frequency);
this.movieClip_11.addEventListener("mouseover", fl_MouseOverHandler_32);
function fl_MouseOverHandler_32()
{
this.movieClip_11.play();
}
/* Play a Movie Clip*/
/* Click to Go to Web Page*/
this.movieClip_11.addEventListener("click", fl_ClickToGoToWebPage_15);
function fl_ClickToGoToWebPage_15() {
window.open("___", "_self");
}
The problem is that javascript handles scope(i.e. this) differently to ActionScript. In AS3 you can assume that the event handler maintains the scope of its containing object. In JS this isn't the case. Here are a couple of solutions to this problem:
You can pass the scope to the event handler using the bind method. For example, this technique is utilized in the code snippets in Flash for HTML5 Canvas/Timeline Navigation/Click to Go to Frame and Play.
this.movieClip_11.stop();
var frequency=3;
stage.enableMouseOver(frequency);
this.movieClip_11.addEventListener("mouseover",
fl_MouseOverHandler_32.bind(this));
function fl_MouseOverHandler_32()
{
this.movieClip_11.play();
}
An alternative solution available in easeljs(the javascript library utilized by Flash for producing HTML canvas content) is achieved by calling the EventDispatcher method called on instead of addEventListener. easeljs docs Now the event handler assumes the scope of the object that dispatched the event.
this.movieClip_11.stop();
var frequency=3;
stage.enableMouseOver(frequency);
this.movieClip_11.on("rollover",fl_MouseOverHandler_32);
function fl_MouseOverHandler_32()
{
this.play();
}

How to properly scroll IFrame to bottom in javascript

For a mockup-webpage used for research on interaction on websites, I created a mockup message-stream using JavaScript. This message stream is loaded in an IFrame and should show images at pre-set intervals and scroll to the bottom of the page after placing a new image at the bottom of the page. Getting the images to appear is working quite well with the provided script. However, both Chrome and IE seem to have trouble scrolling the page to the bottom. I would like to scroll to the bottom of the page as soon as the image is attached, but have for now added a 5 ms delay because that seemed to work sometimes. My questions are:
Is it okay to use document.body.scrollHeight for this purpose?
Can I make the scroll occur directly, or do I need a small interval before scrolling?
How to make the code scroll to the bottom of the IFrame directly after adding an image?
The following functions are used and trypost() is started onLoad:
function scrollToBottom(){
window.scrollBy(0,document.body.scrollHeight);
}
function trypost(){
point = point + 1;
if(point < interval.length){
//create and append a new image
var newImg = document.createElement("IMG");
newImg.src = "images/"+images[point]+".png";
document.getElementById('holder').appendChild(newImg);
//create and append a return
var br = document.createElement("br");
document.getElementById('holder').appendChild(br);
//time scroll to bottom (after an arbitrary 5 seconds)
var stb = window.setTimeout(scrollToBottom, 5);
//time next post
var nextupdate = interval[point]*400;
var tp = window.setTimeout(trypost, nextupdate);
}
}
My script section contains at least the following variables:
var point = -1;
var interval = [10, 10, 15];
var images = ["r1", "a1", "r2"];
This questions is a continuation of the project described in How to proper use setTimeout with IE?
To answer one of your questions, document.body.scrollHeight is appropriate for this purpose, but not if you're actually calling for document. That'll give you the scroll height of the document the iFrame is in, not the iFrame's document. The iFrame's document can be called upon by [insert variable for iFrame here].contentDocument.
Here's how I did it (and by that, I mean I tested it out with my own stuff to make sure it worked):
let i = document.querySelector('iframe')
i.contentWindow.scrollTo(0, i.contentDocument.body.scrollHeight);
That being said, the other answer by Thomas Urban will also work most of the time. The difference is only if your page has a really long scroll height. Most pages won't be longer than 999999 (for all I know that's impossible and that's why they chose that number), but if you have a page longer than that, the method I showed here would scroll to the bottom and the 999999 would scroll to somewhere not yet at the bottom.
Also note, if you have more than one iFrame, you're gonna want to query it in a different way than I did, like by ID.
Scrolling to bottom is always like scrolling to some ridiculously large top offset, e.g. 999999.
iframe.contentWindow.scrollTo( 0, 999999 );
In addition see this post: Scrolling an iframe with javascript?
If scrolling occurs too early it's probably due to images not being loaded yet. Thus, you will have to scroll as soon as added image has been loaded rather than on having placed it. Add
newImg.onload = function() { triggerScrolling(); };
after creating newImg, but before assigning property src.
If several events are required to trigger scrolling you might need to use some "event collector".
function getEventCollector( start, trigger ) {
return function() {
if ( --start == 0 ) { trigger(); )
};
}
You can then use it like this:
var collector = getEventCollector( 2, function() { triggerScrolling(); } );
newImg.onload = collector;
window.setTimeout( collector, 100 );
This way triggerScrolling() is invoked after 100ms at least and after image has been loaded for collector has to be invoked twice for triggerScrolling() being invoked eventually.

iframe contents not appearing on screen even when checking for onload event javascript

We are trying to build an HTML game in which abobe edge is being used for animations and those animations are being inserted into iframes. We are trying to preload the iframes before removing the 'loading screen' so that the users won't see blank iframes initially.
Here is the code for loading the iframes.
We have a global variable var middleBotLoaded = false;
The following function tries to dynamically populate the iframe and once the iframe has loaded , we are assigning the variable to true
function _trackIFrameLoading()
{
if (document.getElementById("botzmiddleidlesequence_iframe").attachEvent)
{
document.getElementById("botzmiddleidlesequence_iframe").attachEvent("onload", function() { middleBotLoaded = true; });
}
else
{
document.getElementById("botzmiddleidlesequence_iframe").onload = function() { middleBotLoaded = true; };
}
document.getElementById("botzmiddleidlesequence_iframe").src = APP_BASE_URL + "blitzbotzidlesequence/blitzbotz/"+middleBotzId;
}
We have a method to check if the global variable has become true and if so , we are removing the loading screen.The method is being called in a interval of 500 milliseconds
setTimeout(_haveAllCharactersLoaded,500);
function _haveAllCharactersLoaded()
{
if(middleBotLoaded == true)
{
$(jOverlay).fadeOut(800, function() {
$(jOverlay).remove();
});
}
else
{
setTimeout(_haveAllCharactersLoaded,500);
}
}
The problem is that even after the loading screen disappears , the iframe contents take time to come up on the screen .
We have observed that the duration depends on the speed of the net connection , but then , isn't using onload the whole point of making sure that the contents have loaded.
Is there any other approach for dealing with this problem.
Thanks.
EDIT : I have to wait for two days before I can start a bounty but I am willing to award it to anyone who can provide a canonical answer to the question.
I have two answers here.
First, I think you should reconsider the way you're coding this game, unless it's a static, turn based game that only relies upon animations (think Pokemon.)
Second, I have a suggestion for you to try in fixing your code.
First Answer:
You asked if there is any other approach to dealing with this problem.
My first reaction to that, would be to skip using iFrames entirely. Adobe Edge may provide you with a good way to craft animations, but for use in a game engine you will only find yourself fighting against the design of how Adobe Edge handles it's animations.
Instead, I would recommend learning how to use HTML5's canvas element. Canvas is built to handle dynamically loaded content (such as your game engine will be generating.) I can only imagine the event of having particle effect animation overlayed onto a game character as he is hit by a weapon. With your current approach, would you place that in an iFrame? Then, how would you ensure that this particle effect is placed on the correct location on the object?
There are many resources out there to help you begin learning the code you need to make a true game engine in the browser. I would recommend beginning by learning how Canvas works. If you want to animate using the DOM, learn about requestAnimationFrame.
http://creativejs.com/
http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial
Second Answer:
I would recommend looking into the variable scope of your middleBotLoaded. This answer (Set variable in parent window from iframe) would be a good place to look.
Instead of using document.getElementById("botzmiddleidlesequence_iframe").attachEvent("onload", function() { middleBotLoaded = true; });
try using document.getElementById("botzmiddleidlesequence_iframe").attachEvent("onload", function() { parent.middleBotLoaded = true; });
Alternatively, try something along these lines:
onLoad event:
document.getElementById("botzmiddleidlesequence_iframe").attachEvent("onload", function() { parent.middleBotLoaded();});
Function to handle loading:
function middleBotLoaded()
{
$(jOverlay).fadeOut(800, function() {
$(jOverlay).remove();
});
}
It's a better practice to directly call an event, rather than polling for variable changes using setTimeout.

Toggling link text when navigating between pages based on selected stylesheet

I have installed a script on my website that allows for a low contrast setting and a high contrast setting, as my site will be used by sight impaired persons. The script works perfectly. The only problem is when a visitor visits multiple pages of the site.
When you first visit the site, the low contrast setting is in effect by default and only the link to the high contrast setting appears. If you then visit other pages of the website, the low contrast setting is in effect by default and only the high contrast link appears (this is perfect and as it should be). The website does this by using a cookie.
Here is the problem. If you click on the high contrast link to view the page in the high contrast setting and then go to another page, the other page appears in the high contrast setting (as it should), but instead of a link to the low contrast setting appearing (which I would like to happen), a link to the high contrast setting appears (which does not make sense, given the page is already in the high contrast setting).
My site is not done, but I published a few pages at http://www.14kt.eu/ so you can see what I am talking about. A number of the members of this site were kind enough to help me with the code/script and things were working perfectly for a bit, but then it just stopped working. I suspect I changed something in the rest of the html that caused this. Rather perplexed over this issue.
If anybody can please tell me how to fix this problem, I would be most grateful.
Thank you for your time, Chris
It looks like you just need your stylesheet buttons to be conditionally hidden based on the cookie.
You can do this with the code below (updated):
function setStylesheetFromCookie() {
var stylesheet = readCookie('mysheet') || 'none';
if( stylesheet == 'highcontrast' ) {
console.log('high');
document.getElementById('Lc').style.display = 'block';
document.getElementById('Hc').style.display = 'none';
} else {
console.log('low');
document.getElementById('Hc').style.display = 'block';
document.getElementById('Lc').style.display = 'none';
}
}
Add that code somewhere in script_1.js.
In order for that to work, it needs to run on window load.
This brings us to problem two. You have two different window.onload assignments in script 1.
You need to consolidate the two. Delete the line
window.onload = FixRows;
And modify the second window.onload = function() to look like the following:
window.onload = function() {
var el = document.getElementById('mydiv');
var size = readCookie('fontsize');
if(size) {
doChangeSize(el, size);
}
var original = readCookie('originalsize');
if(original) {
el.originalSize = original;
}
FixRows(); //You are adding this line
setStylesheetFromCookie(); //and adding this line to the end of the function
}
Notice the two new function calls at the end.
This should solve your problem.
Cheers!
Just kind of poking around and it appears as though you've got javascript running in a couple different directions at the same time. window.onload is tied separately to two different functions. The first one calls FixRows which should work to display 'low contrast'/'high contrast' appropriately (from the cookie you set). I'm thinking the second window.onload is overriding the first.
I don't think this is directly affecting your code, but you have setCookie() in styleswitcher.js and createCookie() in script_1.js - they are doing the same thing. I'd say you should at least consolidate you cookie functions in one or the other library to cut down on confusion.
Hope I've been helpful.

Categories

Resources