Bonjour, j'essaye d'exploiter un peu les possibilités du canvas dans le traitement d'image.
Voici ce que j'essaye de faire :


En gros je récupère une image du bureau en drag&drop. Et je souhaite pouvoir modifier sa taille, son orientation, et la déplacer dans le canvas.

Chaque fonctionnalité prise séparément est facile à mettre en place mais, pour les combiner, c'est autre chose. En effet pour la rotation faire en sorte que mon image tourne sur elle même en changeant l'origine du repère par le centre de l'image quand le canvas à été redimensionner avec scale est plus compliqué.

Voici mon code :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
 
function ImagePicker(dz){
	var dropZone = document.getElementById(dz);
	var zoom = null; // Zoom Slider
	var rotate = null; // Rotate Slider
	var canvas = document.getElementById("canvas");
	var ctx = canvas.getContext("2d");
	var img = new Image();
	var WIDTH = canvas.width; // Canvas width;
	var HEIGHT = canvas.height; // Canvas height;
	var posX = null;
	var posY = null;
 
	/**
	 * Control slider activation and default values.
	 */
	var adaptSlider = function(width, height){
		rotate.disabled = false;
		zoom.disabled = false;
		zoom.oldValue = 100;
	};
 
 
	/**
	 * Handles dropped file and draws it into canvas.
	 */
	var handleFileSelect = function(evt){
 
		evt.stopPropagation();
		evt.preventDefault();
 
		var file = evt.dataTransfer.files[0]; // FileList object.
 
		var reader = new FileReader();
 
		// Closure to capture the file information.
		reader.onload = (function(f) {
			return function(e) {
				img.src = e.target.result;
				img.onload = function(){
					adaptSlider(this.width, this.height);
					ctx.drawImage(this, 0, 0, this.width, this.height);
				};
			};
		})(file);
 
		// Read in the image file as a data URL.
		reader.readAsDataURL(file);
	};
 
	/**
	 * Handles dropped file when it is not on the drop zone
	 */
	var handleDragOver = function(evt){
		evt.stopPropagation();
		evt.preventDefault();
		evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
	};
 
	/**
	 * Handles image zoom.
	 */
	var onZoom = function(evt){
 
			/*
			 * I want to rescale image from its own center if it is smaller that canvas. not from the left-top corner.
			 * Doesn't work.
			 */
			if(img.width * zoom.value / 100 < WIDTH || img.height * zoom.value / 100 < HEIGHT){ 
 
				/*ctx.scale(zoom.value / 100, zoom.value / 100);
				var decalWidth =  - ((img.width * zoom.value / 100));
				var decalHeight = - ((img.height * zoom.value / 100));
				console.log(decalWidth,  decalHeight);
				ctx.translate(WIDTH - decalWidth, HEIGHT - decalHeight);
				ctx.drawImage(img, 0, 0 , img.width, img.height);*/
			} else { // Default béhavior.
				ctx.clearRect ( 0 ,0 , WIDTH , HEIGHT );
				ctx.save();
				ctx.scale(zoom.value / 100, zoom.value / 100);
				ctx.drawImage(img, 0, 0, img.width, img.height);
				ctx.restore();
			}
 
	};
 
	/**
	 * Handles image rotation.
	 */
	var onRotate = function(evt){
		ctx.clearRect ( 0 ,0 , WIDTH , HEIGHT );
		ctx.save();
		/*
		 * Quel valeur dois-je utiliser pour que le point d'origine correspond au centre de mon image même si le canvas à été redimensionné?
		 * Quel valeur doi-je ensuite utilisé comme coordonnée de l'image? 
		 */
		ctx.translate(img.width * (zoom.value/100) /2, img.height * (zoom.value/100) /2); 
		ctx.rotate(rotate.value*Math.PI/180);
		ctx.drawImage(img, -1 * (img.width * (zoom.value/100) /2), -1 * (img.height * (zoom.value/100) /2), img.width, img.height );
		ctx.restore();
	};
 
 
	/**
	 * Handles image move.
	 */
	var onMouseMove = function(evt){
		var newPosX = evt.pageX;
		var newPosY = evt.pageY;
		ctx.clearRect ( 0 ,0 , WIDTH , HEIGHT );
		//ctx.drawImage(img, newPosX - posX , newPosY - posY , img.width, img.height );
 
		if(newPosX > posX && newPosY > posY) 
			ctx.drawImage(img, newPosX - posX , newPosY - posY , img.width, img.height );
		else if(newPosX < posX && newPosY < posY) 
			ctx.drawImage(img, newPosX - posX , newPosY - posY , img.width, img.height );
		else if(newPosX > posX && newPosY < posY) 
			ctx.drawImage(img, newPosX - posX , newPosY - posY , img.width, img.height );
		else if(newPosX < posX && newPosY > posY) 
			ctx.drawImage(img, newPosX - posX , newPosY - posY , img.width, img.height );
	};
 
	var handlePictureMove = function(evt){
		posX = evt.pageX;
		posY = evt.pageY;
		canvas.addEventListener('mousemove', onMouseMove, false);
		canvas.addEventListener('mouseup', function(evt){
			canvas.removeEventListener('mousemove', onMouseMove, false);
		}, false);
	};
 
 
	/**
	 * Set the slider that control zoom.
	 */
	this.setZoom = function(elem){
		zoom = elem;
		zoom.addEventListener('input', onZoom, false);
		zoom.addEventListener('change', onZoom, false);
	};
 
 
	/**
	 * Set the slider that control rotation.
	 */
	this.setRotate = function(elem){
		rotate = elem;
		rotate.addEventListener('input', onRotate, false);
		rotate.addEventListener('change', onRotate, false);
	};
 
	dropZone.addEventListener('dragover', handleDragOver, false);
	dropZone.addEventListener('drop', handleFileSelect, false);
	canvas.addEventListener('mousedown', handlePictureMove, false);
};
Le code qui pose problème est situé dans les fonctions onZoom et onRotate.

