Heim > Web-Frontend > js-Tutorial > Hauptteil

Ausführliche Erklärung, wie Sie mit JS einen Overlay-Wasserzeicheneffekt erzielen

藏色散人
Freigeben: 2023-03-03 19:57:44
nach vorne
2165 Leute haben es durchsucht

Der Anfang des Unsinns: Implementieren Sie einfach eine kleine Funktion, um Wasserzeichen zu Bildern hinzuzufügen, und laden Sie dann die verarbeiteten Bilder direkt herunter. URL Die Bilder werden hier nicht geändert, aber die Wasserzeichen werden direkt hinzugefügt Leinwand Maske auf dem Dom.

1. Wirkung

Vor der Verarbeitung

DIV

Ausführliche Erklärung, wie Sie mit JS einen Overlay-Wasserzeicheneffekt erzielen

IMG

Ausführliche Erklärung, wie Sie mit JS einen Overlay-Wasserzeicheneffekt erzielen

Nach der Verarbeitung

DIV

Ausführliche Erklärung, wie Sie mit JS einen Overlay-Wasserzeicheneffekt erzielen

IMG

Ausführliche Erklärung, wie Sie mit JS einen Overlay-Wasserzeicheneffekt erzielen

Fügen Sie hier „Wasserzeichen“ hinzu " "(Tatsächlich handelt es sich nicht um ein echtes Wasserzeichen) Beim Erreichen von DIV ist das Schaltflächenklickereignis aufgrund der Maske

2. JS-Code

class WaterMark{
    //水印文字
    waterTexts = []
    //需要添加水印的dom集合
    needAddWaterTextElementIds = null
    //保存添加水印的dom
    saveNeedAddWaterMarkElement = []
    //初始化
    constructor(waterTexts,needAddWaterTextElementIds){
        if(waterTexts && waterTexts.length != 0){
            this.waterTexts = waterTexts
        } else {
            this.waterTexts = ['水印文字哈哈哈哈','2022-12-08']
        }
        this.needAddWaterTextElementIds = needAddWaterTextElementIds
    }
    
    //开始添加水印
    startWaterMark(){
        const self = this
        if(this.needAddWaterTextElementIds){
            this.needAddWaterTextElementIds.forEach((id)=>{
                let el = document.getElementById(id)
                self.saveNeedAddWaterMarkElement.push(el)
            })
        } else {
            this.saveNeedAddWaterMarkElement = Array.from(document.getElementsByTagName('img'))
        }
        this.saveNeedAddWaterMarkElement.forEach((el)=>{
            self.startWaterMarkToElement(el)
        })
    }

    //添加水印到到dom对象
    startWaterMarkToElement(el){
        let nodeName = el.nodeName
        if(['IMG','img'].indexOf(nodeName) != -1){
            //图片,需要加载完成进行操作
            this.addWaterMarkToImg(el)
        } else {
            //普通,直接添加
            this.addWaterMarkToNormalEle(el)
        }
    }
        
    //给图片添加水印
    async addWaterMarkToImg(img){
        if(!img.complete){
            await new Promise((resolve)=>{
                img.onload = resolve
            })
        }
        this.addWaterMarkToNormalEle(img)
    }
    
    //给普通dom对象添加水印
    addWaterMarkToNormalEle(el){
        const self = this
        let canvas = document.createElement('canvas')
        canvas.width = el.width ? el.width : el.clientWidth
        canvas.height = el.height ? el.height : el.clientHeight
        let ctx = canvas.getContext('2d')
        let maxSize = Math.max(canvas.height, canvas.width)
        let font = (maxSize / 25)
        ctx.font = font + 'px "微软雅黑"'
        ctx.fillStyle = "rgba(195,195,195,1)"
        ctx.textAlign = "left"
        ctx.textBaseline = "top"
        ctx.save()
        let angle = -Math.PI / 10.0
        //进行平移,计算平移的参数
        let translateX = (canvas.height) * Math.tan(Math.abs(angle))
        let translateY = (canvas.width - translateX) * Math.tan(Math.abs(angle))
        ctx.translate(-translateX / 2.0, translateY / 2.0)
        ctx.rotate(angle)
        //起始坐标
        let x = 0
        let y = 0
        //一组文字之间间隔
        let sepY = (font / 2.0)
        while(y < canvas.height){
            //当前行的y值
            let rowCurrentMaxY = 0
            while(x < canvas.width){
                let totleMaxX = 0
                let currentY = 0
                //绘制水印
                this.waterTexts.forEach((text,index)=>{
                    currentY += (index * (sepY + font))
                    let rect = self.drawWater(ctx,text,x,y + currentY)
                    let currentMaxX = (rect.x + rect.width)
                    totleMaxX = (currentMaxX > totleMaxX) ? currentMaxX: totleMaxX
                    rowCurrentMaxY = currentY
                })
                x = totleMaxX + 20
            }
            //重置x,y值
            x = 0
            y += (rowCurrentMaxY + (sepY + font + (canvas.height / 5)))
        }
        ctx.restore()
        //添加canvas
        this.addCanvas(canvas,el)
    }

