Commit d23b5664 by mamingqun

添加html2canvas生成图片的示例

parent a178f4cf
...@@ -10,7 +10,9 @@ ...@@ -10,7 +10,9 @@
}, },
"dependencies": { "dependencies": {
"axios": "^0.19.0", "axios": "^0.19.0",
"canvas2image": "^1.0.5",
"core-js": "^2.6.5", "core-js": "^2.6.5",
"html2canvas": "^1.0.0-rc.5",
"jquery": "^3.4.1", "jquery": "^3.4.1",
"mint-ui": "^2.2.13", "mint-ui": "^2.2.13",
"vue": "^2.6.10", "vue": "^2.6.10",
......
<template> <template>
<div id="app"> <div id="app">
<div id="nav"> <!-- <div id="nav">
<router-link to="/">Home</router-link>| <router-link to="/">Home</router-link>|
<router-link to="/index">index</router-link>| <router-link to="/index">index</router-link>|
<router-link to="/loading">loading</router-link>| <router-link to="/loading">loading</router-link>|
<router-link to="/user">user</router-link> <router-link to="/user">user</router-link>
</div> </div> -->
<keep-alive> <keep-alive>
<router-view /> <router-view />
</keep-alive> </keep-alive>
......
/**
* covert canvas to image
* and save the image file
*/
var Canvas2Image = function () {
// check if support sth.
var $support = function () {
var canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d');
return {
canvas: !!ctx,
imageData: !!ctx.getImageData,
dataURL: !!canvas.toDataURL,
btoa: !!window.btoa
};
}();
var downloadMime = 'image/octet-stream';
function scaleCanvas (canvas, width, height) {
var w = canvas.width,
h = canvas.height;
if (width == undefined) {
width = w;
}
if (height == undefined) {
height = h;
}
var retCanvas = document.createElement('canvas');
var retCtx = retCanvas.getContext('2d');
retCanvas.width = width;
retCanvas.height = height;
retCtx.drawImage(canvas, 0, 0, w, h, 0, 0, width, height);
return retCanvas;
}
function getDataURL (canvas, type, width, height) {
canvas = scaleCanvas(canvas, width, height);
return canvas.toDataURL(type);
}
function saveFile (strData) {
document.location.href = strData;
}
function genImage(strData) {
var img = document.createElement('img');
img.src = strData;
return img;
}
function fixType (type) {
type = type.toLowerCase().replace(/jpg/i, 'jpeg');
var r = type.match(/png|jpeg|bmp|gif/)[0];
return 'image/' + r;
}
function encodeData (data) {
if (!window.btoa) { throw 'btoa undefined' }
var str = '';
if (typeof data == 'string') {
str = data;
} else {
for (var i = 0; i < data.length; i ++) {
str += String.fromCharCode(data[i]);
}
}
return btoa(str);
}
function getImageData (canvas) {
var w = canvas.width,
h = canvas.height;
return canvas.getContext('2d').getImageData(0, 0, w, h);
}
function makeURI (strData, type) {
return 'data:' + type + ';base64,' + strData;
}
/**
* create bitmap image
* 按照规则生成图片响应头和响应体
*/
var genBitmapImage = function (oData) {
//
// BITMAPFILEHEADER: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx
// BITMAPINFOHEADER: http://msdn.microsoft.com/en-us/library/dd183376.aspx
//
var biWidth = oData.width;
var biHeight = oData.height;
var biSizeImage = biWidth * biHeight * 3;
var bfSize = biSizeImage + 54; // total header size = 54 bytes
//
// typedef struct tagBITMAPFILEHEADER {
// WORD bfType;
// DWORD bfSize;
// WORD bfReserved1;
// WORD bfReserved2;
// DWORD bfOffBits;
// } BITMAPFILEHEADER;
//
var BITMAPFILEHEADER = [
// WORD bfType -- The file type signature; must be "BM"
0x42, 0x4D,
// DWORD bfSize -- The size, in bytes, of the bitmap file
bfSize & 0xff, bfSize >> 8 & 0xff, bfSize >> 16 & 0xff, bfSize >> 24 & 0xff,
// WORD bfReserved1 -- Reserved; must be zero
0, 0,
// WORD bfReserved2 -- Reserved; must be zero
0, 0,
// DWORD bfOffBits -- The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.
54, 0, 0, 0
];
//
// typedef struct tagBITMAPINFOHEADER {
// DWORD biSize;
// LONG biWidth;
// LONG biHeight;
// WORD biPlanes;
// WORD biBitCount;
// DWORD biCompression;
// DWORD biSizeImage;
// LONG biXPelsPerMeter;
// LONG biYPelsPerMeter;
// DWORD biClrUsed;
// DWORD biClrImportant;
// } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
//
var BITMAPINFOHEADER = [
// DWORD biSize -- The number of bytes required by the structure
40, 0, 0, 0,
// LONG biWidth -- The width of the bitmap, in pixels
biWidth & 0xff, biWidth >> 8 & 0xff, biWidth >> 16 & 0xff, biWidth >> 24 & 0xff,
// LONG biHeight -- The height of the bitmap, in pixels
biHeight & 0xff, biHeight >> 8 & 0xff, biHeight >> 16 & 0xff, biHeight >> 24 & 0xff,
// WORD biPlanes -- The number of planes for the target device. This value must be set to 1
1, 0,
// WORD biBitCount -- The number of bits-per-pixel, 24 bits-per-pixel -- the bitmap
// has a maximum of 2^24 colors (16777216, Truecolor)
24, 0,
// DWORD biCompression -- The type of compression, BI_RGB (code 0) -- uncompressed
0, 0, 0, 0,
// DWORD biSizeImage -- The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps
biSizeImage & 0xff, biSizeImage >> 8 & 0xff, biSizeImage >> 16 & 0xff, biSizeImage >> 24 & 0xff,
// LONG biXPelsPerMeter, unused
0,0,0,0,
// LONG biYPelsPerMeter, unused
0,0,0,0,
// DWORD biClrUsed, the number of color indexes of palette, unused
0,0,0,0,
// DWORD biClrImportant, unused
0,0,0,0
];
var iPadding = (4 - ((biWidth * 3) % 4)) % 4;
var aImgData = oData.data;
var strPixelData = '';
var biWidth4 = biWidth<<2;
var y = biHeight;
var fromCharCode = String.fromCharCode;
do {
var iOffsetY = biWidth4*(y-1);
var strPixelRow = '';
for (var x = 0; x < biWidth; x++) {
var iOffsetX = x<<2;
strPixelRow += fromCharCode(aImgData[iOffsetY+iOffsetX+2]) +
fromCharCode(aImgData[iOffsetY+iOffsetX+1]) +
fromCharCode(aImgData[iOffsetY+iOffsetX]);
}
for (var c = 0; c < iPadding; c++) {
strPixelRow += String.fromCharCode(0);
}
strPixelData += strPixelRow;
} while (--y);
var strEncoded = encodeData(BITMAPFILEHEADER.concat(BITMAPINFOHEADER)) + encodeData(strPixelData);
return strEncoded;
};
/**
* saveAsImage
* @param canvasElement
* @param {String} image type
* @param {Number} [optional] png width
* @param {Number} [optional] png height
*/
var saveAsImage = function (canvas, width, height, type) {
if ($support.canvas && $support.dataURL) {
if (typeof canvas == "string") { canvas = document.getElementById(canvas); }
if (type == undefined) { type = 'png'; }
type = fixType(type);
if (/bmp/.test(type)) {
var data = getImageData(scaleCanvas(canvas, width, height));
var strData = genBitmapImage(data);
saveFile(makeURI(strData, downloadMime));
} else {
var strData = getDataURL(canvas, type, width, height);
saveFile(strData.replace(type, downloadMime));
}
}
};
var getBase64Data = function(canvas, width, height, type){
if ($support.canvas && $support.dataURL) {
if (typeof canvas == "string") { canvas = document.getElementById(canvas); }
if (type == undefined) { type = 'png'; }
type = fixType(type);
var strData;
if (/bmp/.test(type)) {
var data = getImageData(scaleCanvas(canvas, width, height));
strData= genBitmapImage(data);
} else {
strData = getDataURL(canvas, type, width, height);
}
var base64;
var dataArray = strData.split("base64,");
if(dataArray && dataArray.length > 1){
base64 = dataArray[1];
}
return base64;
}
};
var convertToImage = function (canvas, width, height, type) {
if ($support.canvas && $support.dataURL) {
if (typeof canvas == "string") { canvas = document.getElementById(canvas); }
if (type == undefined) { type = 'png'; }
type = fixType(type);
if (/bmp/.test(type)) {
var data = getImageData(scaleCanvas(canvas, width, height));
var strData = genBitmapImage(data);
return genImage(makeURI(strData, 'image/bmp'));
} else {
var strData = getDataURL(canvas, type, width, height);
return genImage(strData);
}
}
};
return {
getBase64Data:getBase64Data,
saveAsImage: saveAsImage,
saveAsPNG: function (canvas, width, height) {
return saveAsImage(canvas, width, height, 'png');
},
saveAsJPEG: function (canvas, width, height) {
return saveAsImage(canvas, width, height, 'jpeg');
},
saveAsGIF: function (canvas, width, height) {
return saveAsImage(canvas, width, height, 'gif');
},
saveAsBMP: function (canvas, width, height) {
return saveAsImage(canvas, width, height, 'bmp');
},
convertToImage: convertToImage,
convertToPNG: function (canvas, width, height) {
return convertToImage(canvas, width, height, 'png');
},
convertToJPEG: function (canvas, width, height) {
return convertToImage(canvas, width, height, 'jpeg');
},
convertToGIF: function (canvas, width, height) {
return convertToImage(canvas, width, height, 'gif');
},
convertToBMP: function (canvas, width, height) {
return convertToImage(canvas, width, height, 'bmp');
}
};
}();
export default Canvas2Image
\ No newline at end of file
<template>
<div >
<button @click="haibao">生成海报</button>
<div class="html2canvas-wrap">
<div class="swiper-item-fenxiang" id="v2">
<h2>html2canvas</h2>
<img src="../assets/img/img.jpg" alt />
</div>
</div>
</div>
</template>
<script>
import html2canvas from 'html2canvas'
import canvas2Image from '@/assets/lib/canvas2image'
export default {
mounted() {
},
methods: {
// 分享海报;
haibao() {
var _this = this
var test = document.getElementsByClassName('swiper-item-fenxiang')[0]
var width = test.offsetWidth // 获取dom 宽度
var height = test.offsetHeight // 获取dom 高度
var canvas = document.createElement('canvas')
var scale = 1
canvas.width = width * scale // 定义canvas 宽度 * 缩放
canvas.height = height * scale // 定义canvas高度 *缩放
canvas.getContext('2d').scale(scale, scale)
html2canvas(test, {
useCORS: true,
logging: false, // 日志开关,便于查看html2canvas的内部执行流程
canvas: canvas,
width: width,
height: height,
scale: scale
}).then(function (canvas) {
var context = canvas.getContext('2d')
// 【重要】关闭抗锯齿
context.mozImageSmoothingEnabled = false
context.webkitImageSmoothingEnabled = false
context.msImageSmoothingEnabled = false
context.imageSmoothingEnabled = false
var img = canvas2Image.convertToImage(
canvas,
canvas.width,
canvas.height
)
img.setAttribute('crossOrigin', 'anonymous')
var srcfx = img.src || canvas.toDataURL('image/png')
console.log(srcfx);
})
}
}
}
</script>
<style lang="less" scoped>
.html2canvas-wrap {
position: relative;
height: 400px;
}
.swiper-item-fenxiang {
border: 1px solid red;
position: absolute;
top: 0rem;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
margin: 0 auto;
// opacity: 0;
z-index: -10;
img {
width: 100%;
height: auto;
}
}
</style>
\ No newline at end of file
...@@ -3,7 +3,7 @@ import App from './App.vue' ...@@ -3,7 +3,7 @@ import App from './App.vue'
import router from './router' import router from './router'
import store from './store' import store from './store'
// axios配置 // axios配置
// import './utils/axiosConfig' import './utils/axiosConfig'
// 微信授权登陆 // 微信授权登陆
import wxAuth from './utils/wxAuth' import wxAuth from './utils/wxAuth'
// 配置选项 // 配置选项
......
<template> <template>
<div> <div class="detail-wrap">
<h1>{{detailId}}</h1> <h1>{{detailId}}</h1>
<div>Detail页面</div> <div>Detail页面</div>
<html2canvas />
</div> </div>
</template> </template>
<script> <script>
import config from '@/config/config.js' import config from '@/config/config.js'
import { requestWxInit } from "@/utils/wxShare" import { requestWxInit } from "@/utils/wxShare"
import html2canvas from '@/example/html2canvas.vue'
export default { export default {
...@@ -34,6 +37,15 @@ export default { ...@@ -34,6 +37,15 @@ export default {
? `${config.shareLink}&shareId=${this.detailId}` ? `${config.shareLink}&shareId=${this.detailId}`
: `${config.shareLink}?shareId=${this.detailId}`; : `${config.shareLink}?shareId=${this.detailId}`;
} }
},
components: {
html2canvas
} }
} }
</script> </script>
<style lang="less" scoped>
.detail-wrap {
position: relative;
}
</style>
\ No newline at end of file
<template> <template>
<div class="home"> <div class="home">
<h6>home页{{msg}}</h6> <h6>home页{{msg}}</h6>
<button @click="testJump">跳转详情</button> <button @click="testJump">跳转详情生成海报</button>
<Music /> <Music />
<ossExample /> <ossExample />
</div> </div>
......
...@@ -1512,6 +1512,11 @@ balanced-match@^1.0.0: ...@@ -1512,6 +1512,11 @@ balanced-match@^1.0.0:
resolved "https://registry.npm.taobao.org/balanced-match/download/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" resolved "https://registry.npm.taobao.org/balanced-match/download/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
base64-arraybuffer@^0.2.0:
version "0.2.0"
resolved "https://registry.npm.taobao.org/base64-arraybuffer/download/base64-arraybuffer-0.2.0.tgz#4b944fac0191aa5907afe2d8c999ccc57ce80f45"
integrity sha1-S5RPrAGRqlkHr+LYyZnMxXzoD0U=
base64-js@^1.0.2: base64-js@^1.0.2:
version "1.3.1" version "1.3.1"
resolved "https://registry.npm.taobao.org/base64-js/download/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" resolved "https://registry.npm.taobao.org/base64-js/download/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1"
...@@ -1881,6 +1886,11 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000989: ...@@ -1881,6 +1886,11 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000989:
resolved "https://registry.npm.taobao.org/caniuse-lite/download/caniuse-lite-1.0.30000997.tgz#ba44a606804f8680894b7042612c2c7f65685b7e" resolved "https://registry.npm.taobao.org/caniuse-lite/download/caniuse-lite-1.0.30000997.tgz#ba44a606804f8680894b7042612c2c7f65685b7e"
integrity sha1-ukSmBoBPhoCJS3BCYSwsf2VoW34= integrity sha1-ukSmBoBPhoCJS3BCYSwsf2VoW34=
canvas2image@^1.0.5:
version "1.0.5"
resolved "https://registry.npm.taobao.org/canvas2image/download/canvas2image-1.0.5.tgz#676a094b4363888a2b7662e58b9ce5d3bfbc9d14"
integrity sha1-Z2oJS0NjiIordmLli5zl07+8nRQ=
case-sensitive-paths-webpack-plugin@^2.2.0: case-sensitive-paths-webpack-plugin@^2.2.0:
version "2.2.0" version "2.2.0"
resolved "https://registry.npm.taobao.org/case-sensitive-paths-webpack-plugin/download/case-sensitive-paths-webpack-plugin-2.2.0.tgz#3371ef6365ef9c25fa4b81c16ace0e9c7dc58c3e" resolved "https://registry.npm.taobao.org/case-sensitive-paths-webpack-plugin/download/case-sensitive-paths-webpack-plugin-2.2.0.tgz#3371ef6365ef9c25fa4b81c16ace0e9c7dc58c3e"
...@@ -2389,6 +2399,13 @@ css-declaration-sorter@^4.0.1: ...@@ -2389,6 +2399,13 @@ css-declaration-sorter@^4.0.1:
postcss "^7.0.1" postcss "^7.0.1"
timsort "^0.3.0" timsort "^0.3.0"
css-line-break@1.1.1:
version "1.1.1"
resolved "https://registry.npm.taobao.org/css-line-break/download/css-line-break-1.1.1.tgz#d5e9bdd297840099eb0503c7310fd34927a026ef"
integrity sha1-1em90peEAJnrBQPHMQ/TSSegJu8=
dependencies:
base64-arraybuffer "^0.2.0"
css-loader@^1.0.1: css-loader@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.npm.taobao.org/css-loader/download/css-loader-1.0.1.tgz#6885bb5233b35ec47b006057da01cc640b6b79fe" resolved "https://registry.npm.taobao.org/css-loader/download/css-loader-1.0.1.tgz#6885bb5233b35ec47b006057da01cc640b6b79fe"
...@@ -4039,6 +4056,13 @@ html-webpack-plugin@^3.2.0: ...@@ -4039,6 +4056,13 @@ html-webpack-plugin@^3.2.0:
toposort "^1.0.0" toposort "^1.0.0"
util.promisify "1.0.0" util.promisify "1.0.0"
html2canvas@^1.0.0-rc.5:
version "1.0.0-rc.5"
resolved "https://registry.npm.taobao.org/html2canvas/download/html2canvas-1.0.0-rc.5.tgz#4ee3cac9f6e20a0fa0c2f35a6f99c960ae7ec4c1"
integrity sha1-TuPKyfbiCg+gwvNab5nJYK5+xME=
dependencies:
css-line-break "1.1.1"
htmlparser2@^3.3.0: htmlparser2@^3.3.0:
version "3.10.1" version "3.10.1"
resolved "https://registry.npm.taobao.org/htmlparser2/download/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" resolved "https://registry.npm.taobao.org/htmlparser2/download/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment