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

vue2.x configuration from vue.config.js to project optimization

Table of contents Preface vue.config.js configura...

Using CSS3 to achieve progress bar effect and dynamically add percentage

During the project, I started using the js reques...

How to hide rar files in pictures

You can save this logo locally as a .rar file and...

Implementation of Nginx load balancing cluster

(1) Experimental environment youxi1 192.168.5.101...

A detailed introduction to the CSS naming specification BEM from QQtabBar

BEM from QQtabBar First of all, what does BEM mea...

Share a Markdown editor based on Ace

I think editors are divided into two categories, ...

Solution to the conflict between nginx and backend port

question: When developing the Alice management sy...

Vue.js $refs usage case explanation

Despite props and events, sometimes you still nee...

Solution to MySQL being unable to start due to excessive memory configuration

Problem Description MySQL reports an error when s...

MySQL triggers: creating and using triggers

This article uses examples to describe the creati...

Summary of the main attributes of the body tag

bgcolor="text color" background="ba...

Pure JavaScript to implement the number guessing game

Develop a number guessing game that randomly sele...

Testing of hyperlink opening target

The target attribute of a link determines where th...

HTML small tag usage tips

Phrase elements such as <em></em> can ...