    //绘制水印
    drawWater(ctx,text,x,y){
        //绘制文字
        ctx.fillText(text,x,y)
        //计算尺度
        let textRect = ctx.measureText(text)
        let width = textRect.width
        let height = textRect.height
        return {x,y,width,height}
    }

    //添加canvas到当前标签的父标签上
    addCanvas(canvas,el){
        //创建div(canvas需要依赖一个div进行位置设置)
        let warterMarDiv = document.createElement(&#39;div&#39;)
        //关联水印dom对象
        el.warterMark = warterMarDiv
        //添加样式
        this.resetCanvasPosition(el)
        //添加水印
        warterMarDiv.appendChild(canvas)
        //添加到父标签
        el.parentElement.insertBefore(warterMarDiv,el)
    }

    //重新计算位置
    resetCanvasPosition(el){
        if(el.warterMark){
            //设置父标签的定位
            el.parentElement.style.cssText = `position: relative;`
            //设施水印载体的定位
            el.warterMark.style.cssText = &#39;position: absolute;top: 0px;left: 0px;pointer-events:none&#39;
        }
    }
}
Nach dem Login kopieren

Verwendung

<div>
    <!-- 待加水印的IMG -->
    <img   style="max-width:90%" src="" alt="">
</div>

let waterMark = new WaterMark()
waterMark.startWaterMark();
Nach dem Login kopieren

ctx. save() und ctx.restore() sind hier eigentlich nicht sehr nützlich, werden aber dennoch hinzugefügt. Der Zweck besteht darin, den Kontext vor dem Hinzufügen des Wasserzeichens zu speichern und den Kontext vor dem Wasserzeichen wiederherzustellen , diese kursiv geschriebenen Wörter stehen nur zwischen diesen beiden Codezeilen. Wenn Sie unten andere Zeilen zeichnen, hat dies keine Auswirkungen.

Um zu verhindern, dass das Maskenwasserzeichen darunterliegende Schaltflächen oder andere Ereignisse blockiert, müssen Sie das Attribut pointer-events:none zur Maskenbezeichnung hinzufügen.

Sie müssen zusätzlich zum Label ein Parent-Tag hinzufügen, um das Wasserzeichen hinzuzufügen. Die Funktion dieses Parent-Tags besteht darin, der Position der Mask-Leinwand Einschränkungen hinzuzufügen um die Änderungen in body zu beobachten, um mask version canvas zu aktualisieren, ist dieser Versuch fehlgeschlagen, da in diesem Rückruf komplexe Layoutänderungen ausgelöst werden. Daher müssen Sie direkt außerhalb des Etiketts, an dem das Wasserzeichen hinzugefügt wird, ein „übergeordnetes Tag“ hinzufügen und dieses „übergeordnete Tag“ verwenden, um die Position der „Maskenleinwand“ automatisch einzuschränken. MutationObserver Die Logik ist wie folgt: Sie können das Layout oder andere Vorgänge im Listening-Callback zeitlich ändern (vorübergehend aufgeben).

var MutationObserver = window.MutationObserver || window.webkitMutationObserver || window.MozMutationObserver;
var mutationObserver = new MutationObserver(function (mutations) {
    //修改水印位置
})

mutationObserver.observe(document.getElementsByTagName(&#39;body&#39;)[0], {
    childList: true, // 子节点的变动(新增、删除或者更改)
    attributes: true, // 属性的变动
    characterData: true, // 节点内容或节点文本的变动
    subtree: true // 是否将观察器应用于该节点的所有后代节点
})
Nach dem Login kopieren
Die Größe des Bildes kann erst nach Abschluss des Ladevorgangs bestimmt werden. Für den Betrieb von IMG müssen Sie daher das Ereignis

complete beobachten. 3. Zusammenfassung und Gedanken Das vorherige Auf dem Bild ist dies auch eine Möglichkeit, aber manchmal sind aufgrund des Bildes die base64

-Daten des endgültigen zusammengesetzten Bildes leer, sodass das direkte Hinzufügen einer Maske nur der Anzeige selbst dient und nicht der Generierung eines echten zusammengesetzten Bildes . Es wurde ein einfaches „Pseudo-Wasserzeichen“ implementiert. Der Code ist ungeschickt „

Das obige ist der detaillierte Inhalt vonAusführliche Erklärung, wie Sie mit JS einen Overlay-Wasserzeicheneffekt erzielen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:juejin.im
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!