Edit: Here I'm able to keep it in the back while selected but for some reason it's not dragable now. What might I be doing wrong?
I have the ability to upload an image from my puter and then to move the image around. My problem: When I select the image, it pops forward until I deselect it. Is it possible to have it remain BEHIND the image that I have it upload behind? Please see this JSFiddle of the problem. You'll notice that if you upload an image, the image pops forward above the frame—I want it to remain behind it when I move it, but still see the controls.
Thanks in advance!
var canvas = new fabric.Canvas('c');
var oImg, oImg2, isImageLoaded;
//initialize default frame (light brown wood oval)
fabric.Image.fromURL('.png', function(img) {
isImageLoaded = true;
oImg = img.set({
selectable: false,
}).scale(0.5);
canvas.add(oImg).renderAll();
canvas.sendToBack(oImg);
});
//initialize some text
canvas.add(new fabric.IText('Some Text', {
left: 475,
top: 25,
fontFamily: 'Monsieur La Doulaise',
fontSize: 27,
hasBorders: false,
hasControls: false,
selectable: true,
lockRotation: true,
lockMovementX: true,
lockMovementY: true,
align: 'mid',
originX: 'center',
originY: 'center',
centeredScaling: true,
}));
//initialize Some More Text
canvas.add(new fabric.IText('Some More Text', {
left: 475,
top: 60,
fontFamily: 'cinzel',
fontSize: 27,
hasBorders: false,
hasControls: false,
selectable: true,
lockRotation: true,
lockMovementX: true,
lockMovementY: true,
align: 'mid',
originX: 'center',
originY: 'center',
centeredScaling: true,
}));
//oImgObj bread and butter, kudos @grunt
function replaceImage(oImgObj, imgUrl) {
if (!isImageLoaded) return; //return if initial image not loaded
var imgElem = oImgObj._element; //reference to actual image element
imgElem.src = imgUrl; //set image source
imgElem.onload = () => canvas.renderAll(); //render on image load
}
// Download canvas as image
$("#d").click(function() {
$("#c").get(0).toBlob(function(blob) {
saveAs(blob, "memorialportrait.jpg");
});
});
// Upload an image to the canvas
document.getElementById('file').addEventListener("change", function(e) {
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function(f) {
var data = f.target.result;
fabric.Image.fromURL(data, function(img) {
var oImg = img.set({
left: 400,
top: 102
}).scale(.8);
canvas.add(oImg);
canvas.setActiveObject(oImg);
var image = canvas.getActiveObject();
image.moveTo(-1);
canvas.discardActiveObject();
canvas.renderAll();
canvas.sendToBack(oImg);
});
};
reader.readAsDataURL(file);
});
//fonts
document.getElementById('cinzel').addEventListener('click', function(e) {
canvas.getActiveObject().set("fontFamily", "cinzel");
canvas.renderAll();
});
document.getElementById('monsieurladoulaise').addEventListener('click', function(e) {
canvas.getActiveObject().set("fontFamily", "Monsieur La Doulaise");
canvas.renderAll();
});
document.getElementById('tangerine').addEventListener('click', function(e) {
canvas.getActiveObject().set("fontFamily", "tangerine");
canvas.renderAll();
});
// Upload link
$(function() {
$("#upload_link").on('click', function(e) {
e.preventDefault();
$("#file:hidden").trigger('click');
});
});
a.dropdown-item {
cursor: pointer;
}
.btn {
margin-top: 10px;
cursor: pointer;
}
canvas {
border: 1px solid #dddddd;
border-radius: 4px;
margin: 10px 0px 0px 12px;
cursor: pointer;
}
/* Styling the upload link */
#upload_link {
text-decoration: none;
}
#file {
display: none;
}
<script src=".js/1.7.20/fabric.min.js"></script>
<link href=".0.0-beta/css/bootstrap.min.css" rel="stylesheet"/>
<script src=".2.1.slim.min.js"></script>
<script src=".js/1.3.3/FileSaver.min.js"></script>
<script src=".0.0-beta/js/bootstrap.min.js"></script>
<script src=".js/1.11.0/umd/popper.min.js"></script>
<div class="container">
<div class="row">
<div class="col-md-2">
<button type="file" class="btn btn-dark btn-sm" id="upload_link">New Photo</button>
<br>
<input type="file" id="file" /><a href="" id="upload_link" hidden>Add Photo</a>
<div class="btn-group">
<button class="btn btn-dark btn-sm dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Choose your...</button>
<div class="dropdown-menu">
<!-- <h6 class="dropdown-header">Theme</h6>
<a onclick="replaceImage(oImg2, 'images/themes/none.png')" class="dropdown-item">None</a>
<a onclick="replaceImage(oImg2, 'images/themes/beach.png')" class="dropdown-item">Beach</a>
<div class="dropdown-divider"></div> -->
<h6 class="dropdown-header">Frame</h6>
<a onclick="replaceImage(oImg, 'images/frames/LightBrownWoodOval.png')" class="dropdown-item">Oval Light Brown</a>
<a onclick="replaceImage(oImg, 'images/frames/MidToneWoodFrameOval.png')" class="dropdown-item">Oval Mid Tone Wood</a>
<a onclick="replaceImage(oImg, 'images/frames/SilverFrameOval.png')" class="dropdown-item">Oval Silver</a>
<a onclick="replaceImage(oImg, 'images/frames/DistressedWhiteFrameRec.png')" class="dropdown-item">Rectangle Distressed White</a>
<a onclick="replaceImage(oImg, 'images/frames/GoldScrollFrameRec.png')" class="dropdown-item">Rectangle Gold Scroll</a>
<a onclick="replaceImage(oImg, 'images/frames/MidtoneWoodFrameRec.png')" class="dropdown-item">Rectangle Mid Tone Wood</a>
<a onclick="replaceImage(oImg, 'images/frames/SilverFrameRec.png')" class="dropdown-item">Rectangle Silver</a>
<div class="dropdown-divider"></div>
<h6 class="dropdown-header">Font</h6>
<a class="dropdown-item" id="cinzel" style="font-family:cinzel;">Cinzel</a>
<a class="dropdown-item" id="monsieurladoulaise" style="font-family:Monsieur La Doulaise;">Monsieur La Doulaise</a>
<a class="dropdown-item" id="tangerine" style="font-family:tangerine;">Tangerine</a>
</div>
</div>
<button id="d" type="button" class="btn btn-dark btn-sm">Download</button>
<br>
<button onclick="window.location.reload(true)" type="button" class="btn btn-danger btn-sm">Restart</button>
<br>
<!-- <div class="btn-group">
<button class="btn btn-light btn-sm dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">More</button>
<div class="dropdown-menu">
<a class="dropdown-item">Print</a>
<div class="dropdown-divider"></div>
<h6 class="dropdown-header">Advanced</h6>
<a class="dropdown-item disabled">Export to SVG</a>
</div>
</div> -->
</div>
<div class="col-md-10">
<canvas id="c" width="637" height="412"></canvas>
</div>
</div>
</div>
<!-- Our JS -->
<script src="scripts/memorial-portrait-creator.js"></script>
<!-- Optional JavaScript. jQuery first, then Popper.js, then Bootstrap JS -->
Edit: Here I'm able to keep it in the back while selected but for some reason it's not dragable now. What might I be doing wrong?
I have the ability to upload an image from my puter and then to move the image around. My problem: When I select the image, it pops forward until I deselect it. Is it possible to have it remain BEHIND the image that I have it upload behind? Please see this JSFiddle of the problem. You'll notice that if you upload an image, the image pops forward above the frame—I want it to remain behind it when I move it, but still see the controls.
Thanks in advance!
var canvas = new fabric.Canvas('c');
var oImg, oImg2, isImageLoaded;
//initialize default frame (light brown wood oval)
fabric.Image.fromURL('https://i.imgur./DrzSWSa.png', function(img) {
isImageLoaded = true;
oImg = img.set({
selectable: false,
}).scale(0.5);
canvas.add(oImg).renderAll();
canvas.sendToBack(oImg);
});
//initialize some text
canvas.add(new fabric.IText('Some Text', {
left: 475,
top: 25,
fontFamily: 'Monsieur La Doulaise',
fontSize: 27,
hasBorders: false,
hasControls: false,
selectable: true,
lockRotation: true,
lockMovementX: true,
lockMovementY: true,
align: 'mid',
originX: 'center',
originY: 'center',
centeredScaling: true,
}));
//initialize Some More Text
canvas.add(new fabric.IText('Some More Text', {
left: 475,
top: 60,
fontFamily: 'cinzel',
fontSize: 27,
hasBorders: false,
hasControls: false,
selectable: true,
lockRotation: true,
lockMovementX: true,
lockMovementY: true,
align: 'mid',
originX: 'center',
originY: 'center',
centeredScaling: true,
}));
//oImgObj bread and butter, kudos @grunt
function replaceImage(oImgObj, imgUrl) {
if (!isImageLoaded) return; //return if initial image not loaded
var imgElem = oImgObj._element; //reference to actual image element
imgElem.src = imgUrl; //set image source
imgElem.onload = () => canvas.renderAll(); //render on image load
}
// Download canvas as image
$("#d").click(function() {
$("#c").get(0).toBlob(function(blob) {
saveAs(blob, "memorialportrait.jpg");
});
});
// Upload an image to the canvas
document.getElementById('file').addEventListener("change", function(e) {
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function(f) {
var data = f.target.result;
fabric.Image.fromURL(data, function(img) {
var oImg = img.set({
left: 400,
top: 102
}).scale(.8);
canvas.add(oImg);
canvas.setActiveObject(oImg);
var image = canvas.getActiveObject();
image.moveTo(-1);
canvas.discardActiveObject();
canvas.renderAll();
canvas.sendToBack(oImg);
});
};
reader.readAsDataURL(file);
});
//fonts
document.getElementById('cinzel').addEventListener('click', function(e) {
canvas.getActiveObject().set("fontFamily", "cinzel");
canvas.renderAll();
});
document.getElementById('monsieurladoulaise').addEventListener('click', function(e) {
canvas.getActiveObject().set("fontFamily", "Monsieur La Doulaise");
canvas.renderAll();
});
document.getElementById('tangerine').addEventListener('click', function(e) {
canvas.getActiveObject().set("fontFamily", "tangerine");
canvas.renderAll();
});
// Upload link
$(function() {
$("#upload_link").on('click', function(e) {
e.preventDefault();
$("#file:hidden").trigger('click');
});
});
a.dropdown-item {
cursor: pointer;
}
.btn {
margin-top: 10px;
cursor: pointer;
}
canvas {
border: 1px solid #dddddd;
border-radius: 4px;
margin: 10px 0px 0px 12px;
cursor: pointer;
}
/* Styling the upload link */
#upload_link {
text-decoration: none;
}
#file {
display: none;
}
<script src="https://cdnjs.cloudflare./ajax/libs/fabric.js/1.7.20/fabric.min.js"></script>
<link href="https://maxcdn.bootstrapcdn./bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://code.jquery./jquery-3.2.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js"></script>
<script src="https://maxcdn.bootstrapcdn./bootstrap/4.0.0-beta/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/popper.js/1.11.0/umd/popper.min.js"></script>
<div class="container">
<div class="row">
<div class="col-md-2">
<button type="file" class="btn btn-dark btn-sm" id="upload_link">New Photo</button>
<br>
<input type="file" id="file" /><a href="" id="upload_link" hidden>Add Photo</a>
<div class="btn-group">
<button class="btn btn-dark btn-sm dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Choose your...</button>
<div class="dropdown-menu">
<!-- <h6 class="dropdown-header">Theme</h6>
<a onclick="replaceImage(oImg2, 'images/themes/none.png')" class="dropdown-item">None</a>
<a onclick="replaceImage(oImg2, 'images/themes/beach.png')" class="dropdown-item">Beach</a>
<div class="dropdown-divider"></div> -->
<h6 class="dropdown-header">Frame</h6>
<a onclick="replaceImage(oImg, 'images/frames/LightBrownWoodOval.png')" class="dropdown-item">Oval Light Brown</a>
<a onclick="replaceImage(oImg, 'images/frames/MidToneWoodFrameOval.png')" class="dropdown-item">Oval Mid Tone Wood</a>
<a onclick="replaceImage(oImg, 'images/frames/SilverFrameOval.png')" class="dropdown-item">Oval Silver</a>
<a onclick="replaceImage(oImg, 'images/frames/DistressedWhiteFrameRec.png')" class="dropdown-item">Rectangle Distressed White</a>
<a onclick="replaceImage(oImg, 'images/frames/GoldScrollFrameRec.png')" class="dropdown-item">Rectangle Gold Scroll</a>
<a onclick="replaceImage(oImg, 'images/frames/MidtoneWoodFrameRec.png')" class="dropdown-item">Rectangle Mid Tone Wood</a>
<a onclick="replaceImage(oImg, 'images/frames/SilverFrameRec.png')" class="dropdown-item">Rectangle Silver</a>
<div class="dropdown-divider"></div>
<h6 class="dropdown-header">Font</h6>
<a class="dropdown-item" id="cinzel" style="font-family:cinzel;">Cinzel</a>
<a class="dropdown-item" id="monsieurladoulaise" style="font-family:Monsieur La Doulaise;">Monsieur La Doulaise</a>
<a class="dropdown-item" id="tangerine" style="font-family:tangerine;">Tangerine</a>
</div>
</div>
<button id="d" type="button" class="btn btn-dark btn-sm">Download</button>
<br>
<button onclick="window.location.reload(true)" type="button" class="btn btn-danger btn-sm">Restart</button>
<br>
<!-- <div class="btn-group">
<button class="btn btn-light btn-sm dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">More</button>
<div class="dropdown-menu">
<a class="dropdown-item">Print</a>
<div class="dropdown-divider"></div>
<h6 class="dropdown-header">Advanced</h6>
<a class="dropdown-item disabled">Export to SVG</a>
</div>
</div> -->
</div>
<div class="col-md-10">
<canvas id="c" width="637" height="412"></canvas>
</div>
</div>
</div>
<!-- Our JS -->
<script src="scripts/memorial-portrait-creator.js"></script>
<!-- Optional JavaScript. jQuery first, then Popper.js, then Bootstrap JS -->
Share
Improve this question
edited Dec 1, 2017 at 13:00
anonymoose
asked Nov 25, 2017 at 21:43
anonymooseanonymoose
1,2434 gold badges25 silver badges64 bronze badges
2
- 1 You have to use "z-index" property of css. – Sudarshan Tanwar Commented Nov 25, 2017 at 22:30
- Would you care to elaborate? – anonymoose Commented Nov 25, 2017 at 22:45
1 Answer
Reset to default 9 +50There are some basic reading to do before starting to work with fabricjs in the docs.
http://fabricjs./docs/
1) the selected object jumps on top but you can disable it setting preserveObjectStacking: true
on the canvas.
2) if you need an image to stay always on top, use canvas.overlayImage = fabric.Image
this will give you a top image that do not react to selection that you can use to mask other objects