Canvas rotate – Bild nach Mausposition ausrichten
- September 24th September 2009
- Kommentar schreiben
Mit dem <canvas > Element von HTML lassen sich in Verbindung mit JavaScript und Geometrie sehr kreative Bilder rendern. Seit neustem hält die dritte Dimension Einzug ins <canvas > Element und verspricht in ferner Zukunft Browserspiele in 3D.
Ich hab mit canvas ein wenig rumgebastelt und war sofort sehr angetan von der Funktion rotate(). Mit der Funktion canvas rotate() lasse sich Bilder drehen, jedoch ist der Ursprungspunkt der Originpoint beim 0 Punkt. Das heisst wenn wir dem Bild die Anweisung zur Drehung geben, rotiert es um diesen Punkt und verschwindet in der canvas Zeichenfläche (Elementfläche).
Um das Bild um seinen eigenen Mittelpunkt zu drehen muss man es nach der Rotationsfunktion wieder in die Mitte der Zeichenfläche schieben. Das macht man mit der Funktion translate().
Am besten schaut ihr euch mein Simulation Video an, es verdeutlich die Funktion der normalen rotation in canvas. Es zeigt wie das Bild um den 0 Punkt der Zeichenfläche dreht.
Simulation canvas rotate() mit Cinderella
Das Schwierige an dieser Sache war das erstellen eines Scripts welcher das Bild immer wieder in den Mittelpunkt schiebt. Das Script ist sehr lang geworden und sieht irgendwie ein bisschen kompliziert aus. Die mathematischen Berechnungen laufen korrekt und die Rotation um den Bildmittelpunkt funktioniert jedenfalls.
HTML 5 – Canvas rotate() – Picture rotate, origin center of picture, mouse alignment, without flash
Bild nach Mausposition ausrichten – ohne Flash
<html>
<head>
<title>Ein Bild nach Mausbewegung drehen - Ohne Flash</title>
<style type="text/css" media="screen">
body { text-align:left; font-size:90%; font-family:Verdana, Geneva, Arial, Helvetica, sans-serif; margin:1em 4em; }
canvas, img { border: 0px solid black; }
</style>
<script type="text/javascript">
// Initialisiere Variablen
var add=270; // Fügt das Bild beim laden in diesem Winkel ein
var angle=0;
var Ml=1;
var Mt=1;
var i=0;
function Draw(Catch){ // die Variable Catch übergibt den onmousemove Event
var CAl=parseFloat(document.getElementById('testcanvas1').style.left); // Canvas Position left
var CAt=parseFloat(document.getElementById('testcanvas1').style.top); // Canvas Position top
var canvasx=document.getElementById('testcanvas1').width; // Canvas Breite
var canvasy=document.getElementById('testcanvas1').height; // Canvas Höhe
var imgx=150; // Bild Breite
var imgy=200; // Bild Höhe
if (navigator.appName == "Netscape"&amp;&amp;i==1){ // Mauskoordinaten erfassen - Wenn Firefox
var Ml=Catch.pageX;
var Mt=Catch.pageY;
}
else{
if (navigator.appName == "Microsoft Internet Explorer"&amp;&amp;i==1){ // Mauskoordinaten erfassen - Wenn IE
var Ml=window.event.clientX;
var Mt=window.event.clientY;
}
else{ // Mauskoordinaten setze auf 1:1 , weil kein Browser erkannt wurde oder weil der Script das erste Mal durchlaufen wird
var Ml=1;
var Mt=1;
}
}
var CMl=CAl+(canvasx/2);
var CMt=CAt+(canvasy/2);
// Wir rechnen vom Canvas Mittelpunkt zu den Mauskoordinaten Länge und Höhe
// So errechnen wir später den Ausrichtwinkel zur Maus
var PRl=Ml-CMl;
var PRt=Mt-CMt;
// Ab hier werden Ausnahmefälle abgefragt
if(Mt==CMt&amp;&amp;CMl==Ml||Ml<=0||Mt<=0){ // Wenn Maus Zufällig auf Mittelpunkt des Canvas dann tue nichts!
}
else{
// Ausnahmefälle 0, 90, 180, 270 Grad - in solchen Fällen ist der Winkel bekannt
if(Mt==CMt&amp;&amp;Ml>CMl){
angle=0;
}
else{
if(Mt==CMt&amp;&amp;Ml<CMl){
angle=180;
}
else{
if(Ml==CMl&amp;&amp;Mt<CMt){
angle=270;
}
else{
if(Ml==CMl&amp;&amp;Mt>CMt){
angle=90;
}
else{
// Wenn kein Ausnahmefall zutrifft, dann errechne den Ausrichtwinkel vom Canvas Mittelpunkt zu den Mauskoordinaten
anglex=Math.atan(PRl/PRt)/Math.PI*180;
if(anglex<0){ // Wenn angle Minus dann mache Plus
anglex=anglex*(0-1);
}
else{}
// Ab hier Prüfen wir in welchem Kreissektor die Maus gerade ist, um so die korrekte trigonometrische Berechnung des Winkels zu bekommen
if(Ml>CMl&amp;&amp;Mt>CMt){ // Sektor 1
angle=90-anglex;}
else{
if(Ml<CMl&amp;&amp;Mt>CMt){ // Sektor 2
angle=90+anglex;}
else{
if(Ml<CMl&amp;&amp;Mt<CMt){ // Sektor 3
angle=270-anglex;}
else{
if(Ml>CMl&amp;&amp;Mt<CMt){ // Sektor 4
angle=270+anglex;}
else{}
}
}
}
} // Else 90 Grad
} // Else 270 Grad
} // Else 180 Grad
} // Else 0 Grad
// Drehkompensierung
// Da ich es nicht fertig gebracht habe das Canvas neu zu initialisieren, müssen wird "das zu drehende" minus „das bereits gedrehte" rechnen, um den effektiven Drehwinkel zu errechnen
angle=angle-add; // angle = "das zu drehende" (add ist aus dem letzten Durchlauf bekannt)
add=angle+add; // add = „das bereits gedrehte"
// Ab hier ist der effektiv zu drehenden Winkel "angle" definiert
// Wir errechnen in einer trigonometrischen Abhandlung die Verschiebungsposition
imgDiag=Math.sqrt(Math.pow((canvasx/2),2)+Math.pow((canvasy/2),2));
imgDiagAngle=(Math.asin((canvasx/2)/imgDiag))/Math.PI*180;
VerschHalbAngle=(180-angle)/2;
VerschLange=(imgDiag*Math.cos(VerschHalbAngle*Math.PI/180))*2;
realAngelVersch=imgDiagAngle+VerschHalbAngle;
inversRAV=90-realAngelVersch;
mx=VerschLange*Math.cos(inversRAV*Math.PI/180);
my=VerschLange*Math.sin(inversRAV*Math.PI/180);
// Ab hier sind die Verschiebungspositionen (mx, my) bekannt. Wir überschreiben die Canvas Zeichenfläche mit clearRect und lassen das Bild neu zeichnen
// Hinweis: Damit der Script immer weiss in welchem Winkel sich das Bild gerade befindet, speichern wir den aktuellen Drehwinkel in der Variable add
// Warum so kompliziert? – Wenn man das Bild einmal gedreht hat, muss man bei der nächsten Drehung von dem bereits gedrehten Winkel ausgehen. Siehe Drehkompensierung
var context = document.getElementById('testcanvas1').getContext('2d');
var img = new Image();
img.onload = function(){
context.clearRect(-canvasx*0.5,-canvasx*0.5,canvasx*3,canvasy*3); //(0,0,canvasx+5,canvasy+5);
context.translate(mx, my);
context.rotate(angle*Math.PI/180);
context.drawImage(img, ((canvasx-imgx)/2), ((canvasy-imgy)/2), imgx, imgy);
}
img.src = 'pfeil.png';
} // Else Wenn Maus zufällig auf Mittelpunkt
i=1; // Variable zur Kontrolle ob Script durchlaufen wurde
}
window.setTimeout("document.onmousemove= Draw", 3000); // Lässt Event-Handler verzögert starten damit das Canvas genug Zeit hat zu laden - Überwacht onmousemove und startet Rotationsfunktion Draw
</script>
<!-- ExplorerCanvas Script - ermöglicht die Darstellung von Canvas Elemente im Internetexplorer Visit http://excanvas.sourceforge.net --//>
<script type="text/javascript" src="excanvas.js"></script>
</head>
<body onLoad="javascript:Draw()" bgcolor="black">
<canvas id="testcanvas1" width="250" height="300" style="position: absolute; left: 100; top: 100;">
Dein Browser kann diese Grafik nicht darstellen.
Unterstützte Browser: Mozilla Firefox &amp; Internet Explorer
</canvas>
</body>
</html>
Inspiriation
http://www.peterkroener.de/eine-kleine-canvas-einfuehrung/
Referenz
http://canvas.quaese.de/
Canvas in HTML 5
http://de.wikipedia.org/wiki/HTML_5#Anwendungselemente