preface

Recently, there is a demand for industrial automation in the project. If you make a button, it will have a pop-up effect. Surely you will say it is not so easy? Yes, that’s right, use CSS, write one every minute, but we are making topology diagram, using canvas, so I thought CSS drawing is also gpu drawing, I should be able to achieve the effect that CSS can do, so I tried to use CSS to make a canvas version of the button effect.

Css3 version of the stereo button effect

Think about how to make a button with CSS. The first thing we can think of is that the button needs to have a shadow. We can use box-shadow.

/ * x offset | y offset | shadow color * / box – shadow: 60 px – 16 px teal;

/ * x offset | y offset | | fuzzy shadow radius shadow color * / box – shadow: 10 px 5 px 5 px black;

/ * x offset | y offset | | | fuzzy shadow radius shadow diffusion radius of the shadow color * / box – shadow: 2 p 2 p 2 px 1 px rgba (0, 0, 0, 0.2);

/ * insert (shadow) inward offset | y | x offset | shadow color * / box – shadow: an inset 5 em 1 em gold;

/* Any number of shadows, separated by commas */ box-shadow: 3px 3px red, -1em 0 0.4em olive;

/* box-shadow: inherit; box-shadow: initial; box-shadow: unset;

First we define a BTN class and draw the basic style of a button

.btn {
    border-radius: 5px;
    padding: 15px 25px;
    font-size: 22px;
    text-decoration: none;
    margin: 20px;
    color: #fff;
    position: relative;
    display: inline-block;
}
Copy the code

Then let’s define the background color for the button

.blue {
    background-color: #55acee;
}
Copy the code

Here’s our basic button style, as follows:

Now let’s add a shadow to the button

.btn:active {
    transform: translate(0px, 5px);
    -webkit-transform: translate(0px, 5px);
    box-shadow: 0px 1px 0px 0px;
}

.blue {
    background-color: #55acee;
    box-shadow: 0px 5px 0px 0px #3C93D5;
}
Copy the code

After pressing the button, we need to remove the shadow. Then we need to shift the position of the button down by 5px in response to the effect as follows:

Canvas button effect

CSS buttons are already known to use box-shadow to draw shadows to achieve the style of buttons, so how do we draw shadows on canvas? Take a look at the all-powerful MDN

shadowOffsetX = float

ShadowOffsetX and shadowOffsetY are used to set the extension distance of the shadow on the X and Y axes. They are not affected by the transformation matrix. A negative value means the shadow will go up or left, and a positive value means it will go down or right, both of which default to 0.

shadowOffsetY = float

ShadowOffsetX and shadowOffsetY are used to set the extension distance of the shadow on the X and Y axes. They are not affected by the transformation matrix. A negative value means the shadow will go up or left, and a positive value means it will go down or right, both of which default to 0.

shadowBlur = float

The value of shadowBlur is not linked to the number of pixels and is not affected by the transformation matrix. The default value is 0.

shadowColor = color

ShadowColor is the standard CSS color value used to set the shadowColor effect. The default is full transparent black.

The first step is to draw a rectangle. To draw a rectangle we used moveTo and lineTo, because buttons usually have rounded corners, so we made a rectangle that draws rounded corners

createPath: function (x, y, width, height, radius) {
            this.ctx.moveTo(x, y + radius);
            this.ctx.lineTo(x, y + height - radius);
            this.ctx.quadraticCurveTo(x, y + height, x + radius, y + height);
            this.ctx.lineTo(x + width - radius, y + height);
            this.ctx.quadraticCurveTo(x + width, y + height, x + width, y + height - radius);
            this.ctx.lineTo(x + width, y + radius);
            this.ctx.quadraticCurveTo(x + width, y, x + width - radius, y);
            this.ctx.lineTo(x + radius, y);
            this.ctx.quadraticCurveTo(x, y, x, y + radius);
        },
Copy the code

Once the rounded rectangle is done, we’ll draw the shadows,

setShadow: function (xoffset, yoffset) {
    var style = this.style;
    this.ctx.shadowOffsetX = xoffset || 0;
    this.ctx.shadowOffsetY = yoffset || 5;
    this.ctx.shadowBlur = 0;
    this.ctx.shadowColor = style.shadowColor;
},
Copy the code

After the shadow is drawn, we also need to draw the text. After all, it is canvas, drawing the text is not as convenient as CSS, we need to calculate the text width to position, the code is as follows:

 drawText: function () {
     var xoffset = this.ctx.measureText(this.text).width;
     var x = this.x,
         y = this.y;
     if (this.state === 'active') {
         y = y + 5;
     }
     this.ctx.save();
     this.ctx.beginPath();
     this.ctx.font = "30px Micosoft yahei";
     this.ctx.fillStyle = this.fontColor;
     this.ctx.textBaseline = 'middle';
     this.ctx.textAlign = 'center';
     this.ctx.fillText(this.text, x + (this.width - xoffset) / 2 + 10, y + (this.height - 22) / 2 + 5.this.width);
     this.ctx.closePath();
     this.ctx.restore();
 },

Copy the code

Also attached is the description of textAlign and textBaseLine:

TextAlign:

TextBaseLine:

And then the effect is basically done

Canvas event can be viewed specifically from my code and my previous blog

Canvas glow effect

Above, we introduced how to draw the Canvas shadow stereo button. Next, we will try to achieve a further effect, multi-layer shadow overlay effect. In CSS, our box-shadow can overlay multi-layer shadow effect, separated by commas. So can we do the same for canvas? As we know, Canvas is state-based. If we want to draw multilayer shadow overlay, we need to save the shadows drawn each time and stack them together. So let’s change the code and save the Canvas state for each layer of shadow:

drawText: function (shadowx, shadowy, blur, shadowColor) {
            var xoffset = this.ctx.measureText(this.text).width;
            var x = this.x,
                y = this.y;
            this.ctx.save();
            this.ctx.beginPath();
            this.setShadow(shadowx, shadowy, blur, shadowColor);
            this.ctx.font = "300px Micosoft yahei";
            this.ctx.fillStyle = this.fontColor;
            this.ctx.textBaseline = 'middle';
            this.ctx.textAlign = 'center';
            this.ctx.fillText(this.text, x + (this.width - xoffset) / 2 + 10, y + (this.height - 22) / 2 + 5.this.width);
            this.ctx.closePath();
            this.ctx.restore();
        },
        
        setShadow: function (shadowx, shadowy, blur, shadowColor) {
            this.ctx.shadowOffsetX = shadowx || 0;
            this.ctx.shadowOffsetY = shadowy || 0;
            this.ctx.shadowBlur = blur || 10;
            this.ctx.shadowColor = shadowColor;
        },
Copy the code

The effect is as follows:

Not perfect, I have time to continue to optimize, animation light is not too soft, and the effect is still a little short compared with CSS, I will optimize it later, first mark it, do not spray if you do not like it.

conclusion

All knowledge is interchangeable. Learn more and think more. Do not forget what you have learned.

Refer to the link

Developer.mozilla.org/zh-CN/docs/…

Developer.mozilla.org/zh-CN/docs/…