lo-ga-rie words, lines .. life

26Apr/100

Buzzword bingo

I've been experimenting with mobile apps the last few days. Though the programming part is coming slow my marketing is running like crazy!

The app i came up with is totally useless but it combines some of the things we tend to use and like every day on our mobile devices

  • Updates (twitter)
  • Location based (google maps / foursquare)
  • Photo's (flickr / panoramia)

So i combined them to make "Projected Reality" cause you are so busy on your phone all day you forget the reality around you, my app brings reality back on your phone! So here comes the marketing buzzword bingo

  • "If you can tag it, we can project it" - the slogun
  • Updating your status is placing a purr
  • cats purr so the logo is a big cat on a house
  • a house since it's all local stuff you can read about
  • the hashtag is #pr; do i need to say more ;)

Atm i have a semi working android app; but the tools i use make it that the same code should work on an iphone.
the app also "sort of" works in some browers (firefox is known to sometimes work) from time to time

Anyhow: I am not dead, just busy

28Jan/100

Silverlight wmv playback without using http

Sounds funny but is it even possible?
Our windows media server doesn't have an open http port only rtsp and mms but everything i send to it with a silverlight control is over http.

Edit: Seems like silverlight doesn't use rtsp and mms (as moniker, not the protocol) is depricated so the answer is: NO; you need http in order for silverlight to stream from a windows media server.

Filed under: bericht, werk No Comments
8Dec/090

Google maps v3

Vandaag een technisch verhaal aan de hand van de website onlinereisbeurs.nl gefocused op de scripting die nodig was voor de kaart (google maps) in combinatie met panoramio voor de foto's van de gekozen locatie.

Laten we beginnen met het makkelijkste: de HTML


* <_h2> uiteraard zonder de _ maar anders komt cuffon er weer overheen :p
Eigenlijk maken we hier alleen een div aan voor de map met een blok er overheen voor de info en een apart spannetje voor de pijl die beweegd; met "optimalisatie" voor IE6 omdat die browser zo goed omgaat met png's ...
Met de CSS er bij krijgen een we een set elementen die over elkaar heen vallen en een vlak voor Google maps:

#googleMap {
height:400px;
margin:0 6px 20px 20px;
}
#popup {
background:transparent url(../images/uitleg_bg.png) no-repeat scroll 0 0;
height:100px;
left:350px;
padding:20px 20px 0;
position:absolute;
top:281px;
width:380px;
z-index:100;
}
#popup h2 {
color:#00468E;
font-size:18px;
font-weight:bold;
}
#arrow {
color:#584436;
display:block;
font-size:12px;
font-weight:bold;
height:35px;
padding:10px 10px 0 0;
}
#arrow .blue {
color:#00468E;
}
#arrowImg {
background:transparent url(../images/pijl_icon.png) no-repeat scroll right top;
height:36px;
position:absolute;
right:13px;
top:38px;
width:32px;
}

Door goed gebruikte ID's te gebruiken zijn bijna alle elementen direct te benaderen wat een positieve invloed heeft op het laden van de pagina. In eerste instantie had ik de pijl als achtergrond van de ID arrow meegegeven met een background positie op rechts maar daar kan IE6 niets mee. Aangezien de achtergrond semi transparant is moet dit pijltje wel een png zijn; anders hebben we lelijke randen en leg dat je designer maar weer uit ;) Door het pijltje in een aparte span op te nemen verhelpen we dat probleem; een bijkomend voordeel is dat het weer iets makkelijker is om dit pijltje te animeren; al kan dat voor moderne browsers net zogoed via de de background-position properties.

Nu hebben we een opgemaakt vlak met een 2e vlak met textuele uitleg er over heen, laten we google maps er maar eens bijpakken.

