欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關(guān)于JS前端實(shí)現(xiàn)水印的代碼操作

 更新時(shí)間:2024年06月11日 08:49:53   作者:十串  
這篇文章主要介紹了關(guān)于JS前端實(shí)現(xiàn)水印的代碼操作,文中給出了詳細(xì)的實(shí)現(xiàn)思路和代碼示例供大家參考,對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下

網(wǎng)頁(yè)水印

實(shí)現(xiàn)思路

  • 通過(guò)canvas生成一張水印圖片
  • 通過(guò)css將圖片設(shè)置為目標(biāo)節(jié)點(diǎn)的背景圖
  • 通過(guò)MutationObserver監(jiān)聽(tīng)目標(biāo)節(jié)點(diǎn)的類(lèi)名變化,防止水印被刪除

代碼操作

  • 通過(guò)canvas生成一張水印圖片
function createImgBase(options) {
  const { content, width, height } = options;
  const canvasDom = document.createElement("canvas");
  let ctx = canvasDom.getContext("2d");
  canvasDom.width = width;
  canvasDom.height = height;
  if (ctx) {
    // 設(shè)置畫(huà)筆的方向
    ctx.rotate((-14 * Math.PI) / 180);
    // 設(shè)置水印樣式
    ctx.fillStyle = "rgba(100,100,100,0.4)";
    ctx.font = "italic 20px Arial";
    // 渲染水印
    content.forEach((text, index) => {
      ctx.fillText(text, 10, 30 * (index + 1)); // 縱向拉開(kāi)30的間距
    });
  }
  // document.body.appendChild(canvasDom);
  // 將canvas轉(zhuǎn)為圖片
  return canvasDom.toDataURL("image/png");
}

// createImgBase({
//   content: ["介四嘛呀", "介四sui印", "內(nèi)部機(jī)密材料", "嚴(yán)禁外泄!"],
//   width: 200,
//   height: 200,
// });
  • 將水印設(shè)置為目標(biāo)節(jié)點(diǎn)的背景圖片
function getWaterMark({
  content,
  className,
  canvasHeight = 140,
  canvasWidth = 150,
}) {
  // 生成圖片
  const data_url = createImgBase({
    content,
    width: canvasWidth,
    height: canvasHeight,
  });
  // 通過(guò)設(shè)置偽元素樣式,添加水印圖片為背景圖
  const defaultStyle = `
  .${className} {
    position: relative;
  }
  .${className}::after {
    content: "";
    background-image: url(${data_url});
    display: block;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    pointer-events: none;
  }`;

  const styleDom = document.createElement("style");
  styleDom.innerHTML = defaultStyle;
  document.head.appendChild(styleDom);
}
// getWaterMark({
//   content: ["介四嘛呀", "介四sui印", "內(nèi)部機(jī)密材料", "嚴(yán)禁外泄!"],
//   className: "content",
// });
  • 添加mutationObserver監(jiān)聽(tīng)節(jié)點(diǎn)的變化
function listenerDOMChange(className) {
  // 獲取要監(jiān)聽(tīng)的節(jié)點(diǎn)
  const targetNode = document.querySelector(`.${className}`);
  // 創(chuàng)建監(jiān)聽(tīng)器
  const observer = new MutationObserver(mutationList => {
    // 遍歷變化記錄
    for (let mutationRecord of mutationList) {
      // 如果目標(biāo)節(jié)點(diǎn)的class屬性發(fā)生變化,判斷是不是類(lèi)名被刪了,是的話(huà)把類(lèi)名加回去
      if (mutationRecord.attributeName === "class") {
        if(!Array.from(targetNode.classList).includes(className)) {
          targetNode.classList.add(className)
        }
      }
    }
  });
  // 啟動(dòng)監(jiān)聽(tīng)
  observer.observe(targetNode, {
    attributes: true,
  });
}

function getWaterMark({
      content,
      className,
      canvasHeight = 140,
      canvasWidth = 150,
}) {
  // 監(jiān)聽(tīng)
  listenerDOMChange(className);
  const data_url = createImgBase({
    content,
    width: canvasWidth,
    height: canvasHeight,
  });
  // ...
  const styleDom = document.createElement("style");
  styleDom.innerHTML = defaultStyle;
  document.head.appendChild(styleDom);
}

關(guān)于MutationObserver

