canvas.drawImage() and canvas.fillText() acting funky - javascript

<html>
<script type="text/javascript">
var name="name of troop/general"; var attack="attack"; var defense="defense"; var effect1=""; var effect2=""; var effect3=""; var effect4=""; var effect5=""; var effect6=""; var flavortext1=""; var flavortext2=""; var flavortext3=""; var flavortext4=""; var flavortext5=""; var flavortext6=""; var username="your name here"; var a="troop"; var b="common1"; var c="human"; var d="any"; var e="agility";
function setname()
{
name = document.forms["form"]["name"].value;
alert("unit name = " + name);
}
function setattack()
{
attack = document.forms["form"]["attack"].value;
alert("attack = " + attack);
}
function setdefense()
{
defense = document.forms["form"]["defense"].value;
alert("defense = " + defense);
}
function seteffect()
{
//using document.forms to get the value of effects
alert("effect = " + effect1 + effect2 + effect3 + effect4 + effect5 + effect6);
}
function setflavortext()
{
//using document.forms to get the value of flavortext
alert("flavortext =" + flavortext1 + flavortext2 + flavortext3 + flavortext4 + flavortext5 + flavortext6);
}
function setusername()
{
username = document.forms["form"]["username"].value;
alert("name = " + username);
}
function setimage()
{
base_image = new Image();
base_image.src = document.forms["form"]["image"].value;
base_image.onload = function
{
base.drawImage(base_image, 300, 30, 90, 90);
}
}
</script>
<canvas id="canvas" width="400" height="700" style="solid"></canvas>
<script type="text/javascript">
var mathmath = defense/4;
var attackvalue = attack + mathmath;
function writeall()
{
var can=document.getElementById("canvas");
var base=can.getContext("2d");
base.fillStyle="grey"; //background
base.fillRect(0,0,400,1200);
base.fillStyle="#FFBF00"; //orangeish
base.font="15px Arial";
base.fillText(name, 0, 20);
base.fillStyle="#EFFBF8" //white
base.fillText("Quality:", 0, 40); //this is the only base.fillText that works...
base.fillText(attack, 50, 80);
base.fillText(defense, 60, 100);
base.fillText(attackvalue, 120, 60);
//base.fillText's like the ones above, of varying colors
if(a == "general")
{
base.fillText(a, 350, 20);
}
//ifs like the one above
base.fillStyle="#FF4000" //dark orange
base.fillText(effect1, 0, 180);
//5 more effect vars being fillTexted; do not work...
var y = 0;
//ifs to set y
base.font="italic 15px Arial";
base.fillStyle="#EFFBF8" //white
//ifs to set y
base.font="15px Arial";
var x = 0;
//ifs to set x
base.fillText(username, 0, y+x);
if(c == "human")
{
base_image = new Image();
base_image.src = 'http://images2.wikia.nocookie.net/__cb20120812195219/dotd/images/c/c5/Race_human.png';
base_image.onload = function()
{
base.drawImage(base_image, 0, 105);
}
}
//ifs like the one above, a bunch of them; none work
</script>
</html>
I honestly have no idea where the problem is, but it is noteable it all worked as intended (which I will get into later) before I tried to add the setimage() function...
It is intended to create a large grey rectangle and write a bunch of stuff on it, I messed around a little so it might look weird; but right now all it makes is a grey rectancle with the word quality on it; and nothing happens when i press the button for the setimage() function, not even the alert I put in it... I've looked through it a couple times, then a couple times with notepad++ and I am confused...
Thanks for your time in advance.

Related

Can't create text in easeljs

currelty working on a small matching puzzle game. Currently it displays text for the time remaining and the number of tiles that have been macthes. I'm trying to create on for best completion time as well (How fast the person finishes the game) however have been running into a lot of problems. for two variables that I created "txt" and "matchesFoundText" when I type them the autocomplete box will popup and ".text" is displayed as one of the options so i would get something like "txt.text. however I'm not getting that option at all for "bestTimeTxt" and I have no idea as to why this is happening. I did all three variables the same way so I'm at a loss as to why Text is not available to select from for "bestTimeTxt". Here is my entire script.
<!DOCTYPE html>
<html>
<head>
<title>Recipe: Drawing a square</title>
<script src="easel.js"></script>
<script type="text/javascript">
var canvas;
var stage;
var squareSide = 70;
var squareOutline = 5;
var max_rgb_color_value = 255;
var gray = Graphics.getRGB(20, 20, 20);
var placementArray = [];
var tileClicked;
var timeAllowable;
var totalMatchesPossible;
var matchesFound;
var txt;
var bestTime;
var bestTimeTxt;
var matchesFoundText;
var squares;
function init() {
var rows = 5;
var columns = 6;
var squarePadding = 10;
canvas = document.getElementById('myCanvas');
stage = new Stage(canvas);
var numberOfTiles = rows*columns;
matchesFound = 0;
timeAllowable = 5;
bestTime = 0;
txt = new Text(timeAllowable, "30px Monospace", "#000");
txt.textBaseline = "top"; // draw text relative to the top of the em box.
txt.x = 500;
txt.y = 0;
bestTimeTxt = new Text(bestTime, "30px Monospace", "#000");
bestTimeTxt.textBaseLine = "top";
bestTimeTxt.x = 500;
bestTimeTxt.y = 80;
stage.addChild(txt);
stage.addChild(bestTimeTxt);
squares = [];
totalMatchesPossible = numberOfTiles/2;
Ticker.init();
Ticker.addListener(window);
Ticker.setPaused(false);
matchesFoundText = new Text("Pairs Found: "+matchesFound+"/"+totalMatchesPossible, "30px Monospace", "#000");
matchesFoundText.textBaseline = "top"; // draw text relative to the top of the em box.
matchesFoundText.x = 500;
matchesFoundText.y = 40;
stage.addChild(matchesFoundText);
setPlacementArray(numberOfTiles);
for(var i=0;i<numberOfTiles;i++){
var placement = getRandomPlacement(placementArray);
if (i % 2 === 0){
var color = randomColor();
}
var square = drawSquare(gray);
square.color = color;
square.x = (squareSide+squarePadding) * (placement % columns);
square.y = (squareSide+squarePadding) * Math.floor(placement / columns);
squares.push(square);
stage.addChild(square);
square.cache(0, 0, squareSide + squarePadding, squareSide + squarePadding);
square.onPress = handleOnPress;
stage.update();
};
}
function drawSquare(color) {
var shape = new Shape();
var graphics = shape.graphics;
graphics.setStrokeStyle(squareOutline);
graphics.beginStroke(gray);
graphics.beginFill(color);
graphics.rect(squareOutline, squareOutline, squareSide, squareSide);
return shape;
}
function randomColor(){
var color = Math.floor(Math.random()*255);
var color2 = Math.floor(Math.random()*255);
var color3 = Math.floor(Math.random()*255);
return Graphics.getRGB(color, color2, color3)
}
function setPlacementArray(numberOfTiles){
for(var i = 0;i< numberOfTiles;i++){
placementArray.push(i);
}
}
function getRandomPlacement(placementArray){
randomNumber = Math.floor(Math.random()*placementArray.length);
return placementArray.splice(randomNumber, 1)[0];
}
function handleOnPress(event){
var tile = event.target;
tile.graphics.beginFill(tile.color).rect(squareOutline, squareOutline, squareSide, squareSide);
if(!!tileClicked === false || tileClicked === tile){
tileClicked = tile;
tileClicked.updateCache("source-overlay");
}else{
if(tileClicked.color === tile.color && tileClicked !== tile){
tileClicked.visible = false;
tile.visible = false;
matchesFound++;
matchesFoundText.text = "Pairs Found: "+matchesFound+"/"+totalMatchesPossible;
if (matchesFound===totalMatchesPossible){
gameOver(true);
}
}else{
tileClicked.graphics.beginFill(gray).rect(squareOutline, squareOutline, squareSide, squareSide);
}
tileClicked.updateCache("source-overlay");
tile.updateCache("source-overlay");
tileClicked = tile;
}
stage.update();
}
function tick() {
secondsLeft = Math.floor((timeAllowable-Ticker.getTime()/1000));
txt.text = secondsLeft;
;
if (secondsLeft <= 0){
gameOver(false);
}
stage.update();
}
function gameOver(win){
Ticker.setPaused(true);
for(var i=0;i<squares.length;i++){
squares[i].graphics.beginFill(squares[i].color).rect(5, 5, 70, 70);
squares[i].onPress = null;
if (win === false){
squares[i].uncache();
}
}
var replayParagraph = document.getElementById("replay");
replayParagraph.innerHTML = "<a href='#' onClick='history.go(0);'>Play Again?</a>";
if (win === true){
matchesFoundText.text = "You win!"
}else{
txt.text = secondsLeft + "... Game Over";
}
}
function replay(){
init();
}
</script>
</head>
<body onload="init()">
<header id="header">
<p id="replay"></p>
</header>
<canvas id="myCanvas" width="960" height="400"></canvas>
</body>
</html>
Okay so apparently the reason why I was having issues is because the x and y positions of the bestTimeTxt variable was causing it to be obscured by the position of everything else.

Random bgColor: is it possible for colour to be different for every click?

I have a background that changes colour randomly every time a button is clicked. Is it possible to ensure that the colour is different upon every click (avoiding the possibility that the same colour is generated 2-3 times in a row)? Source code for the .js file is below (HTML is basically just the button).
var bgcolorlist, btn;
function newColor() {
bgcolorlist = '#'+Math.floor(Math.random()*16777215).toString(16);
document.body.style.backgroundColor = bgcolorlist;
}
function initAll() {
btn = document.getElementById('click1');
btn.addEventListener('click', newColor, false);
}
initAll();
Try the following:
var bgcolorlist, btn;
var colorList = [];
function newColor() {
bgcolorlist = '#'+Math.floor(Math.random()*16777215).toString(16);
while(colorList.indexOf(bgcolorlist) != -1){
bgcolorlist = '#'+Math.floor(Math.random()*16777215).toString(16);
}
colorList.push(bgcolorlist);
document.body.style.backgroundColor = bgcolorlist;
}
function initAll() {
btn = document.getElementById('click1');
btn.addEventListener('click', newColor, false);
}
initAll();
Here is a version with constant-time lookup into the set of previously generated colors. There would be significant speed improvements using this method over the used color array if the color array got larger.
var usedColors = {};
function randomColor() {
return Math.floor(Math.random() * 0xFFFFFF).toString(16);
}
function unusedColor() {
var color;
while ((color = randomColor()) in usedColors);
usedColors[color] = true;
return '#' + color;
}
window.onload = function() {
document.body.style.backgroundColor = unusedColor();
};
This strategy compares each channel (new and old) and ensures that on a channel by channel basis there is at least a minimum change (threshold)
function getChannelColor(color, threshold){
var _new = 0;
var _tooCloseMin = color - threshold;
var _tooCloseMax = color + threshold;
do { _new = Math.floor(Math.random() * 256); }
while (_tooCloseMin < _new && _new < _tooCloseMax);
return _new;
}
setInterval(function(){
var target = document.getElementById("target");
var threshold = 5;
var prevRGB = getComputedStyle(target).backgroundColor.match(/\d+/g);
var prevR = parseInt(prevRGB[0]);
var prevG = parseInt(prevRGB[1]);
var prevB = parseInt(prevRGB[2]);
var newR = getChannelColor(prevR, threshold);
var newG = getChannelColor(prevG, threshold);
var newB = getChannelColor(prevB, threshold);
target.style.backgroundColor = "rgb(" + newR + ", " + newG + ", " + newB + ")";
}, 1000);
#target{
width: 100px;
height: 100px;
margin: 1em;
background-color: rgb(255, 255, 255);
}
<div id="target"></div>

