gpt4 book ai didi

javascript - 如何重命名对象并在 FabricJS 中渲染 Canvas ?

转载 作者:行者123 更新时间:2023-12-05 05:35:53 24 4
gpt4 key购买 nike

我正在使用 FabricJS 5 并为我的图层实现了一个简单的显示。

当我按下铅笔按钮时,我会打开提示并使用以下函数重命名图层:

function RenameLayer(name) {
let layerObj = canvas.getItemByAttr("name", name);
let newName = prompt("Rename Layer?", layerObj.name);

while (checkIfNameExists(newName)) {
alert("Your layer name: " + layerObj.name + " is NOT unique please rename your layer differently.")
newName = prompt("Rename Layer?", layerObj.name);
}

layerObj.name = newName;
canvas.renderAll();
}

function checkIfNameExists(newName) {
count = 0;

canvas.forEachObject(function(obj, i) {
if (obj.name == newName) {
count++;
}
});

if (count > 0) {
return true;
} else {
return false;
}
}

但是,重命名后出现错误。

在下面找到我的示例:

<html lang="en">

<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.9.0/font/bootstrap-icons.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css">

<style>
html,
body {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
}

body {
touch-action: none;
background-image: linear-gradient(to bottom left, rgb(214, 240, 201) 10%, rgba(255, 231, 191, 1) 80%);
-webkit-user-select: none;
-moz-user-select: -moz-none;
-ms-user-select: none;
user-select: none;
}

.input-group {
padding: 4px;
}

.canvas-container {
margin: 0 auto;
width: 100%;
overflow: hidden;
background: url(./transparent.png);
background-size: 15px 15px;
box-shadow: rgba(60, 64, 67, 0.3) 0px 1px 2px 0px, rgba(60, 64, 67, 0.15) 0px 1px 3px 1px;
}

.actived {
background: #fff9a8;
}

#sortable {
max-height: 200px;
overflow: scroll;
}

.list-group {
line-height: 35px;
}

.svg-icon {
width: 1em;
height: 1em;
}

.svg-icon path,
.svg-icon polygon,
.svg-icon rect {
fill: #4691f6;
}

.svg-icon circle {
stroke: #4691f6;
stroke-width: 1;
}

#bkboxXX {
background: url(transparent.png);
border: 1px solid rgba(0, 0, 0, 0.3);
display: inline-block;
height: 19px;
width: 20px;
}

.bk-btn {
background: url(/transparent.png);
}

.fl {
float: left;
}

.fr {
float: right;
}

.input-group-text {
background-color: #f4f4f4;
}

.input-group-sm>.input-group-text {
/*
padding: .2rem .3rem !important;
*/
}

.list-group-item {
padding: 2px 10px;
;
cursor: pointer;
}

.list-group {
border-radius: 0;
text-align: left;
}
</style>
</head>

<body>
<div class="container-fluid h-100">
<div class="row h-100">
<div class="col-sm-3 border-end text-center h-100 overflow-scroll bg-light py-3">
<div class="form-floating w-100 mb-3 tour5">
<h6 class="mb-3">Add Element</h6>
<button class="btn btn-outline-primary" onclick="addText();" data-toggle="tooltip" data-placement="top" title="" data-bs-original-title="Add Text" aria-label="Add Text"><i
class="fa fa-font"></i></button>