MutationObserver 用來(lái)監(jiān)聽(tīng)DOM的變化,DOM的增刪、DOM屬性的變化,子結(jié)點(diǎn)和文本內(nèi)容的變化,都可以被監(jiān)聽(tīng)。

MutationObserver 的監(jiān)聽(tīng)和事件不同,事件是同步的,DOM的變化會(huì)立即觸發(fā)對(duì)應(yīng)的事件,而 MutationObserver 是異步的,會(huì)在下一個(gè)微任務(wù)執(zhí)行時(shí)觸發(fā)監(jiān)聽(tīng)回調(diào)。

  • 創(chuàng)建MutationObserver
const observer = new MutationObserver((mutationsList, observer) => {
    // mutationsList mutationRecord數(shù)組 記錄了DOM的變化
    // observer MutationObserver的實(shí)例

    // 監(jiān)聽(tīng)回調(diào)
    console.log(mutationsList, observer);
})

mutationObserver.observe(document.documentElement, {
  attributes: true,
  characterData: true,
  childList: true,
  subtree: true,
  attributeOldValue: true,
  characterDataOldValue: true
});
  • 開(kāi)啟監(jiān)聽(tīng)
// node 監(jiān)聽(tīng)的節(jié)點(diǎn)
// config 監(jiān)聽(tīng)配置(要監(jiān)聽(tīng)哪些內(nèi)容)
// observer.observe(node, config);
mutationObserver.observe(document.documentElement, {
  attributes: true,  // 屬性變化
  attributeOldValue: true,  // 觀(guān)察attributes變動(dòng)時(shí),是否需要記錄變動(dòng)前的屬性值
  attributeFilter: [‘class',‘src']  // 需要觀(guān)察的特定屬性

  characterData: true,  // 節(jié)點(diǎn)內(nèi)容、文本的變化
  characterDataOldValue: true,  // 觀(guān)察characterData變動(dòng)時(shí),是否需要記錄變動(dòng)前的屬性值

  childList: true,  // 子結(jié)點(diǎn)變化
  subtree: true,    // 所有后代節(jié)點(diǎn)
});

// 停止監(jiān)聽(tīng)
mutationObserver.disconnect()

// 清除變動(dòng)記錄
mutationObserver.takeRecords()

圖片水印

實(shí)現(xiàn)思路

方案一:通過(guò)oss添加水印 方案二:通過(guò)canvas生成帶有水印的圖片

oss實(shí)現(xiàn)

oss方式不做過(guò)多描述了 簡(jiǎn)單來(lái)說(shuō)就是通過(guò)在獲取圖片時(shí),在圖片鏈接上增加參數(shù),讓oss生成一張帶水印的圖片。 注意點(diǎn):

  • png圖片的透明區(qū)域無(wú)法被添加水印。 解決方式: 可通過(guò)添加參數(shù)的方式,讓oss將圖片轉(zhuǎn)為jpg格式(jpg格式會(huì)對(duì)透明區(qū)域做顏色填充)。

  • 字體大小寫(xiě)為定值,原圖大小會(huì)影響到水印字體的顯示大小。 解決方式:通過(guò)創(chuàng)建img標(biāo)簽,onLoad獲取圖片后,根據(jù)圖片寬高計(jì)算合適的字體大小,然后再一次獲取帶水印的圖片。

  • 用戶(hù)通過(guò)刪除參數(shù)的方式可以刪除水印 解決方式:設(shè)置oss的安全級(jí)別,不帶水印不可訪(fǎng)問(wèn)。

canvas實(shí)現(xiàn)

  • 將img轉(zhuǎn)為canvas
async function imgToCanvas(cav, imgSrc) {
  const img = new Image();
  img.src = imgSrc;
  // 防止因跨域?qū)е碌膱D片加載失敗(該方法有局限性)
  img.setAttribute("crossOrigin", "anonymous");
  // 等待圖片加載
  await new Promise(resolve => (img.onload = resolve));
  cav.width = img.width;
  cav.height = img.height;
  const ctx = cav.getContext("2d");
  if (ctx) {
    ctx.drawImage(img, 0, 0);
  }
  return cav;
}
  • 添加水印
