An important feature of this demand comes from the H5 technology research project: to achieve 微信长按网页保存为截图
.
Here is a chestnut (Open with a micro-channel, long press on the image to save): 3 minutes to explore the boundaries of your knowledge
Save the whole web page as a picture is a very interesting feature, common in active page H5 end of a page to share. The following is a summary of some of the research projects and stepped pit and summary.
First, realize save the HTML page as image
1.1 Known viable options
Existing known to achieve save the page as a picture of the program include:
- Scenario 1 : The DOM rewritten as canvas, and then use the canvas toDataURL way to achieve the output DOM containing picture shows
data URI
- Scenario 2 : Using
html2canvas.js
achieve (with optionalCanvas2Image.js
realized save the page as a picture) - Scenario 3 : Using
rasterizeHTML.js
achieve
Select 1.2 solutions
-
Scheme 1 : DOM manual calculations for each element
Computed Style
, and element attributes need to calculate the size of the canvas and the like in position.方案1难点
:- Equivalent to completely rewrite the entire page layout styles, increasing the workload.
- Because the canvas is no object concept, elements for rich, complex page layout, easy to reconstruction
- All rewrite the DOM element into the canvas will be some difficulties, such as: difficult to support a responsive, poor clarity of picture elements and text recognition problems hit area.
- Scenario 2 : This class function on Github stars at most (still maintained), Stack Overflow also rich discussion. Simply call html2canvas method and set the configuration items.
- Option 3 : limit the program's more, currently only supports three types of target format can be converted to canvas: page url, html string and document objects.
小结
: Html2canvas is realized to save the page as a picture of the feature combining best choice.
1.3 html2canvas to use
官方GitHub:https://github.com/niklasvh/h...
The following description is for html2canvas version0.5.0-beta4
1.3.1 The first step to achieve saved as a picture: html into canvas
Based on html2canvas.js
one element can be rendered as canvas, simply call html2canvas(element[, options]);
can be. The following html2canvas
method returns a containing <canvas>
elements promise
:
html2canvas(document.body).then(function(canvas) {
document.body.appendChild(canvas);
});
1.3.2 The second step to achieve saved as a picture: canvas transfer image
Previous resulting canvas is the target element contains <canvas>
an element object. Achievement of objectives only need to save the image canvas transfer image can be.
Here's conversion program has 2种
:
- Scheme 1 : Native canvas based
toDataURL
method canvas outputdata: URI
type image address, then the address is assigned to the image<image>
src attribute element to
- Scenario 2 : Using third-party libraries
Canvas2Image.js
, call itsconvertToImage
methods can be ( GitHub )
In fact, Canvas2Image.js
also based on canvas.toDataURL
the package, compared to the native canvas API into the picture for the function to consider more specific (uncompressed package size is 7.4KB), suitable for project use.
Second, to achieve optimization of HD screenshots
2.1 basis of clear shots optimization
The final picture clarity
取决于
the first step in converting into html canvas clarity.
Existing solutions by reference;
- html5 canvas blurred approach under a powerful screen
- html5 canvas draw a blurry picture of the problem
Its basic principle is:
the canvas
attributes width
and height
attribute enlarged 2 times (or setting devicePixelRatio
times), and finally the canvas width and height of the CSS style is set to 1 times the original size.
For example : html desirable actually displayed in <canvas>
width and height, respectively 160px
, 90px
can be set up as follows
<canvas width="320" height="180" style="width:160px;height:90px;"></canvas>
Particular reference to the above documents use case are as follows;
convert2canvas() {
var shareContent = YourTargetElem;
var width = shareContent.offsetWidth;
var height = shareContent.offsetHeight;
var canvas = document.createElement("canvas");
var scale = 2;
canvas.width = width * scale;
canvas.height = height * scale;
canvas.getContext("2d").scale(scale, scale);
var opts = {
scale: scale,
canvas: canvas,
logging: true,
width: width,
height: height
};
html2canvas(shareContent, opts).then(function (canvas) {
var context = canvas.getContext('2d');
var img = Canvas2Image.convertToImage(canvas, canvas.width, canvas.height);
document.body.appendChild(img);
$(img).css({
"width": canvas.width / 2 + "px",
"height": canvas.height / 2 + "px",
})
});
}
Screenshot clear advanced optimization 2.2
These settings can usually solve the problem screenshots effect is not clear, but exploration is far from over.
The actual in our project, even if made 2.1节
after the set, fuzzy rendering results into large fruit is still to clear fantasy hit zero.
Below given directly to three further optimization strategy:
- Change
百分比布局
topx布局
(if the original layout is the percentage of words) -
关闭
canvas default抗锯齿设
setting - Fuzzy set of elements
width
andheight
as the material of the original width and height, and then bytransform: scale
scaling. Herescale
the value is determined by the specific needs.
Fundamental
- If the original use of the percentage of the element's width and height, change to
px为单位
the width and height, to avoid blur caused styles secondary computing - By default, canvas anti-aliasing is turned on, the need
关闭抗锯齿
to achieve sharpen the image of ( the MDN: imageSmoothingEnabled ) - In addition canvas can be increased by enlarging the resolution twice the width and height is then scaled to the original width and height, the DOM for other elements may be used
css样式
toscale
achieve the same scaling
Example: html2canvas Configuration
convert2canvas() {
var cntElem = $('#j-sec-end')[0];
var shareContent = cntElem;//需要截图的包裹的(原生的)DOM 对象
var width = shareContent.offsetWidth; //获取dom 宽度
var height = shareContent.offsetHeight; //获取dom 高度
var canvas = document.createElement("canvas"); //创建一个canvas节点
var scale = 2; //定义任意放大倍数 支持小数
canvas.width = width * scale; //定义canvas 宽度 * 缩放
canvas.height = height * scale; //定义canvas高度 *缩放
canvas.getContext("2d").scale(scale, scale); //获取context,设置scale
var opts = {
scale: scale, // 添加的scale 参数
canvas: canvas, //自定义 canvas
// logging: true, //日志开关,便于查看html2canvas的内部执行流程
width: width, //dom 原始宽度
height: height,
useCORS: true
};
html2canvas(shareContent, opts).then(function (canvas) {
var context = canvas.getContext('2d');
context.mozImageSmoothingEnabled = false;
context.webkitImageSmoothingEnabled = false;
context.msImageSmoothingEnabled = false;
context.imageSmoothingEnabled = false;
var img = Canvas2Image.convertToJPEG(canvas, canvas.width, canvas.height);
document.body.appendChild(img);
$(img).css({
"width": canvas.width / 2 + "px",
"height": canvas.height / 2 + "px",
// 'border': '10px solid #000'
}).addClass('f-full');
$('#j-sec-end').remove();
});
}
Example: DOM element style:
.targetElem {width: 54px;height: 142px;margin-top:2px;margin-left:17px;transform: scale(0.5)}
<! - ## 2.3 Comparative optimization results
(mac the screenshot can be compared) ->
Third, the cross-domain configuration contains pictures
As the canvas for a picture of resources 同源限制
, picture resources if the canvas contains cross-domain will pollute the canvas, causing confusion generated picture style or method does html2canvas and other issues.
Mainly to solve the following picture of cross-domain resource categories include: CORS has been configured through the CDN
images and resources in the 微信用户头像
picture resources.
3.1 For a picture of the CDN configuration
- CDN configuration requirements of a good picture
CORS
.CDN
Once configured, can be seen by the response header should contain chrome developer toolsAccess-Control-Allow-Origin
fields. - Open
html2canvas
theuseCORS
configuration items . That is set up as follows:
useCORS: true
}
html2canvas(element, options);
注意
:
If you do not open html2canvas
the useCORS
configuration items, html2canvas
executes properly and does not complain, but will not output the corresponding CDN picture
(ie on the same page, can be tested simultaneously contain CDN的图片
and 本地图片
page resources, but only 本地图片
to be properly rendered)
3.2 micro-channel configuration for user avatar
If you need a 微信
platform user avatar kept together as a picture, 3.1
the program can do. Can be configured 代理转发
to achieve, not be repeated here.
Other Considerations
Occlusion (1) margin of
Micro-channel, the call up 长按保存图片
the menu requires the object is directly press <image>
element, if <image>
present above the shutter element will not call up the menu.
In fact, not just non-blocking caused <image>
elements may also be a margin
property. For example: if the bottom of the page, the elements of an absolute positioning set value greatly margin-top
, the margin-top
area in question, were unable to call up the menu press. Solution: margin-top
use as top
can be.
(2) Andrews version micro letter failed to save the image problem
canvas2img
The default format to save the image png
, and in the Andrews version micro letter can be generated pictures Despite press evocative menu to save the image, but can not be saved correctly to a local album . 解决方案
: Set canvas2img
generation picture format for configuration items jpeg
can be.
(3) JPEG black screen problem
Set the canvas2img
output format jpeg
, there is a chance to cause the resulting image contains a large amount of a black block. 可能的解决方案
: Reducing the size of the picture element size and the volume of the background image.
(4) dynamic efficiency can not be retained
In the picture 转化前
, you must 停止
post or delete dynamic efficiency in order to correctly render the picture, otherwise the resulting picture is broken.