1、先谈谈css能实现的自定义边框
(直接上图)
这是一个自定义的边框图。会发现、如果简单的强行当背景图片使用,然后撑满整个元素,在元素宽高比例不同的情况下、会出现图片拉伸情况(这里大家都能想到、我就不出代码展示直接上图)
如图:width: 100px; height: 50px时 出现了不想要的变形(不好看了)
(用css解决):border-image属性(边框图属性)。
border-image的5种属性(按顺序如下)
- border-image-source:定义边框图像的路径;
- border-image-slice:定义边框图像从什么位置开始分割;
- border-image-width:定义边框图像的厚度(宽度);
- border-image-outset:定义边框图像的外延尺寸(边框图像区域超出边框的量);
- border-image-repeat:定义边框图像的平铺方式。
(这里的属性就不一一介绍了,有需要的百度或者给楼主留言)
一个简单的例子:
<div class="box">
.box {
width: 200px;
border: 25px solid rgba(0, 0, 0, 0);
height: 100px;
border-image: url(./7.png) 88 round;
}
效果如图: 非常好看不变形,只是四条边被相应的拉长了。这时又会提出新的疑问、如果图我不想变,但是我觉得红色不好看。我要绿色。
变色:filter:drop-shadow(滤镜投影)
注:filter(滤镜)存在多种属性。我们只讲本节的实现属性。
filter:drop-shadow的4中属性(按顺序如下)
- color: 颜色
- offx: X轴偏移量
- offy: Y轴偏移量
- positive: boolear ---- true为所有非透明像素建立可见投影。false与true相反。
(最后一个属性可用png不带底色的镂空照片进行测试下。)
边框变色例子:
.box {
width: 200px;
border: 25px solid rgba(0, 0, 0, 0);
height: 100px;
border-image: url(./7.png) 88 round;
filter: drop-shadow(green 260px 0);
transform: translateX(-260px);
}
<div class="box">
效果如图: 效果实现,将红色自定义边框在不变形的情况下进行了大小调整、颜色改变(原理:生成颜色投影,然后将图片本体移出可视范围即可得到变色)
以上是css自定义边框实现的过程。
2、canvas实现自定义边框
鉴于浏览器兼容等原因。运用canvas也可实现上面的效果。
思路是将边框图切下一个角、和一条边。然后进行顺时针的平铺,最后染色的过程。
代码封装如下、可直接使用快餐。
// canvas生成边框
// 参数、id:绑定id X:绘画区域的宽度 Y:绘画区域的高度 img1:边框角图 img2:边框边图
// color:填充颜色rgb数组形式如黑色:[0,0,0]
const getFaceBorder = (id, x, y, img1, img2, color = null) => {
var cv = document.getElementById(id);
var ctxs = cv.getContext("2d");
ctxs.clearRect(0, 0, x, y);
Promise.all([loadImage(img1), loadImage(img2)]).then((imgs) => {
// 参数 1:要绘制的 img 参数 2、3:绘制的 img 在 canvas 中的坐标 参数4,5是width,height
// 5. 旋转转换,改变画笔的旋转角度
// ctxs.rotate((45 * Math.PI) / 180);
// 6. 调用绘制图片的方法把图片绘制到canvas中
// 自定义图片的大小
var canvasTemp = document.createElement('canvas');
var contextTemp = canvasTemp.getContext('2d');
canvasTemp.width = 20; // 目标宽度
canvasTemp.height = 20; // 目标高度
contextTemp.drawImage(imgs[1], 0, 0, 20, 20)
ctxs.drawImage(imgs[0], 0, 0, 20, 20);
ctxs.fillStyle = ctxs.createPattern(canvasTemp, "repeat-x");
ctxs.fillRect(19, 0, x - 38, 10); //填充画布
ctxs.translate(x, 0);
ctxs.rotate((90 * Math.PI) / 180);
ctxs.drawImage(imgs[0], 0, 0, 20, 20);
ctxs.fillStyle = ctxs.createPattern(canvasTemp, "repeat-x");
ctxs.fillRect(19, 0, y - 38, 10); //填充画布
ctxs.translate(y, 0);
ctxs.rotate((90 * Math.PI) / 180);
ctxs.drawImage(imgs[0], 0, 0, 20, 20);
ctxs.fillStyle = ctxs.createPattern(canvasTemp, "repeat-x");
ctxs.fillRect(19, 0, x - 38, 10); //填充画布
ctxs.translate(x, 0);
ctxs.rotate((90 * Math.PI) / 180);
ctxs.drawImage(imgs[0], 0, 0, 20, 20);
ctxs.fillStyle = ctxs.createPattern(canvasTemp, "repeat-x");
ctxs.fillRect(19, 0, y - 38, 10); //填充画布
ctxs.translate(y, 0);
ctxs.rotate((90 * Math.PI) / 180);
if (color) {
var imageData = ctxs.getImageData(0, 0, x, y);
var length = imageData.data.length;
for (var index = 0; index < length; index += 4) {
imageData.data[index] = color[0];
imageData.data[index + 1] = color[1];
imageData.data[index + 2] = color[2];
}
// 更新新数据
ctxs.putImageData(imageData, 0, 0);
}
})
};
// 实例化promise
const loadImage = (url) => {
return new Promise((resolve) => {
const img = new Image();
img.src = url;
img.setAttribute("crossOrigin", 'anonymous')
img.onload = () => resolve(img);
})
};
实现效果跟上面的css实现的大致一样。细节靠参数微调即可