<button class="btn btn-outline-primary" data-toggle="tooltip" data-placement="top" title="" onclick=" canvas.add(new fabric.Circle({ name: genNextName(), originX:'center', originY:'center', radius: 30, fill: 'green', top: 100, left: 100 }));" data-bs-original-title="Add Circle"
aria-label="Add Circle"><i
class="fa fa-circle"></i></button>
<button class="btn btn-outline-primary" data-toggle="tooltip" data-placement="top" title="" onclick=" canvas.add(new fabric.Triangle({ name: genNextName(), originX:'center', originY:'center', height:100, width:100, fill: 'red', top: 100, left: 100 }));"
data-bs-original-title="Add Triangle">
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="triangle" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class=""
style="height: 16px;top: 9px;">
<path fill="currentColor"
d="M329.6 24c-18.4-32-64.7-32-83.2 0L6.5 440c-18.4 31.9 4.6 72 41.6 72H528c36.9 0 60-40 41.6-72l-240-416z"
class=""></path>
</svg>
</button>
<button class="btn btn-outline-primary" data-toggle="tooltip" data-placement="top" title="" onclick="canvas.add(new fabric.Rect({ name: genNextName(), originX:'center', originY:'center', left: 110, top: 110, fill: '#000', width: 50, height: 50 }))" data-bs-original-title="Add Rectangle"><i class="fa fa-square-full"></i> </button>
</div>
<hr>
<div class="w-100 tour7 Xd-none Xd-sm-block">
<h6 class="mb-3">Elements</h6>
<ul class="list-group" id="sortable"></ul>
</div>
</div>
<div class="col-sm-6 my-auto py-4 overflow-hidden">
<div class="canvas-container" style="width: 329px; height: 329px; position: relative; user-select: none;"><canvas id="c" class="lower-canvas" width="329" height="329" style="position: absolute; width: 329px; height: 329px; left: 0px; top: 0px; touch-action: none; user-select: none;"></canvas>
</div>
</div>
<div class="col-sm-3 border-start py-3 h-100 overflow-scroll bg-light text-center">
right map
</div>
</div>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.js"></script>
<script src="https://unpkg.com/fabric@5.2.1/dist/fabric.min.js"></script>
<script src="https://rawcdn.githack.com/lyzerk/fabric-history/8c223cbdc8305307b4a8f8710f97da54d9146ffa/src/index.js"></script>
<script src="https://rawgit.com/fabricjs/fabric.js/master/lib/centering_guidelines.js"></script>
<script src="https://rawgit.com/fabricjs/fabric.js/master/lib/aligning_guidelines.js"></script>

<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.5.10/webfont.js"></script>

<script>
const rgba2hex = (rgba) => `#${rgba.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+\.{0,1}\d*))?\)$/).slice(1).map((n, i) => (i === 3 ? Math.round(parseFloat(n) * 255) : parseFloat(n)).toString(16).padStart(2, '0').replace('NaN', '')).join('')}`

function cn2h(cn) {
if (!cn) {
return 'transparent';
}
d = document.createElement("span");
d.style.display = "none";
d.style.color = cn
document.body.appendChild(d)
return rgba2hex(window.getComputedStyle(d).color);
}
</script>
<script>
var canvas;
var apiUrl;
var startedLoadingFamilies = false;
var to;
var scale;

fabric.Text.prototype.set({
_getNonTransformedDimensions() { // Object dimensions
return new fabric.Point(this.width, this.height).scalarAdd(this.padding);
},
_calculateCurrentDimensions() { // Controls dimensions
return fabric.util.transformPoint(this._getTransformedDimensions(), this.getViewportTransform(), true);
}
});

function fitCanvas(w, h) {
var scaleW = (document.querySelectorAll(".col-sm-6")[0].offsetWidth - 100) / w;
var scaleH = (document.querySelectorAll("body")[0].offsetHeight - 100) / h;
scale = Math.min(scaleH, scaleW);

if (scale > 1) {
scale = 1;
}


canvas.setZoom(scale);
canvas.setWidth(w * scale);
canvas.setHeight(h * scale);

initAligningGuidelines(canvas);
initCenteringGuidelines(canvas);

canvas.renderAll();
console.log("finished!!");

}

(function() {
canvas = new fabric.Canvas('c', {
allowTouchScrolling: true
});
WebFont.load({
google: {
families: ["Inter:200"]
},
active: function() {
canvas.loadFromJSON({
"height": "500",
"width": "500",
"edit": "yes",
"objects": [],
"backgroundImage": {
"crossOrigin": "anonymous"
}
}, function() {
fitCanvas(500, 500);
})
}
});

canvas.on('before:render', function(opt) {
canvas.getObjects().map(function(o, i) {
if (o.type.toLowerCase() == "textbox") {
var maxH = (o.maxHeight) ? (o.maxHeight) : (canvas.height);
o.set({
'maxHeight': maxH
});
if (o.fontSize > 0 && (maxH > o.fontSize)) {
while (o.height > maxH) {
o.set({
'fontSize': o.fontSize - 1
});
}
}
}

if (o.circleFrame) {
o.set({
clipPath: new fabric.Circle({
radius: o.width / 2,
originX: 'center',
originY: 'center'
})
});

}

if ((o.rx || o.ry) && o.type == "image") {

let rx = (o.rx || 0);
let ry = (o.ry || 0);

o.set({
clipPath: new fabric.Rect({
rx: rx,
ry: ry,
height: o.height,
width: o.width,
originX: 'center',
originY: 'center'
})
});
}
});
});
})();
</script>

<script>
fabric.Object.prototype.objectCaching = false;

function setCanvasBG(clr) {
canvas.backgroundColor = clr;
canvas.renderAll();
}

