2010-09-25 25 views
25

Eksperymentuję z animacją w wersji <canvas> i nie mogę ustalić, jak narysować obrazek pod kątem. Pożądanym efektem jest kilka obrazów narysowanych jak zwykle, a jeden obraz obraca się powoli. (Ten obraz nie znajduje się na środku ekranu, jeśli to robi jakąkolwiek różnicę).Rysowanie płótna HTML5 z kątem pod kątem

Odpowiedz

53

Należy zmodyfikować macierz transformacji przed rysowaniem obrazu, który ma zostać obrócony.

Założenie obrazu wskazuje na obiekt HTMLImageElement.

var x = canvas.width/2; 
var y = canvas.height/2; 
var width = image.width; 
var height = image.height; 

context.translate(x, y); 
context.rotate(angleInRadians); 
context.drawImage(image, -width/2, -height/2, width, height); 
context.rotate(-angleInRadians); 
context.translate(-x, -y); 

współrzędne x, y oznacza centrum obrazu na płótnie.

+4

zamiast obracać/tłumaczyć na końcu, można zrobić 'context.save()' i 'context.restore()' przed i po wykonaniu transformacji i rysunku. –

+24

Podczas korzystania save()/restore() może wydawać się czystsze, byłoby to znacznie bardziej nieefektywne. Silnik będzie musiał przechowywać/przywracać wszystkie właściwości kontekstu, a nie tylko te, którymi manipulujemy. Ma to znaczenie we wrażliwej ścieżce kodu. –

+0

Aby zobaczyć inny przykład, zobacz to (zduplikowane) pytanie i odpowiedź: [Pokrętło wskaźnika przy użyciu płótna HTML5 - Obróć o punkt arbitrażowy] (http://stackoverflow.com/questions/4649836/dial-of-a-gauge-using -html5-canvas-rotate-about-arbitrary-point/4650102 # 4650102). – Phrogz

8

Pisałem funkcję (na podstawie odpowiedzi Jakuba), który pozwala użytkownikowi malować obraz w pozycji X, Y oparta na niestandardowym obrotu w punkcie zwyczaj obrotów:

function rotateAndPaintImage (context, image, angleInRad , positionX, positionY, axisX, axisY) { 
    context.translate(positionX, positionY); 
    context.rotate(angleInRad); 
    context.drawImage(image, -axisX, -axisY); 
    context.rotate(-angleInRad); 
    context.translate(-positionX, -positionY); 
} 

Następnie można wywołać to tak:

var TO_RADIANS = Math.PI/180; 
ctx = document.getElementById("canvasDiv").getContext("2d"); 
var imgSprite = new Image(); 
imgSprite.src = "img/sprite.png"; 

// rotate 45º image "imgSprite", based on its rotation axis located at x=20,y=30 and draw it on context "ctx" of the canvas on coordinates x=200,y=100 
rotateAndPaintImage (ctx, imgSprite, 45*TO_RADIANS, 200, 100, 20, 30); 
2

Ciekawostką jest, że pierwsze rozwiązanie pracował dla tak wielu ludzi, że nie daje wynik potrzebne. W końcu musiałem to zrobić:

ctx.save(); 
ctx.translate(positionX, positionY); 
ctx.rotate(angle); 
ctx.translate(-x,-y); 
ctx.drawImage(image,0,0); 
ctx.restore(); 

gdzie (positionX, positionY) to współrzędne na płótnie, że obraz ma być zlokalizowany na i (x, y) to punkt na obrazie, gdzie chcę obracanie obrazu.