• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# CanvasRenderingContext2D
2
3
4Use **CanvasRenderingContext2D** to draw objects such as graphics, texts, line segments, and images on the **<canvas>** component. For details, see [CanvasRenderingContext2D](../reference/arkui-js/js-components-canvas-canvasrenderingcontext2d.md).
5
6
7## Drawing Line Segments
8
9Use **moveTo** and **lineTo** to draw a line segment. Use the **closePath** method to end current path, obtaining a closed path. Set **quadraticCurveTo** (quadratic bezier curve) or **bezierCurveTo** (cubic bezier curve) to draw a graphic.
10
11
12```html
13<!-- xxx.hml -->
14<div class="container">
15  <canvas ref="canvas1"></canvas>
16  <select @change="change">
17    <option value="value1"> line </option>
18    <option value="value2"> quadratic </option>
19    <option value="value3"> bezier </option>
20    <option value="value4"> arc/ellipse </option>
21    <option value="value5"> lineJoin/miterLimit </option>
22  </select>
23</div>
24```
25
26
27```css
28/* xxx.css */
29.container{
30  width: 100%;
31  height: 100%;
32  flex-direction: column;
33  justify-content: center;
34  align-items: center;
35  background-color: #F1F3F5;
36}
37canvas{
38  width: 600px;
39  height: 500px;
40  background-color: #fdfdfd;
41  border: 5px solid red;
42}
43select{
44  margin-top: 50px;
45  width: 250px;
46  height: 100px;
47  background-color: white;
48}
49```
50
51
52```js
53// xxx.js
54export default {
55  data:{
56    el: null,
57    ctx: null,
58  },
59  onShow(){
60    this.el = this.$refs.canvas1;
61    this.ctx = this.el.getContext("2d",{antialias: true});
62    // Clear the contents on the canvas.
63    this.ctx.clearRect(0, 0, 600, 500);
64    // Create a drawing path.
65    this.ctx.beginPath();
66    // Square off the endpoints of the line.
67    this.ctx.lineCap = 'butt';
68    // Border width
69    this.ctx.lineWidth = 15;
70    // Create a drawing path.
71    this.ctx.beginPath();
72    // Move a drawing path from the current point to a target position.
73    this.ctx.moveTo(200, 100);
74    // Connect the current point to a target position.
75    this.ctx.lineTo(400, 100);
76    // Stroke a path.
77    this.ctx.stroke();
78    this.ctx.beginPath();
79    // Round the endpoints of the line.
80    this.ctx.lineCap = 'round';
81    this.ctx.moveTo(200, 200);
82    this.ctx.lineTo(400, 200);
83    this.ctx.stroke();
84    // Square off the endpoints of the line.
85    this.ctx.beginPath();
86    this.ctx.lineCap = 'square';
87    this.ctx.moveTo(200, 300);
88    this.ctx.lineTo(400, 300);
89    this.ctx.stroke();
90  },
91  change(e){
92    if(e.newValue == 'value1'){
93      this.el = this.$refs.canvas1;
94      this.ctx = this.el.getContext("2d",{antialias: true});
95      this.ctx.clearRect(0, 0, 600, 500);
96      // Top
97      this.ctx.beginPath();
98      this.ctx.lineCap = 'butt';
99      this.ctx.moveTo(200, 100);
100      this.ctx.lineTo(400, 100);
101      this.ctx.stroke();
102      // Center
103      this.ctx.beginPath();
104      this.ctx.lineCap = 'round';
105      this.ctx.moveTo(200, 200);
106      this.ctx.lineTo(400, 200);
107      this.ctx.stroke();
108      // Bottom
109      this.ctx.beginPath();
110      this.ctx.lineCap = 'square';
111      this.ctx.moveTo(200, 300);
112      this.ctx.lineTo(400, 300);
113      this.ctx.stroke();
114    }else if(e.newValue == 'value2'){
115      this.ctx.clearRect(0, 0, 600, 500);
116      // Top
117      this.ctx.beginPath();
118      this.ctx.moveTo(100, 150);
119      // Path of the quadratic bezier curve
120      this.ctx.quadraticCurveTo(300, 50, 500, 150);
121      this.ctx.stroke();
122      // Left
123      this.ctx.beginPath();
124      this.ctx.moveTo(200, 150);
125      this.ctx.quadraticCurveTo(250, 250, 250, 400);
126      this.ctx.stroke();
127      // Right
128      this.ctx.beginPath();
129      this.ctx.moveTo(400, 150);
130      this.ctx.quadraticCurveTo(350, 250, 350, 400);
131      this.ctx.stroke();
132    }else if(e.newValue == 'value3'){
133      this.ctx.clearRect(0, 0, 600, 500);
134      // Bottom
135      this.ctx.beginPath();
136      this.ctx.moveTo(100, 200);
137      // Path of the cubic bezier curve
138      this.ctx.bezierCurveTo(150, 100, 200, 100,250, 200);
139      this.ctx.stroke();
140      // Left
141      this.ctx.beginPath();
142      this.ctx.moveTo(350, 200);
143      this.ctx.bezierCurveTo(400, 100, 450, 100,500, 200);
144      this.ctx.stroke();
145      // Right
146      this.ctx.beginPath();
147      this.ctx.moveTo(200, 350);
148      this.ctx.bezierCurveTo(250, 500, 350, 500, 400, 350);
149      this.ctx.stroke();
150    }else if(e.newValue == 'value4'){
151      this.ctx.clearRect(0, 0, 600, 500);
152      this.ctx.beginPath();
153      this.ctx.moveTo(100, 200);
154      // Arc
155      this.ctx.arcTo(150, 300, 350, 300, 150);
156      this.ctx.stroke();
157      this.ctx.beginPath();
158      // Ellipse
159      this.ctx.ellipse(400, 250, 50, 100, Math.PI * 0.25, Math.PI * 0.5 , Math.PI , 1);
160      this.ctx.stroke();
161    }else if(e.newValue == 'value5'){
162      this.ctx.clearRect(0, 0, 600, 500);
163      // Upper left
164      this.ctx.beginPath();
165      // Draw a sector centered at the common endpoint of connected line segments.
166      this.ctx.lineJoin = 'round';
167      this.ctx.moveTo(100, 100);
168      this.ctx.lineTo(200, 200);
169      this.ctx.lineTo(100, 250);
170      this.ctx.stroke();
171      // lower left
172      this.ctx.beginPath();
173      // Fill a triangular between the common endpoint of connected segments.
174      this.ctx.lineJoin = 'bevel';
175      this.ctx.moveTo(100, 300);
176      this.ctx.lineTo(200, 400);
177      this.ctx.lineTo(100, 450);
178      this.ctx.stroke();
179      // Top right
180      this.ctx.beginPath();
181      // Distance between the internal angle and exterior angle at the intersection of lines
182      this.ctx.lineJoin = 'miter';
183      this.ctx.miterLimit = 3;
184      this.ctx.moveTo(400, 100);
185      this.ctx.lineTo(450, 200);
186      this.ctx.lineTo(400, 250);
187      // Draw a closed path.
188      this.ctx.closePath();
189      this.ctx.stroke();
190      // Lower right
191      this.ctx.beginPath();
192      this.ctx.lineJoin = 'miter';
193      this.ctx.miterLimit = 10;
194      this.ctx.moveTo(400, 300);
195      this.ctx.lineTo(450, 400);
196      this.ctx.lineTo(400, 450);
197      this.ctx.closePath();
198      this.ctx.stroke();
199    }
200  },
201}
202```
203
204![en-us_image_0000001232162320](figures/en-us_image_0000001232162320.gif)
205
206
207## Drawing Border
208
209Globally define the canvas (**el**) and brush (**ctx**), and create a rectangle with the border width of 5 upon initialization. Change the border width (**lineWidth**), color (**strokeStyle**), and line dash level (**setLineDash**). Add the **change** event to the **&lt;select&gt;** component. The **change** event will be triggered upon selection and the changed image will be displayed.
210
211
212
213```html
214<!-- xxx.hml -->
215<div class="container">
216  <canvas ref="canvas1"></canvas>
217  <select @change="change">
218    <option value="value1">strokeRect</option>
219    <option value="value2">arc</option>
220    <option value="value3">lineDashRect</option>
221    <option value="value4">fillRect</option>
222  </select>
223</div>
224```
225
226
227
228```css
229/* xxx.css */
230.container{
231  width: 100%;
232  height: 100%;
233  flex-direction: column;
234  justify-content: center;
235  align-items: center;
236  background-color: #F1F3F5;
237}
238canvas{
239  width: 600px;
240  height: 500px;
241  background-color: #fdfdfd;
242  border: 5px solid red;
243}
244select{
245  margin-top: 50px;
246  width: 250px;
247  height: 100px;
248  background-color: white;
249}
250```
251
252
253
254```js
255// xxx.js
256export default {
257  data:{
258    el: null,
259    ctx: null,
260  },
261  onShow(){
262    this.el = this.$refs.canvas1;
263    this.ctx = this.el.getContext("2d",{antialias: true});
264    this.ctx.lineWidth = 5;
265    this.ctx.strokeRect(200, 150, 200, 200);
266  },
267  change(e){
268    if(e.newValue == 'value1'){
269      // Clear the contents on the canvas.
270      this.ctx.clearRect(0,0,600,500);
271      // Border width
272      this.ctx.lineWidth = 5;
273      // Border color
274      this.ctx.strokeStyle = '#110000';
275      // Line dash level of the border
276      this.ctx.setLineDash([0,0]);
277      // Draw a stroked rectangle.
278      this.ctx.strokeRect(200, 150, 200, 200);
279    }else if (e.newValue == 'value2'){
280      this.ctx.clearRect(0,0,600,500);
281      this.ctx.lineWidth = 30;
282      this.ctx.strokeStyle = '#0000ff';
283      this.ctx.setLineDash([0,0]);
284      // Draw a circle.
285      this.ctx.arc(300, 250, 150,0,6.28);
286      // Draw borders.
287      this.ctx.stroke();
288    }else if (e.newValue == 'value3'){
289      this.ctx.clearRect(0,0,600,500);
290      this.ctx.lineWidth = 5;
291      this.ctx.setLineDash([5,5]);
292      this.ctx.strokeRect(200, 150, 200, 200);
293    }else if (e.newValue == 'value4'){
294      this.ctx.clearRect(0,0,600,500);
295      // Draw and fill a rectangle.
296      this.ctx.fillStyle = '#0000ff';
297      this.ctx.fillRect(200, 150, 200, 200);
298    }
299  },
300}
301```
302
303
304![en-us_image_0000001232003004](figures/en-us_image_0000001232003004.gif)
305
306
307## Setting Gradient Fill Colors
308
309Add the **createLinearGradient** and **createRadialGradient** attributes to create a gradient container, use the **addColorStop** method to add multiple color blocks to form a gradient color, and set **fillStyle** as **gradient** to apply the gradient color to a rectangle. Then set the shadow blur level by using **shadowBlur**, the shadow color by using **shadowColor**, and the shadow offset by using **shadowOffset**.
310
311
312```html
313<!-- xxx.hml -->
314<div class="container">
315  <canvas ref="canvas1"></canvas>
316  <select @change="change">
317    <option value="value1">LinearGradient</option>
318    <option value="value2">RadialGradient</option>
319    <option value="value3">shadowBlur</option>
320    <option value="value4">shadowOffset</option>
321  </select>
322</div>
323```
324
325
326```css
327/* xxx.css */
328.container{
329  width: 100%;
330  height: 100%;
331  flex-direction: column;
332  justify-content: center;
333  align-items: center;
334  background-color: #F1F3F5;
335}
336canvas{
337  width: 600px;
338  height: 500px;
339  background-color: #fdfdfd;
340  border: 5px solid red;
341}
342select{
343  margin-top: 50px;
344  width: 250px;
345  height: 100px;
346  background-color: white;
347}
348```
349
350
351```js
352// xxx.js
353export default {
354  data:{
355    el: null,
356    ctx: null,
357  },
358  onShow(){
359    this.el = this.$refs.canvas1;
360    this.ctx = this.el.getContext("2d",{antialias: true});
361    // Create a linear gradient.
362    let gradient = this.ctx.createLinearGradient(100,100, 400,300);
363    // Add gradient colors.
364    gradient.addColorStop(0.0, 'red');
365    gradient.addColorStop(0.7, 'white');
366    gradient.addColorStop(1.0, 'green');
367    // Apply the gradient.
368    this.ctx.fillStyle = gradient;
369    this.ctx.fillRect(100, 100, 400, 300);
370  },
371  change(e){
372    if(e.newValue == 'value1'){
373      // Clear the contents on the canvas.
374      this.ctx.clearRect(0,0,600,500);
375      let gradient = this.ctx.createLinearGradient(100,100, 400,300);
376      gradient.addColorStop(0.0, 'red');
377      gradient.addColorStop(0.7, 'white');
378      gradient.addColorStop(1.0, 'green');
379      this.ctx.fillStyle = gradient;
380      // Set the level of shadow blur.
381      this.ctx.shadowBlur = 0;
382      // Set the distance that shadows will be offset vertically.
383      this.ctx.shadowOffsetY = 0;
384      // Set the distance that shadows will be offset horizontally.
385      this.ctx.shadowOffsetX = 0;
386      this.ctx.fillRect(100, 100, 400, 300);
387    }else if(e.newValue == 'value2'){
388      this.ctx.clearRect(0,0,600,500);
389      // Create a radial gradient.
390      let gradient = this.ctx.createRadialGradient(300,250,20,300,250,100);
391      gradient.addColorStop(0.0, 'red');
392      gradient.addColorStop(0.7, 'white');
393      gradient.addColorStop(1.0, 'green');
394      this.ctx.shadowBlur = 0;
395      this.ctx.shadowOffsetY = 0;
396      this.ctx.shadowOffsetX = 0;
397      this.ctx.fillStyle = gradient;
398      this.ctx.fillRect(100, 100, 400, 300);
399    }else if(e.newValue == 'value3'){
400      this.ctx.clearRect(0,0,600,500);
401      let gradient = this.ctx.createLinearGradient(100,100, 400,400);
402      gradient.addColorStop(0.0, 'red');
403      gradient.addColorStop(0.5, 'white');
404      gradient.addColorStop(1, '#17ea35');
405      // Set the level of shadow blur.
406      this.ctx.shadowBlur = 30;
407      // Set the shadow color.
408      this.ctx.shadowColor = 'rgb(229, 16, 16)';
409      this.ctx.fillStyle = gradient;
410      this.ctx.fillRect(100, 100, 400, 300);
411    }else if(e.newValue == 'value4'){
412      this.ctx.clearRect(0,0,600,500);
413      this.ctx.clearRect(0,0,600,500);
414      let gradient = this.ctx.createRadialGradient(300,250,20,300,250,200);
415      gradient.addColorStop(0.0, 'red');
416      gradient.addColorStop(0.5, 'white');
417      gradient.addColorStop(1, '#17ea35');
418      // Set the level of shadow blur.
419      this.ctx.shadowBlur = 30;
420      this.ctx.shadowOffsetY = 30;
421      // Set the shadow color.
422      this.ctx.shadowColor = 'rgb(23, 1, 1)';
423      this.ctx.fillStyle = gradient;
424      this.ctx.fillRect(100, 100, 400, 300);
425    }
426  },
427}
428```
429
430![en-us_image_0000001231683148](figures/en-us_image_0000001231683148.gif)
431
432
433## Filling Texts
434
435Create a text and use the **fillText** method to write the text on the canvas. Use the **globalAlpha** attribute to change the baseline transparency to avoid the text being hidden by the baseline. Then set the **textAlign** and **textBaseline** attributes to determine the text position based on the baseline.
436
437
438```html
439<!-- xxx.hml -->
440<div class="container">
441  <canvas ref="canvas1"></canvas>
442  <select @change="change">
443    <option value="value1">text</option>
444    <option value="value2">textBaseline</option>
445    <option value="value3">textAlign</option>
446  </select>
447</div>
448```
449
450
451```css
452/* xxx.css */
453.container{
454  width: 100%;
455  height: 100%;
456  flex-direction: column;
457  justify-content: center;
458  align-items: center;
459  background-color: #F1F3F5;
460}
461canvas{
462  width: 600px;
463  height: 500px;
464  background-color: #fdfdfd;
465  border: 5px solid red;
466}
467select{
468  margin-top: 50px;
469  width: 250px;
470  height: 100px;
471  background-color: white;
472}
473```
474
475
476```js
477// xxx.js
478export default {
479  data:{
480    el: null,
481    ctx: null,
482  },
483  onShow(){
484    this.el = this.$refs.canvas1;
485    this.ctx = this.el.getContext("2d",{antialias: true});
486    // Create a text.
487    let text = "Hello World";
488    // Set the font.
489    this.ctx.font = '30px';
490    this.ctx.fillText("with:"+this.ctx.measureText(text).width, 200, 300);
491    // Set the fill text.
492    this.ctx.fillText(text, 200, 250);
493  },
494  change(e){
495    if(e.newValue == 'value1'){
496      // Clear the contents on the canvas.
497      this.ctx.clearRect(0,0,600,500);
498      // Start a new path.
499      this.ctx.beginPath();
500      // Initialize the textAlign value.
501      this.ctx.textAlign = 'left';
502      // Initialize textBaseline.
503      this.ctx.textBaseline = 'alphabetic';
504      // Set the font.
505      this.ctx.font = '30px';
506      let text = "Hello World";
507      // Obtain the font width.
508      this.ctx.fillText("with:"+this.ctx.measureText(text).width, 200, 300);
509    // Set the fill text.
510      this.ctx.fillText(text, 200, 250);
511    }else if(e.newValue == 'value2'){
512      this.ctx.clearRect(0,0,600,500);
513      this.ctx.beginPath();
514      // Set the Alpha value.
515      this.ctx.globalAlpha = 0.1;
516      // Set the line width.
517      this.ctx.lineWidth = 10;
518      // Set the line segment color.
519      this.ctx.strokeStyle = '#0000ff';
520      // Move from the current point to a target position.
521      this.ctx.moveTo(0, 240);
522      // Connect the current point to a target position.
523      this.ctx.lineTo(600, 240);
524      this.ctx.stroke();
525      this.ctx.font = '35px';
526      this.ctx.globalAlpha = 1;
527      // Initialize the textAlign value.
528      this.ctx.textAlign = 'left';
529      // Set textBaseline.
530      this.ctx.textBaseline = 'top';
531      this.ctx.fillText('Top', 50, 240);
532      this.ctx.textBaseline = 'bottom';
533      this.ctx.fillText('Bottom', 200, 240);
534      this.ctx.textBaseline = 'middle';
535      this.ctx.fillText('Middle', 400, 240);
536    }else if(e.newValue == 'value3'){
537      // Clear the contents on the canvas.
538      this.ctx.clearRect(0,0,600,500);
539      this.ctx.beginPath();
540      this.ctx.globalAlpha = 0.1;
541      this.ctx.lineWidth = 10;
542      this.ctx.strokeStyle = '#0000ff';
543      this.ctx.moveTo(300, 0);
544      this.ctx.lineTo(300, 500);
545      this.ctx.stroke();
546      this.ctx.font = '35px';
547      this.ctx.globalAlpha = 1;
548      // Initialize textBaseline.
549      this.ctx.textBaseline = 'alphabetic';
550      // Set textAlign.
551      this.ctx.textAlign = 'left';
552      this.ctx.fillText('textAlign=left',300, 100);
553      this.ctx.textAlign = 'center';
554      this.ctx.fillText('textAlign=center',300, 250);
555      this.ctx.textAlign = 'right';
556      this.ctx.fillText('textAlign=right',300, 400);
557    }
558  }
559}
560```
561
562![en-us_image_0000001276162745](figures/en-us_image_0000001276162745.gif)
563
564> **NOTE**
565>
566> In the **ltr** layout mode, the value **start** equals **left**. In the **rtl** layout mode, the value **start** equals **right**.
567
568
569## Adding Images
570
571After creating an image object, use the **drawImage** attribute to draw the image and set animation styles such as scaling, translating, and rotating.
572
573
574```html
575<!-- xxx.hml -->
576<div class="container">
577  <div class="content">
578    <canvas ref="canvas0"></canvas>
579    <text onclick="change">change</text>
580    <canvas ref="canvas1"></canvas>
581    <text onclick="rotate">rotate</text>
582    <canvas ref="canvas2"></canvas>
583    <text onclick="scale">scale</text>
584    <canvas ref="canvas3"></canvas>
585    <text onclick="translate" style="width: 300px;">translate</text>
586    <canvas ref="canvas4"></canvas>
587    <text onclick="transform" style="width: 300px;">transform</text>
588    <canvas ref="canvas5"></canvas>
589    <text onclick="setTransform" style="width: 300px;">setTransform</text>
590    <canvas ref="canvas6"></canvas>
591  </div>
592</div>
593```
594
595
596```css
597/* xxx.css */
598.container{
599  width: 100%;
600  flex-direction: column;
601  background-color: #F1F3F5;
602  align-items: center;
603}
604canvas{
605  width: 600px;
606  height: 300px;
607  margin-bottom: 100px;
608  background-color: #fdfdfd;
609  border: 5px solid red;
610}
611.content{
612  width: 80%;
613  margin-top: 50px;
614  margin-bottom: 50px;
615  display: flex;
616  flex-wrap: wrap;
617  justify-content: space-around;
618}
619text{
620  font-size: 35px;
621  width: 200px;
622  height: 80px;
623  color: white;
624  border-radius: 20px;
625  text-align: center;
626  background-color: #6060e7;
627  margin-bottom: 30px;
628}
629```
630
631
632```js
633// xxx.js
634import promptAction from '@ohos.promptAction';
635export default {
636  data:{
637    compositeOperation: 'source-over'
638  },
639  onShow(){
640    let ctx = this.$refs.canvas0.getContext("2d");
641    // Create an image object.
642    let img = new Image();
643    // Set the image path.
644    img.src = 'common/images/2.png';
645    // Set the image width.
646    img.width= 150;
647    // Set the image height.
648    img.height=150;
649    // Create an image tiling container.
650    var pat = ctx.createPattern(img, 'repeat');ctx.fillStyle = pat;
651    ctx.fillRect(0, 0, 600, 300);
652  },
653  change(){
654    // Obtain the brush after the canvas is created.
655    let ctx = this.$refs.canvas1.getContext("2d");
656    ctx.clearRect(0,0,600,1000);
657    if(this.compositeOperation == "source-over"){
658      this.compositeOperation = "destination-over";
659    }else{
660      this.compositeOperation = "source-over";
661    }
662    ctx.globalCompositeOperation = this.compositeOperation;
663    let img = new Image();
664    img.src = 'common/images/2.png';
665    // Invoked when the image is successfully obtained.
666    img.onload = function() {
667      ctx.drawImage(img, 150, 20, 200, 200);
668    };
669    let img1 = new Image();
670    img1.src = 'common/images/3.png';
671    img1.onload = function() {
672      // Draw an image.
673      ctx.drawImage(img1, 250, 80, 200, 200);
674    };
675    // A method is triggered when the image fails to be obtained.
676    img1.onerror = function() {
677      promptAction.showToast({message:"error",duration:2000})
678    };
679  },
680  rotate(){
681    let ctx = this.$refs.canvas2.getContext("2d");
682    ctx.clearRect(0,0,600,300);
683    // Rotate the image.
684    ctx.rotate(10 * Math.PI / 180);
685    let img = new Image();
686    img.src = 'common/images/2.png';
687    img.onload = function() {
688      ctx.drawImage(img, 300, 0, 100, 100);
689    };
690  },
691  scale(){
692    let ctx = this.$refs.canvas3.getContext("2d");
693    ctx.clearRect(0,0,600,200);
694    // Scale the image.
695    ctx.scale(1.3,1.2);
696    let img = new Image();
697    img.src = 'common/images/2.png';
698    img.onload = function() {
699      ctx.drawImage(img, 0, 0, 50, 50);
700    };
701  },
702  translate(){
703    let ctx = this.$refs.canvas4.getContext("2d");
704    ctx.clearRect(0,0,600,300);
705    ctx.translate(10,0);
706    let img = new Image();
707    img.src = 'common/images/2.png';
708    img.onload = function() {
709      ctx.drawImage(img, 0, 50, 300, 200);
710    };
711  },
712  transform(){
713    let ctx = this.$refs.canvas5.getContext("2d");
714    ctx.clearRect(0,0,600,300);
715    ctx.transform(1.1, 0.1, 0.1, 1, 10, 0);
716    let img = new Image();
717    img.src = 'common/images/2.png';
718    img.onload = function() {
719      ctx.drawImage(img, 0, 50, 100, 100);
720     };
721  },
722  setTransform(){
723    let ctx = this.$refs.canvas6.getContext("2d");
724    ctx.clearRect(0,0,600,300);
725    ctx.setTransform(1.1, 0.1, 0.1, 1, 10, 0);
726    let img = new Image();
727    img.src = 'common/images/2.png';
728    img.onload = function() {
729      ctx.drawImage(img, 0, 50, 100, 100);
730    };
731  },
732}
733```
734
735![en-us_image_0000001232003008](figures/en-us_image_0000001232003008.gif)
736
737> **NOTE**
738> - Unlike the **transform()** function, the **setTransform()** function resets the existing transformation matrix and creates a transformation matrix even if it uses the same parameters.
739>
740> - The following formulas calculate coordinates of the transformed graph. **x** and **y** represent coordinates before transformation, and **x'** and **y'** represent coordinates after transformation.
741>   x' = scaleX \* x + skewY \* y + translateX
742>
743>   y' = skewX \* x + scaleY \* y + translateY
744
745
746## Adding Methods
747
748Use the **save** method to save the brush style, and use the **restore** method to restore the saved settings. In the following example, set the brush to red. After the brush setting is saved, clear the canvas and change the brush to blue. In this moment, directly using the brush will get a blue rectangle; using the brush after the restore operation will get a red rectangle.
749
750
751```html
752<!-- xxx.hml -->
753<div class="container">
754  <div class="content">
755    <canvas ref="canvas"></canvas>
756  </div>
757  <div class="content">
758    <text onclick="save">save</text>
759    <text onclick="clear">clear</text>
760    <text onclick="restore">restore</text>
761  </div>
762</div>
763```
764
765
766```css
767/* xxx.css */
768.container{
769  width: 100%;
770  height: 100%;
771  flex-direction: column;
772  background-color: #F1F3F5;
773  align-items: center;
774}
775canvas{
776  margin-top: 300px;
777  width: 600px;
778  height: 500px;
779  background-color: #fdfdfd;
780  border: 5px solid red;
781}
782.content{
783  width: 80%;
784  margin-top: 50px;
785  margin-bottom: 50px;
786  display: flex;
787  flex-wrap: wrap;
788  justify-content: space-around;
789}
790text{
791  width: 150px;
792  height: 80px;
793  color: white;
794  border-radius: 20px;
795  text-align: center;
796  background-color: #6060e7;
797  margin-bottom: 30px;
798}
799```
800
801
802```js
803// xxx.js
804import promptAction from '@ohos.promptAction';
805export default {
806  data:{
807    ctx: '',
808  },
809  onShow(){
810    this.ctx = this.$refs.canvas.getContext("2d");
811    this.ctx.fillStyle = "red"
812    this.ctx.fillRect(200, 150, 200, 200);
813  },
814  save(){
815    // Save the brush setting.
816    this.ctx.save();
817    promptAction.showToast({message:"save succeed"});
818  },
819  clear(){
820    this.ctx.clearRect(0,0,600,500);
821    // Change the brush color.
822    this.ctx.fillStyle = "#2133d2";
823  },
824  restore(){
825    this.ctx.beginPath();
826    // Restore the brush setting.
827    this.ctx.restore();
828    this.ctx.fillRect(200, 150, 200, 200);
829  },
830}
831```
832
833![en-us_image_0000001231683144](figures/en-us_image_0000001231683144.gif)
834