function changeDim() {
fitCanvas($("#widthC").val(), $("#heightC").val());
}

function setColor(clr, what = 'fill') {
canvas.getActiveObject().set(what, clr);
canvas.renderAll();
}

(function() {

$(document).on("mouseenter", "[data-label]", function() {
$("#font-search").val($(this).data("label"));
loadFont($(this).data("label"));
});

fabric.Canvas.prototype.getItemByAttr = function(attr, name) {
var object = null,
objects = this.getObjects();
for (var i = 0, len = this.size(); i < len; i++) {
if (objects[i][attr] && objects[i][attr] == name) {
object = objects[i];
break;
}
}
return object;
};

$("form#f").hide();

var activeObject;

$("#f input, #f select").on("input", function() {
if (["height", "width", "top", "left", "strokeWidth", "charSpacing"].includes(this.name)) {
canvas.getActiveObject().set(this.name, parseFloat(this.value)).setCoords();

} else {
canvas.getActiveObject().set(this.name, this.value).setCoords();
}
canvas.renderAll();
});

canvas.preserveObjectStacking = true;

fabric.Object.prototype.toObject = (function(toObject) {
return function() {
return fabric.util.object.extend(toObject.call(this), {
name: this.name,
text: this.text,
textAlign: this.textAlign,
fontSize: this.fontSize,
charSpacing: this.charSpacing,
lineHeight: this.lineHeight,
fontWeight: this.fontWeight,
fontFamily: this.fontFamily,
fontStyle: this.fontStyle,
textBackgroundColor: this.textBackgroundColor,
originX: this.originX,
originY: this.originY,
maxHeight: this.maxHeight,
height: this.height,
width: this.width,
radius: this.radius,
rx: this.rx,
ry: this.ry,
stroke: this.stroke,
padding: this.padding,
circleFrame: this.circleFrame
});
};
})(fabric.Object.prototype.toObject);

canvas.on('object:scaling', function(e) {
if (e.target.toObject().type != "image" && e.target.toObject().type != "circle") {
e.target.set({
width: e.target.width * e.target.scaleX,
height: e.target.height * e.target.scaleY,
scaleX: 1,
scaleY: 1
})
}
});

canvas.on('object:modified', function(opt) {
document.body.style.cursor = 'progress';
});

canvas.on("after:render", function() {

$("#sortable").empty();

canvas.includeDefaultValues = false;
canvas.toObject().objects.forEach(function(layer, id) {

if (typeof layer.name !== 'undefined') {
//console.log(id,layer.name);
//canvas.getItemByAttr(`name`, layer.name).set({ "name": String.fromCharCode(65 + id).toLowerCase() })
canvas.getItemByAttr(`name`, layer.name).set({
"name": layer.name.replace(/ /g, "_")
})
var actived = '';
if (canvas.getActiveObject()) {
actived = (canvas.getActiveObject().name == layer.name) ? " actived" : "";
}

$("#sortable").append('<li class="list-group-item ui-sortable-handle clearfix ' + actived + '" onClick="canvas.setActiveObject(canvas.getItemByAttr(`name`,`' + layer.name + '`)); canvas.renderAll();" id=' + layer.name + '>' + layer.name + ' (' + layer.type + ')' + '<span class="fr button-group"><a class="mx-2" title="Edit" href="#" onClick="RenameLayer(`' + layer.name + '`)"><i class="fa fa-pencil-alt" aria-hidden="true"></i></a><a class="mx-2" title="Delete" href="#" onClick="if(confirm(`Are you sure?`)){canvas.remove(canvas.getItemByAttr(`name`,`' + layer.name + '`)); canvas.renderAll();}"><i class="fa fa-trash-alt" aria-hidden="true"></i></a><a class="me-2" title="Duplicate this layer" href="#" onClick="Duplicate(`' + layer.name + '`); canvas.renderAll();"><i class="fa fa-clone" aria-hidden="true"></i></a></span></li>');
}
});
document.body.style.cursor = 'default'
});

canvas.on("selection:created", function(obj) {
if ("image" == obj.selected[0].type) {
canvas.getActiveObject().setControlsVisibility({
mb: false,
ml: false,
mt: false,
mr: false
});
}
$("form#f input[type!='hidden'], #f select").parent().hide();
$("form#f").hide();
canvas.renderAll();
});

canvas.on("selection:updated", function(obj) {
if ("image" == obj.selected[0].type) {
canvas.getActiveObject().setControlsVisibility({
mb: false,
ml: false,
mt: false,
mr: false
});
}
canvas.renderAll();
$("form#f").hide();
$("form#f input[type!='hidden'] , #f select, #f textarea").parent().hide();
});

canvas.on("selection:cleared", function() {
canvas.renderAll();
$("form#f").hide();
$("form#f input[type!='hidden'], #f select, #f textarea").parent().hide();
});

canvas.hoverCursor = 'default';
canvas.on('mouse:over', function(e) {
if (e.target) {
e.target._renderControls(canvas.contextTop, {
hasControls: false
})
}
});

canvas.on('mouse:out', function(e) {
canvas.clearContext(canvas.contextTop);
});
canvas.on('mouse:down', function(e) {
canvas.clearContext(canvas.contextTop);
});

addText = function() {
var text = new fabric.Textbox("Edit this Text", {
name: genNextName(),
left: canvas.getWidth() / canvas.getZoom() / 2,
top: canvas.getHeight() / canvas.getZoom() / 2,
width: (canvas.getWidth() / canvas.getZoom()) / 2,
fill: "#000000",
originX: "center",
originY: "center",
fontFamily: "Inter",
fontWeight: 400,
fontSize: 60,
padding: 20
});
text.setControlsVisibility({
mt: false,
mb: false,
ml: true,
mr: true,
tl: true,
tr: true,
bl: true,
br: true
});

canvas.add(text);
canvas.setActiveObject(text);
canvas.renderAll();
};
})();

