aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/mozilla/add-ons/code_snippets/canvas/index.html
blob: 002a1b86000c64c4a1070cac5738a81be012d81d (plain)
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
---
title: Canvas 代码片段
slug: Mozilla/Add-ons/Code_snippets/Canvas
translation_of: Archive/Add-ons/Code_snippets/Canvas
---
<p><span style="color: #000000; display: inline !important; float: none; font-family: Cantarell; font-size: 14.666666984558105px; font-style: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal;">{{LegacyAddonsNotice}}</span></p>

<p>关于使用<code>&lt;canvas&gt;</code>的一般信息,请参阅 <a class="internal" href="/en-US/docs/Web/API/Canvas_API" title="En/HTML/Canvas">canvas topic page</a>.</p>

<h2 id="网页中可以用到的代码">网页中可以用到的代码</h2>

<h3 id="在画布中获取特定颜色的像素数量">在画布中获取特定颜色的像素数量</h3>

<p>下面的函数将返回画布上颜色(RGB格式)为r、g、b的像素数量。如果用户希望像<a href="https://hacks.mozilla.org/2013/06/building-a-simple-paint-game-with-html5-canvas-and-vanilla-javascript/" title="https://hacks.mozilla.org/2013/06/building-a-simple-paint-game-with-html5-canvas-and-vanilla-javascript/">这篇博客文章</a>中在另一个区域绘画,那么这将非常有用。 </p>

<pre class="brush: js">function getpixelamount(canvas, r, g, b) {
  var cx = canvas.getContext('2d');
  var pixels = cx.getImageData(0, 0, canvas.width, canvas.height);
  var all = pixels.data.length;
  var amount = 0;
  for (i = 0; i &lt; all; i += 4) {
    if (pixels.data[i] === r &amp;&amp;
        pixels.data[i + 1] === g &amp;&amp;
        pixels.data[i + 2] === b) {
      amount++;
    }
  }
  return amount;
};
</pre>

<h3 id="在画布中获取某一个像素的颜色">在画布中获取某一个像素的颜色</h3>

<p>下面的代码片段返回一个对象,该对象在画布的x和y的位置上具有RGBA值。这可以用来确定鼠标光标是否在一个特定的形状中。</p>

<pre class="brush: js">function getpixelcolour(canvas, x, y) {
  var cx = canvas.getContext('2d');
  var pixel = cx.getImageData(x, y, 1, 1);
  return {
    r: pixel.data[0],
    g: pixel.data[1],
    b: pixel.data[2],
    a: pixel.data[3]
  };
}
</pre>

<h3 id="链式调用方法">链式调用方法</h3>

<p>这个类允许可以像jQuery那样链式地访问 2D 渲染上下文的方法和属性 。</p>

<pre class="brush: js">function Canvas2DContext(canvas) {
  if (typeof canvas === 'string') {
    canvas = document.getElementById(canvas);
  }
  if (!(this instanceof Canvas2DContext)) {
    return new Canvas2DContext(canvas);
  }
  this.context = this.ctx = canvas.getContext('2d');
  if (!Canvas2DContext.prototype.arc) {
    Canvas2DContext.setup.call(this, this.ctx);
  }
}
Canvas2DContext.setup = function() {
  var methods = ['arc', 'arcTo', 'beginPath', 'bezierCurveTo', 'clearRect', 'clip',
    'closePath', 'drawImage', 'fill', 'fillRect', 'fillText', 'lineTo', 'moveTo',
    'quadraticCurveTo', 'rect', 'restore', 'rotate', 'save', 'scale', 'setTransform',
    'stroke', 'strokeRect', 'strokeText', 'transform', 'translate'];

  var getterMethods = ['createPattern', 'drawFocusRing', 'isPointInPath', 'measureText', // drawFocusRing not currently supported
    // The following might instead be wrapped to be able to chain their child objects
    'createImageData', 'createLinearGradient',
    'createRadialGradient', 'getImageData', 'putImageData'
  ];

  var props = ['canvas', 'fillStyle', 'font', 'globalAlpha', 'globalCompositeOperation',
    'lineCap', 'lineJoin', 'lineWidth', 'miterLimit', 'shadowOffsetX', 'shadowOffsetY',
    'shadowBlur', 'shadowColor', 'strokeStyle', 'textAlign', 'textBaseline'];

  for (let m of methods) {
    let method = m;
    Canvas2DContext.prototype[method] = function() {
      this.ctx[method].apply(this.ctx, arguments);
      return this;
    };
  }

  for (let m of getterMethods) {
    let method = m;
    Canvas2DContext.prototype[method] = function() {
      return this.ctx[method].apply(this.ctx, arguments);
    };
  }

  for (let p of props) {
    let prop = p;
    Canvas2DContext.prototype[prop] = function(value) {
      if (value === undefined)
        return this.ctx[prop];
      this.ctx[prop] = value;
      return this;
    };
  }
};

var canvas = document.getElementById('canvas');

// Use context to get access to underlying context
var ctx = Canvas2DContext(canvas)
  .strokeStyle('rgb(30, 110, 210)')
  .transform(10, 3, 4, 5, 1, 0)
  .strokeRect(2, 10, 15, 20)
  .context;

// Use property name as a function (but without arguments) to get the value
var strokeStyle = Canvas2DContext(canvas)
  .strokeStyle('rgb(50, 110, 210)')
  .strokeStyle();