var latLng = new google.maps.LatLng(-10, 150); // we zetten een bepaalde marker neer; hier later meer over
	map = new google.maps.Map(document.getElementById('googleMap'), {
		zoom: 1, // we kunnen zoomen van lvl 0 (alles tot 21; straatniveau)
		center: new google.maps.LatLng(0, 0), // wat is het centrum van de kaart?
		mapTypeId: google.maps.MapTypeId.TERRAIN, // welk type map willen we gebruiken
		mapTypeControl: false // willen we de gebruiker de controle geven over welk type map ze kunnen kiezen? Nu niet iig
	});
	var markerImg = "/include/images/koffer.png"; // plaatje gebruikt voor de marker
	marker = new google.maps.Marker({
		position: latLng, // welke positie heeft de marker
		title: 'Sleep de koffer naar uw droombestemming', // wat is de titel van de marker als je er met je muis overheen gaat?
		map: map, // welke map gebruikt deze marker; ja we kunnen meerdere maps op 1 pagina zetten
		draggable: true, // kan je deze marker slepen?
		icon: markerImg // verrek ons eerder gedefinieerde plaatje voor de marker
	});

	// Update current position info.
	geocodePosition(latLng, false); // tja leuk die lat.lon. getallen maar waar zijn we dan?

	google.maps.event.addListener(marker, 'dragend', function() {
		geocodePosition(marker.get_position(), true); // we hebben de marker versleept, update de positie
	});
function geocodePosition(pos, remove) {
	if (remove) $("#popup").hide(); // moeten we onze div met begin informatie verwijderen?
	if (remove) $.scrollTo("#googleMap", 1000); // om de focus echt op de map te leggen scrollen we daar heen zodat de map goed in beeld is
	geocoder.geocode({
		latLng: pos
	}, function(responses) {
	if (responses && responses.length > 0) {
/*
 de geocoder zal een set van resultaten terug geven, van zo precies mogelijk tot aan eigenlijk "ja je zit nog op de aarde"
Zodra we dus een set resultaten hebben gaan we bekijken welke we nu exact willen gebruiken
*/
			var lat = responses[0].geometry.location.lat(); // we nemen de meest nauwkeurige; de gegevens die wij nodig hebben zitten ook opgeslagen in dit object
			var lng = responses[0].geometry.location.lng();
/*
  Door het zoekgebied te vergroten krijg je niet alleen resultaten van de straat terug maar van de stad; onderstaande berekening is nogal grof maar werkt behoorlijk goed
*/
			var minLng = Math.floor((lat) * 100) / 100;
			var maxLng = Math.ceil((lat) * 100) / 100;

			var minLat = Math.floor((lng) * 100) / 100;
			var maxLat = Math.ceil((lng) * 100) / 100;

			// console.log("getting photo's for LAT: " + lat + ", LON: " + lng);
			// panoramio
/*
Op panoramio staan mooie foto's; meer op de omgeving dan op mensen gefocussed in tegenstelling tot flickr. Panoramio heeft ook een API om via JSON mooi een set resultaten terug te krijgen; ons zoekgebied is waar de marker gesleept is + de omgeving
*/
			$.getJSON("http://www.panoramio.com/map/get_panoramas.php?order=popularity&set=full&" +
					"from=0&to=10&minx=" + minLat + "&miny=" + minLng + "&maxx=" + maxLat + "&maxy=" + maxLng + "&size=small&callback=?",
					{},
					function(data) {
						$("#photos").html(""); // reset de div waar de foto's staan/stonden
						$(data).each(function(i, item) {
							for (var j = 0; j < item.count; j++) {
								try {
									var img = new Image();
									img.src = item.photos[j].photo_file_url; // maak een image object aan voor elke foto die we terugkrijgen, via het javascript image object zorgen we er direct voor dat deze preloaded worden
									var currentHTML = $("#photos").html();
									$("#photos").html(currentHTML + ""); // voeg de nieuwe foto toe aan de HTML
								} catch (e) { }
							} if (item.count == 0) {
								$("#photos").html("");
								// Tja geen foto's zouden we nu ons zoekscherm moeten uitbreiden misschien? versie 2.0 ;)
							}
						});
					}
				);
			if (remove) updateMarkerAddress(formatAddress(responses[0]), true); // nieuw adres = laat dit nieuwe adres ook zien
		} else {
			updateMarkerAddress('Geen locatie gevonden', false); // aah geen adres gevonden; komt eigenlijk alleen maar voor als je in de zee een straat probeert te vinden ;)
		}
	});
}
function formatAddress(address) {
	var wantedTypes = ["locality", "country"]; // welke types van het adres willen we zien? Je kan postcodes terug krijgen, huisadressen, landmarks e.d. maar wij willen nu alleen de locality (stad) en country (land)
	var formattedAddress = [];
	for (var i = 0; i < address.address_components.length; i++) { 		var component = address.address_components[i]; // een google address bestaat uit verschillende componenten, daar gaan we es doorheen 		var type = component.types[0]; 		if ($.inArray(type, wantedTypes) > -1) {
			formattedAddress.push(component.long_name); // ja dir compontent willen we!
		}
	}
	if (formattedAddress.length > 1) { // kunnen we een adres opbouwen dat uit meerdere compontenten bestaat?
		return formattedAddress[0] + " - " + formattedAddress[1]; // zo ja dan graag stad - land (volgorde bepaal je in de array
	} else {
		return formattedAddress[0]; // zo niet dan laten we maar zien wat we hebben (alleen land)
	}
}
function updateMarkerAddress(str, isAbleToGo) {
	$("#results .text").html(str); // laat maar zien
	var fontSize = 17;
	if (str.length > 13) fontSize = 15;
	if (str.length > 23) fontSize = 13;
	if (str.length > 28) fontSize = 11;
/*
 we passen de fontsize aan aan de hoeveelheid karakters
*/
	$("#results .text").css("fontSize", fontSize);
	$("#results a").attr("href", "step2.html?loc=" + escape(str)); // we sturen het adres escapped en al door naar de volgende pagina; mits je klikt natuurlijk
	(isAbleToGo) ? $("#results a").show() : $("#results a").hide(); // de knop laten we alleen zien als je er ook daadwerkelijk heen kan, helaas geen droomreis mogelijk naar de bodem van de oceaan
	$("#results").show(); // laat de div met resultaten zien.
}

