fabric js set shadow to null after canvas render - javascript

I am setting the shadow to fabric js rectangle using
o.setShadow("1px 1px 15px yellow");
Now the shadow is set to the respective rectangle where o is the current object But I regenerate the rectangle using a timeout after every 30 second the new rectangle gets generated but the shadow is still there on the old place so if rectangle no had shadow when the rectangle gets regenerated the shadow is still there but ideally all the shadows should be removed.
I tried
o.setShadow(null) and o.setShadow(0px 0px 0px) and canvas.renderAll()
But it does not work all the new rectangle does not have a shadow property has a shadow of null
but the shadow is still there I need to remove the shadow altogether in the next iteration of the settimeout. I Am using the 3.4.0 version of the Fabric js.

Do obj.shadow = null; followed by canvas#requestRenderAll, it will remove the shadow of the object.
DEMO
const canvas = new fabric.Canvas('canvas');
const square = new fabric.Rect({
width: 50,
height: 50,
left: 50,
top: 50,
fill: '#000'
});
square.setShadow("1px 1px 15px yellow");
canvas.add(square);
setTimeout(() => {
square.shadow = null;
//or square.setShadow(null);
canvas.requestRenderAll();
},1500);
canvas {
border : 1px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.4.0/fabric.js"></script>
<canvas id="canvas"></canvas>

Related

Why does my browser render double the height value? [duplicate]

This question already has answers here:
Canvas is stretched when using CSS but normal with "width" / "height" properties
(10 answers)
Closed 1 year ago.
If run below code and DOM, my browser is renderred double all height value.
First, I tested below code in about:blank.
In html:
...
<canvas id="canvasArea" style="
width: 500px;
height: 500px;
background-color: E0E0E0;
"></canvas>
...
and In js:
let cv = document.getElementById("canvasArea");
let cvArea = cv.getContent('2d');
cvArea.fillRect(10, 10, 50, 50); // I was thinking this Rect is square
cvArea.fillRect(60, 10, 50, 25); // and this Rect is long rectangle
I was thinking first rect will be draw square.
But first is long rectangle.
Why does this happen?
JS Canvases are not aware of dimensions set by CSS.
Use HTML attributes or set using JS.
let cv = document.getElementById("canvasArea");
let cvArea = cv.getContext('2d');
cvArea.fillRect(10, 10, 50, 50); // I was thinking this Rect is square
//cvArea.fillRect(60, 10, 50, 25); // and this Rect is long rectangle
<canvas id="canvasArea" width="500" height="500" style="
background-color: #E0E0E0;
"></canvas>

How to change the shape of the canvas itself?

I'm working on a project and I use createCapture(VIDEO); using p5js libraries, to get the video using my web camera. Then I store every image of that capture (from < video> element) and draw it in a canvas in the function draw().
I was wondering if it's possible the change the shape of the canvas(such as a mirror for example (oval or circle)).
Again, notice that I don't want to crop the image but the canvas itself.
Here is some code:
function setup(){
canvas = createCanvas(640, 480); //480p
canvas.parent('editedCanvas-container');
originalCapture = createCapture(VIDEO);
originalCapture.parent('originalVideo-container');
originalCapture.size(640, 480); //480p
}
function draw(){
frame = image(originalCapture, 0, 0, width, height);
}
If somebody has a clue please let me know.
You can change the shape of your canvas tag by applying css rules,
So try this css code
#canvasObject {
border: 2px solid black;
width: 200px;
height: 150px;
border-radius: 100px / 50px;
}
<canvas id="canvasObject">
</canvas>
For more info about how to achieve shapes in css, please refer this amazing post for css-tricks

Move Section of Canvas to Other Canvas

