Example of implementing dashed border with html2canvas

Example of implementing dashed border with html2canvas

html2canvas is a library that generates canvas from html elements. Most of the styles of the drawn canvas are consistent with CSS. For example, as of 1.0.0-alpha.12, dashed borders are still drawn as solid lines, and border-collapse still has problems.

Here, based on an idea in github issues, the dashed border effect is simulated and implemented.

Applicable situations: There are many separate borders, that is, not a complete border, and border-radius is not considered

1. First, before drawing in html2canvas, find out the direction and position of all dotted borders in the element where the canvas needs to be drawn

findDashedBorders = (page) => {
        const tds = page.querySelectorAll("td");
        const borders = [];
        tds.forEach(td => {
            const computedStyle = window.getComputedStyle(td);
            const borderStyle = computedStyle.borderStyle ? computedStyle.borderStyle.split(' ') : [];
            const dashedIndex = findAll(borderStyle, 'dashed');
            if (dashedIndex.length) {
                const rect = td.getBoundingClientRect();
                dashedIndex.map(index => {
                    const border = {
                        rect,
                        border: dashedBorder[index]
                    }
                    borders.push(border);
                    td.style[`border${dashedBorder[index]}Color`] = 'transparent';
                });
            }
        });
        return borders;
    }

Page is the element that needs to draw the canvas. All the elements with dashed borders are td elements, so find all td elements and use the getComputedStyle() method to find its borderStyle. If it has a dashed border, the value of this attribute is in the form of "dashed dashed none none", so find all dashed directions according to the custom findAll() method (for example, "dashed dashed none none" will return [0, 1]), where the dashedBorder array is as follows:

const dashedBorder = ["Top", "Right", "Bottom", "Left"];

After finding the direction, get its position at the same time, store the direction and position information in the borders array, and set this border to transparent so that html2canvas does not draw this frame. We will deal with it separately later. (Note: The dotted borders on this page will become transparent. This does not consider changing the transparent border back to its original color after drawing is completed.)

2. Use html2canvas to get the drawn canvas

pages.forEach((page, idx) => {
    const borders = this.findDashedBorders(page);
    const parentRect = page.getBoundingClientRect();
    html2canvas(page, {scale: 2, logging: false, useCORS: true}).then((canvas) => {
       this.drawDashedBorder(canvas, borders, parentRect);
       ......
    })
})

Pages are all the elements that need to be drawn on the canvas. When we get the dashed border of each page, we also get the position of the page so that when we draw the dashed border, we can get the position of the border relative to the page. After html2canvas draws the canvas, we further draw the dashed border through the drawDashedBorder() method. Let's implement this method.

3. drawDashedBorder() further draws the dotted line after getting the canvas.

drawDashedBorder = (canvas, borders, parentRect) => {
        var ctx = canvas.getContext("2d");
        ctx.setLineDash([6, 3]);
        ctx.strokeStyle = '#3089c7';
        ctx.lineWidth = 1;
        ctx.globalAlpha = 1;

        borders.forEach(border => {
            var left = (border.rect.left + 0.5 - parentRect.left)*2;
            var right = (border.rect.right - 0.5 - parentRect.left)*2;
            var top = (border.rect.top + 0.5 - parentRect.top)*2;
            var bottom = (border.rect.bottom - 0.5 - parentRect.top)*2;

            switch (border.border) {
                case 'Top':
                    ctx.beginPath();
                    ctx.moveTo(left, top);
                    ctx.lineTo(right, top);
                    ctx.stroke();
                    break;
                case 'Right':
                    ctx.beginPath();
                    ctx.moveTo(right, top);
                    ctx.lineTo(right, bottom);
                    ctx.stroke();
                    break;
                case 'Bottom':
                    ctx.beginPath();
                    ctx.moveTo(left, bottom);
                    ctx.lineTo(right, bottom);
                    ctx.stroke();
                    break;
                case 'Left':
                    ctx.beginPath();
                    ctx.moveTo(left, top);
                    ctx.lineTo(left, bottom);
                    ctx.stroke();
                    break;
                default:
                    break;
            }
        })
    }

This means that according to the direction and position information of the dashed border in borders, the dashed line is drawn using the setLineDash method after obtaining the 2D context in the canvas. The positions are all *2 because we used twice the size of the canvas before.

4. This method is currently only available for testing in Chrome, and is invalid in Firefox because the information returned by getComputedStyle in Firefox is different from that in Chrome.

Since I don't have a deep understanding of canvas and cannot pr, I can only look forward to the official implementation of html2canvas.

The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM.

<<:  A Brief Analysis of MySQL - MVCC

>>:  Velocity.js implements page scrolling switching effect

Recommend

Several commonly used methods for centering CSS boxes (summary)

The first one: Using the CSS position property &l...

How to view and terminate running background programs in Linux

Linux task management - background running and te...

Introduction to general_log log knowledge points in MySQL

The following operation demonstrations are all ba...

How to develop uniapp using vscode

Because I have always used vscode to develop fron...

Detailed explanation of Deepin using docker to install mysql database

Query the MySQL source first docker search mysql ...

JavaScript Basics Variables

Table of contents 1. Variable Overview 1.1 Storag...

How to query and update the same table in MySQL database at the same time

In ordinary projects, I often encounter this prob...

Detailed explanation on how to modify the default port of nginx

First find out where the configuration file is wh...

Detailed explanation of DOM style setting in four react components

1. Inline styles To add inline styles to the virt...

JavaScript to achieve the effect of tab bar switching

Tab bar: Click different tabs to display differen...

Vue implements multi-tab component

To see the effect directly, a right-click menu ha...

javascript:void(0) meaning and usage examples

Introduction to void keyword First of all, the vo...

Content-type description, that is, the type of HTTP request header

To learn content-type, you must first know what i...