svg-porr, testkört raphaelJS

Arcs
Arcs

Det är väldigt lätt att man som webbutvecklare ibland fastnar i mönster för hur man bygger och renderar sidor, även om det finns nyare effektivare alternativ, då detta framförallt sparar tid. Tid är ett ständigt återkommande problem som ofta bankar skiten ur ens nyfikenhet och får en att stagnera kunskapsmässigt. Det resulterar i att man får försöka hålla sig uppdaterad när man kan och vill, vilket ofta blir kvällar och liknande =) Ett bibliotek som jag blev tipsad om av en kollega och sen spenderade några kvällar förra veckan med att titta på är RaphaelJS.
Ett bibliotek som hjälper dig rendera SVG med hjälp av javascript 🙂 Möjligheterna är stora och det finns ordentligt dokumenterat, vissa delar fick mitt huvud att värka lite, men det gick att ta sig igenom och jag tycker det var värt besväret.
Ibland vill man visualisera data på olika sätt, vilket jag använt biblioteket till, och då för att skapa lite olika charts/diagram. Ett av de mer intressanta som jag tänkte dela med mig av är arc/bågen som är ett rätt trevligt sätt att visa procentuell data på.

Här har jag gjort ett enkelt plugin som hjälper mig att med jquery rendera objekten i raphael. Storleken på objekten styr jag med css.
[sourcecode language=”css”]
.arc {
width: 100px;
height: 100px;
display: block;
}
[/sourcecode]
Och den enda HTML jag då renderar ut på sidorna är följande:
[sourcecode language=”html”]
<meter id=”arc1″ class=”arc” data-value=”70″ data-color=”#00006b” data-label=”70″></meter>
<meter id=”arc2″ class=”arc” data-value=”35″ data-color=”#00006b” data-label=”35″></meter>
[/sourcecode]
Det gör att man får väldigt clean HTML vilket jag är ett stort fan av =D, samt att man kan isolera procedurerna för renderingen och hålla saker där de ska vara! och hör sen alla som kladdar med script inline ^^

Från min script.js kallar jag sen enkelt på pluginet:
[sourcecode langauge=”javascript”]
$(‘.arc’).arcThis();
[/sourcecode]

Mycket renare än så kan knappast vyn bli och resten fixar vi med hjälp av raphaelJS och lite jquery. När det gäller att rendera bågar/arcs blir det matte på lite tölig nivå men det är egentligen inga knepigheter. Vi tar hjälp av rapahels .path funktion för att tala om start-slut positioner på sträckan samt vilken kurva den ska ha. Sen räknar vi ut positionsmässigt vart vi ska placera den baserat på storleken på objektet, vilket vi bestämt med CSS. Har även satt lite statiska värden i options som man kan overrida när man kallar på funktionen etc. Väldigt enkelt. Hade gjort ett innan som renderade flera bågar i samma med underelement osv men det blev lite rörigt att visa =P