Zo een lap code is het wel, maar het resultaat is er ook naar, een volledig interactieve map met een versleepbare marker die zodra je die ergens neerzet foto's uit de buurt ophaalt, het adres ophaalt, het adres formatteerd naar een gewenst formaat en vervolgens deze gegevens keurig toont.

Google maps in onlinereisbeurs.nl

Google maps in onlinereisbeurs.nl

Filed under: jquery, json, werk No Comments
28Nov/090

Is het al vandaag?

Als ik nou eens alles een kwart slag draai; dan heb ik optisch meer ruimte in de woonkamer; maar dat klinkt al als veel moeite te moeten doen en daar heb ik geen zin op de vrije dag :P Vandaag geen nieuwe Stargate Universe; begint die serie eindelijk eens interessant te worden zenden ze geen nieuwe aflevering uit! Hoe dan?!

Qua werk was afgelopen week niet de beste ooit; maar mede door mij kan je nu wel kans maken op een droomreis! Verder veel moeten stoeien met R3 nieuwsbrieven en dat gaat een stuk trager dan ik wil; documentatie heb ik er nog niet echt over gevonden, hebben die gasten niet ergens een "dit kan je allemaal wel en niet gebruiken" website? Tegen de tijd dat iemand me daar antwoord op kan geven is het toch al te laat want a.s. maandag moet de template waar ik nu op vastloop af zijn.