function hide_mh_box() {
canvas.remove(canvas.getItemByAttr("isBB", true));
}

function show_mh_box() {
var h = parseInt($("[name=maxHeight]").val());
var n = new fabric.Rect({
top: canvas.getActiveObject().get('top'),
left: canvas.getActiveObject().get('left'),
width: canvas.getActiveObject().get('width'),
height: h,
originX: canvas.getActiveObject().get('originX'),
originY: canvas.getActiveObject().get('originY'),
angle: canvas.getActiveObject().get('angle'),
opacity: 1,
strokeWidth: 2,
stroke: "#FF00FF",
fill: "rgba(0,0,0,0)",
evented: !1,
isBB: true
});
canvas.add(n);
canvas.renderAll();
}

var visited = [];

$(document).ready(function() {

$("input[type=color]").on("input", function() {
$(this).parent().parent().find('input').first().val(this.value);
});

$("textarea, input").attr("autocomplete", "off");

if (window !== window.parent) {
const url = new URL(document.referrer);
$(".isIframe").removeClass('d-none');
$(".notIframe").hide();
}
});
</script>

<script>
function Duplicate(name) {
Copy(name);
}

function Copy(name) {
canvas.getItemByAttr("name", name).clone(function(cloned) {
cloned.set({
"name": genNextName()
})
_clipboard = cloned;
Paste(name);
canvas.renderAll();
});
}

function RenameLayer(name) {
let layerObj = canvas.getItemByAttr("name", name);

let newName = prompt("Rename Layer?", layerObj.name);

while (checkIfNameExists(newName)) {
alert("Your layer name: " + layerObj.name + " is NOT unique please rename your layer differently.")
newName = prompt("Rename Layer?", layerObj.name);
}

layerObj.name = newName;

canvas.renderAll();
}

function checkIfNameExists(newName) {
count = 0;

canvas.forEachObject(function(obj, i) {
if (obj.name == newName) {
count++;
}
});

if (count > 0) {
return true;
} else {
return false;
}
}

function Paste(name) {
_clipboard.clone(function(clonedObj) {
canvas.discardActiveObject();
clonedObj.set({
left: clonedObj.left + 10,
top: clonedObj.top + 10,
evented: true,
});
if (clonedObj.type === 'activeSelection') {
clonedObj.canvas = canvas;
clonedObj.forEachObject(function(obj) {
canvas.add(obj);
});
clonedObj.setCoords();
} else {
canvas.add(clonedObj);
}
_clipboard.top += 10;
_clipboard.left += 10;
canvas.setActiveObject(clonedObj);
canvas.requestRenderAll();
});
}

function genNextName() {
canvas.renderAll();
var total = canvas.getObjects().length;
return String.fromCharCode(65 + total).toLowerCase()
}

fabric.Object.prototype.transparentCorners = false;
fabric.Object.prototype.borderColor = '#5cdce4';
fabric.Object.prototype.cornerColor = 'white';
fabric.Object.prototype.cornerStrokeColor = 'blue';
fabric.Object.prototype.cornerStyle = 'circle';
fabric.Object.prototype.cornerSize = 10;
fabric.Object.prototype.borderScaleFactor = 2;
</script>
</body>