I have two canvases, let's say Canvas A and Canvas B. The user uploads a file and it gets put on Canvas A, which I already have done. Once that happens, I want to start copying sections of Canvas A to Canvas B.
I have tried doing this
source = a.getContext('2d');
b.drawImage(source, 0, 0, source.width, source.height);
but that copies the whole thing. So my question is, how do I copy a part of Canvas A to Canvas B.
Edit:
I have also tried...
var imgData=atx.getImageData(10,10,20,20);
btx.putImageData(imgData, 0, 0);
but that just copies the imgData back onto Canvas A at (0, 0).
To start with, b.drawImage takes a CanvasImageSource as its first argument, not a Context. Pass your entire HTMLCanvasElement in there.
drawImage takes nine arguments, and you're gonna need all of them. If you only use five, it's assumed that you're taking the entire source image and drawing it at your destination. The full signature is
drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh);
sx, sy, sw, and sh define the rectangle you're copying from your source. dx, dy, dw, and dh define the rectangle you're drawing in at your destination. Note that sw and sh don't have to match up with dw and dh. If the source and destination rectangles don't have the same size, the copied image will be squashed or stretched to fit the destination rectangle.
I've made a snippet that lets you play around with drawImage to see what it's doing. It works best when you view it as a full page:
const srcCanvas = document.querySelector('#source');
const srcContext = srcCanvas.getContext('2d');
const destContext = document.querySelector('#destination')
.getContext('2d');
// The overlay canvas is where we draw the red rectangle. It's
// positioned directly on top of the source canvas.
const overlay = document.querySelector('#overlay')
.getContext('2d');
overlay.fillStyle = 'rgba(255, 0, 0, 0.3)';
overlay.strokeStyle = 'red';
const inputs = Array.from(
document.querySelectorAll('input[type="number"]')
);
const lockScale = document.querySelector('#lockScale');
lockScale.addEventListener('change', () => {
inputs[6].disabled = lockScale.checked;
inputs[7].disabled = lockScale.checked;
if (lockScale.checked) update();
});
// Grab an image and draw it on the source canvas...
fetch('https://picsum.photos/320/240/?image=451')
.then(res => res.blob())
.then(createImageBitmap)
.then(bitmap => {
srcContext.drawImage(bitmap, 0, 0);
// ...and only then start watching for changes in the input boxes.
// There's no point in spending cycles copying an empty canvas.
inputs.forEach(i => {
i.addEventListener('input', update);
});
update();
});
function update() {
if (lockScale.checked) {
inputs[6].value = inputs[2].value;
inputs[7].value = inputs[3].value;
}
const values = inputs.map(i => Number(i.value));
destContext.clearRect(0, 0, 320, 240);
overlay.clearRect(0, 0, 320, 240);
overlay.beginPath();
overlay.rect(
// These adjustments move the overlay path off the boundary
// between pixels so the rectangle border is a crisp 1px line.
values[0] + 0.5,
values[1] + 0.5,
// JavaScript uses half-open intervals, which makes sense for
// code. But for a visualization of graphics work, fully-
// closed intervals are preferable. These adjustments make the
// overlay rectangle exactly cover the pixels that will be
// copied.
values[2] - 1,
values[3] - 1
);
overlay.fill();
overlay.stroke();
// The real drawing code of this snippet doesn't look like the
// code you would actually use. We call apply() on drawImage()
// so we can pass in the entire values array without listing out
// every element.
destContext.drawImage.apply(
destContext, // We don't want to change what 'this' points to
[srcCanvas].concat(values));
// The spread operator provides a more elegant way of doing this:
// destContext.drawImage(srcCanvas, ...values);
// But it doesn't work with IE.
}
canvas {
height: 240px;
width: 320px;
position: absolute;
top: 0;
left: 0;
}
.canvasbox {
display: inline-block;
position: relative;
width: 320px;
height: 240px;
border: 1px solid black;
}
input[type="number"] {
font-family: monospace;
border: none;
background: silver;
color: black;
width: 3em;
}
input[disabled] {
color: silver;
background: grey;
}
code {
color: navy;
}
<div class="canvasbox">
<canvas id="source" width="320" height="240"></canvas>
<canvas id="overlay" width="320" height="240"></canvas>
</div>
<div class="canvasbox">
<canvas id="destination" width="320" height="240"></canvas>
</div>
<div>
<code>
destContext.drawImage(srcCanvas,
<input id="sx" type="number" value="180">,
<input id="sy" type="number" value="100">,
<input id="sw" type="number" value="40">,
<input id="sh" type="number" value="50">,
<input id="dx" type="number" value="10">,
<input id="dy" type="number" value="10">,
<input id="dw" type="number" value="40">,
<input id="dh" type="number" value="50">);
</code>
</div>
<div>
<label>
<input id="lockScale" type="checkbox">Lock scale
</label>
</div>