Het was deze week ook weer tijd voor de Company Meeting waar ik net iets te lang ben blijven hangen met Marijke en Vinnie en in alle hectiek zijn we vergeten het alarm aan te zetten toen we weg gingen, bam 20 euro down the drain :( Als nou volgende keer 10 mensen vergeten af te sluiten is het maar 6 euro per persoon ;) Als je dan buiten staat in de koude november avond; geen zin hebt om al naar huis te gaan en de avond kan doorzetten dan ga je daar op in, toch? Nou ik wel in ieder geval en uiteindelijk een zeer vermakelijke avond met en bij Marijke gehad maar kolere wat had ik een koppijn vrijdag! Begin ik echt een ouwe lul te worden? Vrijdag was de productiviteit bijna 0, en veul geslapen. T wordt maar eens tijd om boodschappen te gaan doen.

Filed under: bericht, werk No Comments
18Nov/090

Bezig

Op het moment ben ik bezig met een google maps project waarbij ik verschillende onderdelen van de nieuwe google maps v3 api gebruik om een interactieve "sleur en pleur" ervaring te bewerkstelligen met een onderwerp waar veel mensen wel iets mee hebben: Vakantie!

Binnenkort online en vlak erna de uitleg, wees gerust ;)
Een kleine verdieping op het gebied van google maps, geocoding, utf8, "using the cloud" en meer. Voor nu hou ik het even op een mooie functie in javascript die soms erg makkelijk kan zijn: (un)escape

Situatie

We hebben een input van een gebruiker die via de url doorgestuurd moet worden naar een andere pagina (GET, iframe)

Als je dit post zal je browser dit automagisch escapen naar

/?send=hello%20world

En als je vervolgens dit in een veld wilt tonen, bv met ID jwz dan zal de %20 meegenomen worden als je het volgende gebruikt:

document.getElementById("jwz").innerHTML = document.location.search.substr(document.location.search.indexOf("=") + 1);

Om hier van af te komen gebruik je de unescape functie van javascript

document.getElementById("jwz").innerHTML = unescape(document.location.search.substr(document.location.search.indexOf("=") + 1));

Maar stel je wilt dit formulier via AJAX posten (ik gebruik nu even jQuery omdat ik dat het meest gebruik, maar (un)escaping is standaard javascript)

$("form").submit(function () {
 var escaped = escape($("toSend").val());
  // do stuff with the escaped string
});

Nu is de var escaped ook via de URL door te sturen zonder dat je rekening hoeft te houden met of er niet correcte karakters worden gebruikt.
Soms is het handig om te hebben en nu weet je het ;)

Filed under: jquery, werk No Comments
26Oct/094

Eerste stapjes in de wondere wereld van mobiele websites

Toen ik werd getracteerd op een url met een website die gewoon heel netjes rendere op het schermpje van mn Hero dacht ik: daar wil ik meer van weten!
Een eerste stap was natuurlijk de wordpress addon die er zorgt dat deze website het zelfde doet; maar zelf uitzoeken je weet zelf :)

Ok wat verwacht ik op het moment van een mobiele browser wil ik me er druk om gaan maken:

  • Enige vorm van HTML4 / xHTML ondersteuning
  • Enige vorm van CSS; minimaal 1.0
  • Javascript?

WAP browsers vallen wat mij betreft af nu aangezien ik me nu vooral focus op wat er anders is qua html opmaak en CSS gebruik, WAP sites zijn gewoon een eigen niche (die uitsterft).
Eigenlijk hou ik het nu dus op "smartphones" en dus op:

  • Windows Mobile 6.1+ (brakke ie6 achtige render engine)
  • (Symbian) -- kan ik nu niet zelf testen
  • Android (Webkit)
  • iPhone (Webkit)

De 3 doelgroepen die ik kan testen bieden tegenwoordig allemaal browsers aan die zelf kunnen switchen tussen de normale en de mobiele website. Sommige mensen zullen het fijner vinden om je echte website te zien en zelf te pannen en zoomen, anderen weer niet; dus die keuze laten we aan de gebruiker zelf; maar bieden in eerste instantie wel een eigen website aan. Hoe gaan we dat doen?

Webserver:

