文章來源地址http://www.zghlxwxcb.cn/news/detail-810038.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div {
margin: 0 auto;
}
</style>
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.6/fabric.min.js"></script>
</head>
<body>
<div>
<button class="btn">點擊</button>
<button class="add-text">添加文案</button>
<button class="to-base64">生成圖片</button>
<canvas id="canvas" width="500" style="border:1px solid black"></canvas>
</div>
<script>
const btn = document.querySelector('.btn')
const addText = document.querySelector('.add-text')
const base64Image = document.querySelector('.to-base64')
var canvas = document.getElementById("canvas")
var ctx = canvas.getContext('2d');
var left = 0
// 實例化
let fabricObj = new fabric.Canvas('canvas')
// 設(shè)置畫布寬高 可以動態(tài)設(shè)置畫布寬高,如果在標(biāo)簽上也設(shè)置了寬高,則會將其覆蓋掉
fabricObj.setWidth(500)
fabricObj.setHeight(500)
// 設(shè)置背景圖
function setBackImage() {
function setPictureBg(src) {
const newImg = new Image();
newImg.src = src;
newImg.onload = () => {
fabricObj.setBackgroundImage(src, fabricObj.renderAll.bind(fabricObj), {
scaleX: fabricObj.width / newImg.width,
scaleY: fabricObj.height / newImg.height,
crossOrigin: 'anonymous'
});
};
}
setPictureBg('https://sput.xwabx.com/file/background/1/image_02.png')
let num = -1
const urls = [
'https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
'https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg',
'https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg',
'https://fuss10.elemecdn.com/9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg',
'https://fuss10.elemecdn.com/d/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg',
'https://fuss10.elemecdn.com/3/28/bbf893f792f03a54408b3b7a7ebf0jpeg.jpeg',
'https://fuss10.elemecdn.com/2/11/6535bcfb26e4c79b48ddde44f4b6fjpeg.jpeg',
]
btn.onclick = () => {
if (num == 6) {
num = -1
}
num++
setPictureBg(urls[num])
}
}
setBackImage()
var count = 1
var arr = [`text${count}`]
function setTextBorder() {
function setTextStyle(cur) {
// 創(chuàng)建文本對象并設(shè)置相關(guān)屬性
cur = new fabric.Textbox(
'阿里士大夫艱苦', {
lineHeight: 1.2,
left: 5,
top: 40,
fontSize: 40,
fontFamily: 'HanKangLiJinhei',
fill: '#000',
stroke: 'blue', // 設(shè)置描邊顏色為黑色
strokeWidth: 1, // 設(shè)置描邊寬度為3像素
textAlign: 'center',
editable: false, // 不能編輯
hasControls: false, //沒有控制角,只能移動操作
splitByGrapheme: true, //文字自動換行
lockScalingY: true, // 禁止Y軸伸縮
// lockMovementX: true //禁止橫向移動
}
);
// 將文本添加到畫布上
fabricObj.add(cur);
cur.on('moving', function () {
movingFn(cur)
});
}
setTextStyle(arr[0])
// 添加文案
addText.onclick = () => {
count++
arr.push(`text${count}`)
setTextStyle(arr[count - 1])
}
}
setTextBorder()
// 移動操作限制
function movingFn(currentText) {
const { width: cWidth, height: cHeight } = canvas.style;
const { width: fWidth, height: fHeight, left, top } = currentText;
let isOutSide = false;
//超出左邊界
if (left < 0) {
currentText.left = 10;
isOutSide = true;
}
// 超出右邊界
if (left + fWidth >= Number(cWidth.slice(0, -2))) {
currentText.left = Number(cWidth.slice(0, -2)) - fWidth - 10;
isOutSide = true;
}
// 超出上邊界
if (top <= 0) {
currentText.top = 0;
isOutSide = true;
}
// 超出下邊界
if (top + fHeight > Number(cHeight.slice(0, -2))) {
currentText.top = Number(cHeight.slice(0, -2)) - fHeight - 10;
isOutSide = true;
}
isOutSide && fabricObj.renderAll();
}
base64Image.onclick = () => {
const base64 = canvas.toDataURL({
format: 'png',
quality: 1
})
console.log(base64);
}
let timer
window.onresize = () => {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
const { innerHeight, innerWidth } = window
let objects = fabricObj.getObjects();
canvas.style.width = innerWidth - 100 + 'px'
canvas.style.height = innerHeight - 100 + 'px'
fabricObj.setWidth(canvas.style.width.slice(0, -2));
fabricObj.setHeight(canvas.style.height.slice(0, -2));
fabricObj.remove.apply(fabricObj, objects);
resizeCanvasFn(objects)
console.log(canvas.style.width);
console.log('尺寸發(fā)生了變化');
}, 1000)
}
function resizeCanvasFn(objects) {
// 更新所有對象的位置和大小
const { width, height } = canvas.style
for (let i = 0; i < objects.length; i++) {
let object = objects[i];
if (object.isType('image')) {
object.set({
left: width.slice(0, -2) - object.width * 0.5 - 22,
top: 10
});
} else {
object.set({
left: width.slice(0, -2) * 0.5 - object.width * 0.5,
top: object.top > height.slice(0, -2) ? height.slice(0, -2) - 40 : object.top
});
}
}
//重新將所有對象添加到畫布中;
for (let i = 0; i < objects.length; i++) {
fabricObj.add(objects[i]);
}
// fabricObj.setPictureBg('https://fuss10.elemecdn.com/2/11/6535bcfb26e4c79b48ddde44f4b6fjpeg.jpeg'); ///static/img/img.2b735807.png'
// 設(shè)置新的背景圖片路徑或URL
setBackImage()
fabricObj.renderAll();
}
</script>
</body>
</html>
文章來源:http://www.zghlxwxcb.cn/news/detail-810038.html
到了這里,關(guān)于canvas+fabric實現(xiàn)自定義封面的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!