diagonal image overlay via css/javascript

I want to create a div overlay, set at 5% opacity, which creates a diagonal bounding box around the first line of text in this image. It seems to me that if I have the x,y coordinates for the four corners I should be able to create the overlay but I cannot figure out what the proper syntax would be to mark out the div. Am I wrong in thinking this can be done, and if not can someone point me at some methods for doing so?
Instead of using a canvas and javascript for simple cases you can use instead the transform property of css divs. For example with
#diag {
background-color: rgba(255, 0, 255, 0.25);
width: 700px;
height: 60px;
position: absolute;
left: 100px;
top: 160px;
transform: rotate(2deg) skew(30deg)
}
you can get a div positioned on the first line of the text in the image that can be styled easily with CSS for borders and that can be used directly for events (hover, clicks).
If you need to specify 4 corners however just a single transform is not enough in general and you have to draw your overlay in a canvas placed over the image. This works because a canvas is by default transparent and only what you explicitly draw will be visible leaving the image untouched in other areas. For example using:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
ctx.beginPath();
ctx.moveTo(166, 282);
ctx.lineTo(855, 296);
ctx.lineTo(897, 351);
ctx.lineTo(212, 349);
ctx.closePath();
ctx.fillStyle = "rgba(0, 255, 0, 0.25)";
ctx.strokeStyle = "#0F0";
ctx.lineWidth = 4;
ctx.fill();
ctx.stroke();
I've highlighted the third row in green (fill command) also adding a border (stroke command).
http://jsfiddle.net/hr9afs4z/1/

How to add a background color to Kinetic JS stage or layer?

I have a Kinetic JS stage and a layer
var stage = new Kinetic.Stage({
container: 'container',
width : STAGE_WIDTH,
height : STAGE_HEIGHT
});
var layer = new Kinetic.Layer();
I've set the page color to be #bbb.
body {
background: #bbb;
}
I'd like to set the canvas color to be white. But I can't seem to find a method or a way to add a background color to the stage itself or the layer that I add all the object on.
You can also set the background color of your container element through CSS. That's essentially the same as setting the background color of the stage. If you want a background at the layer level, you'll need to add a filled rectangle or similar, as previously mentioned.
I had the same problem, I wanted to add a "background". I added a rectagle with the 100% height and width, with this code:
var rect = new Kinetic.Rect({
x: 0,
y: 0,
width: stageDimensions.width, //full width
height: stageDimensions.height, //full height
fill: 'white', //background color
});
layer.add(rect);
Since I wanted to be able to remove the "background", this is how I manage to solve my problem.
Hope it helps you.
You can change the background color with JavaScript...
document.getElementById('container').style.background = '#fff';
There isn't an API method to add a background color.
Instead add a colored rectangle that covers the layer.
Of course, add the background rectangle before all other shapes.
Old question, but you can use the get properties of the stage, and fill a full rectangle, adding it to the layer before anything else. Sample code:
var stage = new Kinetic.Stage({
container: 'canvas-container',
width: 900,
height: 450
});
// create background
var stageBg = new Kinetic.Rect({
x: 0,
y: 0,
width: stage.getWidth(),
height: stage.getHeight(),
fill: "rgb(40,40,40)"
});
layer.add(stageBg);
stage.add(layer);

Categories

Resources