首页 前端知识 jquery bootstrap实现DOM转图片并下载

jquery bootstrap实现DOM转图片并下载

2024-07-29 00:07:28 前端知识 前端哥 54 426 我要收藏

🍊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"><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;
}
转载请注明出处或者链接地址:https://www.qianduange.cn//article/14498.html
评论
发布的文章

Unity数据持久化之Json

2024-08-10 22:08:00

simdjson 高性能JSON解析C 库

2024-08-10 22:08:00

npm常用命令详解(一)

2024-08-10 22:08:34

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!