jquery+bootstrap实现DOM转图片并下载

🍊jquery实现DOM结构转图片并下载

版本介绍:

  • Bootstrap v3.3.7
  • jQuery v3.5.1
  • domToImage.js
    根据Bootstrap实现dialog上一步下一步多个弹窗交互进行大肆修改,完善了第二步生成图片的功能与更强的交互
1.、功能说明
  1. 重新设置bootstrap主题色
  • 包括按钮:默认(default)、成功(success)、错误(danger)、主要(primary)
  • 提示:成功(success)、错误(danger)
  1. 内容区以card形式展示,纯js实现分页功能
  2. 共两步骤:
  • 第一步选择模板,
  • 第二步自定义编辑信息,预览模板信息
  • 点击按钮将DOM生成png图片(或者gif图片),并下载
  • 预览DOM生成的模板:会由于符号等问题出现占不满的情况,会再次进行填充,重新渲染panel
2. 效果图
  1. 效果图一:
    n0nw5-viseo.gif
  2. 效果图二:
    广告22.gif
3. 代码
  1. index.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><link rel="stylesheet" href="./css/bootstrap3.3.7.css"><link rel="stylesheet" href="./css/theme.css"><link rel="stylesheet" href="./css/index.css"><script src="./js/jquery3.5.1.js"></script><script src="./js/bootstrap3.3.7.js"></script><script src="./js/domToImage.js"></script>
</head><body><!-- Button trigger modal --><button type="button" class="btn btn-primary btn-lg openModule">在线生成</button><!-- 选择模板 --><div class="modal fade in" id="module" tabindex="-1" role="dialog" aria-labelledby="moduleLabel"><div class="modal-dialog" role="document"><div class="modal-content"><div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-label="Close"><spanaria-hidden="true">&times;</span></button><h4 class="modal-title" id="moduleLabel">生成广告</h4></div><div class="modal-body"><!-- 模板列表 --><div class="module-list"></div><!-- 分页 --><nav aria-label="Page navigation" class="pagination-box"><ul class="pagination"></ul></nav></div><div class="modal-footer"><button type="button" class="btn btn-primary next">下一步</button></div></div></div></div><!-- 生成广告 --><div class="modal fade in" id="advertising" tabindex="-1" role="dialog" aria-labelledby="advertisingLabel"><div class="modal-dialog" role="document"><div class="modal-content"><div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-label="Close"><spanaria-hidden="true">&times;</span></button><h4 class="modal-title" id="advertisingLabel">生成广告</h4></div><div class="modal-body"><!-- 输入表单 --><form class="form-horizontal"><div class="form-group company_name"><label for="inputEmail3" class="col-sm-3 control-label">公司名称:</label><div class="col-sm-7"><input class="form-control" id="company_name" maxlength="100" placeholder="请输入公司名称"><span class="company_name_verification help-block">请输入公司名称</span></div></div><div class="form-group"><label for="inputPassword3" class="col-sm-3 control-label">联系人:</label><div class="col-sm-7"><input class="form-control" id="contact_name" maxlength="20" placeholder="请输入联系人"></div></div><div class="form-group"><label for="inputPassword3" class="col-sm-3 control-label">联系电话:</label><div class="col-sm-7"><input class="form-control" id="contact_phone" maxlength="50" placeholder="请输入联系电话"></div></div><div class="form-group"><label for="inputPassword3" class="col-sm-3 control-label">广告语:</label><div class="col-sm-7"><textarea class="form-control" id="ad_words" rows="3" maxlength="500" placeholder="请输入广告语"style="resize: none;"></textarea></div></div></form><!-- 预览图 --><div class="image-container"></div></div><div class="modal-footer"><button type="button" class="btn btn-default last">上一步</button><button type="button" class="btn btn-success confirmGIF">生成*.gif</button><button type="button" class="btn btn-primary confirmJPG">生成*.jpg</button></div></div></div></div><script src="./js/index.js"></script></body></html>
  1. index.js
