I'm using fabric.js to manipulate images added to my canvas. I have a shadow but I'd like it to be even around the image. What I have now is below, but here's what I'm trying to replicate with the images added. What am I doing wrong that's causing the shadow to not display?
var canvas = new fabric.Canvas('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) {
//create shadow
var shadow = {
color: 'rgba(0,0,0,0.6)',
blur: 20,
offsetX: 0,
offsetY: 0,
opacity: 0.6,
fillShadow: true,
strokeShadow: true
}
var oImg = img.set({
left: 0,
top: 0,
angle: 0,
stroke: '#222',
strokeWidth: 40
}).scale(0.2);
oImg.setShadow(shadow); //set shadow
canvas.add(oImg).renderAll();
var dataURL = canvas.toDataURL({
format: 'png',
quality: 1
});
});
};
reader.readAsDataURL(file);
});
oImg.setShadow(shadow);
canvas {
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.min.js"></script>
<input type="file" id="file">
<br />
<br>
<canvas id="canvas" width="200" height="200"></canvas>
If uploaded image is a png, it will show effect to the borders, for others it will effect to border, you can use affectStroke which will affect to stroke as well. Here is the doc.
DEMO
var canvas = new fabric.Canvas('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) {
//create shadow
var shadow = {
color: 'rgba(0,0,0,0.6)',
blur: 20,
offsetX: 20,
offsetY: 20,
affectStroke: true
}
var oImg = img.set({
left: 0,
top: 0,
stroke: 'black',
strokeWidth: 10
}).scale(0.2);
oImg.setShadow(shadow); //set shadow
canvas.add(oImg).renderAll();
var dataURL = canvas.toDataURL({
format: 'png',
quality: 1
});
});
};
reader.readAsDataURL(file);
});
canvas {
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.min.js"></script>
<input type="file" id="file">
<br />
<br>
<canvas id="canvas" width="400" height="400"></canvas>
Your shadow is actually displayed, its right behind the object.
If you change offsetX or offsetY you will see it.
Like here
var shadow = {
color: 'rgba(0,0,0,0.6)',
blur: 20,
offsetX: 50,
offsetY: 50,
opacity: 0.6,
fillShadow: true,
strokeShadow: true
}
http://jsfiddle.net/5KKQ2/2565/
There is also an issue https://github.com/kangax/fabric.js/issues/1214 about shadow size but it's not completed yet.
Hope it helps.
Related
What I'd like to achieve: I need to load different images in different canvas, move and resize them and show a preview. I'm using fabricJs. With rectangular canvas everything works fine, the problem is when I want to concatenate canvas with a diagonal section. Something like this:
I tried something with the transform property in CSS, but then I could no longer interract with the canvas. Any idea on how to do this? Or is there a way to have only one canvas with something like sections?
What I have right now (only part of the code to interract with the canvas, the preview it's another canvas where I draw again everything):
$( document ).ready(function() {
addImage('canvas1', 'imageLoader1');
addImage('canvas2', 'imageLoader2');
});
function addImage(canvas, input) {
var canvas = new fabric.Canvas(canvas);
document.getElementById(input).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: 0,
top: 0,
angle: 00,
width: 100,
height: 100
}).scale(0.9);
canvas.add(oImg).renderAll();
var a = canvas.setActiveObject(oImg);
var dataURL = canvas.toDataURL({
format: 'png',
quality: 0.8
});
});
};
reader.readAsDataURL(file);
});
}
.container {
width: 544px;
}
.canvas-container {
float: left;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.12/fabric.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="container">
<canvas id="canvas1" width="272px" height="465px"></canvas>
<canvas id="canvas2" width="272px" height="465px" style="float: left;"></canvas>
</div>
<div>
<input type="file" id="imageLoader1" name="imageLoader1"/>
<input type="file" id="imageLoader2" name="imageLoader1"/>
</div>
</body>
In reply to #Observer comment:
clipTo is deprecated since v2.0.0. You could achieve this with clipPath (which is more powerful and more flexible than clipTo since it accepts a fabric.Object):
const canvas = new fabric.Canvas("canvas", {backgroundColor: "#d3d3d3"})
const container = new fabric.Rect({
width: 200,
height: 200,
left: 100,
top: 100,
})
const obj = new fabric.Circle({
radius: 50,
left: 150,
top: 150,
fill: "blue"
})
canvas.clipPath = container
canvas.add(obj)
canvas.requestRenderAll()
#canvas {
background: #e8e8e8;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.0.0-beta.5/fabric.min.js"></script>
<canvas id="canvas" width="400" height="400"></canvas>
Thanks to #ℊααnd I was able to add stroke styling to images added to the canvas. I'd like to also have a drop shadow on any images added to give them more of a "stacked" look. I've tried adding boxShadow: "5px 5px 20px 0px #888888", and taking queues from the documentation but I'm not having any luck. How would I achieve this? Styling in JS is still totally new to me. Any help would be greatly appreciated. Thanks in advance.
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: 0,
top: 0,
angle: 0,
border: '#000',
stroke: '#F0F0F0',
strokeWidth: 40
}).scale(0.2);
canvas.add(oImg).renderAll();
//var a = canvas.setActiveObject(oImg);
var dataURL = canvas.toDataURL({
format: 'png',
quality: 1
});
});
};
reader.readAsDataURL(file);
});
I tried plugging all of my code into the snippet inserter but for some reason it didn't want to run there. I figure the above is what's applicable.
You could simply create a shadow object, like this ...
var shadow = {
color: '#888888',
blur: 70,
offsetX: 45,
offsetY: 45,
opacity: 0.8
}
and then, set it for the image object, like so ...
oImg.setShadow(shadow);
ᴅᴇᴍᴏ
var canvas = new fabric.Canvas('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) {
//create shadow
var shadow = {
color: '#888888',
blur: 70,
offsetX: 45,
offsetY: 45,
opacity: 0.8
}
var oImg = img.set({
left: 0,
top: 0,
angle: 0,
stroke: '#222',
strokeWidth: 40
}).scale(0.2);
oImg.setShadow(shadow); //set shadow
canvas.add(oImg).renderAll();
var dataURL = canvas.toDataURL({
format: 'png',
quality: 1
});
});
};
reader.readAsDataURL(file);
});
canvas {border: 1px solid black;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.min.js"></script>
<input type="file" id="file"><br />
<canvas id="canvas" width="180" height="180"></canvas>
I'm playing a lot with fabric.js. I read here how to add my own images. How would I do this but give each uploaded photo a certain style? In other words, I'd like each picture uploaded to have a border or stroke to look like this:
.
The code I'm playing with:
var canvas = new fabric.Canvas('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: 0,
top: 0,
angle: 00,
width: 100,
height: 100
}).scale(0.9);
canvas.add(oImg).renderAll();
var a = canvas.setActiveObject(oImg);
var dataURL = canvas.toDataURL({
format: 'png',
quality: 0.8
});
});
};
reader.readAsDataURL(file);
});
canvas {
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.min.js"></script>
<input type="file" id="file"><br />
<canvas id="canvas" width="450" height="450"></canvas>
You would have to set stroke and strokeWidth property for the image object to accomplish that ...
var canvas = new fabric.Canvas('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: 40,
top: 40,
angle: 00,
width: 100,
height: 100,
stroke: '#07C', //<-- set this
strokeWidth: 5 //<-- set this
}).scale(0.9);
canvas.add(oImg).renderAll();
var a = canvas.setActiveObject(oImg);
var dataURL = canvas.toDataURL({
format: 'png',
quality: 0.8
});
});
};
reader.readAsDataURL(file);
});
canvas {border: 1px solid black;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.min.js"></script>
<input type="file" id="file"><br />
<canvas id="canvas" width="180" height="180"></canvas>
I want to save my canvas image on another image.
$(document).on('click','#local-save', function(event) {
var imgURL = "assets/images/bg.png";
canvas.overlayImage.filters = [];
canvas.overlayImage.applyFilters();
canvas.renderAll();
window.open(canvas.toDataURL({
format: 'png',
multiplier: 2,
left: 300,
height: 500,
width: 500
}));
});
In here I can get canvas image. But I want to save it on background image. How to do this?
use your data url as the background property for something..
var dataurl = canvas.toDataURL({
format: 'png',
multiplier: 2,
left: 300,
height: 500,
width: 500
});
someElement.style.background = "url("+dataurl+")";
Run the snippet and click on click me then canvas converted into image. I thing this is helpful for you
var canvas = new fabric.Canvas('canvas');
canvas.setBackgroundImage('https://c1.staticflickr.com/5/4051/4510967899_293f0dd5ac_z.jpg',
canvas.renderAll.bind(canvas),
// here set the crossOrigin attribute
{crossOrigin: 'anonymous'}
);
document.getElementById('file').addEventListener("change", function(e) {
var file = e.target.files[0];
var reader = new FileReader();
console.log("reader " + reader);
reader.onload = function(f) {
var data = f.target.result;
fabric.Image.fromURL(data, function(img) {
var oImg = img.set({
left: 70,
top: 100,
width: 250,
height: 200,
angle: 0
}).scale(0.9);
canvas.add(oImg).renderAll();
canvas.setActiveObject(oImg);
});
};
reader.readAsDataURL(file);
});
document.querySelector('#txt').onclick = function(e) {
e.preventDefault();
canvas.deactivateAll().renderAll();
document.querySelector('#preview').src = canvas.toDataURL();
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.min.js"></script>
<div class="col-sm-12">
<div class="text-center" style="font-size:25;margin-top:17px;margin-bottom: 30px;"><strong>Customize T-Shirt From Here</strong>
</div>
<input type="file" id="file">
<br/>
<canvas id="canvas" width="750" height="550" style="border: 1px solid black; box-shadow: rgba(0,0,0,0.8) 0 0 10px;"></canvas>
Click Me!!
<br />
<img id="preview" />
</div>
I have solved my problem as follows. My background image open under another canvas id MyID. My normal canvas id is canvas .
var MaskImg = canvas.toDataURL({
format: 'png',
multiplier: 2,
left: 300,
height: 400,
width: 400
});
var c=document.getElementById("MyID");
var ctx=c.getContext("2d");
c.width = 1748;
c.height = 2481;
var imageObj1 = new Image();
var imageObj2 = new Image();
imageObj1.src = "assets/images/bg.png"
imageObj1.onload = function() {
ctx.drawImage(imageObj1, 0, 0, 1748, 2480);
imageObj2.src = MaskImg;
imageObj2.onload = function() {
event.preventDefault();
ctx.drawImage(imageObj2, (100, 100 , 400, 400);
event.preventDefault();
var img = c.toDataURL({
format: 'png',
});
window.open(img);
}
};
We are using stackoverflow links code to upload image in a site
once we upload, its occupying only little part in box as here.
But image should occupy full box.
var canvas = new fabric.Canvas('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: 0, top: 0, angle: 00,width:100, height:100}).scale(0.9);
canvas.add(oImg).renderAll();
var a = canvas.setActiveObject(oImg);
var dataURL = canvas.toDataURL({format: 'png', quality: 0.8});
});
};
reader.readAsDataURL(file);
});
canvas{
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.min.js"></script>
<input type="file" id="file"><br />
<canvas id="canvas" width="450" height="450"></canvas>
Replace the line
var oImg = img.set({left: 0, top: 0, angle: 00,width:100, height:100}).scale(0.9);
with
var oImg = img.set({left: 0, top: 0, angle: 00, width: canvas.getWidth(), height: canvas.getHeight()});
This is what was restricting your image size. Also, I don't know why you have the scale there - but if you keep it as .scale(0.9), it won't fill the whole box. Instead it will fill only 90% of its width and height.
Snippet
var canvas = new fabric.Canvas('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: 0, top: 0, angle: 00,width:canvas.getWidth(), height:canvas.getHeight()});
canvas.add(oImg).renderAll();
var a = canvas.setActiveObject(oImg);
var dataURL = canvas.toDataURL({format: 'png', quality: 0.8});
});
};
reader.readAsDataURL(file);
});
canvas{
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.min.js"></script>
<input type="file" id="file"><br />
<canvas id="canvas" width="450" height="450"></canvas>
Run code snippet