<template>
<div>
<div style="margin-bottom: 20px">
<el-button style="margin-left: 20px" @click="add">添加</el-button>
<el-button style="margin-left: 20px" type="success" @click="handleDown"
>下载
</el-button>
</div>
<canvas id="myCanvas"></canvas>
</div>
</template>
<script setup lang="ts">
import { onMounted } from "vue";
import { baseImgUrl } from "@/api/utils";
onMounted(() => {
initCancas();
});
let product_list = [
{
cover: "product/6455efe66a52a51a98642da71690451253763.jpg",
name: "云南元谋冬枣9kg装一级泡沫箱装大果",
width: 100,
height: 100,
price: 100
},
{
cover: "product/6455efe66a52a51a98642da71719627894157.jpg",
name: "曲靖华硕苹果21kg筐装一级",
width: 100,
height: 100,
price: 120
},
{
cover: "product/6455efe66a52a51a98642da71705285150862.jpg",
name: "陕西甜王西瓜22kg纸箱装一级",
width: 100,
height: 100,
price: 68
},
{
cover: "product/6455efe66a52a51a98642da71705285150862.jpg",
name: "陕西甜王西瓜22kg纸箱装一级",
width: 100,
height: 100,
price: 68
},
{
cover: "product/6455efe66a52a51a98642da71705285150862.jpg",
name: "陕西甜王西瓜22kg纸箱装一级",
width: 100,
height: 100,
price: 68
},
{
cover: "product/6455efe66a52a51a98642da71705285150862.jpg",
name: "陕西甜王西瓜22kg纸箱装一级",
width: 100,
height: 100,
price: 68
},
{
cover: "product/6455efe66a52a51a98642da71705285150862.jpg",
name: "陕西甜王西瓜22kg纸箱装一级",
width: 100,
height: 100,
price: 68
}
];
function initCancas() {
let canvas = document.getElementById("myCanvas");
let ctx = canvas.getContext("2d");
let width = 400;
canvas.width = width;
let imgW = 300;
let canvasStyleH = 0;
let dpi = window.devicePixelRatio;
product_list.forEach(ele => {
if (ele.name.length > 7) {
ele.name_1 = ele.name.substring(0, 10);
ele.name_2 = ele.name.substring(10);
} else {
ele.names = "";
}
ele.src = baseImgUrl + ele.cover;
let ratio = ele.height / ele.width;
if (imgW * ratio > canvasStyleH) {
canvasStyleH = imgW * ratio;
}
});
// ctx.rect(0, 0, canvas.width, canvas.height);
let row = Math.ceil(product_list.length / 3);
let group = new Array(row);
let temp_list = [];
product_list.forEach((res, index) => {
let i = parseInt(index / 3);
if (index % 3 == 0) {
temp_list = [];
}
temp_list.push(res);
group[i] = temp_list;
});
let row_height = 180;
let bottom_height = 120;
let height = row * row_height;
canvas.height = height + bottom_height + 120;
ctx.lineJoin = "round";
ctx.lineWidth = 10;
ctx.fillStyle = "#ff9f3360"; //矩形填充色
ctx.fillRect(0, 0, width, height + 120);
let headImg = new Image();
headImg.onload = function () {
ctx.drawImage(headImg, 0, 0, 400, 120);
};
headImg.src =
"https://image.guoshut.top/topic/648bce7e7a9b75ca6f4258501713859985246.png";
headImg.setAttribute("crossOrigin", "Anonymous");
group.forEach((item, row_index) => {
item.forEach((res, index) => {
let img = new Image();
img.crossOrigin = "Anonymous";
let x = index * 106 + 20;
if (index > 0) {
x += index * 20;
}
let y = row_index * 175 + 120;
if (row_index > 0) {
}
img.onload = function () {
// 绘制产品被包裹的矩形
ctx.lineJoin = "round";
ctx.lineWidth = 10;
ctx.strokeStyle = "#eee";
ctx.fillStyle = "rgba(238, 238, 238, 1)"; //矩形填充色
ctx.fillRect(x, y + 20, 106, 155);
ctx.strokeRect(x, y + 20, 106, 155);
// ctx.stroke();
// 上部分产品里字体颜色
let gradients = ctx.createLinearGradient(0, 0, 10, 0);
gradients.addColorStop("0", "#707171");
ctx.fillStyle = gradients;
ctx.font = "12px Arial";
ctx.fillText(res.name_1, x, y + 140);
ctx.fillText(res.name_2, x, y + 155);
let gradientss = ctx.createLinearGradient(0, 0, 10, 0);
gradientss.addColorStop("0", "red");
ctx.fillStyle = gradientss;
ctx.font = "16px Arial";
ctx.fillText("¥" + res.price, x + 10, y + 175);
ctx.font = "12px normal";
ctx.drawImage(img, x, y + 20, 106, 106);
};
img.src = res.src;
img.setAttribute("crossOrigin", "Anonymous");
});
});
const iconImg = new Image();
iconImg.src = baseImgUrl + "icon/mini_qr_430.jpg";
ctx.stroke();
ctx.fill();
ctx.lineJoin = "round";
ctx.lineWidth = 10;
ctx.strokeStyle = "red";
ctx.fillStyle = "#ff9f33"; //矩形填充色
ctx.fillRect(0, row * row_height + 120, 400, 120);
iconImg.onload = () => {
ctx.drawImage(iconImg, 40, row * row_height + 140, 80, 80);
// 二维码字体颜色
let gradient = ctx.createLinearGradient(0, 0, 10, 0);
gradient.addColorStop("0", "#eee");
ctx.fillStyle = gradient;
ctx.font = "14px Arial";
ctx.fillText("果蔬团服务", 150, row * row_height + 160);
ctx.fillText("长按图片前往小程序", 150, row * row_height + 190);
};
iconImg.setAttribute("crossOrigin", "Anonymous");
// ctx.save();
}
function handleDown() {
let canvas = document.getElementById("myCanvas");
let b64 = canvas.toDataURL("image/jpeg", 1);
const blob = base64ToBlob(b64.split(",")[1], "image/jpeg");
const objectURL = URL.createObjectURL(
new Blob([blob], { type: "image/png" })
);
const anchor = document.createElement("a");
anchor.href = objectURL;
anchor.download = "Filename.png";
anchor.click();
}
function base64ToBlob(base64, mimeType) {
const byteCharacters = atob(base64);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += 512) {
const slice = byteCharacters.slice(offset, offset + 512);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
return new Blob(byteArrays, { type: mimeType });
}
function add() {}
</script>
<style scoped></style>
vue canvas 拼接图片制作海报简易版
于 2024-07-03 09:45:42 首次发布