OnZoom :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 
/**
	 * Handles image zoom.
	 */
	var onZoom = function(evt){
 
			/*
			 * I want to rescale image from its own center if it is smaller that canvas. not from the left-top corner.
			 * Doesn't work.
			 */
			if(img.width * zoom.value / 100 < WIDTH || img.height * zoom.value / 100 < HEIGHT){ 
 
				/*ctx.scale(zoom.value / 100, zoom.value / 100);
				var decalWidth =  - ((img.width * zoom.value / 100));
				var decalHeight = - ((img.height * zoom.value / 100));
				console.log(decalWidth,  decalHeight);
				ctx.translate(WIDTH - decalWidth, HEIGHT - decalHeight);
				ctx.drawImage(img, 0, 0 , img.width, img.height);*/
			} else { // Default béhavior.
				ctx.clearRect ( 0 ,0 , WIDTH , HEIGHT );
				ctx.save();
				ctx.scale(zoom.value / 100, zoom.value / 100);
				ctx.drawImage(img, 0, 0, img.width, img.height);
				ctx.restore();
			}
 
	};
onRotate :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
/**
	 * Handles image rotation.
	 */
	var onRotate = function(evt){
		ctx.clearRect ( 0 ,0 , WIDTH , HEIGHT );
		ctx.save();
		/*
		 * Quel valeur dois-je utiliser pour que le point d'origine correspond au centre de mon image même si le canvas à été redimensionné?
		 * Quel valeur doi-je ensuite utilisé comme coordonnée de l'image? 
		 */
		ctx.translate(img.width * (zoom.value/100) /2, img.height * (zoom.value/100) /2); 
		ctx.rotate(rotate.value*Math.PI/180);
		ctx.drawImage(img, -1 * (img.width * (zoom.value/100) /2), -1 * (img.height * (zoom.value/100) /2), img.width, img.height );
		ctx.restore();
	};
Quelqu'un aurait une idée pour résoudre mon problème?