首頁 > web前端 > H5教程 > HTML5之7 __Canvas: 縮放、旋轉、建立陰影

HTML5之7 __Canvas: 縮放、旋轉、建立陰影

黄舟
發布: 2017-02-18 14:34:18
原創
1579 人瀏覽過

一.  canvas API 的scale() 函數用於縮放. 

scale() 帶有兩個參數,分別代表在x, y 兩個維度的值, 每個參數在canvas 顯示圖像的時候, 向其傳遞在本方向軸上影像要放大(或縮小) 的量, 如果x為2,  就代表所繪製影像中全部元素都會變成兩倍寬, 如果y 值為0.5 ,繪製出來的影像全部元素都會變成之前的一半高。

例如以下程序很方便地在canvas 上創建出新的樹.


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

<!DOCTYPE html>

<html>

<meta charset="UTF-8">

  <title>缩放示例</title>

  <canvas id="trails" style="border: 1px solid;"  width="400" height="600"> </canvas>

  <script>

        var gravel = new Image();

        gravel.src = "gravel.jpg";

        gravel.onload = function () {

            drawTrails();

        }

 

        function createCanopyPath(context) {

            context.beginPath();

            context.moveTo(-25, -50);

            context.lineTo(-10, -80);

            context.lineTo(-20, -80);

            context.lineTo(-5, -110);

            context.lineTo(-15, -110);

 

            context.lineTo(0, -140);

            context.lineTo(15, -110);

            context.lineTo(5, -110);

            context.lineTo(20, -80);

            context.lineTo(10, -80);

            context.lineTo(25, -50);

            context.closePath();

        }

 

        // 将绘制树的方法 放到 drawTree(),方便重用

        function drawTree(context) {

            var trunkGradient = context.createLinearGradient(-5, -50, 5, -50);

            trunkGradient.addColorStop(0, &#39;#663300&#39;);

            trunkGradient.addColorStop(0.4, &#39;#996600&#39;);

            trunkGradient.addColorStop(1, &#39;#552200&#39;);

            context.fillStyle = trunkGradient;

            context.fillRect(-5, -50, 10, 50);

 

            var canopyShadow = context.createLinearGradient(0, -50, 0, 0);

            canopyShadow.addColorStop(0, &#39;rgba(0, 0, 0, 0.5)&#39;);

            canopyShadow.addColorStop(0.2, &#39;rgba(0, 0, 0, 0.0)&#39;);

            context.fillStyle = canopyShadow;

            context.fillRect(-5, -50, 10, 50);

 

            createCanopyPath(context);

 

            context.lineWidth = 4;

            context.lineJoin = &#39;round&#39;;

            context.strokeStyle = &#39;#663300&#39;;

            context.stroke();

 

            context.fillStyle = &#39;#339900&#39;;

            context.fill();

        }

 

        function drawTrails() {

            var canvas = document.getElementById(&#39;trails&#39;);

            var context = canvas.getContext(&#39;2d&#39;);

            // 在 X=130, Y=250的位置绘制第一棵树

            context.save();

            context.translate(130, 250);

            drawTree(context);

            context.restore();

            // 在 X=260, Y=500 位置绘制第二棵树

            context.save();

            context.translate(260, 500);

 

            // 将第二棵树的宽高分别放大至原来的2倍

            context.scale(2, 2);

            drawTree(context);

            context.restore();

 

            context.save();

            context.translate(-10, 350);

            context.beginPath();

            context.moveTo(0, 0);

            context.quadraticCurveTo(170, -50, 260, -190);

            context.quadraticCurveTo(310, -250, 410,-250);

            context.strokeStyle = context.createPattern(gravel, &#39;repeat&#39;);

            context.lineWidth = 20;

            context.stroke();

            context.restore();

        }

  </script>

</html>

登入後複製


 二.  旋轉context.rotate(angle),    參數angle 以弧度為單位

看程式碼 


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

<!DOCTYPE html>

<html>

<meta charset="UTF-8">

  <title>旋转示例</title>

  <canvas id="trails" style="border: 1px solid;"  width="400" height="600"> </canvas>

  <script>

        var gravel = new Image();

        gravel.src = "gravel.jpg";

        gravel.onload = function () {

            drawTrails();

        }

 

        function createCanopyPath(context) {

            context.beginPath();

            context.moveTo(-25, -50);

            context.lineTo(-10, -80);

            context.lineTo(-20, -80);

            context.lineTo(-5, -110);

            context.lineTo(-15, -110);

 

            context.lineTo(0, -140);

 

            context.lineTo(15, -110);

            context.lineTo(5, -110);

            context.lineTo(20, -80);

            context.lineTo(10, -80);

            context.lineTo(25, -50);

            context.closePath();

        }

 

        // 将绘制树的方法 放到 drawTree()

        function drawTree(context) {

            var trunkGradient = context.createLinearGradient(-5, -50, 5, -50);

            trunkGradient.addColorStop(0, &#39;#663300&#39;);

            trunkGradient.addColorStop(0.4, &#39;#996600&#39;);

            trunkGradient.addColorStop(1, &#39;#552200&#39;);

            context.fillStyle = trunkGradient;

            context.fillRect(-5, -50, 10, 50);

 

            var canopyShadow = context.createLinearGradient(0, -50, 0, 0);

            canopyShadow.addColorStop(0, &#39;rgba(0, 0, 0, 0.5)&#39;);

            canopyShadow.addColorStop(0.2, &#39;rgba(0, 0, 0, 0.0)&#39;);

            context.fillStyle = canopyShadow;

            context.fillRect(-5, -50, 10, 50);

 

            createCanopyPath(context);

 

            context.lineWidth = 4;

            context.lineJoin = &#39;round&#39;;

            context.strokeStyle = &#39;#663300&#39;;

            context.stroke();

 

            context.fillStyle = &#39;#339900&#39;;

            context.fill();

        }

 

        function drawTrails() {

            var canvas = document.getElementById(&#39;trails&#39;);

            var context = canvas.getContext(&#39;2d&#39;);

            // 在 X=130, Y=250的位置绘制第一棵树

            context.save();

            context.translate(100, 150);

            context.rotate(1.57);    //旋转角度以弧度为单位

            drawTree(context);

            context.restore();

 

            context.save();

            context.translate(-10, 450);

            context.beginPath();

            context.moveTo(0, 0);

            context.quadraticCurveTo(170, -50, 260, -190);

            context.quadraticCurveTo(310, -250, 410,-250);

            context.strokeStyle = context.createPattern(gravel, &#39;repeat&#39;);

            context.lineWidth = 20;

            context.stroke();

            context.restore();

        }

 

  </script>

</html>

登入後複製


以上兩個範例,需注意之處:

           總是在原點執行圖形和路徑的變換操作             範例中示範了為什麼要在原點執行圖形和路徑的變換操作, 執行完後再統一平移. 因為縮放scale 和旋轉rotate 等變換操作都是針對原點進行的.
如果對一個不在原點的圖形進行旋轉, 那麼圖形繞著原點旋轉而不是在原地旋轉。 類似地,如果進行縮放操作時沒有將圖形放置到適當的座標上,那麼所有座標都會被同時縮放,  新的座標可能會超出canvas 範圍。

三。 相關代碼:

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

<!DOCTYPE html>

<html>

<meta charset="UTF-8">

  <title>变换阴影</title>

  <canvas id="trails" style="border: 1px solid;"  width="400" height="600"> </canvas>

  <script>

        var gravel = new Image();

        gravel.src = "gravel.jpg";

        gravel.onload = function () {

            drawTrails();

        }

 

        function createCanopyPath(context) {

            context.beginPath();

            context.moveTo(-25, -50);

            context.lineTo(-10, -80);

            context.lineTo(-20, -80);

            context.lineTo(-5, -110);

            context.lineTo(-15, -110);

 

            context.lineTo(0, -140);

            context.lineTo(15, -110);

            context.lineTo(5, -110);

            context.lineTo(20, -80);

            context.lineTo(10, -80);

            context.lineTo(25, -50);

            context.closePath();

        }

 

        function drawTree(context) {

            context.save();

            // X值随着Y值的增加而增加,借助拉伸变换,可以创建一棵用作阴影的倾斜的树,应用了

            // 变换以后,所有坐标都与矩阵相乘

            context.transform(1, 0, -0.5, 1,  0, 0);

 

            // 在Y轴方向,将阴影的高度压缩为原来的60%

            context.scale(1, 0.6);

 

            // 使用透明度为20%的黑色填充树干

            context.fillStyle = &#39;rgba(0, 0, 0, 0.2)&#39;;

            context.fillRect(-5, -50, 10, 50);

 

            // 使用已有的阴影效果重新绘制

            createCanopyPath(context);

            context.fill();

            context.restore();

 

            var trunkGradient = context.createLinearGradient(-5, -50, 5, -50);

            trunkGradient.addColorStop(0, &#39;#663300&#39;);

            trunkGradient.addColorStop(0.4, &#39;#996600&#39;);

            trunkGradient.addColorStop(1, &#39;#552200&#39;);

            context.fillStyle = trunkGradient;

            context.fillRect(-5, -50, 10, 50);

 

            var canopyShadow = context.createLinearGradient(0, -50, 0, 0);

            canopyShadow.addColorStop(0, &#39;rgba(0, 0, 0, 0.5)&#39;);

            canopyShadow.addColorStop(0.2, &#39;rgba(0, 0, 0, 0.0)&#39;);

            context.fillStyle = canopyShadow;

            context.fillRect(-5, -50, 10, 50);

 

            createCanopyPath(context);

 

            context.lineWidth = 4;

            context.lineJoin = &#39;round&#39;;

            context.strokeStyle = &#39;#663300&#39;;

            context.stroke();

 

            context.fillStyle = &#39;#339900&#39;;

            context.fill();

        }

        function drawTrails() {

            var canvas = document.getElementById(&#39;trails&#39;);

            var context = canvas.getContext(&#39;2d&#39;);

            context.save();

            context.translate(130, 250);

            drawTree(context);

            context.restore();

 

            context.save();

            context.translate(260, 500);

            context.scale(2, 2);

            drawTree(context);

            context.restore();

 

            context.save();

            context.translate(-10, 350);

            context.beginPath();

            context.moveTo(0, 0);

            context.quadraticCurveTo(170, -50, 260, -190);

            context.quadraticCurveTo(310, -250, 410,-250);

            context.strokeStyle = context.createPattern(gravel, &#39;repeat&#39;);

            context.lineWidth = 20;

            context.stroke();

            context.restore();

        }

  </script>

</html>

登入後複製

分析這種變換背後的數學意義, 可以看出透過調整與Y軸值相對應的參數改變了X軸的值, 這樣做是為了拉伸出一查灰色的樹做陰影。 接下來, 我們按照60% 的比例將剪裁出的樹縮小到了合適的尺寸。


      剪裁過的 「陰影」 樹會先被顯示出來, 這樣一來, 真正的樹就會按照Z軸(canvas 中物件的重疊順序) 顯示在陰影的上面。 此外樹影的填充用到了CSS 的RGBA特性, 透過特性我們將透明度值設為正常情況下的20%,  至此,帶有半透明效果的樹影就做好了。

範例中用到圖片 gravel.jpg  在之前部落格文章可找到.

陰影、創造詞請關注PHP中文網(www.php.cn)!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板