</html>

enter image description here

对我做错了什么有什么建议吗?

感谢您的回复!

最佳答案

我没有对代码进行深入调试,但由于在很多地方图层“名称”用作键值,您可以尝试在单独的 macrotask 中重命名图层(以及后续更新) , 使用 setTimeout

代替这段代码:

layerObj.name = newName;
canvas.renderAll();

试试这段代码:

setTimeout(() => {
layerObj.name = newName;
canvas.renderAll();
});

使用 setTimeout 的代码示例:

<html lang="en">

<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.9.0/font/bootstrap-icons.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css">

<style>
html,
body {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
}

body {
touch-action: none;
background-image: linear-gradient(to bottom left, rgb(214, 240, 201) 10%, rgba(255, 231, 191, 1) 80%);
-webkit-user-select: none;
-moz-user-select: -moz-none;
-ms-user-select: none;
user-select: none;
}

.input-group {
padding: 4px;
}

.canvas-container {
margin: 0 auto;
width: 100%;
overflow: hidden;
background: url(./transparent.png);
background-size: 15px 15px;
box-shadow: rgba(60, 64, 67, 0.3) 0px 1px 2px 0px, rgba(60, 64, 67, 0.15) 0px 1px 3px 1px;
}

.actived {
background: #fff9a8;
}

#sortable {
max-height: 200px;
overflow: scroll;
}

.list-group {
line-height: 35px;
}

.svg-icon {
width: 1em;
height: 1em;
}

.svg-icon path,
.svg-icon polygon,
.svg-icon rect {
fill: #4691f6;
}

.svg-icon circle {
stroke: #4691f6;
stroke-width: 1;
}

#bkboxXX {
background: url(transparent.png);
border: 1px solid rgba(0, 0, 0, 0.3);
display: inline-block;
height: 19px;
width: 20px;
}

.bk-btn {
background: url(/transparent.png);
}

.fl {
float: left;
}

.fr {
float: right;
}

.input-group-text {
background-color: #f4f4f4;
}

.input-group-sm>.input-group-text {
/*
padding: .2rem .3rem !important;
*/
}

.list-group-item {
padding: 2px 10px;
;
cursor: pointer;
}

.list-group {
border-radius: 0;
text-align: left;
}
</style>
</head>

<body>
<div class="container-fluid h-100">
<div class="row h-100">
<div class="col-sm-3 border-end text-center h-100 overflow-scroll bg-light py-3">
<div class="form-floating w-100 mb-3 tour5">
<h6 class="mb-3">Add Element</h6>
<button class="btn btn-outline-primary" onclick="addText();" data-toggle="tooltip" data-placement="top" title="" data-bs-original-title="Add Text" aria-label="Add Text"><i
class="fa fa-font"></i></button>

<button class="btn btn-outline-primary" data-toggle="tooltip" data-placement="top" title="" onclick=" canvas.add(new fabric.Circle({ name: genNextName(), originX:'center', originY:'center', radius: 30, fill: 'green', top: 100, left: 100 }));" data-bs-original-title="Add Circle"
aria-label="Add Circle"><i
class="fa fa-circle"></i></button>
<button class="btn btn-outline-primary" data-toggle="tooltip" data-placement="top" title="" onclick=" canvas.add(new fabric.Triangle({ name: genNextName(), originX:'center', originY:'center', height:100, width:100, fill: 'red', top: 100, left: 100 }));"
data-bs-original-title="Add Triangle">
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="triangle" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class=""
style="height: 16px;top: 9px;">
<path fill="currentColor"
d="M329.6 24c-18.4-32-64.7-32-83.2 0L6.5 440c-18.4 31.9 4.6 72 41.6 72H528c36.9 0 60-40 41.6-72l-240-416z"
class=""></path>
</svg>
</button>
<button class="btn btn-outline-primary" data-toggle="tooltip" data-placement="top" title="" onclick="canvas.add(new fabric.Rect({ name: genNextName(), originX:'center', originY:'center', left: 110, top: 110, fill: '#000', width: 50, height: 50 }))" data-bs-original-title="Add Rectangle"><i class="fa fa-square-full"></i> </button>
</div>
<hr>
<div class="w-100 tour7 Xd-none Xd-sm-block">
<h6 class="mb-3">Elements</h6>
<ul class="list-group" id="sortable"></ul>
</div>
</div>
<div class="col-sm-6 my-auto py-4 overflow-hidden">
<div class="canvas-container" style="width: 329px; height: 329px; position: relative; user-select: none;"><canvas id="c" class="lower-canvas" width="329" height="329" style="position: absolute; width: 329px; height: 329px; left: 0px; top: 0px; touch-action: none; user-select: none;"></canvas>
</div>
</div>
<div class="col-sm-3 border-start py-3 h-100 overflow-scroll bg-light text-center">
right map
</div>
</div>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.js"></script>
<script src="https://unpkg.com/fabric@5.2.1/dist/fabric.min.js"></script>
<script src="https://rawcdn.githack.com/lyzerk/fabric-history/8c223cbdc8305307b4a8f8710f97da54d9146ffa/src/index.js"></script>
<script src="https://rawgit.com/fabricjs/fabric.js/master/lib/centering_guidelines.js"></script>
<script src="https://rawgit.com/fabricjs/fabric.js/master/lib/aligning_guidelines.js"></script>