// TODO
const info = {company_name: "测试服务有限公司",contact_name: "耿先生",contact_phone: "1513006500 195**1155",ad_words:"这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告这是测试广告广告",
};/*** @function 获取模板列表数据* @variable listParams 请求列表分页参数* @variable total 总条数* @variable maxPage 最大分页数*/let listParams = {pageSize: 10,pageNumber: 1,
};
let total = 0;
let maxPage = 0;
function getList() {$.ajax({type: "POST",url: " https://mock.mengxuegu.com/mock/66a0c71a904326081fb3bdf9/module_list",data: listParams,}).done(function (res) {if (res.code === 200) {console.log(res.result);total = res.result.total;renderModuleList(res.result.items);renderActiveModule(res.result.items);renderPagination();renderActivePagination();}});
}/*** @function 渲染模板列表*/
function renderModuleList(data) {// 渲染前先清空$(".module-list").empty();let ctx = "";data.map((item) => {ctx +='<div class="module-item" data-kid=' +item.id +"><div>模板名称:" +item.temp_title +"</div><div>尺寸:" +item.width +"x" +item.height +'</div><div class="module-image"><img src="' +item.img_url +'" class="img-responsive" alt="' +item.temp_title +'"></div></div>';});$(".module-list").append($(ctx));
}/*** @function 选择模板*/
let selectedModuleId = null;
$(".module-list").on("click", ".module-item", function () {selectedModuleId = $(this).data("kid");$(this).addClass("module-item-active").siblings().removeClass("module-item-active");
});/*** @function 渲染选中模板*/
function renderActiveModule() {if (!selectedModuleId) {return;}$(".module-item").map((item, v) => {if ($(v).data("kid") === selectedModuleId) {$($(".module-item")[item]).addClass("module-item-active");}});
}/*** @function 渲染分页*/
function renderPagination() {// 渲染前先清空$(".pagination").empty();maxPage = Math.ceil(total / 10);// 1. 上一页let page = `<li data-prop="prev"><a href="#" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>`;// 2. 页码for (let i = 1; i <= maxPage; i++) {page += '<li><a href="#" data-prop="' + i + '">' + i + "</a></li>";}// 3. 下一页page += `<li data-prop="next"><a href="#" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>`;$(".pagination").append($(page));
}/*** @function 渲染高亮分页*/
function renderActivePagination() {$($(".pagination li")[listParams.pageNumber]).addClass("active").siblings().removeClass("active");
}/*** @function 点击分页*/
$(".pagination").on("click", "li", function () {const prop = $(this).data("prop");if (prop === "prev") {// 上一页if (listParams.pageNumber > 1) {listParams.pageNumber--;}} else if (prop === "next") {// 下一页if (listParams.pageNumber < maxPage) {listParams.pageNumber++;}} else {// 页码const page = $(this).text();listParams.pageNumber = page * 1;}getList();
});/*** @function 设置提示内容* @param { string } message 提示消息* @param { 'success' | 'danger' } type 提示类型*/
function setMessage(message, type = "success") {const len = $(".text-message").length;if (len) {return;}$("body").append(`<div class="text-message">` + message + `</div>`);setTimeout(() => {$(".text-message").eq(0).addClass("text-" + type);$(".text-message").eq(0).css({top: "45px",});}, 200);setTimeout(() => {$(".text-message").eq(0).css({top: "-45px",});setTimeout(() => {$(".text-message").eq(0).remove();}, 200);}, 3000);
}/*** @function 重置数据*/
function reset() {$(".module-list").empty();$(".pagination").empty();listParams = {pageSize: 10,pageNumber: 1,};total = 0;maxPage = 0;
}/*** @function 点击在线生成按钮*/
$(".openModule").on("click", function () {$("#module").modal("show");
});/*** @function 打开模板列表弹窗*/
$("#module").on("show.bs.modal", function () {if ($("#advertising").css("display") === "block") {return;}getList();
});/*** @function 关闭模板列表弹窗*/
$("#module").on("hidden.bs.modal", function () {// 如果是第二步回到第一步,不重置数据if ($("#advertising").css("display") === "block") {return;}reset();
});/*** @function 点击下一步*/
$(".next").click(function () {if (!selectedModuleId) {setMessage("请选择模板", "danger");return;}$("#module").modal("hide");$("#advertising").modal("show");
});/*** @function 点击上一步*/
$(".last").click(function () {$("#advertising").modal("hide");$("#module").modal("show");
});/*** @function 打开生成广告弹窗*/
$("#advertising").on("show.bs.modal", function () {$(".image-container").empty();const { company_name, contact_name, contact_phone, ad_words } = info;$("#company_name").val(company_name);$("#contact_name").val(contact_name);$("#contact_phone").val(contact_phone);$("#ad_words").val(ad_words);getModuleDetail();
});/*** @function 关闭生成广告弹窗*/
$("#advertising").on("hidden.bs.modal", function () {$(".company_name").removeClass("has-error");$(".company_name_verification").hide();// 如果是第二步回到第一步,不重置数据if ($("#module").css("display") === "block") {return;}reset();
});/*** form表单input改变事件*/
$("#company_name").on("input", function () {companyNameVerify();setCompanyNameVal();
});
$("#contact_name").on("input", function () {setContactVal();
});
$("#contact_phone").on("input", function () {setContactVal();
});
$("#ad_words").on("input", function () {const { is_two_page } = moduleDetail;if (is_two_page) {descStatus = "init";calcPanelNum();} else {setDescVal();}
});/*** 设置预览DOM显示值*/
function setCompanyNameVal() {$(".text-company").text($("#company_name").val().trim()? $("#company_name").val(): "请输入公司名称");
}
function setContactVal() {const contact_name = $("#contact_name").val().trim();const contact_phone = $("#contact_phone").val().trim();const contact_name_phone = contact_name + contact_phone;$(".text-contact").text(contact_name_phone || "请输入联系信息");
}
function setDescVal() {$(".text-desc").text($("#ad_words").val() ? $("#ad_words").val() : "请输入广告语");
}/*** @function 获取选中模板详情* @variable 模板详情*/
let moduleDetail = null;
function getModuleDetail() {$.ajax({type: "POST",url: "https://mock.mengxuegu.com/mock/66a0c71a904326081fb3bdf9/module_detail/",data: { id: selectedModuleId },}).done(function (res) {if (res.code === 200) {moduleDetail = res.data;drawingDomElements();}});
}/*** @function 绘制dom元素*/
function drawingDomElements() {// 判断广告语是不是展示在第2页const { is_two_page: descNewPage } = moduleDetail;if (descNewPage) {drawingMultiPanel();} else {drawingImageContainer();}
}/*** @function 绘制公司标题元素*/
function drawingImageContainer() {const { is_two_page: descNewPage } = moduleDetail;$(".image-container").prepend(` <div class="image-panel image-1" id="DomToImage1"><div class="content"><div class="text-company"></div><div class="text-contact"></div><div class="text-desc"></div></div></div>`);drawingImagePanel();drawingMaskName();drawingContentName("content");drawingCompany();drawingContact();if (descNewPage) {$(".text-desc").remove();} else {drawingDesc();}
}
/*** @function 绘制image-panel元素*/
function drawingImagePanel() {const {width: basicWidth,height: basicHeight,is_backcolor_or_img: basicBackground, // 1 color 2 imgbackground_color: basicBackgroundColor,back_img_url: basicBackgroundImg,} = moduleDetail;const style = {width: basicWidth + "px",height: basicHeight + "px",};if (basicBackground === 1) {// 判断是否是渐变色const basicBackgroundColorType = basicBackgroundColor.includes(",")? "gradient": "single";if (basicBackgroundColorType === "single") {style.background = basicBackgroundColor;} else {const colorList = basicBackgroundColor.split(",");style.background = `linear-gradient(135deg, ${colorList[0]}, ${colorList[1]})`;}} else {style.backgroundImage = `url(${basicBackgroundImg})`;style.backgroundRepeat = "no-repeat";style.backgroundSize = "cover";}$(".image-panel").css(style);
}/*** @function 绘制mask元素* @variable basicBackgroundMaskCheck 蒙版* @variable basicBackgroundMaskColor 蒙版颜色* @variable basicBackgroundMaskOpacityCheck 是否透明* @variable basicBackgroundMaskOpacity 透明度*/
function drawingMaskName() {const { back_mask, mask_tm_val, is_backcolor_or_img } = moduleDetail;const style = {};basicBackgroundMaskCheck = back_mask === "" ? false : true;basicBackgroundMaskColor = back_mask === "" ? "#000000" : back_mask;if (basicBackgroundMaskCheck) {style.background = basicBackgroundMaskColor;}basicBackgroundMaskOpacityCheck = mask_tm_val === 101 ? false : true;basicBackgroundMaskOpacity = mask_tm_val === 101 ? 50 : mask_tm_val;if (basicBackgroundMaskOpacityCheck) {style.opacity = basicBackgroundMaskOpacity + "%";}if (is_backcolor_or_img === 2 && basicBackgroundMaskCheck) {$(".image-panel").prepend('<div class="mask"></div>');$(".mask").css(style);} else {$(".mask").remove();}
}/*** @function 绘制content元素*/
function drawingContentName(name) {const { up_down_margin, left_right_margin } = moduleDetail;const style = {};style.paddingTop = style.paddingBottom = (up_down_margin || 20) + "px";style.paddingLeft = style.paddingRight = (left_right_margin || 20) + "px";$("." + name).css(style);
}/*** @function 绘制company元素*/
function drawingCompany() {const {company_font: companyFontFamily,company_font_size: companyFontSize,company_font_color: companyFontColor,is_company_bold: companyFontBold,is_company_xt: companyFontItalic,} = moduleDetail;const style = {fontFamily: companyFontFamily,fontSize: companyFontSize + "px",color: companyFontColor,};if (companyFontBold) {style.fontWeight = "bold";}if (companyFontItalic) {style.fontStyle = "italic";}$(".text-company").css(style);setCompanyNameVal();
}/*** @function 绘制contact元素*/
function drawingContact() {const {contact_font: contactFontFamily,contact_font_size: contactFontSize,contact_font_color: contactFontColor,contact_margin: contactMarginTop,is_contact_bold: contactFontBold,is_contact_xt: contactFontItalic,} = moduleDetail;const style = {fontFamily: contactFontFamily,fontSize: contactFontSize + "px",color: contactFontColor,marginTop: contactMarginTop + "px",};if (contactFontBold) {style.fontWeight = "bold";}if (contactFontItalic) {style.fontStyle = "italic";}$(".text-contact").css(style);setContactVal();
}/*** @function 绘制desc元素*/
function drawingDesc() {const {is_two_page: descNewPage,ad_font: descFontFamily,ad_font_size: descFontSize,ad_font_color: descFontColor,is_ad_bold: descFontBold,is_ad_xt: descFontItalic,ad_top_margin: descMarginTop,line_height: descLineHeight,} = moduleDetail;const style = {fontFamily: descFontFamily,fontSize: descFontSize + "px",color: descFontColor,lineHeight: descLineHeight,};if (descFontBold) {style.fontWeight = "bold";}if (descFontItalic) {style.fontStyle = "italic";}if (!descNewPage) {style.marginTop = descMarginTop + "px";setDescVal();}$(".text-desc").css(style);
}/*** @function 广告语展示在第2页,绘制panel* @variable descList 广告语panel列表基础文字* @variable panelFontBaseCount panel内字体基础数量* @variable descCopy 复制广告内容,填充处理*/
let descList = [];
let panelFontBaseCount = 0;
let descCopy = "";function drawingMultiPanel() {const {width: basicWidth,height: basicHeight,ad_font_size: descFontSize,line_height: descLineHeight,up_down_margin,left_right_margin,} = moduleDetail;const containerW = basicWidth - (left_right_margin || 20) * 2;const containerH = basicHeight - (up_down_margin || 20) * 2;const lineHeight = descFontSize * descLineHeight;const lineCount = parseInt(containerH / lineHeight);const preLineCount = parseInt(containerW / descFontSize);panelFontBaseCount = preLineCount * lineCount;calcPanelNum();
}/*** @function 计算panel数量, 给descList赋初始值,panelFontBaseCount基础值,会由于符号等问题出现占不满的情况,需要再次进行填充,重新渲染panel*/
function calcPanelNum() {currentIndex = 0;descStatus = "init";descList = [];descCopy = $("#ad_words").val();const ad_words = $("#ad_words").val();const pages = Math.ceil(ad_words.length / panelFontBaseCount);for (let i = 0; i < pages; i++) {const start = i * panelFontBaseCount;const end = start + panelFontBaseCount;const page = ad_words.substring(start, end);descList.push(page);}drawingOtherPanel();
}/*** @function 广告语展示在第2页,绘制panel*/
function drawingOtherPanel() {$(".image-container").empty();drawingImageContainer();descList.map((item, i) => {$(".image-container").append(`<div class="image-panel" id="DomToImage2` +i +`"><div class="content-padding"></div></div>`);$(".content-padding").eq(i).append(`<div class="content" id="descContent` +i +`"><div class="text-desc">` +item +`</div></div>`);drawingImagePanel();drawingMaskName();drawingContentName("content-padding");drawingDesc();});setTimeout(() => {if (descStatus === "init") {isOverFlow(panelFontBaseCount);}}, 200);
}/*** @function 判断是否超出容器*/
let descStatus = "init";
let currentIndex = 0;
function isOverFlow(textCount) {if (!$("#descContent" + currentIndex).length) {return;}let scrollHeight = $("#descContent" + currentIndex)[0].scrollHeight;let offsetHeight = $("#descContent" + currentIndex)[0].offsetHeight;// 初始进入肯定会等于或者小于if (scrollHeight <= offsetHeight) {// 填充一个字const end = textCount + 1;descList[currentIndex] = descCopy.substring(0, end);$("#descContent" + currentIndex + " .text-desc").text(descList[currentIndex]);if (descList[currentIndex].length < descCopy.length) {if (currentIndex < $(".content-padding").length - 1) {isOverFlow(textCount + 1);}} else {descStatus = "end";descList.splice(currentIndex + 1);drawingOtherPanel();}} else {// 超出减1,还原到最后填充之前const exceedCount = textCount - 1;// 截取, 修改descCopydescCopy = descCopy.substring(exceedCount);descList[currentIndex] = descList[currentIndex].substring(0, textCount - 1);$("#descContent" + currentIndex + " .text-desc").text(descList[currentIndex]);currentIndex++;isOverFlow(panelFontBaseCount);}
}/*** @function 点击生成*.jpg按钮*/
$(".confirmJPG").click(function (e) {companyNameVerify();getToJPG();
});/*** @function 公司名称校验*/
function companyNameVerify() {if (!$("#company_name").val().trim()) {$(".company_name").addClass("has-error");$(".company_name_verification").fadeIn(200);} else {$(".company_name").removeClass("has-error");$(".company_name_verification").fadeOut(50);}
}/*** @function 生成.jpg图片*/
function getToJPG() {const { is_two_page } = moduleDetail;drawingDomToImage("DomToImage1", function (dataUrl) {setMessage("生成成功");downloadFileByBase64(dataUrl, $("#company_name").val().trim());});// 广告展示多张图if (is_two_page && $("#ad_words").val()) {const len = $(".image-container").children().length;for (let i = 0; i < len - 1; i++) {drawingDomToImage("DomToImage2" + i, function (dataUrl) {setMessage("生成成功");downloadFileByBase64(dataUrl, $("#company_name").val().trim() + i);});}}
}/*** @function 绘制方法* @param {string} 绘制DOM id* @param {function} 回调函数*/
function drawingDomToImage(id, cb) {let node = document.getElementById(id);domtoimage.toPng(node).then(function (dataUrl) {cb(dataUrl);}).catch(function () {setMessage("生成失败", "danger");});
}function downloadFileByBase64(base64, name) {var myBlob = dataURLtoBlob(base64);var myUrl = URL.createObjectURL(myBlob); //创建图片的临时urldownloadFile(myUrl, name);
}/*** @function url转blob*/
function dataURLtoBlob(dataUrl) {var arr = dataUrl.split(","),mime = arr[0].match(/:(.*?);/)[1],bstr = atob(arr[1]),n = bstr.length,u8arr = new Uint8Array(n);while (n--) {u8arr[n] = bstr.charCodeAt(n);}return new Blob([u8arr], { type: mime });
}/*** @function 下载图片*/
function downloadFile(url, name) {var a = document.createElement("a"); //新建一个a链接a.setAttribute("href", url); // a链接的url为图片的urla.setAttribute("download", name);a.setAttribute("target", "_blank");let clickEvent = document.createEvent("MouseEvents");clickEvent.initEvent("click", true, true);a.dispatchEvent(clickEvent);
}/*** @function 点击生成*.gif按钮*/
$(".confirmGIF").click(function () {const { is_two_page } = moduleDetail;if (is_two_page && $("#ad_words").val()) {companyNameVerify();getToGIF();} else {setMessage("必须两张图片以上才可生成gif", "danger");}
});/*** @function 生成.gif图片*/
function getToGIF() {const len = $(".image-container").children().length;for (let i = 0; i < len; i++) {if (i) {drawingDomToImage("DomToImage2" + (i - 1), function (dataUrl) {handleCreateImageDone({ url: dataUrl, index: i });});} else {drawingDomToImage("DomToImage1", function (dataUrl) {handleCreateImageDone({ url: dataUrl, index: i });});}}
}let uploadImgList = [];
function handleCreateImageDone({ url, index }) {uploadImgList.push({ url, index });jpgCreateGif();
}// 上传jpg生成gif
function jpgCreateGif() {const files = uploadImgList.sort((a, b) => a.index - b.index).map((item, index) => {return base64ToFile(item.url, index);});const len = $(".image-container").children().length;const filesLen = files.length;if (filesLen === len) {apiCreateGif(jsToFormData({ files }));}
}function base64ToFile(base64Data, fileName) {const blob = dataURLtoBlob(base64Data);return new File([blob], fileName);
}/*** @function 对象转formdata格式*/
function jsToFormData(obj) {let formData = new FormData();for (var key in obj) {if (Array.isArray(obj[key])) {obj[key].map((item) => {formData.append(key, item);});} else {formData.append(key, obj[key]);}}return formData;
}/*** @function 广告生成gif接口返回*/
function apiCreateGif(formData) {$.ajax({type: "POST",url: "https://mock.mengxuegu.com/mock/66a0c71a904326081fb3bdf9/add_gif/",data: formData,processData: false,contentType: false,xhrFields: {responseType: "blob",},}).done(function (res) {// 返回gif数据流,需要后台接口实现return;downloadGifFile(res, $("#company_name").val().trim());uploadImgList = [];});
}function downloadGifFile(res, name) {const url = window.URL.createObjectURL(new Blob([res], { type: "image/gif" }));let a = document.createElement("a");a.download = name + ".gif"; // 文件名a.href = url;document.body.appendChild(a);a.click();document.body.removeChild(a);window.URL.revokeObjectURL(url);
}
  • 方法说明:

    1. 计算panel数量calcPanelNum:
    • 当获取容器的实际高度与可视高度时,由于无渲染,所以获取不到,需要计算出基准字数进行渲染,然后计算填充
    • 获取容器的实际高度与可视高度,当超出,则说明不需要填充
    let scrollHeight = $("#descContent" + currentIndex)[0].scrollHeight;
    let offsetHeight = $("#descContent" + currentIndex)[0].offsetHeight;
    
    1. 判断是否超出容器:isOverFlow: 若在渲染完panel后不添加此方法,会出现占位不满的情况
      image.png
  1. index.css
html, body {line-height: 1.15!important;
}.modal{overflow-x: hidden;overflow-y: auto;
}
.modal-content{width: 80vh;min-width: 750px;
}/* 模板列表*/
.module-list{display: flex;flex-wrap: wrap;
}.module-item {box-sizing: border-box;width: calc(50% - 20px);display: flex;flex-direction: column;padding: 10px;margin: 10px;border: 1px solid #e5e5e5;border-radius: 10px;cursor: pointer;
}.module-item:hover {border-color: #c6e2ff;background-color: #ecf5ff;
}.module-item:active,.module-item:focus {border-color: #409eff;background-color: #ecf5ff;
}.module-item-active,.module-item-active:hover{border-color: #409eff;background-color: #ecf5ff;
}.module-image{flex: 1;display: flex;justify-content: flex-end;align-items: end;margin-top: 5px;
} 
.module-image img {max-width: 100px;max-height: 100px;
}/* 分页容器 */
.pagination-box{display: flex;justify-content: center;
}/*生成广告
*/
.company_name_verification{display: none;
}/* 模板DOM/预览图 */
.image-container{display: flex;flex-direction: column;justify-content: center;align-items: center;padding: 20px;overflow-x: auto;
}
.image-panel{width: 708px;height: 316px;background: #000000;border-radius: 4px;margin-bottom: 30px;box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);overflow: hidden;position: relative;
}.mask {width: 100%;height: 100%;position: absolute;left: 0;top: 0;
}.content-padding {width: 100%;height: 100%;
}.content {width: 100%;height: 100%;position: relative;z-index: 1;
}.image-1 .content {display: flex;flex-direction: column;justify-content: center;align-items: center;
}/* 公司名称 */
.text-company {font-size: 30px;color: green;text-align: center;
}/* 联系信息 */
.text-contact {font-size: 20px;color: #ffffff;text-align: center;margin-top: 50px;white-space: pre-wrap;
}/* 广告语 */
.text-desc {width: 100%;height: 100%;font-size: 16px;color: #ffffff;white-space: pre-wrap;text-align: justify;
}
  1. 修改主题theme.css
/* 默认按钮 */
.btn-default{border-color: #dcdfe6;background-color: #ffffff;
}.btn-default:hover{border-color: #c6e2ff;background-color: #ecf5ff;
}.btn-default:active{color: #409eff;border-color: #409eff;background-color: #ecf5ff;outline:none;
}.btn-default:focus{border-color: #dcdfe6!important;background-color: #ffffff!important;outline:none!important;
}/* 主要按钮 */
.btn-primary{border-color: #409EFF;background-color: #409EFF;
}.btn-primary:hover{border-color: #79bbff;background-color: #79bbff;
}.btn-primary:active{border-color: #337ecc;background-color: #337ecc;outline:none;
}.btn-primary:focus{border-color: #409EFF!important;background-color: #409EFF!important;outline:none!important;
}/* 成功按钮 */
.btn-success{border-color: #67c23a;background-color: #67c23a;
}.btn-success:hover{border-color: #95d475;background-color: #95d475;
}.btn-success:active{border-color: #529b2e;background-color: #529b2e;outline:none;
}.btn-success:focus{border-color: #67c23a!important;background-color: #67c23a!important;outline:none!important;
}/* error */.has-error .control-label,.has-error .help-block{color: #f56c6c;
}.has-error .form-control,
.has-error .form-control:focus {border-color: #f56c6c;
}/* 提示信息 */
.text-message {position: fixed;top: 0;left: 50%;z-index: 2000;transform: translate(-50%, 0);width: 500px;padding: 8px 16px;border-radius: 4px;text-align: center;opacity: 0;transition: opacity 0.2s, top .2s;
}.text-danger{background-color: #fef0f0;border: 1px solid #f56c6c;color: #f56c6c;opacity: 1;
}.text-success{background-color: #f0f9eb;border: 1px solid #67c23a;color: #67c23a;opacity: 1;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/50557.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DNS应用以及扩展知识

&#xff08;一&#xff09;DNS正向代理 1.首先在DNS服务器上安装bind包&#xff0c;安装环境 此部分参考上一个笔记 2.修改配置文件 vim /etc/named.conf 在配置文件中加上"any;" 3.然后配置/etc/named.rfc1912.zonesw文件 添加选中部分 选中部分有一个file文…

24年第三届钉钉杯大学生大数据挑战赛浅析

需要完整资料&#xff0c;请关注WX&#xff1a;“小何数模”&#xff01; 本次钉钉杯大数据挑战赛的赛题已正式出炉&#xff0c;无论是赛题难度还是认可度&#xff0c;该比赛都是仅次于数模国赛的独一档&#xff0c;可以用于国赛前的练手训练。考虑到大家解题实属不易&#xf…

气膜足球馆:经济高效的室内足球场馆解决方案—轻空间

如果你有一片足球场&#xff0c;想要建一个室内的足球馆&#xff0c;为什么不考虑一下气膜建筑呢&#xff1f;气膜建筑以其独特的优势和高性价比&#xff0c;成为现代体育场馆建设中的一匹黑马。它不仅具有传统建筑无法比拟的经济效益和快速施工优势&#xff0c;还在智能控制、…

vue实现电子签名、图片合成、及预览功能

业务功能&#xff1a;电子签名、图片合成、及预览功能 业务背景&#xff1a;需求说想要实现一个电子签名&#xff0c;然后需要提供一个预览的功能&#xff0c;可以查看签完名之后的完整效果。 需求探讨&#xff1a;后端大佬跟我说&#xff0c;文档我返回给你一个PDF的oss链接…

7.27扣...

知识点补充&#xff1a; 1.StringBuilder StringBuilder 类在 Java 中是一个可变字符序列。与 String 类不同&#xff0c;StringBuilder 可以在创建之后被修改。这意味着你可以向 StringBuilder 对象追加、插入或删除字符&#xff0c;而不需要创建新的对象&#xff08;辅助数…

企业公户验证API如何使用JAVA、Python、PHP语言进行应用

在纷繁复杂的金融与商业领域&#xff0c;确保每笔交易的安全与合规是至关重要的。而企业公户验证API&#xff0c;正是这样一位默默守护的数字卫士&#xff0c;它通过智能化的手段&#xff0c;简化了企业对公账户验证流程&#xff0c;让繁琐的审核变得快捷且可靠。 什么是企业公…

chrome浏览器驱动(所有版本)

chrome浏览器驱动 114之前版本 https://chromedriver.storage.googleapis.com/index.html 125以后 125以后版本下载链接在此&#xff0c;只有后面status是绿色对勾的才可以下载&#xff0c;驱动大版本一致就可以使用&#xff0c;不需版本号一模一样&#xff1b;下载所需版本只…

语言转文字

因为工作原因需要将语音转化为文字&#xff0c;经常搜索终于找到一个免费的好用工具&#xff0c;记录下使用方法 安装Whisper 搜索Colaboratory 右上方链接服务 执行 !pip install githttps://github.com/openai/whisper.git !sudo apt update && sudo apt install f…

高性能 Java 本地缓存 Caffeine 框架介绍及在 SpringBoot 中的使用

在现代应用程序中&#xff0c;缓存是一种重要的性能优化技术&#xff0c;它可以显著减少数据访问延迟&#xff0c;降低服务器负载&#xff0c;提高系统的响应速度。特别是在高并发的场景下&#xff0c;合理地使用缓存能够有效提升系统的稳定性和效率。 Caffeine 是一个高性能的…

《程序猿入职必会(4) · Vue 完成 CURD 案例 》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

【C++刷题】优选算法——队列+宽搜

N 叉树的层序遍历 vector<vector<int>> levelOrder(Node* root) {vector<vector<int>> ret;if (root nullptr) return ret;queue<Node*> q;q.push(root);ret.push_back({root->val});int size 1;while (!q.empty()) {vector<int> v…

【机器学习】Jupyter Notebook如何使用之基本步骤和进阶操作

引言 Jupyter Notebook 是一个交互式计算环境&#xff0c;它允许创建包含代码、文本和可视化内容的文档 文章目录 引言一、基本步骤1.1 启动 Jupyter Notebook1.2 使用 Jupyter Notebook 仪表板1.3 在笔记本中工作1.4 常用快捷键1.5 导出和分享笔记本 二、进阶用法2.1 组织笔…

从零开始学习网络安全渗透测试之基础入门篇——(二)Web架构前后端分离站Docker容器站OSS存储负载均衡CDN加速反向代理WAF防护

Web架构 Web架构是指构建和管理Web应用程序的方法和模式。随着技术的发展&#xff0c;Web架构也在不断演进。当前&#xff0c;最常用的Web架构包括以下几种&#xff1a; 单页面应用&#xff08;SPA&#xff09;&#xff1a; 特点&#xff1a;所有用户界面逻辑和数据处理都包含…

劝你不要上自动化立体库,非要上,砸锅了吧

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。 新书《智能物流系统构成与技术实践》 在当今这个科技日新月异的时代&#xff0c;自动化立体库作为仓储物流领域的佼佼者&#xff0c;以其高效、精准、节省人力的优势&#xff0c;吸引…

Windows下帆软BI(finebi)单机部署移植(Tomcat)攻略

一、基础环境 操作系统&#xff1a;Windows 10 64bit 帆软BI 版本&#xff1a;V9.0/V10.0 HTTP工具&#xff1a;Tomcat 外置数据库&#xff1a;Oracle 11g 实验内容&#xff1a;将已经部署好的帆软BI从一台电脑移植到另一台电脑 二、前期准备 1、做好外置数据库移植&…

【Three.js基础学习】17.imported-models

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 前言 课程回顾&#xff1a; 如何在three.js 中引入不同的模型&#xff1f; 1. 格式 &#xff08;不同的格式&#xff09; https://en.wikipedia.org/wiki/List_of_file_form…

杭州东网约车管理再出行方面取得的显著成效

随着科技的飞速发展&#xff0c;网约车已成为人们日常出行的重要选择。在杭州这座美丽的城市&#xff0c;网约车服务更是如雨后春笋般蓬勃发展。特别是杭州东站&#xff0c;作为杭州的重要交通枢纽&#xff0c;网约车管理显得尤为重要。近日&#xff0c;沧穹科技郑重宣告已助力…

达梦数据库系列—33.日志总结

目录 1、SQL日志 SQL 日志开启 SQL日志分析 2、Redo日志 3、归档日志 联机配置归档 手动配置归档 归档信息的查看 清理归档日志 4、闪回 查看闪回功能状态 开启闪回 闪回查询 5、其他事件日志 数据库实例日志 DMAP进程日志 数据库备份日志 dmwatcher日志 dm…

【STM32本科毕业设计】基于STM32的多功能MP3播放器设计

目录 一. 概述二. 系统硬件设计2.1 整体设计思路2.2 硬件器件的选择2.2.1 MP3解码芯片选择 2.2.2 收音机芯片选择2.2.3 温度传感器选择2.2.4 彩灯驱动芯片选择2.2.5 音效处理芯片选择2.2.6 EEPROM芯片选择2.2.7 功率放大芯片选择2.2.8 电源芯片选择2.2.9 人机交互设备选择 2.3 …

Django学习第一天(如何创建和运行app)

前置知识&#xff1a; URL组成部分详解&#xff1a; 一个url由以下几部分组成&#xff1a; scheme&#xff1a;//host:port/path/?query-stringxxx#anchor scheme:代表的是访问的协议&#xff0c;一般为http或者ftp等 host&#xff1a;主机名&#xff0c;域名&#xff0c;…