function addWaterMask(cav, content) {
  const ctx = cav.getContext("2d");
  ctx.fillStyle = "rgba(100,100,100,0.2)";
  ctx.font = `24px serif`;
  ctx.translate(0, 0);
  ctx.rotate((5 * Math.PI) / 180);
  // 生成水印
  let x = 0, y = 0;
  while (x < cav.width) {
    y = 0;
    while (y < cav.height) {
      ctx.fillText(content, x, y);
      y += 100;
    }
    x += 150;
  }
}
  • 使用
(async function () {
  const canvas = document.createElement("canvas");
  await imgToCanvas(
    canvas,
    "https://pp.myapp.com/ma_pic2/0/shot_54360764_1_1716462139/0"
  );
  addWaterMask(canvas, "介四sui印");
  // document.body.appendChild(canvas);
  return canvas.toDataUrl("image/png")
})();

到此這篇關(guān)于關(guān)于JS前端實(shí)現(xiàn)水印的代碼操作的文章就介紹到這了,更多相關(guān)JS實(shí)現(xiàn)水印內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 如何用RxJS實(shí)現(xiàn)Redux Form

    如何用RxJS實(shí)現(xiàn)Redux Form

    這篇文章主要介紹了如何用RxJS實(shí)現(xiàn)Redux Form,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-12-12
  • JavaScript this綁定過(guò)程深入詳解

    JavaScript this綁定過(guò)程深入詳解

    這篇文章主要介紹了JavaScript this綁定過(guò)程,結(jié)合實(shí)例形式深入分析了JavaScript中this關(guān)鍵字的功能、原理、綁定方式及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2018-12-12
  • js獲取URL的參數(shù)的方法(getQueryString)示例

    js獲取URL的參數(shù)的方法(getQueryString)示例

    getQueryString方法默認(rèn)返回的是 string如果是int類(lèi)型,則JS使用的時(shí)候,要進(jìn)行轉(zhuǎn)換一下,下面有個(gè)不錯(cuò)的示例,大家可以參考下
    2013-09-09
  • js實(shí)現(xiàn)簡(jiǎn)單的購(gòu)物車(chē)有圖有代碼

    js實(shí)現(xiàn)簡(jiǎn)單的購(gòu)物車(chē)有圖有代碼

    這篇文章主要介紹了用js實(shí)現(xiàn)的簡(jiǎn)單購(gòu)物車(chē),配有截圖,適合初學(xué)者
    2014-05-05
  • JavaScript中的for...of和for...in循環(huán)容易遇到的問(wèn)題及解決方法總結(jié)

    JavaScript中的for...of和for...in循環(huán)容易遇到的問(wèn)題及解決方法總結(jié)

    在 JavaScript 編程中,for...of 和 for...in 是常用的循環(huán)語(yǔ)法,但它們?cè)谑褂脮r(shí)可能會(huì)引發(fā)一些意想不到的問(wèn)題,本文將分享我在使用這兩種循環(huán)時(shí)所遇到的坑和經(jīng)驗(yàn),需要的朋友可以參考下
    2023-08-08
  • pdfmake生成pdf的使用方法

    pdfmake生成pdf的使用方法

    本文介紹了如何使用pdfmake第三方庫(kù)在項(xiàng)目中根據(jù)模板生成PDF文件,文中還提到了常用的配置,如頁(yè)眉和頁(yè)腳效果,對(duì)pdfmake pdf使用方法感興趣的朋友一起看看吧
    2024-09-09
  • Valerio 發(fā)布了 Mootools

    Valerio 發(fā)布了 Mootools

    Valerio 發(fā)布了 Mootools...
    2006-09-09
  • 第二章之Bootstrap 頁(yè)面排版樣式

    第二章之Bootstrap 頁(yè)面排版樣式

    Bootstrap 是基于 HTML、CSS、JAVASCRIPT 的,它簡(jiǎn)潔靈活,使得 Web 開(kāi)發(fā)更加快捷。本文給大家介紹Bootstrap 頁(yè)面排版樣式的相關(guān)知識(shí),希望對(duì)大家有所幫助!
    2016-04-04
  • JavaScript之clipboard用法詳解

    JavaScript之clipboard用法詳解

    這篇文章主要介紹了JavaScript之clipboard用法詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • js png圖片(有含有透明)在IE6中為什么不透明了

    js png圖片(有含有透明)在IE6中為什么不透明了

    png-8模式的圖片,如果沒(méi)有漸變的話(huà)是透明的,如果有漸變就不透明了。需要js的支持。
    2010-02-02

最新評(píng)論