My (simple) javascript works in every browser but Firefox - Why? - javascript

For universoty we had to "build" a xmas tree (svg) and use javascript to make the stars (ger stern(e)) rotate and the balls (ger (kugel(n)) change colors - one star had to be a shooting star. Everything work full points... but one penalty point as it doesn't work in Firefox
Does anyone has any idea why not?
The SVG is down below.
https://www.dropbox.com/s/vi4lxgortgyeq3f/uebung4.svg
Thanks in advance... and please keep in mind it's my very first time to use javascript :D
<script type="text/javascript">
function farbe()
{
var a = "#ff0000";
var b = "#007f00";
if (document.getElementById("kugeln").style.fill == a)
{
document.getElementById("kugeln").style.setProperty('fill', b);
}
else
{
document.getElementById("kugeln").style.setProperty('fill', a);
}
}
var initialTheta = 0;
var thetaDelta = 0.3;
var delay = 10;
var stern;
var timer;
function drehen()
{
stern = document.getElementById("stern_1");
stern.currentTheta = initialTheta;
timer = setInterval(Animation, delay);
stern_2 = document.getElementById("stern_2");
stern_3 = document.getElementById("stern_3");
stern_4 = document.getElementById("stern_4");
}
function stop()
{
clearInterval(timer);
return;
}
function Animation()
{
stern.setAttribute("transform", "rotate(" + stern.currentTheta + " 50,50)");
stern.currentTheta += thetaDelta;
stern_2.setAttribute("transform", "rotate(" + stern.currentTheta + " 50,50)");
stern.currentTheta += thetaDelta;
stern_3.setAttribute("transform", "rotate(" + stern.currentTheta + " 50,50)");
stern.currentTheta += thetaDelta;
stern_4.setAttribute("transform", "rotate(" + stern.currentTheta + " 0,2000)");
stern.currentTheta += thetaDelta;
}

The drehen function gets called two times in a row for each mouse over, so you are calling two times setInterval but recording only the last return value. You should call clearInterval before setting the new one.
Try something like
if(timer != undefined){
clearInterval(timer);
}
timer = setInterval(Animation, delay);

You are comparing colours against hex values
var a = "#ff0000";
if (document.getElementById("kugeln").style.fill == a)
UAs don't have to return colours as hex values and in fact Firefox does not. It will convert your colour to an rgb or rgba representation. If you add an alert
alert(document.getElementById("kugeln").style.fill);
you'll see Firefox returns rgb(255, 0, 0) as the colour which is the same as #ff0000 expressed in a different way. So you could add a check for this kind of colour format or...
A more robust solution would be to have a visiblity:hidden element with the colour you want to compare to and then check against the fill property of that.

Related

Use after effects to create a blinking courser typewriter effect with highlight effect at the same time

I am trying to replicate the typing animation from - https://imgur.com/a/TqOypip - in after effects.
For the text I'm using:
`var sign = "|"; // change the blinking sign to "▌"or "_"
var blinkInterval = 15; // edit the blinking interval in frames
// slider with text length
var i = effect("Text")("ADBE Slider Control-0001");
// checkbox to turn the cursor on and off
var on = effect("On/Off")("ADBE Checkbox Control-0001");
var frames = timeToFrames(time);
var check = frames / blinkInterval;
if (on == 1) {
if (i.valueAtTime(time + thisComp.frameDuration) > i) {
end = sign;
} else {
if (Math.floor(check) % 2 == 0) {
end = sign;
} else {
end = " ";
}
}
} else {
end = " ";
}
text.sourceText.substr(0,parseInt(i)) + end; `
Which works but then I have to manually add the white revealing lines behind the text. The example I'm trying to emulate seems to have this connected to the typewriter function somehow. This will also be of benefit as I won't have to modify many trim paths if I change the length of the text at any time.
Any help greatly appreciated.
Thanks!
See above for the code I tried.

Javascript Color Iterator Not Working?

First off, yes, I'm AWARE there's a much easier way to do this in jQuery, but I'm trying to learn how to do it by hand in Javascript to get a better understanding of the language.
I have a div that I want to slowly fade through many colors of the rainbow. Here's what I have so far:
<script type="text/javascript">
var bar = document.getElementById("workbar");
var x = 0;
bar.onclick = change;
function change() {
requestAnimationFrame(color);
}
function color() {
window.alert("color!");
bar.style.background = "hsl(" + x + ", 100%, 50%);";
if (x < 358) {
x++;
requestAnimationFrame(color);
}
else {
x = 0;
requestAnimationFrame(color);
}
}
</script>
I'm iterating through the first digit of the hsl color system, which will provide me with hundreds of color variations but not every single unnecessary color shade in the universe.
I click on it, and nothing happens. Now I know it's getting through to the color function because I put that alert box there and it went off. I also know it's looping through the color function because after you x out of the alert box another appears. So it must be a problem with the part where it assigns the color. Any ideas?
Remove the semicolon
"hsl(" + x + ", 100%, 50%);";
^
(function () {
var bar = document.getElementById("workbar"),
x = 0;
function color() {
bar.style.background = "hsl(" + x + ", 100%, 50%)";
x++;
if (x >= 358) {
x = 0;
}
requestAnimationFrame(color);
}
function change() {
requestAnimationFrame(color);
}
bar.addEventListener("click", change, false);
}());
<div id="workbar">Click Me</div>

Text pagination inside a DIV with image

I want to paginate a text in some div so it will fit the allowed area
Logic is pretty simple:
1. split text into words
2. add word by word into and calculate element height
3. if we exceed the height - create next page
It works quite good
here is JS function i've used:
function paginate() {
var newPage = $('<pre class="text-page" />');
contentBox.empty().append(newPage);
var betterPageText='';
var pageNum = 0;
var isNewPage = false;
var lineHeight = parseInt(contentBox.css('line-height'), 10);
var wantedHeight = contentBox.height() - lineHeight;
for (var i = 0; i < words.length; i++) {
if (isNewPage) {
isNewPage = false;
} else {
betterPageText = betterPageText + ' ' + words[i];
}
newPage.text(betterPageText + ' ...');
if (newPage.height() >= wantedHeight) {
pageNum++;
if (pageNum > 0) {
betterPageText = betterPageText + ' ...';
}
newPage.text(betterPageText);
newPage.clone().insertBefore(newPage)
betterPageText = '...';
isNewPage = true;
} else {
newPage.text(betterPageText);
}
}
contentBox.craftyslide({ height: wantedHeight });
}
But when i add an image it break everything. In this case text overflows 'green' area.
Working fiddle: http://jsfiddle.net/74W4N/7/
Is there a better way to paginate the text and calculate element height?
Except the fact that there are many more variables to calculate,not just only the word width & height, but also new lines,margins paddings and how each browser outputs everything.
Then by adding an image (almost impossible if the image is higher or larger as the max width or height) if it's smaller it also has margins/paddings. and it could start at the end of a line and so break up everything again.basically only on the first page you could add an image simply by calculating it's width+margin and height+margin/lineheight. but that needs alot math to get the wanted result.
Said that i tried some time ago to write a similar script but stopped cause of to many problems and different browser results.
Now reading your question i came across something that i read some time ago:
-webkit-column-count
so i made a different approach of your function that leaves out all this calculations.
don't judge the code as i wrote it just now.(i tested on chrome, other browsers need different prefixes.)
var div=document.getElementsByTagName('div')[0].firstChild,
maxWidth=300,
maxHeigth=200,
div.style.width=maxWidth+'px';
currentHeight=div.offsetHeight;
columns=Math.ceil(currentHeight/maxHeigth);
div.style['-webkit-column-count']=columns;
div.style.width=(maxWidth*columns)+'px';
div.style['-webkit-transition']='all 700ms ease';
div.style['-webkit-column-gap']='0px';
//if you change the column-gap you need to
//add padding before calculating the normal div.
//also the line height should be an integer that
// is divisible of the max height
here is an Example
http://jsfiddle.net/HNF3d/10/
adding an image smaller than the max height & width in the first page would not mess up everything.
and it looks like it's supported by all modern browsers now.(with the correct prefixes)
In my experience, trying to calculate and reposition text in HTML is almost an exercise in futility. There are too many variations among browsers, operating systems, and font issues.
My suggestion would be to take advantage of the overflow CSS property. This, combined with using em sizing for heights, should allow you to define a div block that only shows a defined number of lines (regardless of the size and type of the font). Combine this with a bit of javascript to scroll the containing div element, and you have pagination.
I've hacked together a quick proof of concept in JSFiddle, which you can see here: http://jsfiddle.net/8CMzY/1/
It's missing a previous button and a way of showing the number of pages, but these should be very simple additions.
EDIT: I originally linked to the wrong version for the JSFiddle concept
Solved by using jQuery.clone() method and performing all calculations on hidden copy of original HTML element
function paginate() {
var section = $('.section');
var cloneSection = section.clone().insertAfter(section).css({ position: 'absolute', left: -9999, width: section.width(), zIndex: -999 });
cloneSection.css({ width: section.width() });
var descBox = cloneSection.find('.holder-description').css({ height: 'auto' });
var newPage = $('<pre class="text-page" />');
contentBox.empty();
descBox.empty();
var betterPageText = '';
var pageNum = 0;
var isNewPage = false;
var lineHeight = parseInt(contentBox.css('line-height'), 10);
var wantedHeight = contentBox.height() - lineHeight;
var oldText = '';
for (var i = 0; i < words.length; i++) {
if (isNewPage) {
isNewPage = false;
descBox.empty();
}
betterPageText = betterPageText + ' ' + words[i];
oldText = betterPageText;
descBox.text(betterPageText + ' ...');
if (descBox.height() >= wantedHeight) {
if (i != words.length - 1) {
pageNum++;
if (pageNum > 0) {
betterPageText = betterPageText + ' ...';
}
oldText += ' ... ';
}
newPage.text(oldText);
newPage.clone().appendTo(contentBox);
betterPageText = '... ';
isNewPage = true;
} else {
descBox.text(betterPageText);
if (i == words.length - 1) {
newPage.text(betterPageText).appendTo(contentBox);
}
}
}
if (pageNum > 0) {
contentBox.craftyslide({ height: wantedHeight });
}
cloneSection.remove();
}
live demo: http://jsfiddle.net/74W4N/19/
I actually came to an easier solution based on what #cocco has done, which also works in IE9.
For me it was important to keep the backward compatibility and the animation and so on was irrelevant so I stripped them down. You can see it here: http://jsfiddle.net/HNF3d/63/
heart of it is the fact that I dont limit height and present horizontal pagination as vertical.
var parentDiv = div = document.getElementsByTagName('div')[0];
var div = parentDiv.firstChild,
maxWidth = 300,
maxHeigth = 200,
t = function (e) {
div.style.webkitTransform = 'translate(0,-' + ((e.target.textContent * 1 - 1) * maxHeigth) + 'px)';
div.style["-ms-transform"] = 'translate(0,-' + ((e.target.textContent * 1 - 1) * maxHeigth) + 'px)';
};
div.style.width = maxWidth + 'px';
currentHeight = div.offsetHeight;
columns = Math.ceil(currentHeight / maxHeigth);
links = [];
while (columns--) {
links[columns] = '<span>' + (columns + 1) + '</span>';
}
var l = document.createElement('div');
l.innerHTML = links.join('');
l.onclick = t;
document.body.appendChild(l)

JavaScript -Change CSS color for 5 seconds - How to add easing effect?

With the reference to this question:-
JavaScript -Change CSS color for 5 seconds
Working demo of the answer:-
http://jsfiddle.net/maniator/dG2ks/
I need to know how i can add an easing effect to it, so that slowly and slowly color get 100% opaque and similarly get 100% transperent.
Code
function makeRGBStr(obj) {
if (obj.a == null) return "rgb(" + obj.r + "," + obj.g + "," + obj.b + ")";
else return "rgba(" + obj.r + "," + obj.g + "," + obj.b + "," + obj.a + ")";
}
window["highlight"] = function(obj, color) {
var highlightColor = color || {
"r": 255,
"g": 0,
"b": 0
};
var orig = obj.style.backgroundColor;
var curAlpha = 1;
obj.style.backgroundColor = makeRGBStr(highlightColor);
setTimeout(function() {
curAlpha -= 0.1;
var newColor = highlightColor;
newColor.a = curAlpha;
obj.style.backgroundColor = makeRGBStr(newColor);
if (curAlpha <= 0) {
obj.style.backgroundColor = orig;
}
else {
setTimeout(arguments.callee, 100);
}
});
}
jsFiddle: http://jsfiddle.net/dG2ks/32/
Some examples
Highlight if specific $_GET variable is present:
Code: http://jsfiddle.net/dG2ks/36/, see it in action: http://jsfiddle.net/dG2ks/36/show/?someVar=there
Highlight table cell: http://jsfiddle.net/dG2ks/38/
Highlight all table cells with different colors: http://jsfiddle.net/dG2ks/40/
You can add the jquery library, combined with jquery ui - if you don't use it already - and use the switchClass method.
All info here : http://jqueryui.com/demos/switchClass/
It will only take 5 lines to do what you want :
Place jquery en jquery ui in the head section of your page (2 lines of code).
These are the remotely hosted files, you can copy/paste the code 'as is'.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script src="http://code.jquery.com/ui/1.8.18/jquery-ui.min.js" type="text/javascript"></script>
And then, at the end of the body, place a script that contains these three lines of code :
$(".yourbutton".click(function() {
switchClass('.currentclass','.redclass',500)
// transition from .currentclass to .redclass in 500 milliseconds
});

changing background image with a for loop

i have a table with 3 cells the middel 1 in a black image so it will look like there is a line in the middle of the screen.
now in the other cell i want to show pictures, so i tryed to do a loop that changing the images every second with by hiding the cells and then show them.
the script:
$(window).ready(function () {
//the images sits in a div with a hidden property.
var AlumniumPictures = $("#AlumnimPictureHolder").children();
var ShipozimPictures = $("#ShipozimPictureHolder").children();
//var timer = $.timer(yourfunction, 10000);
for (var i = 0; i < 10; i++) {
$(".almoniyomButtonTD").css({
"background-image": "url(" + $(AlumniumPictures[i]).attr('src') + ")"
});
$(".shipozimButtonTD").css({
"background-image": "url(" + $(ShipozimPictures[i]).attr('src') + ")"
});
$(".almoniyomButtonTD").hide();
$(".shipozimButtonTD").hide();
$(".almoniyomButtonTD").show(1100);
$(".shipozimButtonTD").show(1100);
//for some reson the code dosnt work if im not using the setInterval method.
document.setInterval(1000);
}
});
this is not working it only show me the first images and then stop.
is there a batter way to do this?
am im doing this right?
I think you might do this for the background:
$(window).ready(function () {
//the images sits in a div with a hidden property.
var AlumniumPictures = $("#AlumnimPictureHolder").children();
var ShipozimPictures = $("#ShipozimPictureHolder").children();
//var timer = $.timer(yourfunction, 10000);
time = 0;
step = 1000; // One secund
for (var i = 0; i < 10; i++) {
time+= step;
$(".almoniyomButtonTD").hide();
$(".shipozimButtonTD").hide();
$(".almoniyomButtonTD").show(1100);
$(".shipozimButtonTD").show(1100);
//for some reson the code dosnt work if im not using the setInterval method.
document.setInterval("changeBG('" + $(AlumniumPictures[i]).attr('src') + "', '.almoniyomButtonTD')", time);
document.setInterval("changeBG('" + $(AlumniumPictures[i]).attr('src') + "', '.shipozimButtonTD')", time);
}
});
function changeBG(image, obj) {
$(obj).css({
"background-image": "url(" + image + ")"
});
}
But I don't undestand what you want to do with this:
$(".almoniyomButtonTD").hide();
$(".shipozimButtonTD").hide();
$(".almoniyomButtonTD").show(1100);
$(".shipozimButtonTD").show(1100);
See the docs about setInterval. You need to tell it what code you are running.
window.setInterval(code, delay);
You aren't specifying any code for it to run! Try placing your for statement in a function and calling that.
Also, from Mozilla and MS docs setInterval seems to be on the window object, not on the document object. I don't think it will work the way you have it. I imagine if you looked in a debugger you would see an error thrown.
window.setInterval(myFunction, 1000);
function myFunction() {
for (var i = 0; i < 10; i++) {
$(".almoniyomButtonTD").css({
"background-image": "url(" + $(AlumniumPictures[i]).attr('src') + ")"
});
$(".shipozimButtonTD").css({
"background-image": "url(" + $(ShipozimPictures[i]).attr('src') + ")"
});
$(".almoniyomButtonTD").hide();
$(".shipozimButtonTD").hide();
$(".almoniyomButtonTD").show(1100);
$(".shipozimButtonTD").show(1100);
}
}

Categories