Je kan 2 paden bewandelen: Alles client-side of Server-client. Ik vind hier persoonlijk Server-client mooier werken; de HTML die we uiteindelijk aan de browser geven is helemaal geoptimaliseerd en zo minimaal mogelijk en dus minder bytes om te downloaden terwijl je trein een tunnel inrijdt en 3G wegvalt.
Uit het request object wat je binnenkrijgt op de server kan je destileren welke user-agent gebruikt wordt om de pagina te bekijken, aan de hand daarvan kan je redirecten, een andere masterpage aanbieden, een response variablele aanpassen; wat jij wilt ;)
Voor de bovenstaande browsers moet 1 van de volgende strings in je user-agent staan:

  • "iphone",                   // Apple iPhone
  • "ipod",                      // Apple iPod touch
  • "aspen",                  // iPhone simulator
  • "dream",                  // Pre 1.5 Android
  • "android",              // 1.5+ Android
  • "cupcake",              // 1.5+ Android
  • "Windows CE"    //windows mobile

Client-side:

Om voor alle platformen het zelfde aan te bieden maken we gebruik van een 1 kolom structuur; een content item is altijd 100% breed

< !DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">
<_html_>
  <_head_>
    <_title_>Mobiele test site
  
  <_body_>
    <_h1_>Welkom op de mobiele test site
<_h2_>Content item titel <_p_>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus semper laoreet pharetra. Donec malesuada nulla at est dictum viverra. Proin scelerisque orci ut massa dapibus viverra. Praesent adipiscing aliquam dapibus. Pellentesque at nibh sem, et dictum diam. Vivamus vel ante vitae ligula tempor auctor at vel ante. In lacinia quam vel odio placerat tristique. Vestibulum eu diam velit, vitae eleifend neque. Aenean nunc velit, tristique egestas tempus a, dapibus id mauris. Aenean pulvinar imperdiet sem sed vestibulum. Curabitur consectetur consectetur mi id luctus.
<_h2_>Content item titel <_p_>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus semper laoreet pharetra. Donec malesuada nulla at est dictum viverra. Proin scelerisque orci ut massa dapibus viverra. Praesent adipiscing aliquam dapibus. Pellentesque at nibh sem, et dictum diam. Vivamus vel ante vitae ligula tempor auctor at vel ante. In lacinia quam vel odio placerat tristique. Vestibulum eu diam velit, vitae eleifend neque. Aenean nunc velit, tristique egestas tempus a, dapibus id mauris. Aenean pulvinar imperdiet sem sed vestibulum. Curabitur consectetur consectetur mi id luctus.

* Sorry voor de incorrecte HTML maar anders krijg ik niet alle tags zichtbaar ...

.post {
	-webkit-border-radius: 8px; /* rounded corners in webkit */
        -moz-border-radius: 8px; /* rounded corners in firefox */
	background-color: #fff;
	padding: 10px;
	margin-bottom: 12px;
	position: relative;
	margin-right: 10px;
	margin-left: 10px;
	border: 1px solid #b1b1b1;
	overflow: hidden;
}

Maar hoe breedt is dat dan? iPhone is makkelijk dat is minimaal 320px (portrait mode); Android was makkelijk maar met de komst van Android 1.6 ondersteund Android ook meerdere resoluties zoals WindowsMobile dat al doet. Met onderstaande 2 meta tags geven we aan de browser aan wat er verwacht mag worden:

<_meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0">  
<_meta name="MobileOptimized" content="240" /> 

* Sorry voor de incorrecte HTML maar anders krijg ik niet alle tags zichtbaar ...
Zo, nu hebben we een 1 kolom template die altijd 100% breed is op wat voor resolutie we ook kijken, op wat voor OS.

Uiteindelijk krijg je dan dit te zien:

Lo-Ga-Rie Mobile

Lo-Ga-Rie Mobile