Why do my values mutate inside the arrays?

I wrote a little test program, exploring my problem, and it works the way I expect it, printing "four, five, six".
var foo = function() {
console.log("just one more test")
var destination = new Array;
data = [ "four", "five" , "six" ]
var parent = [ 0, 1, 2 ];
var something;
parent.forEach(function(element) {
something = data[element];
destination.push(something);
})
destination.forEach(function (thing) {
console.log(thing);
})
}
foo();
But in my real code, when I push things on to my 'clickable' array, all of the entries mutate into the current value of the 'clicker' variable. There are 3 entries in my 'scheme_list', and they draw correctly, but as I try to build areas to click on, at each iteration of the loop "in the loop" prints the value just pushed on to the array for every instance. That is, the instances of 'clicker' already in the loop change to the current value of clicker. I'm scratching my head trying to understand the difference between my real code and my test code. Or, more to the point, how to fix my real code.
var layout_color_schemes = function(scheme_list) {
var canvas = document.getElementById('color_picker_canvas');
var ctx = canvas.getContext('2d');
var x_upper_left = 5;
var y_upper_left = 5;
var width = 200;
var height = 30;
var clickables = new Array;
var clicker = {};
clicker.rect = {};
clicker.rect.width = width;
clicker.rect.height = height;
scheme_list.forEach(function(row) {
var grad = ctx.createLinearGradient(0, 0, 100, 0);
var cscheme = jQuery.parseJSON(row.json);
cscheme.forEach(function(color_point) {
grad.addColorStop(color_point[0], 'rgb(' + color_point[1] + ','
+ color_point[2] + ',' + color_point[3] + ')');
})
ctx.fillStyle = grad;
ctx.fillRect(x_upper_left, y_upper_left, width, height);
clicker.rect.x = x_upper_left;
clicker.rect.y = y_upper_left;
clicker.scheme = cscheme;
clicker.name = row.name;
clickables.push(clicker);
printf("clickables size = %d", clickables.length)
for (index = 0; index < clickables.length; ++index) {
printf("Index is %d", index)
printf("in the loop %j", clickables[index])
}
ctx.fillStyle = 'black'
ctx.fillText(row.name, x_upper_left + width + 10, 5 + y_upper_left
+ (height / 2));
y_upper_left = y_upper_left + height + 10;
});
clickables.forEach(function(area) {
printf("before call clickable area = %j", area)
});
wire_clickables(clickables);
};
function wire_clickables(clickables) {
clickables.forEach(function(area) {
if (area.hasOwnProperty('rect')) {
printf("wiring a clickable %j", area);
$("#color_picker_canvas").mousemove(function(e) {
var inside = false;
var offsetX = e.pageX - $(this).position().left;
var offsetY = e.pageY - $(this).position().top;
if (area && contains(area.rect, offsetX, offsetY)) {
document.body.style.cursor = 'pointer'
}
else {
document.body.style.cursor = 'default'
}
})
}
})
}
function contains(rect, x, y) {
return (x >= rect.x && x <= rect.x + rect.width && y >= rect.y && y <= rect.y
+ rect.height)
}
The clicker object exists outside of the loop, so all you are doing is pushing the same reference onto clickables. Instead, you want to push a copy of it. There are many ways to do this, but in your case this may be one of the simplest ways:
Replace
clickables.push(clicker);
with
clickables.push(JSON.parse(JSON.stringify(clicker));
Alternatively, move the clicker declaration and initialization inside the loop.

Mouseover doesn't work on an animated path

I used the following code to change the stroke-width when mouseover the path, but it doesn't work... I have checked many solutions on this matter, they seem to use the same solution as mine. My canvas is Raphael("svgContainer", 100, 100);
function drawPath(i,floorlevel,pointsNum){
var x1 = floorlevel[i].x;
var y1 = floorlevel[i].y;
var x2 = floorlevel[i+1].x;
var y2 = floorlevel[i+1].y;
var p = canvas.path("M"+x1 +" "+ y1);
p.attr("stroke", get_random_color());
p.attr("stroke-width",4);
p.attr("id",floorlevel[i].node+floorlevel[i+1].node);
p.animate({path:"M"+x1 +" "+ y1+ " L" + x2 +" "+ y2}, 1000);
var set = canvas.set();
var hoverIn = function() {
this.attr({"stroke-width": 10});
};
var hoverOut = function() {
this.attr({"stroke-width": 10});
}
p.hover(hoverIn, hoverOut, p, p);
set.push(p);
}
It seems to work fine when I sub in dummy values for the arguments you pass to the function:
http://jsfiddle.net/hKCDg/
I noticed you have the same stroke-width for hoverIn and hoverOut, which defeats the purpose.
var hoverIn = function() {
this.attr({"stroke-width": 10});
};
var hoverOut = function() {
this.attr({"stroke-width": 10});
};
I changed the latter to 5 in the demo here for visual effect.
Perhaps there's an error in the values you pass to the function?

Javascript Color Animation

I want to animate (transition) from 1 color to another in raw javascript.
I dont want to use any framework (jquery, mootools) or css3. plain raw javascript.
I have been really having trouble to do this, can someone help me out ? :)
maybe something like this:
lerp = function(a, b, u) {
return (1 - u) * a + u * b;
};
fade = function(element, property, start, end, duration) {
var interval = 10;
var steps = duration / interval;
var step_u = 1.0 / steps;
var u = 0.0;
var theInterval = setInterval(function() {
if (u >= 1.0) {
clearInterval(theInterval);
}
var r = Math.round(lerp(start.r, end.r, u));
var g = Math.round(lerp(start.g, end.g, u));
var b = Math.round(lerp(start.b, end.b, u));
var colorname = 'rgb(' + r + ',' + g + ',' + b + ')';
el.style.setProperty(property, colorname);
u += step_u;
}, interval);
};
You can play around an try it out as a jsfiddle or check out the full working example below. You might want to improve this by using HSL/HSV colors, which gives you a prettier transition, but i'll leave that up to you.
<html>
<head>
<title>Fade</title>
<style type="text/css">
#box {
width: 100px;
height: 100px;
background-color: rgb(255,0,0);
}
</style>
</head>
<body>
<div id="box"></div>
<script type="text/javascript" charset="utf-8">
// linear interpolation between two values a and b
// u controls amount of a/b and is in range [0.0,1.0]
lerp = function(a,b,u) {
return (1-u) * a + u * b;
};
fade = function(element, property, start, end, duration) {
var interval = 10;
var steps = duration/interval;
var step_u = 1.0/steps;
var u = 0.0;
var theInterval = setInterval(function(){
if (u >= 1.0){ clearInterval(theInterval) }
var r = parseInt(lerp(start.r, end.r, u));
var g = parseInt(lerp(start.g, end.g, u));
var b = parseInt(lerp(start.b, end.b, u));
var colorname = 'rgb('+r+','+g+','+b+')';
el.style.setProperty(property, colorname);
u += step_u;
}, interval);
};
// in action
el = document.getElementById('box'); // your element
property = 'background-color'; // fading property
startColor = {r:255, g: 0, b: 0}; // red
endColor = {r: 0, g:128, b:128}; // dark turquoise
fade(el,'background-color',startColor,endColor,1000);
// fade back after 2 secs
setTimeout(function(){
fade(el,'background-color',endColor,startColor,1000);
},2000);
</script>
</body>
</html>
Here is also my solution:
<html><head>
<script type="text/javascript">
<!--
function animate(id,color0,color1,duration){
//public attributes
this.elem = document.getElementById(id);
//private attributes
var r0= parseInt(color0.substring(0,2),16);
var g0= parseInt(color0.substring(2,4),16);
var b0= parseInt(color0.substring(4,6),16);
var r1= parseInt(color1.substring(0,2),16);
var g1= parseInt(color1.substring(2,4),16);
var b1= parseInt(color1.substring(4,6),16);
var wait = 100; //100ms
var steps = duration/wait;
var rstep = (r1 - r0) / (steps);
var gstep = (g1 - g0) / (steps);
var bstep = (b1 - b0) / (steps);
var self = this;
//public functions
this.step = function() {
steps--;
if ( steps>0 ) {
r0 = Math.floor(r0 + rstep);
g0 = Math.floor(g0 + gstep);
b0 = Math.floor(b0 + bstep);
elem.style.backgroundColor = 'rgb('+r0+','+g0+','+b0+')';
//alert(steps + ' ; ' + elem.style.backgroundColor);
window.setTimeout(function(){self.step();}, wait);
} else {
elem.style.backgroundColor = '#'+color1;
}
}
step();
//alert(this.r0);
}
//-->
</script>
</head><body>
<div id="anim" style="width:100px; height:100px; background-color:#ff0000"></div>
<input type="button" onclick="animate('anim','1122ff','ff2211',1000)" value="test" />
</body>
</html>
html at pastebin, how to call the timeout function - see for example 1, 2
if canvas would be ok you could try doing it like this ;)
var context = document.getElementsByTagName('canvas')[0].getContext('2d');
var hue = 0;
function bgcolor() {
hue = hue + Math.random() * 3 ;
context.fillStyle = 'hsl(' + hue + ', 100%, 50%)';
context.fillRect(0, 0, context.canvas.width, context.canvas.height);
}
setInterval(bgcolor, 20 );
Yes ;) it`s not perfect and just an excample but give it a try. Here is the complete pen on codepen.
One way might be to use setTimeout to call some function which incrementally changes the colour (I'm assuming background-color) by some small amount each time it's called. At each iteration, just check to see if you've arrived at your target colour and if not, increase or decrease your RGB value as necessary.

Categories

Resources