Navigate/Search

Archive for the 'knockout.js' Category

RGB Color Trainer: Functionally Complete

Saturday, July 5th, 2014

I finished up the RGB Color Trainer.  You can try it out at http://www.rgb.peachyga.com/.  While it is functionally complete it will never be complete because it can always get better.  There is a lot of room for improvement on the UI, new functionality, and the code is pretty rough.  I have been playing it for a few minutes and I have already gotten a lot better and seeing the RGB code.  I have gone from about 18 guesses to 4 guesses.

Here’s the code…

HTML:

<!DOCTYPE html>
<html lang=”en”>
<head>
    <meta charset=”utf-8″>
    <title>RGB Trainer</title>
    <link href=”css/styles.css” rel=”stylesheet”>
    <script type=”text/javascript” src=”js/knockout-3.0.0.js”></script>
    <script type=”text/javascript” src=”js/jquery-1.10.2.js”></script>
    <script type=”text/javascript” src=”js/rgbTrainer.js”></script>
</head>
<body>
    <h1>RGB Trainer</h1>
    <div id=”colorViewers”>
        <div id=”targetColor” style=”background-color:#CCCCCC”></div>
        <div id=”guessedColor” style=”background-color:#FFFFFF”></div>
        <div>
            <span>Guess Count <span data-bind=”text: guessCount”></span> </span>
        </div>        
        <div>        
            <span id=”guessedRed”>Red:</span> <span data-bind=”text: guessRed”></span> (<span data-bind=”text: guessRedPercent”></span>%)
            <div id=”guessedRedError”></div>
        </div>
        <div>        
            <span id=”guessedGreen”>Green: </span><span data-bind=”text: guessGreen”></span> (<span data-bind=”text: guessGreenPercent”></span>%)
            <div id=”guessedGreenError”></div>
        </div>
        <div>
            <span id=”guessedBlue”>Blue:</span> <span data-bind=”text: guessBlue”></span> (<span data-bind=”text: guessBluePercent”></span>%)
            <div id=”guessedBlueError”></div>
        </div>
        <div>
        <div id=”guessInput”>
            <input data-bind=”value: guessText, valueUpdate: ‘afterkeydown’”  type=”text”>
            <span  data-bind=”click: function(data,event){clickGuessLink()}”>[guess]</span>
        </div>
        <div>
    </div>
</body>
</html>

JS

