I am using FabricJS to draw and erase lines on top of an image. I made 2 layers for the canvas, with the bottom layer as the background image and the top layer for sketching. Whenever I erase the markings, if I use freeDrawingBrush.color =white, or any basic color, it gets erased. However, if I use transparent, 'rgba(0,0,0,0)', as the color of the freeDrawingBrush, the markings are not erased.
How can I erase the marking on the top layer with a transparent as the background of the path created as I erase?
<div style="position: relative;">
<canvas id="my-canvas" width="800" height="400" style="position: absolute; left: 0; top: 0; z-index: 1;background-color:rgba(0,0,0,0)"> </canvas>
<canvas id="layer3" width="800" height="400" style="position: absolute; left: 0; top: 0; z-index: 0;background-image:url(http://gallery.nanfa.org/d/52271-3/DSC_7537.jpg);"></canvas>
</div>
<script>
canvas = window._canvas = new fabric.Canvas('layer1');
canvas.isDrawingMode= 1;
canvas.freeDrawingBrush.width = 10;
canvas.renderAll();
//eraser function
function eraser(){
canvas.freeDrawingBrush.color = "white"; // if "rgba(0,0,0,0)", not work
canvas.on('path:created', function (opt) {
opt.path.globalCompositeOperation = 'destination-out';
canvas.renderAll();
});
}
//drawing function
function draw(){
canvas.freeDrawingBrush.color = "black";
canvas.on('path:created', function (opt) {
opt.path.globalCompositeOperation = 'source-over';
canvas.renderAll();
});
}
</script>
Im using fabricjs on html https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.min.js
Any help will be very much appreciated. Thanks in advance!
Related
i made a loading bar for my website. On the live preview with brackets, when I scroll down to my bar, the animation become visible. When I open my html page with a browser (chrome or edge), The loading bar animation does not appear... Although I think I used the right prefixes. Below you can see my code:
**CSS**
.laden100 {
animation-name: laden100;
-webkit-animation-name: laden100;
animation-duration: 4s;
-webkit-animation-duration: 4s;
visibility: visible;
width: 100%;
height: 20px;
background-image: linear-gradient(to bottom, #308355, #308355, #308355, #00cc66);
background-image: -webkit-linear-gradient(to bottom, #308355, #308355, #308355, #00cc66);
box-shadow: 5px 5px 5px grey;
border-radius: 5px 5px 5px 5px;
position: relative;
margin-top: 20px;
margin-left: 20px;
margin-right: 20px;
}
#keyframes laden100 {
0% {
opacity: 0;
width: 0%;
}
100% {
opacity: 1;
width: 100%;
}
}
#-webkit-keyframes laden100 {
0% {
opacity: 0;
width: 0%;
}
100% {
opacity: 1;
width: 50%;
}
}
**HTML**
<div class="container wit mt-5">
<h1 id="skills">Skills</h1>
<p style="color:#308355">Below you can see my skills I have. This learning process is still ongoing. I hope to achieve at least 80% for each coding language.</p>
<br>
<div class="container">
<div class="row">
<div class="vak">HTML</div>
<div class="laadbalk100"></div>
<div class="score100">%</div>
</div>
<br>
</div>
</div>
**JAVASCRIPT**
<!----------------------- only load the load bar on scroll-------------->
<script>
$(document).ready(function() {
// Add smooth scrolling to all links in navbar + footer link
$(".navbar a, footer a[href='#myPage']").on('click', function(event) {
// Make sure this.hash has a value before overriding default behavior
if (this.hash !== "") {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (900) specifies the number of milliseconds it takes to scroll to the specified area
$('html, body').animate({
scrollTop: $(hash).offset().top
}, 900, function() {
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
});
} // End if
});
$(window).scroll(function() {
$(".laadbalk100").each(function() {
var pos = $(this).offset().top;
var winTop = $(window).scrollTop();
if (pos < winTop + 600) {
$(this).addClass("laden100");
}
});
});
})
</script>
I used prefixes because I think it has something to do with browser support. According to me, Brackets uses plugins to add the right prefixes.
OK sry Guys,
I found the answer to my own question... :D.
Because browsers have different screen resolutions, I had to increase wintop +600 to wintop +1000. See the correction below:
$(window).scroll(function() {
$(".laadbalk100").each(function() {
var pos = $(this).offset().top;
var winTop = $(window).scrollTop();
if (pos < winTop + 1000) {
$(this).addClass("laden100");
}
});
});
I'm currently learning Phaser 3. However, all the documentation I can find is about Phaser2.
When you create a game you have to set the width and height in the config:
var config = {
type: Phaser.AUTO,
width: 800,
height: 600,
};
How can I scale the scene to fullscreen?
UPDATE
Phaser 3.16 is released on now (Feb, 2019), which has inbuilt Scale Manager. It provide various methods to scale your game. Check it out before trying the code below.
Phaser.Scale Docs
Notes on Scale Manager
Old Answer
You can resize the canvas element using resize function mentioned in code snippet and execute that function before starting game and whenever screen is resized. This way you can maintain the aspect ratio of 800:600(4:3) and fit the canvas element to full-screen according to screen ratio.
Run code snippet in Full Page Mode and resize your browser to see how canvas element is resized. Size of blue rectangle is the size of your canvas(game).
var game;
var gameWidth = 800;
var gameHeight = 600;
window.onload = function() {
var config = {
type: Phaser.CANVAS,
width: gameWidth,
height: gameHeight,
scene: [intro]
};
game = new Phaser.Game(config);
resize();
window.addEventListener("resize", resize, false);
};
function resize() {
var canvas = document.querySelector("canvas");
var windowWidth = window.innerWidth;
var windowHeight = window.innerHeight;
var windowRatio = windowWidth / windowHeight;
var gameRatio = game.config.width / game.config.height;
if (windowRatio < gameRatio) {
canvas.style.width = windowWidth + "px";
canvas.style.height = (windowWidth / gameRatio) + "px";
} else {
canvas.style.width = (windowHeight * gameRatio) + "px";
canvas.style.height = windowHeight + "px";
}
}
var intro = new Phaser.Scene('intro');
intro.create = function() {
var rect = new Phaser.Geom.Rectangle(0, 0, 800, 600);
var graphics = this.add.graphics({
fillStyle: {
color: 0x0000ff
}
});
graphics.fillRectShape(rect);
};
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
body {
background: #000000;
padding: 0px;
margin: 0px;
}
canvas {
display: block;
margin: 0;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
<script src="https://cdn.jsdelivr.net/npm/phaser#3.6.0/dist/phaser.min.js"></script>
</head>
<body>
</body>
</html>
You should check out this post. It explains this code in detail.
css style (in index.html) should be as simple as
body { margin:0; padding:0; overflow:hidden }
body>canvas { width:100%!important; height:100%!important;
position:fixed; top:0; left:0 }
!important suffix is needed to override the dynamic html style
for example
<canvas width="800" height="600"
style="width: 681.778px; height: 511.333px;
margin-left: 0px; margin-top: 0px;"></canvas>
phaser config in index.js
const config = {
parent: "phaser-example",
type: Phaser.AUTO,
width: 800,
height: 600,
scene: {
preload: preload,
create: create
},
// https://rexrainbow.github.io/phaser3-rex-notes/docs/site/scalemanager/
scale: {
// ignore aspect ratio:
mode: Phaser.Scale.RESIZE,
// keep aspect ratio:
//mode: Phaser.Scale.FIT,
//mode: Phaser.Scale.ENVELOP, // larger than Scale.FIT
//mode: Phaser.Scale.HEIGHT_CONTROLS_WIDTH, // auto width
//mode: Phaser.Scale.WIDTH_CONTROLS_HEIGHT, // auto height
autoCenter: Phaser.Scale.NO_CENTER,
//autoCenter: Phaser.Scale.CENTER_BOTH,
//autoCenter: Phaser.Scale.CENTER_HORIZONTALLY,
//autoCenter: Phaser.Scale.CENTER_VERTICALLY,
},
autoRound: false,
};
I am trying to format selection border style to look like in inkscape(image left side).
I have tried to set the object padding to zero with this:
fabric.Object.prototype.set({
padding: 0,
});
If I zoom in this is more apparent and padding grows.
Example: Left side inkscape selection box style, right side actual fabric.js selection box
How can i remove the padding?
Here is jsFiddle.
That's because of stroke width, set strokeWidth:0 to object.
DEMO
var canvas = window.__canvas = new fabric.Canvas('canvas');
var rect = new fabric.Rect({left: 10, top: 10,strokeWidth:0, width: 60, height: 60, fill: 'blue'});
rect.editable = true;
rect.customType = 'shape';
rect.describtion = 'fabric.js rect object';
rect.cornerColor = 'red';
rect.borderColor = 'red';
rect.cornerSize = 8;
rect.padding = 0;
canvas.add(rect);
canvas.setActiveObject(rect);
canvas.setZoom(20);
canvas{
border:2px solid #000;
}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="canvas" width="400" height="400"></canvas>
If I want to add an extra line to an existing polyline, should I remove this existing polyline from the canvas first, modify the points matrix, and add the new polyline? Or is it possible to change the existing polyline, like changing the text of a text object?
You may remove whole polyline and add a new one or else you need to calculate the dimensions(left,top and pathoffset) and set it to polyline.
DEMO
var canvas = new fabric.Canvas('c');
var points = [];
var random = fabric.util.getRandomInt;
points.push(new fabric.Point(random(100,200),random(200,300)));
points.push(new fabric.Point(random(200,300),random(100,200)));
points.push(new fabric.Point(random(200,250),random(150,200)));
var polyLine = new fabric.Polyline(points, {
stroke: 'black',
fill: ''
});
canvas.add(polyLine);
setPolyCoords();
function addPoint(){
polyLine.points.push(new fabric.Point(random(100,400),random(100,400)));
setPolyCoords();
}
function setPolyCoords(){
polyLine._calcDimensions();
polyLine.set({
top : polyLine.minY,
left : polyLine.minX,
pathOffset : {
x: polyLine.minX + polyLine.width / 2,
y: polyLine.minY + polyLine.height / 2
}
});
polyLine.dirty = true;
polyLine.setCoords();
canvas.renderAll();
}
canvas {
border: 1px solid #f00;
margin: 0px;
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.js"></script>
<button onclick='addPoint()'>Add Point</button>
<canvas id="c" width="400" height="400"></canvas>
With Fabric version 2.7.0 this is become easier then in #Durga his answer.
See the new code in the demo below.
You can also skip setting the dirty flag manually by passing objectCaching: false to your polyline during construction:
var polyLine = new fabric.Polyline(points, {
stroke: 'black',
fill: '',
objectCaching: false
});
DEMO
var canvas = new fabric.Canvas('c');
var points = [];
var random = fabric.util.getRandomInt;
points.push(new fabric.Point(random(100,200),random(200,300)));
points.push(new fabric.Point(random(200,300),random(100,200)));
points.push(new fabric.Point(random(200,250),random(150,200)));
var polyLine = new fabric.Polyline(points, {
stroke: 'black',
fill: ''
});
canvas.add(polyLine);
function addPoint(){
polyLine.points.push(new fabric.Point(random(100,400),random(100,400)));
polyLine.dirty = true;
canvas.renderAll();
}
canvas {
border: 1px solid #f00;
margin: 0px;
display: block;
}
<script src="https://rawgit.com/fabricjs/fabric.js/master/dist/fabric.min.js"></script>
<button onclick='addPoint()'>Add Point</button>
<canvas id="c" width="400" height="400"></canvas>
Is there a way to listen to key events while you are editing a text? (in itext or textbox or whatever). Our goal is to be able to hit cmd-b or cmd-i to set the selected part of your text in bold or italic.
Thanks for your help!
DEMO
window.addEventListener("keydown",onKeyDown);
function onKeyDown(e){
if (event.which == 73 && event.ctrlKey ) {
//ctrl+i
makeItalic();
}
if (event.which == 66 && event.ctrlKey ) {
//ctrl+b
makeBold();
}
}
var canvas = new fabric.Canvas('canvas');
var text = 'FabricJS Is Awsome';
var itext = new fabric.IText(text, {
left: 100,
top: 100,
fontSize: 40,
fill: '#000'
})
canvas.add(itext);
canvas.setActiveObject(itext);
function makeItalic(){
itext.setSelectionStyles({fontStyle:'italic'});// set your property
canvas.renderAll();
}
function makeBold(){
itext.setSelectionStyles({fontWeight:'bold'});
canvas.renderAll();
}
.canvas-wrappter {
position: relative;
}
canvas {
border: 1px solid #000;
}
.itext {
width: 300px;
background: transparent;
position: absolute;
z-index: 2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.16/fabric.min.js"></script>
<div class="canvas-wrapper">
<canvas id="canvas" width="500" height="500"></canvas>
</div>
setSelectionStyles(style) use this function to set your style.