</pre>

<h2 id="Saving_a_canvas_image_to_a_file" name="Saving_a_canvas_image_to_a_file">Code usable only from privileged code</h2>

<p>These snippets are only useful from privileged code, such as extensions or privileged apps.</p>

<h3 id="Saving_a_canvas_image_to_a_file" name="Saving_a_canvas_image_to_a_file">将canvas图片保存到文件中</h3>

<p>The following function accepts a canvas object and a destination file path string. The canvas is converted to a PNG file and saved to the specified location. The function returns a promise which resolves when the file has been completely saved.</p>

<pre class="brush: js">function saveCanvas(canvas, path, type, options) {
    return Task.spawn(function *() {
        var reader = new FileReader;
        var blob = yield new Promise(accept =&gt; canvas.toBlob(accept, type, options));
        reader.readAsArrayBuffer(blob);

        yield new Promise(accept =&gt; { reader.onloadend = accept });

        return yield OS.File.writeAtomic(path, new Uint8Array(reader.result),
                                         { tmpPath: path + '.tmp' });
    });
}
</pre>

<h3 id="Loading_a_remote_page_onto_a_canvas_element" name="Loading_a_remote_page_onto_a_canvas_element">将一个远程页面加载到canvas元素上</h3>

<p>The following class first creates a hidden iframe element and attaches a listener to the frame's load event. Once the remote page has loaded, the remotePageLoaded method fires. This method gets a reference to the iframe's window and draws this window to a canvas object.</p>

<p>Note that this only works if you are running the page from chrome. If you try running the code as a plain webpage, you will get a 'Security error" code: "1000' error.</p>

<pre class="brush: js">RemoteCanvas = function() {
    this.url = 'http://developer.mozilla.org';
};

RemoteCanvas.CANVAS_WIDTH = 300;
RemoteCanvas.CANVAS_HEIGHT = 300;

RemoteCanvas.prototype.load = function() {
    var windowWidth = window.innerWidth - 25;
    var iframe;
    iframe = document.createElement('iframe');
    iframe.id = 'test-iframe';
    iframe.height = '10px';
    iframe.width = windowWidth + 'px';
    iframe.style.visibility = 'hidden';
    iframe.src = this.url;
    // Here is where the magic happens... add a listener to the
    // frame's onload event
    iframe.addEventListener('load', this.remotePageLoaded, true);
    //append to the end of the page
    window.document.body.appendChild(iframe);
    return;
};

RemoteCanvas.prototype.remotePageLoaded = function() {
    // Look back up the iframe by id
    var ldrFrame = document.getElementById('test-iframe');
    // Get a reference to the window object you need for the canvas
    // drawWindow method
    var remoteWindow = ldrFrame.contentWindow;

    //Draw canvas
    var canvas = document.createElement('canvas');
    canvas.style.width = RemoteCanvas.CANVAS_WIDTH + 'px';
    canvas.style.height = RemoteCanvas.CANVAS_HEIGHT + 'px';
    canvas.width = RemoteCanvas.CANVAS_WIDTH;
    canvas.height = RemoteCanvas.CANVAS_HEIGHT;
    var windowWidth = window.innerWidth - 25;
    var windowHeight = window.innerHeight;

    var ctx = canvas.getContext('2d');
    ctx.clearRect(0, 0,
                  RemoteCanvas.CANVAS_WIDTH,
                  RemoteCanvas.CANVAS_HEIGHT);
    ctx.save();
    ctx.scale(RemoteCanvas.CANVAS_WIDTH / windowWidth,
              RemoteCanvas.CANVAS_HEIGHT / windowHeight);
    ctx.drawWindow(remoteWindow,
                   0, 0,
                   windowWidth, windowHeight,
                   'rgb(255, 255, 255)');
    ctx.restore();
};
</pre>

<p>Usage:</p>

<pre class="brush: js">var remoteCanvas = new RemoteCanvas();
remoteCanvas.load();
</pre>

<h3 id="Loading_a_remote_page_onto_a_canvas_element" name="Loading_a_remote_page_onto_a_canvas_element">将图像文件转换为base64字符串</h3>

<p>下面代码加载远程图片,并把它的内容转化为 <code><a href="/en/data_URIs">Data URI scheme</a></code></p>

<pre class="brush: js">var canvas = document.createElement('canvas');
var ctxt = canvas.getContext('2d');
function loadImageFile(url, callback) {
  var image = new Image();
  image.src = url;
  return new Promise((accept, reject) =&gt; {
    image.onload = accept;
    image.onerror = reject;
  }).then(accept =&gt; {
    canvas.width = this.width;
    canvas.height = this.height;
    ctxt.clearRect(0, 0, this.width, this.height);
    ctxt.drawImage(this, 0, 0);
    accept(canvas.toDataURL());
  });
}
</pre>

<p>Usage:</p>

<pre class="brush: js">loadImageFile('myimage.jpg').then(string64 =&gt; { alert(string64); });
</pre>

<p>如果你想获取本地文件(使用文件选择input元素)的 base64 内容,你必须使用 <code><a href="/en/DOM/FileReader#readAsDataURL%28%29" title="en/DOM/FileReader#readAsDataURL%28%29">FileReader</a></code> 对象。</p>