<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.5.10/webfont.js"></script>

<script>
const rgba2hex = (rgba) => `#${rgba.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+\.{0,1}\d*))?\)$/).slice(1).map((n, i) => (i === 3 ? Math.round(parseFloat(n) * 255) : parseFloat(n)).toString(16).padStart(2, '0').replace('NaN', '')).join('')}`

function cn2h(cn) {
if (!cn) {
return 'transparent';
}
d = document.createElement("span");
d.style.display = "none";
d.style.color = cn
document.body.appendChild(d)
return rgba2hex(window.getComputedStyle(d).color);
}
</script>
<script>
var canvas;
var apiUrl;
var startedLoadingFamilies = false;
var to;
var scale;

fabric.Text.prototype.set({
_getNonTransformedDimensions() { // Object dimensions
return new fabric.Point(this.width, this.height).scalarAdd(this.padding);
},
_calculateCurrentDimensions() { // Controls dimensions
return fabric.util.transformPoint(this._getTransformedDimensions(), this.getViewportTransform(), true);
}
});

function fitCanvas(w, h) {
var scaleW = (document.querySelectorAll(".col-sm-6")[0].offsetWidth - 100) / w;
var scaleH = (document.querySelectorAll("body")[0].offsetHeight - 100) / h;
scale = Math.min(scaleH, scaleW);

if (scale > 1) {
scale = 1;
}


canvas.setZoom(scale);
canvas.setWidth(w * scale);
canvas.setHeight(h * scale);

initAligningGuidelines(canvas);
initCenteringGuidelines(canvas);

canvas.renderAll();
console.log("finished!!");

}

(function() {
canvas = new fabric.Canvas('c', {
allowTouchScrolling: true
});
WebFont.load({
google: {
families: ["Inter:200"]
},
active: function() {
canvas.loadFromJSON({
"height": "500",
"width": "500",
"edit": "yes",
"objects": [],
"backgroundImage": {
"crossOrigin": "anonymous"
}
}, function() {
fitCanvas(500, 500);
})
}
});

canvas.on('before:render', function(opt) {
canvas.getObjects().map(function(o, i) {
if (o.type.toLowerCase() == "textbox") {
var maxH = (o.maxHeight) ? (o.maxHeight) : (canvas.height);
o.set({
'maxHeight': maxH
});
if (o.fontSize > 0 && (maxH > o.fontSize)) {
while (o.height > maxH) {
o.set({
'fontSize': o.fontSize - 1
});
}
}
}

if (o.circleFrame) {
o.set({
clipPath: new fabric.Circle({
radius: o.width / 2,
originX: 'center',
originY: 'center'
})
});

}

if ((o.rx || o.ry) && o.type == "image") {

let rx = (o.rx || 0);
let ry = (o.ry || 0);

o.set({
clipPath: new fabric.Rect({
rx: rx,
ry: ry,
height: o.height,
width: o.width,
originX: 'center',
originY: 'center'
})
});
}
});
});
})();
</script>

<script>
fabric.Object.prototype.objectCaching = false;

function setCanvasBG(clr) {
canvas.backgroundColor = clr;
canvas.renderAll();
}

function changeDim() {
fitCanvas($("#widthC").val(), $("#heightC").val());
}

function setColor(clr, what = 'fill') {
canvas.getActiveObject().set(what, clr);
canvas.renderAll();
}

