I’ve got an interest in beefing up my JavaScript tools in 2012- I’ve mildly dabbled on and off, but am far behind in the current state of the code. I started doing more trying to build more of the onboard interfaces for the StoryBox, mainly because I lacked the python chops to do so.
But there is a lot of power in moving interaction browser side, especially with sophistication of jQuery libraries for a lot of functionality. I am seeing things I typically do in PHP that I can see doing in JS. This was the thinking when I decided a few nights ago to build a web tool to randomly generate some words that have no English Equivalent:
I will roll through some technical stuff which might be hairy or not. But just want to share what I am doing; there are likely much more elegant ways to do the coding here. but oh well. There are two portions to run through- the code/functionality and the design. Let’s start with the basics of the CSS to make a slick web effect. I’l provide the full source at the end. As far as I can test it works well on most browsers (though I have no access to the dreaded cursed IE) including mobile ones.
If you mess around with the window size for the site, you should notice that the background graphic resizes automatically to match the window size. I spotted this effect on someone’s bio page, dug into the source code, and came across the jQuery Backstretch plugin that made this work.
Backstretch is a simple jQuery plugin that allows you to add a dynamically-resized background image to any page. The image will stretch to fit the page, and will automatically resize as the window size changes.
Basically, jQuery is a whole library of code you can just include to provide a whole raft of cool things to your site, and the plugins just extend what it can do. ALmost every modern web site (include many wordpress templates) tide on jQuery.
To make backstretch work, you simply download the back.js file. I usually make a 1024×768 jpg image for the background. The first time I used it was to make a splash page for the domain I use for my experiments, http://lab.cogdogblog.com/ so visitors could not fish around my web directories.
The basic web page to make it work is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<!doctype html> <html> <head> <title>Stay Out of the Lab!</title> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <link rel="stylesheet" href="style.css" type="text/css" /> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> <script type="text/javascript" src="back.js"></script> <script type="text/javascript"> $.backstretch("guard-dog.jpg", {speed: 150}); </script> </head> <body> <div id="stuff"> <h1>CogDogBlog Lab</h1> <p>Be Careful</p> <p class="small">cc licensed ( BY ) flickr photo by Perfecto Insecto: <a href="http://flickr.com/photos/perfectoinsecto/4301508866/"> http://flickr.com/photos/perfectoinsecto/4301508866/</a></p> </div> </body> </html> |
The key parts are in the <head>…</head> You should note we are loading jquery remotely form Google (if you are doing this on something like the StoryBox which is not connected to the ent, you would want to download and reference a local library version). We also link to the local back.js library, the jquery extension. The magic that makes it work is the call:
1 2 3 |
<script type="text/javascript"> $.backstretch("guard-dog.jpg", {speed: 150}); </script> |
which applies the effect using the guard-dog.jpg file (you would change this to reflect the name of whatever file you are using). The local style sheet just has some simple formatting, using absolute positioning for the screen text.
My No Words site uses a graphic I seem t always land on when searching for “translation”, the flickr photo shared by tochis.
All of the content was lifted from four web sites:
- 15 Wonderful Words With No English Equivalent (Hot For Words)
- French Words With No English Translation (didi’s World)
- 20 awesomely untranslatable words from around the world (matador abroad)
- 10 Words That Can’t Be Translated into English (Listverse)
Now let’s get down to code! The way this works, each time I want to provide a new word and definition pair, we do not have to reload the page- it is all done in place.
To make the site work, I lazily made two arrays (one multi-dimensional array, or better yet, some object construct would have been more elegant), one to hold the name of the word, the other to hold the text that explains it:
1 2 3 4 5 |
// create an array for the words var wordBox=new Array('Zhaghzhagh', 'Yuputka', 'Lampadato', 'Luftmensch', 'Iktsuarpok', 'Cotisuelto', ' Pana Po\'o', 'Gumusservi', 'Vybafnout', 'Mencolek', 'Faamiti', 'Glas wen', 'Bakku-shan', 'Boketto', 'Kummerspeck', 'Dépaysement', 'La douleur exquise', 'Esprit d\'escalier', 'Retrouvailles', 'Empêchement', 'Toska', 'Mamihlapinatapei', 'Jayus', 'Iktsuarpok', 'Kyoikumama', 'Tartle', 'Ilunga', 'Prozvonit', 'Cafuné', 'Schadenfreude', 'Wabi-Sabi', 'Tingo', 'Ya\'aburnee', 'Saudade', 'Uitwaaien', 'Zalatwic', 'Biritululo'); //create an array for the definitions var meaningBox=new Array('The chattering of teeth from the cold or from rage', 'A word made for walking in the woods at night, it's the phantom sensation of something crawling on your skin.', 'Addicted to the infra-red glow of tanning salons? This word describes you.', 'The Yiddish have scores of words to describe social misfits. This one is for an impractical dreamer with no business sense. Literally, air person.', 'You know that feeling of anticipation when you're waiting for someone to show up at your house and you keep going outside to see if they're there yet? This is the word for it.', 'A word that would aptly describe the prevailing fashion trend among American men under 40, it means one who wears the shirt tail outside of his trousers.', 'It means to scratch your head in order to help you remember something you\'ve forgotten.', 'Meteorologists can be poets in Turkey with words like this at their disposal. It means moonlight shining on water.', 'A word tailor-made for annoying older brothers-- it means to jump out and say boo.', 'You know that old trick where you tap someone lightly on the opposite shoulder from behind to fool them? The Indonesians have a word for it.', 'To make a squeaking sound by sucking air past the lips in order to gain the attention of a dog or child.', 'A smile that is insincere or mocking. Literally, a blue smile.', 'The experience of seeing a woman who appears pretty from behind but not from the front.', 'It\'s nice to know that the Japanese think enough of the act of gazing vacantly into the distance without thinking to give it a name.', 'Excess weight gained from emotional overeating. Literally, grief bacon.', 'The sensation of being in another country.', 'The heart-wrenching pain of wanting someone you can't have. Even a Sex in the City episode was named after it!', 'The literal translation is \'staircase wit\', but it means to think of a comeback when it\'s too late.', 'The happiness of meeting again after a long time.', ' An unexpected last-minute change of plans. A great excuse without having to be specific.', 'At its deepest and most painful, it is a sensation of great spiritual anguish, often without any specific cause. At less morbid levels it is a dull ache of the soul, a longing with nothing to long for, a sick pining, a vague restlessness, mental throes, yearning', 'The wordless, yet meaningful look shared by two people who both desire to initiate something but are both reluctant to start', 'A joke so poorly told and so unfunny that one cannot help but laugh', 'To go outside to check if anyone is coming', 'A mother who relentlessly pushes her children toward academic achievement', 'The act of hestitating while introducing someone because you've forgotten their name.', 'the stature of a person who is ready to forgive and forget any first abuse, tolerate it the second time, but never forgive nor tolerate on the third offense.', 'This word means to call a mobile phone and let it ring once so that the other person will call back, saving the first caller money.', 'The act of tenderly running one\'s fingers through someone\'s hair.', 'the feeling of pleasure derived by seeing another's misfortune.', 'a way of living that focuses on finding beauty within the imperfections of life and accepting peacefully the natural cycle of growth and decay.', 'It comes from Easter Island and it means a person who borrows things from a friend's house one by one until there is nothing left. ', 'Both morbid and beautiful at once, this incantatory word means "You bury me," a declaration of one's hope that they'll die before another person because of how difficult it would be to live without them.', 'refers to the feeling of longing for something or someone that you love and which is lost', 'Literally, this Dutch word means to walk in the wind, but in the more figurative (and commonly used) sense, it means to take a brief break in the country side to clear one's head.', 'Zalatwic is a Polish term which, in one aspect does have a similar term in English (to do a cash job), but the Polish term means far more and is much more subtle. Zalatwic is the use of friends, bribes, personal charm or connections to get something done.', 'What do you normally do when you have a dispute? Do you talk things over? Go to court? Well, in New Guinea, to settle disputes, the people rely on biritululo. Biritululo is the act of comparing yams (and I am hoping that is meant in the literal sense) to settle a dispute.'); |
Each item in the array is string that is in quotes (which means if the text includes an apostrophe or a quote, I have to write it as \’).
The last thing is a small temp variable I use to keep track of the last item selected, so if we generate a new word, we want to make sure it is different form the old one. All of the tracking is done by referencing the index to the array.
1 2 |
// holder for the last word chosen var lastim = -1; |
Now, for the randomizing part, we do via a function, so we can call it as needed:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
function chooseWord() { // This function does all the work! // temp flag var done = 0; do { // generate a random index for the arrays var im = Math.floor(Math.random()*wordBox.length); // check if we have a new index (not used last time around) if (im != lastim) { // we are done, update the last word chosen done=1; lastim = im; } } while (done == 0); // element in the doc to place our string var disp = document.getElementById("gimme"); //update the page content disp.innerHTML = '<strong>' + wordBox[im] + '</strong><br />"' + meaningBox[im] + '"'; } |
The logic here is:
- set a flag to indicate we are not done (done = 0)
- run a do…while loop that repeats until we change that done flag; it checks the exit condition on every round, and once done is something else… we are done looping!
- We use some math functions to generate a random number between 0 and the number of items in the arrays, this is the pointer for the word/definition we will display.
- The check to see if it is different from the last number used (lastim), and if so, we are done, so change the value of done=1, and update the new value of lastim to the number chosen.
- The last part is how we update the page content dynamically. The default page as an empty holder
1<p id="gimme"></p>
and the code is what is used to dynamically update page content referenced by CSS ids, in this case the word chosen wrapped in <strong>…</strong> tags with a line break and then the definition.
That may not be 100% clear, but I tried to comment everything in the source code.
We make it happen the first time by calling the function when the page loads:
1 |
<body onLoad="chooseWord()"> |
and make it available to update using a basic form button
1 |
<form id="fbomb"><input type="button" value="Gimme Another" onClick="chooseWord()"></form> |
Those are most of the working bits. Not sure if this makes any sense. Frankly I found the best way to understand coding was to dive in and bang it til it works. I rely a lot know on the JavaScript Console in Chrome to find errors (View -> Developer -> JavaScript Console).
You can download the entire batch of code for this site, and maybe try making your own changes to it. There are just 4 files that site in the directory and you can download it all from http://cogdogblog.com/code/nowords.zip
- back.js
- index.html
- style.css
- translate.jpg
2012, everyone wants to be coding. It’s the new thang. Bust your chops out.
Nice stuff, I’ve been refreshing the word page for a while, but still in holiday mode as far as doing any work. I am interested in the way this sort of code experiment parallels the creative element of ds106.
Are you thinking of css or code assignments? I am wondering about hackasaurus, popcorn.js or some of these sites that let you edit html, js & css in the browser (raking addled memory for a lovely one).
Also reminded me of http://iheartquotes.com/api so I messed about with it a little today:
http://johnjohnston.info/tests/quote.html
Which if I could figure out an angle could b a ds106 assignment?
I had no idea you were this advanced in your programming chops. I’m impressed! I need to get up to speed. I know just enough to nod along when other people do most of the work and try to hack it to make it work. I signed up for http://codeyear.com/ from the folks at http://www.codecademy.com/ which will hopefully help to get some more practice under my belt.
John- your demo is tres cool and would love to see the insides; I understand now how you did the Flickr part with the json calls like I did?
My suggestion is to tweak the interaction a bit- call it something like “Visualize That Quote”- rather than provide choices to pick from Flickr for each word; maybe random generate one image per word. The activity would be to illustrate/explain the quote in pictures with the least number of pictures required. The user could X out ones they did not need (and they would dissapear) and perhaps allow a click to generate a new random image to replace it. They would then do a screenshot to save their work? Perhaps generate a score where there is advantages to lower numbers of pictures and fewer image replacements?
Whatever the deal I like it! We will give some thoughts to code/CSS assignments for sure.
Alan, thanks.
Trying some of your suggestions:
http://johnjohnston.info/tests/quote2.html
By no means finished and pretty slow as it needs a search for each word.
The insides are pretty horrible, I am not a coder. I start and just keep jamming stuff in;-) The logic is pretty odd.
All the js & css is in the html file. I had to proxy the quotes json as I can’t get it directly due to some cross domain stuff. the json comes via ‘shortquote.php’ and is pulled in via jquery ajax.
The flickr search is in ‘randomflickr.php’ which uses phpFlickr to get a list of images with the tag and send the image tag for a random one, this slows the load down as it is called for each word.
In testing I’ve yet to produce a nice set of images to go with a quote that might just be me. Been good fun for me and I really appreciate the interest.
Alan, John:
All I can say is Wow.
I dig the direction you guys are pushing this. The idea of using the web to present authentic prompting language selected randomly to students is very powerful and important.
What really excites me about this is that it is developing in this informal almost play-like setting of ds106.
If you guys keep cobbling together the tools – imperfect as they may be – you’ll find a willing community of creative and wacky testers (myself included).
Thanks.
I am convinced that your example – retrouvailles – is similar in spirit to the motto of this fair City (local cooncil excluded) of Aberdeen. I am told that Bon Accord means “Happy to part, hope to see you soon”. A bit like my coding experience ….