Canvas en events toepassen op onderdelen van de tekening

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Blue-eagle
  • Registratie: September 2000
  • Niet online
Voor een nieuwe opdracht wilde ik gebruik gaan maken van de canvas tag. Hierin wilde ik middels javascript elementen gaan tekenen om bepaalde data weer te geven. Een simpele voorstelling: horizontaal een aantal aanklikbare bolletjes met daartussen lijntjes.

Niet zo heel moeilijk, ik was nog niet bekend met hoe je in een canvas kan tekenen, maar daar is genoeg over te vinden, uiteraard. Nu schetst mijn verbazing eigenlijk dat het tekenen erg lineair is: je hebt een huidige kleur die je instelt, vervolgens teken je iets en "zet je dat op papier". Ik wil Photoshop met al haar lagen, en ik krijg MS Paint.. zo voelt het althans ;)

Ik had eigenlijk verwacht dat je een cirkel kon toevoegen als zijnde een object binnen de canvas.

Pseudo-code:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
var canvas = document.getElementById("canvashier");
canvas.setDrawMode = "2d";

var rondje = canvas.createCircle(5, 5, 5, Math.pi*2);
rondje.fill = "#000333"; // simpele hex of rgb/rgba/cmyk etc waarden
rondje.stroke = "1px solid #aabb33"; // zoals in css
rondje.paint(20, 20); // x en y coordinaten

rondje.onClick = function() {
    this.fill = "#9313aa";
    this.width = "10px";
    this.height = "10px";
}


Again, puur uit mijn hoofd gebaseerd-op-niks pseudo-code. Dit is dus een voorbeeldje van wat had verwacht voordat ik hier mee bezig ging.

Wat ik wil bereiken is dat men op een rondje kan klikken (dus NIET op de transparante corners) waarna deze groter wordt en van kleur verandert.

Alternatieven (helaas niet in dit geval) zijn Flash of Silverlight, echter.. beiden zijn geen optie vanwege de aversie die ik persoonlijk * heb jegens deze plugins, en de aankomende "oorlog" waar Apple zich ook in lijkt te willen mengen staat me ook niet aan. Daarnaast kan de eindgebruiker deze software niet altijd installeren. Ook kan ik gebruik maken van CSS3 zijn corner-radius mogelijkheid om rondjes te simuleren; dit heeft echter als nadeel dat een HTML element wat eruit ziet als een rondje altijd nog een rechthoek (of vierkant) is, de hoeken zullen dus ook onclick en onmouseover events afvangen.

Je zou zeggen dat SVG (mits je de namespace opneemt in je HTML namespace) inline binnen je HTML zou moeten werken, alleen ik krijg dit niet werkende. Ook op W3Schools staat dit omschreven als een "I wish.." onderdeel.

Het W3C lijkt er wel mee bezig te zijn, maar dit werkt in de doel-browser (Firefox) nog niet.

Het wordt overigens wel in Firefox 4 ingebakken, alleen laat die release nog even op zich wachten.

De enige oplossing die ik kan bedenken is de onclick en onmouseover events te simuleren door de X en Y coordinaten simpelweg in de canvas zelf af te vangen, en bij te houden welke coordinaten "hit areas" zijn. Zodra de muis binnen deze areas komt zou ik de complete canvas opnieuw tekenen met alleen de huidige "hit area" gehighlight. Dit lijkt me niet alleen best veel werk, maar ook redelijk zwaar mits je dit op een ondervoed Citrix machientje moet verrichten.

Kortom: Heb ik nog andere opties?

* Ik vind Actionscript ronduit ranzig en Silverlight heb ik een jaar geleden het een en ander mee gedaan, backwards compatibility bestond niet en de ontwikkeltools waren zelf zo brak als ikzelf zaterdagochtend ben.

[ Voor 9% gewijzigd door Blue-eagle op 12-05-2010 00:21 ]


Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 06:48

Sebazzz

3dp

Blue-eagle schreef op woensdag 12 mei 2010 @ 00:14:
Je zou zeggen dat SVG (mits je de namespace opneemt in je HTML namespace) inline binnen je HTML zou moeten werken, alleen ik krijg dit niet werkende. Ook op W3Schools staat dit omschreven als een "I wish.." onderdeel.
Ook geprobeerd door een XHTML1.1 of XHTML5 pagina te maken, te verzenden met application/xhtml+xml en je SVG te embedden op die manier?

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:22