$( document ).ready( function() {
    function AppViewModel() {
        this.guessCount        = ko.observable(0);
        this.targetRed        = ko.observable(getRandomHex());
        this.guessRedPercent    = ko.observable(“?”);
        this.targetGreen        = ko.observable(getRandomHex());
        this.guessGreenPercent    = ko.observable(“?”);
        this.targetBlue        = ko.observable(getRandomHex());
        this.guessBluePercent    = ko.observable(“?”);
        this.targetRgb        = “#” + this.targetRed() + this.targetGreen() + this.targetBlue();
        this.guessRgb        = “”;
        this.guessRed        = ko.observable(“FF”);
        this.guessGreen        = ko.observable(“FF”);
        this.guessBlue        = ko.observable(“FF”);
        this.guessText        = ko.observable(“#FFFFFF”);
        this.guessText.subscribe(
        function(newValue){            
            var validValue = validateGuessedValue(newValue);
            if(newValue != validValue){
                this.guessText(validValue);            }            

        },this
        );

        $(“#targetColor”).css(“background-color”,this.targetRgb);
        $(“#guessedRedError”).css(“background-color”,”#FF0000″);
        $(“#guessedGreenError”).css(“background-color”,”#00FF00″);
        $(“#guessedBlueError”).css(“background-color”,”#0000FF”);
        this.clickGuessLink = function(){

        var hexString = this.guessText();

        this.guessRed(hexString.substring(1,3));
        var redGuessDecimal = parseInt(this.guessRed(),16);
        var redTargetDecimal = parseInt(this.targetRed(),16);
        var difference    = Math.floor(100*(redGuessDecimal – redTargetDecimal)/255);
        $(“#guessedRedError”).css(“background-color”,”#”+this.guessRed()+”0000″);
        this.guessRedPercent(difference);

        this.guessGreen(hexString.substring(3,5));
        var greenGuessDecimal = parseInt(this.guessGreen(),16);
        var greenTargetDecimal = parseInt(this.targetGreen(),16);
        difference    = Math.floor(100*(greenGuessDecimal – greenTargetDecimal)/255);
        $(“#guessedGreenError”).css(“background-color”,”#00″+this.guessGreen()+”00″);
        this.guessGreenPercent(difference);

        this.guessBlue(hexString.substring(5,7));
        var blueGuessDecimal = parseInt(this.guessBlue(),16);
        var blueTargetDecimal = parseInt(this.targetBlue(),16);
        difference    = Math.floor(100*(blueGuessDecimal – blueTargetDecimal)/255);
        $(“#guessedBlueError”).css(“background-color”,”#0000″+this.guessBlue());
        this.guessBluePercent(difference);

        if(this.guessBluePercent() == 0 && this.guessGreenPercent() == 0 && this.guessRedPercent() == 0 ){
            alert(“You got it in ” + this.guessCount() + ” attempts!”);
        }

        updateGuessed(this.guessText());
        this.guessCount(this.guessCount() + 1);    
        };
    }
    ko.applyBindings(new AppViewModel());
});

function validateGuessedValue(value){
// set all characters to uppercase
    value = value.toUpperCase();
// make sure the first char is #
    var firstChar    = value.substring(0,1);
    if(firstChar != “#”) value = “#” + value;
// make sure all characters are HEX
    var valueLength = value.length;
    var tempValue = “”;
    var currentChar = “”;
    var onePlus = 0;
    for(var i = 0; i < value.length; i++){
        onePlus = i + 1;        
        currentChar = value.substring(i, onePlus);        
        if(i == 0){
            tempValue = “#”;
        } else if(currentChar.search(/[0-9A-F]/) == 0) {
            tempValue = tempValue + currentChar;
        }
    }
    value = tempValue;

// make sure there aren’t too many characters
    valueLength = value.length;
    var valueDif    = 7 – valueLength;
    if(valueLength > 7) value = value.substring(0,7);
// make suere there aren’t too few characters
    if(valueDif > 0){
        for(var i = 0; i < valueDif; i++){
            value = value + “0″;
        }
    }

    return value;
}

function updateGuessed(hexValue){
        $(“#guessedColor”).css(“background-color”,hexValue);
}

function getRandomHex(){
    var firstChar     = getRandomChar();
    var secondChar    = getRandomChar();
    var hex = firstChar + secondChar;
    return hex;
};

function getRandomChar(){
    var chars = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"];
    var rnd   = Math.floor(Math.random()*16)
    var char  = chars[rnd];
    return char;
};

CSS:

.colorPreview{
    border:1px solid black;
    width:200px;
    height:50px
}
.previewDiv{
    float:left
}
.colorViewers{
    width:70%;
    padding:0 20px;
    margin-left:auto;
    margin-right:auto;
}
.colorView{
    float:left;
    width:49%;
    height:200px;
    border: 1px solid black
}
.link{
    color:#0000FF;
    cursor:pointer;
}
.guessInput{
    padding:10px 0;
}
.clearBoth{
    clear:both
}

RGB Trainer: Project Completion In Striking Distance

Saturday, July 5th, 2014

I’ve been working on a knockout.js project for a couple of weeks.  I think I might be able to finish it today.  That would be cool because I think I am going to have some extra time on my hands soon and I would love to become an RGB master during that time.  I am going to focus on that today.

What I need.

1) Validation

The validation plumbing is complete.  Right now all it does is ensure that the RGB string is never more that 7 characters.  I need to add a few more items:

a. The RGB String can’t be less than 7 characters.

b. The RGB String must be all upper case.

c. The RGB String must start with #

d. Characters 2-7 must be a 0-9 or A, B, C, D, E, F

2) Guess Button

The guess button is on the UI but it’s not doing anything.    When the button is clicked the UI needs to:

a. Update the Guess Color.

b. Update the Red Guess Color.

c. Update the Green Guess Color.

d. Update the Blue Guess Color.

e. Update the Guess Percent Off

f. Update the Red Guess Percent Off

g. Update the Green Guess Percent Off

h. Update the Blue Guess Percent Off

i. Update the Win State

And then it should be 100% functional.  Hopefully I can finish it before I go to  bed tonight!

 

Basic app and model for RGB Trainer

Tuesday, July 1st, 2014

Today I set up the RGB trainer’s initial app code and model.  The thing with knockout.js is that it’s so dang DANG easy.

Here’s what I’ve done so far:

HTML

<!DOCTYPE html>
<html lang=”en”>
<head>
    <meta charset=”utf-8″>
    <title>RGB Trainer</title>
    <link href=”css/styles.css” rel=”stylesheet”>
    <script type=”text/javascript” src=”js/knockout-3.0.0.js”></script>
    <script type=”text/javascript” src=”js/jquery-1.10.2.js”></script>
    <script type=”text/javascript” src=”js/rgbTrainer.js”></script>
</head>
<body>
    <h1>RGB Trainer</h1>
    <div id=”colorViewers”>
        <div id=”targetColor” style=”background-color:#CCCCCC”></div>
        <div id=”guessedColor” style=”background-color:#000000″></div>
        <div>
            <span>Guess Count: </span>
        </div>        
        <div>        
            <span id=”guessedRed”>Red:</span>
            <span id=”guessedRedError”></span>
        </div>
        <div>        
            <span id=”guessedGreen”>Green:</span>
            <span id=”guessedGreenError”></span><br>
        </div>
        <div>        
            <span id=”guessedBlue”>Blue:</span>
            <span id=”guessedBlueError”></span><br>
        </div>
        <div id=”guessInput”>
            <input data-bind=”value: guessText, valueUpdate: ‘afterkeydown’”  type=”text”>
            <span>[guess]</span>
        </div>
        <div>
    </div>
</body>
</html>

JavaScript

$( document ).ready( function() {
    function AppViewModel() {
        this.targetRgb    = “”;
        this.guessRgb    = “”;
        this.guessRed    = “”;
        this.guessGreen    = “”;
        this.guessBlue    = “”;
        this.guessText    = “#000000″;
    }
    ko.applyBindings(new AppViewModel());
});

Knockout.js… swiss cheese.

Tuesday, May 27th, 2014

One of the most frustrating things about being a programmer for a long time is that it’s easy to get large gaps in knowledge when learning a new technology.  I imagine black belts in martial arts experience similar things when learning a new style.

What happens is that experience programmers unknowingly skip pieces of knowledge while attempting to build advanced implementations of a new technology.

I was trying to build a throwers listing application.  At the highest level I have a list of throwers and each thrower has a list of throws.  The number of throws is variable and the user needs to be able to specify the number of throws.

The data structure is easy for me to understand because I have been coding for so long.  But getting KO to manage an array within and array is something I haven’t learned.  In short I learned an advanced concept with other technologies, but I never learned how to implement that advanced concept in the technology I am trying to learn… which leads to frustration.

I was reading over the 80 or so KO blog entries I wrote this year and reviewing the KO documentation and I think I have discovered my gap.

I don’t understand and I haven’t read or commented about observable arrays or computed observables.  I tried to set KO up to use arrays within arrays without understanding the basics of observable arrays.

So over the next couple of weeks I am going to post about computed observables and observable arrays and then take another run at building my throwers application.  Fun Fun Fun!

Hit a roadblock on my Knockout.js thrower listing program.

Monday, May 26th, 2014

I was hoping to get my application done yesterday… But I couldn’t because I can’t figure out how to link arrays within arrays to the UI.  I guess I don’t understand data-binding as well as I thought I did.

I need to think of a project that will help me master this subject.

Got the add button working on my thrower’s list app

Saturday, May 17th, 2014

Today I added a couple things to the thrower’s listing app:

 

1) Ties the table list to the throwers array:

<tbody  data-bind=”foreach: throwers”>
<tr>
<td data-bind=”text: name”></td>
<td>Throws List</td>
</tr>
</tbody>

2)  Made a change to the model so the user can add records to the list:

function AppViewModel() {
this.throwCount = 6;
this.throwerName = ko.observable(“”);
        this.throwers = ko.observableArray([]);
this.changeThrowCount = function(){
alert(“Redraw The Grid with ” + this.throwCount + ” columns”);
return true;
}

this.clickAddToList = function(){
            if(this.throwerName() != “”){
                this.throwers.push(new Throws(this.throwerName()));
this.throwerName(“”);
            }
return true;
}
}

That’s it for this week!  Now I add throwers.  In two weeks, when I get back to this, I should be able to get the thrower delete and updating throws working.

Quick Night… just added the table for my throw list application

Friday, May 16th, 2014

It was a late night.  I am desperately trying to understand jQuery promises and defers… I think that’s going to be next week’s topic.

Anyways…

I added the follow markup to my application:

<table border=1 cellpadding=2 cellspacing=0>
<thead>
<tr>
<th>Thower Name</th><th>Throws</th>
</tr>
</thead>
<tbody></tbody>
</table>

Hopefully I can be adding rows tomorrow!