Windows Mobile heeft standaard een zeer brakke browser die iets weg heeft van IE6 maar dan nog erger. Het is wel erg handig om je site eerst te bekijken in IE6 voor je de emulator of je telefoon aanslingert, Veel voorkomende problemen die je hebt in IE6 heb je namelijk ook in Windows Mobile IE. Gebruik ook vooral geen png files, die doen het leuk op je iPhone, Android en Windows Mobile 6.5 maar Windows Mobile 6.1 heeft een png fix nodig. Of het überhaubt werkt weet ik niet eens maar het includen en uitvoeren van een pngfix neemt zo veel tijd in beslag dat het echt niet slim is om dit te proberen. In dit geval kan je, als je dan toch echt png's wilt gebruiken voor IE een andere CSS aan te spreken. Een goed idee hier is bij het serveren van je pagina je server al een id of class op de body te zetten.

Meer later

Filed under: Mobiel, css, werk 4 Comments
25Aug/090

jquery.xhtml()

tired of firefox messing up perfectly good xhtml when you put it in a jqeury object? check out the projects page, i might just have the solution for you

Filed under: jquery, werk No Comments
23Jul/090

banners & es3x

Banners: Deze week 70 banners gemaakt voor Rabomobiel. 1 dag de basis opzetten met scripted animaties, 1 dag wachten op goedkeuring en dan 2 dagen doorrammen om alle andere banners te maken. Met een goeie basis is dat meer dan haalbaar. We hadden van alle telefoons en teksten aparte movieclips gemaakt en hoefde per formaat / telefoon alleen de juiste movieclips te vervangen en opnieuw te publishen in flash. Heerlijk als een simpel idee zo krachtig kan zijn. Heerlijk als noobs denken dat je het onmogelijke gedaan hebt :)

ES3x: Vandaag variphone over de werkvloer, klachten meegedeeld en er is een nieuwe afgiet van met mijn linkeroor gemaakt. Maandag gaat de hele buts naar belgië om nogmaals te kijken of alles wel goed is. De afgelopen 2 dagen waren ze al zoveel beter dan daarvoor dat ik die blauwe rakkers alweer mis :) <-- ja die smiley meen ik, er is en blijft iets speciaals met custom in ears, zeker als ze perfect zijn en ik hoop over 2 à 3 weken nogmaals te kunnene posten om te zeggen: nu zijn ze perfect!

fancyButton update: Also updated the fancyButton project. You can use a (custom) class to add a mouse-over effect to the buttons now. Copy the latest version here

Filed under: werk No Comments
3Jul/090

Projects @ lo-ga-rie

I made a page for all my projects, well scripts actually, that i made in the past and present that i want to share with the world. Check them out and give me feedback where needed. All script are released under the GPL licence.

Look at them here the first script is also added and i call it fancyButton a simple script that will transform any normal link into an apealing one without altering the plain HTML page so people without scripting enabled will still be able to click the link.

Filed under: jquery, werk No Comments
17Jun/090

Iframes die meegroeien met de content / font-size

Stel je maakt een site met een iframe waarvan de content d.m.v. zoom buttons kan veranderd worden.
Men neme:

  1. buttons om de font-size aan te passen
  2. een iframe met content
  3. een paar regels script

Om initieel de iframe de juiste hoogte te geven kan je het volgende gebruiken

$('iframe').load(function(){
  this.style.height =
  this.contentWindow.document.body.offsetHeight + 30 + 'px';
});

De 30 extra px is voor webkit browsers.
Als je de font-size knopjes indrukt dan kan je in je click event de volgende code gebruiken om iframe mee te laten scalen:

var iframeDoc = $("iframe").contents();
iframeDoc.find("body").attr("class", $(this).attr("class")); // $(this) is de font-size knop met een class 'normal' of 'big' of 'bigger'
$("#myContent").css("height", iframeDoc.find("body").height() + 30);

Dit werkt goed als je de CSS zo opbouwd dat alle font-sizes em based zijn dan kan je via

body.normal {
  font-size: 100%;
}
body.big {
  font-size: 120%;
}
body.bigger {
  font-size: 140%;
}

De font-size van het document en de iframe in 1x aanpassen.

Bad Behavior has blocked 27 access attempts in the last 7 days.