[sourcecode language=”javascript”]
(function( $ ) {
$.fn.arcThis = function( options ) {
var calcCirclePath = function(value, bar, maxValue) {
var alpha = 360 / maxValue * value;
var a = (90 – alpha) * Math.PI / 180;
var x = bar.xpos + bar.radius * Math.cos(a);
var y = bar.ypos – bar.radius * Math.sin(a);
if(value == maxValue) {
return [[“M”, bar.xpos, bar.ypos – bar.radius], [“A”, bar.radius, bar.radius, 0, 1, 1, (bar.xpos-0.01), bar.ypos – bar.radius]];
} else {
return [[“M”, bar.xpos, bar.ypos – bar.radius], [“A”, bar.radius, bar.radius, 0, +(alpha > 180), 1, x, y]];
}
};

return this.each(function () {
var $this = $(this);
var settings = $.extend( {
maxValue: 100,
contId: $this.attr(‘id’),
contHeight: $this.height(),
contWidth: $this.width(),
strokeWidth: 15
}, options);

$cont = document.getElementById(settings.contId);

var bar = {
value: $(this).attr(‘data-value’),
stroke: $(this).attr(‘data-color’),
title: $(this).attr(‘data-label’)
};

var maxDia;
if ( settings.contHeight > settings.contWidth ) { maxDia = settings.contWidth; }
else { maxDia = settings.contHeight; }

maxDia = maxDia – (settings.strokeWidth * 2);

bar.radius = (maxDia / 2);

bar.xpos = bar.radius + settings.strokeWidth;
bar.ypos = bar.radius + settings.strokeWidth;

var paper = new Raphael(document.getElementById(settings.contId), settings.contWidth, settings.contHeight);

var arc = paper.path(calcCirclePath( 100, bar, settings.maxValue));
arc.attr({ stroke: ‘#dddddd’, ‘stroke-width’: settings.strokeWidth });

var arc = paper.path(calcCirclePath( bar.value, bar, settings.maxValue ));
arc.attr({
stroke: bar.stroke,
‘stroke-width’: settings.strokeWidth,
title: bar.title + ‘%’
});

var text = paper.text(bar.xpos, bar.ypos, bar.title + ‘%’);
});
};
})( jQuery );
[/sourcecode]

Jag tycker det är väldigt lite besvär för en väldigt trevlig funktion, vi får fint renderade svg objekt som skalerar gudomligt, något som även är fascinerande är att det är kompatibelt ända ner till IE7. Texten får sig en liten törn i IE7 men inte så det blir oläsbart. Har även sett vissa kompatibilitetsproblem med mobilversionen av IE9, men det fungerar i övrigt på det mesta som vi provat. (jo iphone verkar ok med). På samma sätt går det väldigt mycket enklare att rendera t.ex. stapeldiagram mm. Biblioteket har även stöd för animering! och event! woop woop. Så ja jag kommer nog leka vidare med detta ^^

Såja. Lycka till att läsa kladdet ovan vilket inte alltid är så lätt när det gäller andras jquery ^^

lek med CSS3 & ikoner

Tro jag hade dåligt tråkigt ikväll eller, skulle spela men så blev det inget, var inge sugen på att jobba med något riktigt så surfade runt lite. Började läsa om former och så i Css, fick se lite grejer folk hade gjort och kände mig inspirerad. Jag har haft mycket Facebook på huvudet idag pga jobbet och fick därför idén att leka med Facebook-ikonen. I övrig notis så bakade jag även scones som resultat av det rubbade kvällsschemat.

En sak som är lite trevlig med css är att det blir webbläsaren som ritar upp det, vilket också gör att det skalerar väldigt bra. dvs du kan zooma och joxxa utan elaka pixelmonster. Här valde jag för demonstrationssyftet att rendera några versioner med hjälp av “zoom:” elementet i css. Eftersom många webbläsare är lite svältfödda på vissa attribut så tog jag även en bild.

fbIcons Css3

Allt är som sagt gjort med hjälp av Css3, användningsområdet är än så länge obestämt. Men om man har några timmar över och vill rita med kod så kör.

Html
[sourcecode language=”html”]
<div class="fbIcon zoom1">
<div class="outerbox">outer</div>
<div class="bottombox">bottom</div>
<div class="boxring">box</div>

<div class="white f1">f1</div>
<div class="white f2">f2</div>
<div class="white f2_2">f2_2</div>

<div class="white f3">f3</div>
</div>
[/sourcecode]

unt der css,
[sourcecode language=”css”]
.fbIcon {
margin: auto;
position: relative;
display: block;
height: 700px;
width: 700px;
text-indent: -9999px;
margin: 5px;
float: left;
}

.fbIcon div {
position: absolute;
display: block;
}

.fbIcon .outerbox {
height: 700px;
width: 700px;
border-radius: 60px;
background: #4370a9;
background: -moz-linear-gradient(-90deg, #164c8b, #4370a9);
background: -o-linear-gradient(#164c8b, #4370a9);
background: -webkit-gradient(linear, 0 top, 0 bottom, from(#164c8b), to(#4370a9));
}

.fbIcon .bottombox {
width: 645px;
height: 160px;
border-radius: 40px;
bottom: 25px;
left: 30px;
background: #6d84b5;
background: -moz-linear-gradient(-90deg, #6d84b5, #83a3d3);
background: -o-linear-gradient( #6d84b5, #83a3d3);
background: -webkit-gradient(linear, 0 top, 0 bottom, from(#6d84b5), to(#83a3d3));
}

.fbIcon .boxring {
height: 670px;
width: 670px;
border-radius: 60px;
background: transparent;
top: 5px;
left: 5px;
border: 10px solid #164C8B;
}

.white { background: #fff; }

.fbIcon .f1 {
width: 125px;
bottom: 25px;
height: 530px;
right: 180px;
}

.fbIcon .f2 {
width: 280px;
bottom: 360px;
height: 100px;
right: 80px;
-webkit-transform: skew(-5deg);
-moz-transform: skew(-5deg);
-o-transform: skew(-5deg);
transform: skew(-5deg);
}
.fbIcon .f2_2 {
height: 100px;
right: 350px;
width: 20px;
bottom: 360px;
}
.fbIcon .f3 {
width: 240px;
height: 100px;
bottom: 555px;
right: 65px;
border-top-left-radius: 100px 100px;
}
[/sourcecode]