(function() {

$(document).on("mouseenter", "[data-label]", function() {
$("#font-search").val($(this).data("label"));
loadFont($(this).data("label"));
});

fabric.Canvas.prototype.getItemByAttr = function(attr, name) {
var object = null,
objects = this.getObjects();
for (var i = 0, len = this.size(); i < len; i++) {
if (objects[i][attr] && objects[i][attr] == name) {
object = objects[i];
break;
}
}
return object;
};

$("form#f").hide();

var activeObject;

$("#f input, #f select").on("input", function() {
if (["height", "width", "top", "left", "strokeWidth", "charSpacing"].includes(this.name)) {
canvas.getActiveObject().set(this.name, parseFloat(this.value)).setCoords();

} else {
canvas.getActiveObject().set(this.name, this.value).setCoords();
}
canvas.renderAll();
});

canvas.preserveObjectStacking = true;

fabric.Object.prototype.toObject = (function(toObject) {
return function() {
return fabric.util.object.extend(toObject.call(this), {
name: this.name,
text: this.text,
textAlign: this.textAlign,
fontSize: this.fontSize,
charSpacing: this.charSpacing,
lineHeight: this.lineHeight,
fontWeight: this.fontWeight,
fontFamily: this.fontFamily,
fontStyle: this.fontStyle,
textBackgroundColor: this.textBackgroundColor,
originX: this.originX,
originY: this.originY,
maxHeight: this.maxHeight,
height: this.height,
width: this.width,
radius: this.radius,
rx: this.rx,
ry: this.ry,
stroke: this.stroke,
padding: this.padding,
circleFrame: this.circleFrame
});
};
})(fabric.Object.prototype.toObject);

canvas.on('object:scaling', function(e) {
if (e.target.toObject().type != "image" && e.target.toObject().type != "circle") {
e.target.set({
width: e.target.width * e.target.scaleX,
height: e.target.height * e.target.scaleY,
scaleX: 1,
scaleY: 1
})
}
});

canvas.on('object:modified', function(opt) {
document.body.style.cursor = 'progress';
});

canvas.on("after:render", function() {

$("#sortable").empty();

canvas.includeDefaultValues = false;
canvas.toObject().objects.forEach(function(layer, id) {

if (typeof layer.name !== 'undefined') {
//console.log(id,layer.name);
//canvas.getItemByAttr(`name`, layer.name).set({ "name": String.fromCharCode(65 + id).toLowerCase() })
canvas.getItemByAttr(`name`, layer.name).set({
"name": layer.name.replace(/ /g, "_")
})
var actived = '';
if (canvas.getActiveObject()) {
actived = (canvas.getActiveObject().name == layer.name) ? " actived" : "";
}

$("#sortable").append('<li class="list-group-item ui-sortable-handle clearfix ' + actived + '" onClick="canvas.setActiveObject(canvas.getItemByAttr(`name`,`' + layer.name + '`)); canvas.renderAll();" id=' + layer.name + '>' + layer.name + ' (' + layer.type + ')' + '<span class="fr button-group"><a class="mx-2" title="Edit" href="#" onClick="RenameLayer(`' + layer.name + '`)"><i class="fa fa-pencil-alt" aria-hidden="true"></i></a><a class="mx-2" title="Delete" href="#" onClick="if(confirm(`Are you sure?`)){canvas.remove(canvas.getItemByAttr(`name`,`' + layer.name + '`)); canvas.renderAll();}"><i class="fa fa-trash-alt" aria-hidden="true"></i></a><a class="me-2" title="Duplicate this layer" href="#" onClick="Duplicate(`' + layer.name + '`); canvas.renderAll();"><i class="fa fa-clone" aria-hidden="true"></i></a></span></li>');
}
});
document.body.style.cursor = 'default'
});

canvas.on("selection:created", function(obj) {
if ("image" == obj.selected[0].type) {
canvas.getActiveObject().setControlsVisibility({
mb: false,
ml: false,
mt: false,
mr: false
});
}
$("form#f input[type!='hidden'], #f select").parent().hide();
$("form#f").hide();
canvas.renderAll();
});

canvas.on("selection:updated", function(obj) {
if ("image" == obj.selected[0].type) {
canvas.getActiveObject().setControlsVisibility({
mb: false,
ml: false,
mt: false,
mr: false
});
}
canvas.renderAll();
$("form#f").hide();
$("form#f input[type!='hidden'] , #f select, #f textarea").parent().hide();
});

canvas.on("selection:cleared", function() {
canvas.renderAll();
$("form#f").hide();
$("form#f input[type!='hidden'], #f select, #f textarea").parent().hide();
});

canvas.hoverCursor = 'default';
canvas.on('mouse:over', function(e) {
if (e.target) {
e.target._renderControls(canvas.contextTop, {
hasControls: false
})
}
});

canvas.on('mouse:out', function(e) {
canvas.clearContext(canvas.contextTop);
});
canvas.on('mouse:down', function(e) {
canvas.clearContext(canvas.contextTop);
});

addText = function() {
var text = new fabric.Textbox("Edit this Text", {
name: genNextName(),
left: canvas.getWidth() / canvas.getZoom() / 2,
top: canvas.getHeight() / canvas.getZoom() / 2,
width: (canvas.getWidth() / canvas.getZoom()) / 2,
fill: "#000000",
originX: "center",
originY: "center",
fontFamily: "Inter",
fontWeight: 400,
fontSize: 60,
padding: 20
});
text.setControlsVisibility({
mt: false,
mb: false,
ml: true,
mr: true,
tl: true,
tr: true,
bl: true,
br: true
});

canvas.add(text);
canvas.setActiveObject(text);
canvas.renderAll();
};
})();

