本帖最后由 夸克逃逸 于 2024-1-19 21:25 编辑
历史文章:【运营福利】一键免费下载高清无水印海报和LOGO,支持自动裁剪
插件Github项目地址:https://github.com/quarkape/free-canvas
----------
Free Canvas更新了!此次更新版本为4.2.0,重要更新如下:
1. 修复了标智客官网代码修改,导致浏览器拓展程序不能正常导出LOGO和海报的问题
2. 优化了UI界面
3. 删除了非登录状态下标智客导出的功能(该网站在非登录状态下功能受限)
----------
主要代码逻辑:
1. 定位网站LOGO位置
2. 将LOGO的网页代码另存为 .svg 文件
其中,特别要注意裁剪为正方形功能,需要判断logo的边界,然后确定logo合适的移动方向和距离,最后确定是否需要移动背景。主要代码如下:
function calcEdge() {
let svgRect = svg_part_copy.getBoundingClientRect();
let leftMin = Number.MAX_SAFE_INTEGER, topMin = Number.MAX_SAFE_INTEGER;
let rightMax = Number.MIN_SAFE_INTEGER, bottomMax = Number.MIN_SAFE_INTEGER;
let nodes = svg_part_copy.children;
let boxNodes = svgBoxNodes.children;
// 对应的删除rect-box里面的内容
let placeCount = -1;
// 判断是否存在
// 由于已经去除了水印,所以克隆节点的节点数比原节点少一个,如果勾选了去除背景,那就少两个
let nodesNum = keepbg ? 2 : 1;
if ((nodes.length - nodesNum) !== boxNodes.length) {
resp('检测到插件不适用于此logo,请检查logo中是否有文字素材。如果有,请单击文字素材,然后点击左上角取消编组,重复此过程直到logo中所有文字素材都取消了编组。');
return false;
}
// 排除一些非g标签对index的影响
for (let index=0;index<nodes.length;index++) {
// 计算上下左右边界
if (nodes[index].nodeName.toLowerCase() === 'defs') {
continue;
}
placeCount++;
let transAttr = nodes[index].getAttribute("transform");
let transl = transAttr.match(pat)[0].split(",");
let transLeft = parseFloat(transl[0]), transTop = parseFloat(transl[1]), transRight = 0, transBottom = 0;
// 消除rect对实际宽高的影响
let innersvg_part_copys = nodes[index].firstChild.children;
// 部分组件的参考点不是左上角,需要对比处理
// 这里要注意index+1,因为克隆的那个背景被去掉了,因此要在克隆的节点的基础上加上1才能得到原始节点的数据
let boxTrans = boxNodes[placeCount].style.transform.match(patBox)[0].split(",");
/**
* box的translate属性一定是正确的,参考点一定是左上角,所以需要与之判断,进而确定svg节点是不是以左上角为参考点
* 在做对比看参考点的时候,用原来的的svg与原来的box比较,但是最后是在克隆的svg上面做修改
* 如果参考点x为0(假设此时y的参考点也为0)
* 这里的判断方法并非完美
*/
if (Math.abs(parseInt(transLeft) - parseInt(boxTrans[0])) <= 1) {
if (innersvg_part_copys[0].nodeName !== "rect") {
// 第一层没有第二层有
let finalsvg_part_copys = innersvg_part_copys[0].children;
if (finalsvg_part_copys.length > 1 && finalsvg_part_copys[0].nodeName === "rect") {
let gRect = finalsvg_part_copys[1].getBoundingClientRect();
transLeft = gRect.left - svgRect.left;
transTop = gRect.top - svgRect.top;
// 上面已经计算了部分内容,下面只需要加上width就够了
transRight = transLeft + gRect.width;
transBottom = transTop + gRect.height;
} else {
// 第一层没有第二层也没有
transRight = transLeft + parseFloat(innersvg_part_copys[1].getAttribute("width"));
transBottom = transTop + parseFloat(innersvg_part_copys[1].getAttribute("height"));
}
} else {
// 第一层有
transRight = transLeft + parseFloat(innersvg_part_copys[1].getAttribute("width"));
transBottom = transTop + parseFloat(innersvg_part_copys[1].getAttribute("height"));
}
} else { // 参考点x不为0
if (innersvg_part_copys[0].nodeName !== "rect") {
let finalsvg_part_copys = innersvg_part_copys[0].children;
// 第一层没有第二层有
if (finalsvg_part_copys.length > 1 && finalsvg_part_copys[0].nodeName === "rect") {
let gRect = innersvg_part_copys[0].lastChild.getBoundingClientRect();
transLeft = gRect.left - svgRect.left;
transTop = gRect.top - svgRect.top;
// 上面已经计算了部分内容,下面只需要加上width就够了
transRight = transLeft + gRect.width;
transBottom = transTop + gRect.height;
} else {
// 第一层没有第二层也没有
let itemRect = nodes[index].getBoundingClientRect();
transLeft = itemRect.left - svgRect.left;
transTop = itemRect.top - svgRect.top;
transRight = transLeft + itemRect.width;
transBottom = transTop + itemRect.height;
}
} else {
// 第一层有
// let itemRect = nodes[index].getBoundingClientRect();
// 这里默认第二个元素不再是rect,而且是svg
let itemRect = innersvg_part_copys[1].getBoundingClientRect();
transLeft = itemRect.left - svgRect.left;
transTop = itemRect.top - svgRect.top;
transRight = transLeft + itemRect.width;
transBottom = transTop + itemRect.height;
}
}
if (transLeft < leftMin) {
leftMin = transLeft;
}
if (transTop < topMin) {
topMin = transTop;
}
if (transRight > rightMax) {
rightMax = transRight;
}
if (transBottom > bottomMax) {
bottomMax = transBottom;
}
}
const conf = {
'leftMin': leftMin,
'topMin': topMin,
'rightMax': rightMax,
'bottomMax': bottomMax
}
return conf;
}
----------
未来发展:
目前,项目一直开源,已经累积了298个star。从22年底第一次开源项目以来,受到了一些朋友的关注,也陆陆续续收到了一些反馈。未来,我还是想要继续把这个插件做下去,主要包括几个方面的发展:
1. 增加更多可用的网站
2. 增加更多功能,例如圆形裁剪、裁剪自定义留白等
-----------
因为LOGO官网代码更新,插件需要不断维护,维护成本不小。未来想要在谷歌浏览器商店上面推出插件,开放基础功能。用户可以通过一次性付费开通高级功能,并持续获得更新后的代码~~ |