.oisyn

Moderator Devschuur®

Demotivational Speaker

Blue-eagle schreef op woensdag 12 mei 2010 @ 00:14:
Dit lijkt me niet alleen best veel werk, maar ook redelijk zwaar mits je dit op een ondervoed Citrix machientje moet verrichten.
Wat natuurlijk onzin is :). Het opnieuw tekenen is waar de bottleneck zit, niet de javascript om dat aan te roepen. En ja, als het Flash, Silverlight, SVG of met DOM elementen geïmplementeerd wordt moet er óók opnieuw getekend worden. Canvas hoeft daarbij echt niet trager te zijn dan willekeurig andere implementatie.

Het is dus prima te implementeren met javascript en canvas. Wat je in code wilt is gewoon een verzameling van objecten die zichzelf kunnen tekenen op het canvas. Vervolgens maak je bij een verandering het canvas leeg en teken je al die objecten opnieuw. Als performance een issue wordt bij heel veel objecten kun je eraan denken om alleen die objecten te tekenen die overlappen met het gebied dat veranderd is (op basis van hun bounding rectangle oid).

Als je die objecten eenmaal hebt dan is de rest van je implementatie niet veel anders dan hoe je met het SVG zou implementeren. Alleen het opnieuw tekenen doe je dus zelf, ipv dat je de browser het voor je op laat lossen.

[ Voor 10% gewijzigd door .oisyn op 12-05-2010 01:17 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • pieturp
  • Registratie: April 2004
  • Laatst online: 27-08 14:18

pieturp

gaffa!

SVG Kan prima in een object tag op je html pagina staan, mits de SVG als XML wordt geserveerd.

Niets weerhoud je overigens om meerdere (trransparante) canvas elementen te gebruiken ;-)

... en etcetera en zo


Acties:
  • 0 Henk 'm!

  • Blue-eagle
  • Registratie: September 2000
  • Niet online
Sebazzz schreef op woensdag 12 mei 2010 @ 00:24:
[...]

Ook geprobeerd door een XHTML1.1 of XHTML5 pagina te maken, te verzenden met application/xhtml+xml en je SVG te embedden op die manier?
Neen, het moet een prototype worden wat via het filesystem geladen wordt door mensen die de software moeten verkopen, die gaan geen servertje draaien :)
.oisyn schreef op woensdag 12 mei 2010 @ 01:15:
[...]

Wat natuurlijk onzin is :). Het opnieuw tekenen is waar de bottleneck zit, niet de javascript om dat aan te roepen. En ja, als het Flash, Silverlight, SVG of met DOM elementen geïmplementeerd wordt moet er óók opnieuw getekend worden. Canvas hoeft daarbij echt niet trager te zijn dan willekeurig andere implementatie.
Dat is mooi om te horen, maar het voelt zo.. onnodig omslachtig. Alsof het beter moet kunnen.
Het is dus prima te implementeren met javascript en canvas. Wat je in code wilt is gewoon een verzameling van objecten die zichzelf kunnen tekenen op het canvas. Vervolgens maak je bij een verandering het canvas leeg en teken je al die objecten opnieuw. Als performance een issue wordt bij heel veel objecten kun je eraan denken om alleen die objecten te tekenen die overlappen met het gebied dat veranderd is (op basis van hun bounding rectangle oid).
Interessant idee. Ik zat zelf te spelen met het idee om een soort layer-structuur te simuleren. Maar dat zijn dan inderdaad de objecten die jij schetst. Ik ga eens kijken hoe dit qua performance zit met flink wat tekenwerk en dit vervolgens een paar duizend keer opnieuw te tekenen.
Als je die objecten eenmaal hebt dan is de rest van je implementatie niet veel anders dan hoe je met het SVG zou implementeren. Alleen het opnieuw tekenen doe je dus zelf, ipv dat je de browser het voor je op laat lossen.
Makes sense :) Ik ga dat nu proberen.
pieturp schreef op woensdag 12 mei 2010 @ 10:34:
SVG Kan prima in een object tag op je html pagina staan, mits de SVG als XML wordt geserveerd.

Niets weerhoud je overigens om meerdere (trransparante) canvas elementen te gebruiken ;-)
Da's de moeite van het proberen ook wel waard. Al vermoed ik dat 2 overlappende canvas-tags alsnog squares zullen zijn. Ook dat ga ik even proberen.

Thanks :)