function hide_mh_box() {
canvas.remove(canvas.getItemByAttr("isBB", true));
}

function show_mh_box() {
var h = parseInt($("[name=maxHeight]").val());
var n = new fabric.Rect({
top: canvas.getActiveObject().get('top'),
left: canvas.getActiveObject().get('left'),
width: canvas.getActiveObject().get('width'),
height: h,
originX: canvas.getActiveObject().get('originX'),
originY: canvas.getActiveObject().get('originY'),
angle: canvas.getActiveObject().get('angle'),
opacity: 1,
strokeWidth: 2,
stroke: "#FF00FF",
fill: "rgba(0,0,0,0)",
evented: !1,
isBB: true
});
canvas.add(n);
canvas.renderAll();
}

var visited = [];

$(document).ready(function() {

$("input[type=color]").on("input", function() {
$(this).parent().parent().find('input').first().val(this.value);
});

$("textarea, input").attr("autocomplete", "off");

if (window !== window.parent) {
const url = new URL(document.referrer);
$(".isIframe").removeClass('d-none');
$(".notIframe").hide();
}
});
</script>

<script>
function Duplicate(name) {
Copy(name);
}

function Copy(name) {
canvas.getItemByAttr("name", name).clone(function(cloned) {
cloned.set({
"name": genNextName()
})
_clipboard = cloned;
Paste(name);
canvas.renderAll();
});
}

function RenameLayer(name) {
let layerObj = canvas.getItemByAttr("name", name);

let newName = prompt("Rename Layer?", layerObj.name);

while (checkIfNameExists(newName)) {
alert("Your layer name: " + layerObj.name + " is NOT unique please rename your layer differently.")
newName = prompt("Rename Layer?", layerObj.name);
}

setTimeout(() => {
layerObj.name = newName;
canvas.renderAll();
})

}

function checkIfNameExists(newName) {
count = 0;

canvas.forEachObject(function(obj, i) {
if (obj.name == newName) {
count++;
}
});

if (count > 0) {
return true;
} else {
return false;
}
}

function Paste(name) {
_clipboard.clone(function(clonedObj) {
canvas.discardActiveObject();
clonedObj.set({
left: clonedObj.left + 10,
top: clonedObj.top + 10,
evented: true,
});
if (clonedObj.type === 'activeSelection') {
clonedObj.canvas = canvas;
clonedObj.forEachObject(function(obj) {
canvas.add(obj);
});
clonedObj.setCoords();
} else {
canvas.add(clonedObj);
}
_clipboard.top += 10;
_clipboard.left += 10;
canvas.setActiveObject(clonedObj);
canvas.requestRenderAll();
});
}

function genNextName() {
canvas.renderAll();
var total = canvas.getObjects().length;
return String.fromCharCode(65 + total).toLowerCase()
}

fabric.Object.prototype.transparentCorners = false;
fabric.Object.prototype.borderColor = '#5cdce4';
fabric.Object.prototype.cornerColor = 'white';
fabric.Object.prototype.cornerStrokeColor = 'blue';
fabric.Object.prototype.cornerStyle = 'circle';
fabric.Object.prototype.cornerSize = 10;
fabric.Object.prototype.borderScaleFactor = 2;
</script>
</body>

</html>

这个解决方案不是最优的。但老实说,整个代码需要认真重构。但是,也许目前这样的解决方案能够适合您。

关于javascript - 如何重命名对象并在 FabricJS 中渲染 Canvas ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73409688/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com