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

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

版本介绍:

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"><span
              aria-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"><span
              aria-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 img
    background_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;
    // 截取, 修改descCopy
    descCopy = 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); //创建图片的临时url
  downloadFile(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为图片的url
  a.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;
}
  • 15
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
jQuery是一个功能强大的JavaScript库,它简化了JavaScript在网页开发中的使用。jQuery提供了许多用于操作HTML元素、处理事件和动画效果、发送网络请求等常用操作的方法,使得开发者能够更高效地编写交互性的网页应用。 Bootstrap是一个流行的前端开发框架,它提供了一套美观、易用、响应式的CSS和JavaScript组件,可以快速构建现代化的网站和Web应用。Bootstrap包含了许多预定义的CSS样式和布局,可以轻松实现响应式设计、网格系统、表单样式等常见的页面组件。 HTML5是最新的HTML标准,引入了许多新的特性和功能,使得在网页上实现丰富多样的内容和交互效果变得更加容易。HTML5提供了新的标签和API,例如video和audio标签可以直接在网页上播放视频和音频,canvas标签可以实现绘图功能,localStorage和sessionStorage API可以在客户端存储数据等等。 这三个技术和工具常常被同时使用于网页开发中。我们可以使用jQuery来简化DOM操作,例如选择元素、修改元素属性、添加删除元素等。而Bootstrap提供了美观的CSS样式和用户界面组件,可以用于快速构建网页的外观和布局。HTML5则提供了更多的交互功能和多媒体支持,例如使用canvas标签来绘制动画,使用localStorage来缓存数据等。 虽然这三个技术和工具的源代码非常庞大,但是它们的功能和用法相对简单。开发者可以在官方文档和各种教程中找到详细的用法和示例代码,可以根据自己的需要进行学习和使用。同时,这三个技术和工具都有着活跃的开发者社区和丰富的插件生态系统,可以进一步扩展它们的功能和应用范围。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值