setBackgroundImage not working as expected with multiple functions - javascript

I'm trying to follow the Fabric.js tutorial to setBackgroundImage to one of a few images I have associated with the buttons and am getting some weirdness. Basically, the buttons 1 and 3 are both slow/unresponsive/take two clicks to take effect, and button two doesn't want to load locally or via Imgur. Anyways, I'm using Fabric.js v. 1.7.22 and jQuery 3.3.1.
var canvas = new fabric.Canvas('canvas');
canvas.setHeight(400);
canvas.setWidth(400);
$("#one").click(function(event) {
canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png');
canvas.renderAll();
});
$("#two").click(function(event) {
canvas.setBackgroundImage('https://i.imgur.com/4Ut8gsw.png');
canvas.renderAll();
});
$("#three").click(function(event) {
canvas.setBackgroundImage('https://i.imgur.com/2S08Y3b.jpg');
canvas.renderAll();
});
canvas {
border: 1px solid #dddd;
}
button {
margin-top: 20px;
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.min.js"></script>
<canvas id="canvas"></canvas>
<button id="one">
One
</button>
<button id="two">
Two
</button>
<button id="three">
Three
</button>
What is going on here? Thanks in advance.

setBackgroundImage accepts three arguments.
url
callback
options for image.
call renderAll() inside the callback.
var canvas = new fabric.Canvas('canvas');
canvas.setHeight(400);
canvas.setWidth(400);
$("#one").click(function(event) {
canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png',function(){
canvas.renderAll();
},{
width:canvas.width,
height:canvas.height
});
});
$("#two").click(function(event) {
canvas.setBackgroundImage('https://i.imgur.com/4Ut8gsw.png',function(){
canvas.renderAll();
},{
width:canvas.width,
height:canvas.height
});
});
$("#three").click(function(event) {
canvas.setBackgroundImage('https://i.imgur.com/2S08Y3b.jpg',function(){
canvas.renderAll();
},{
width:canvas.width,
height:canvas.height
});
});
canvas {
border: 1px solid #dddd;
}
button {
margin-top: 20px;
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.min.js"></script>
<canvas id="canvas"></canvas>
<button id="one">
One
</button>
<button id="two">
Two
</button>
<button id="three">
Three
</button>

Related

Change div border-color by clicking on div

I have a question regarding this given code: https://stackoverflow.com/a/34404172/11460885.
My situation is, I have different divs and some of them should have the border-color red, when clicking on them and some of them should be green.
How could I change the JS, so I can have more than on color, depending on the parameter?
JS:
function fnChangeBorder(boxId)
{document.getElementById(boxId).style.border = "solid #AA00FF";}
HTML:
<div class="box" id="A" onclick="fnChangeBorder('A')">Click here !!</div>
Thank you all very much.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
.green-border {
border: green 0px solid;
}
.red-border {
border: red 0px solid;
}
.show-border {
border-width: 1px;
}
</style>
</head>
<body>
<div class="green-border">Im green</div>
<div class="red-border">Im red</div>
<div class="green-border">Im green</div>
<div class="red-border">Im red</div>
</body>
<script>
document.querySelectorAll(".green-border,.red-border").forEach((div) => {
div.addEventListener("click", () => {
div.classList.contains("show-border")
? div.classList.remove("show-border")
: div.classList.add("show-border");
});
});
</script>
</html>
You can create a second parameter in your function to do that
/*----- Defining Function ------*/
function changeBorder(elementID, colorHex){
/*----- Getting Element & Assign new borders ------*/
document.getElementById(elementID).style.border = "solid "+colorHex;
}
<!-- Turns Red -->
<div class="box" id="A" onclick="changeBorder('A', '#ff0000')">I'll be red</div>
<!-- Turns Green -->
<div class="box" id="B" onclick="changeBorder('B', '#00ff00')">I'll be green</div>
function fnChangeBorder(boxId)
{
var color = "";
if(boxId === 'A')
{color = "solid #AA00FF";}
else if(boxId == 'B')
{color = "solid black";}
document.getElementById(boxId).style.border = color;
}
This is really simple js, perhaps you should check out https://www.w3schools.com/js/js_if_else.asp
I did the same as others did, but I thought it is easier passing a config parameter in case you want to change other css properties here:
HTML:
<div class="box" id="A" onclick="fnChangeBorder('A', config={type: 'solid', width: '20px', color: 'red'})">Click here !!</div>
JS:
function fnChangeBorder(boxId, config={})
{
//SETS DEFAULT VALUES IN CASE CONFIG VALUE IS UNDEFINED
const {type = "solid", width = "10px", color = "#000"} = config
document.getElementById(boxId).style.border = `${type} ${width} ${color}`
}

How can I load a canvas inside a div with Vue?

I am really new to Vue and for this project, I was trying to load canvas inside a div. If the canvas is loaded outside of a div it works correctly but I want to display a canvas if loadModal is true only. In this code I have used two canvas one is inside div and other one is outside of div. It loads canvas correctly outside of div only. Is there a way to load canvas inside div as well? Here is my code below on JsFiddle
JsFiddle Code = https://jsfiddle.net/ujjumaki/6vg7r9oy/9/
View
<div id="app">
<button #click="runModal()">
Click Me
</button>
<br><br>
<div v-if="loadModal == true">
<canvas id="myCanvas" width="200" height="100" style="border:3px solid #d3d3d3; color:red;">
</canvas>
</div>
<!-- this one loads correctly -->
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;">
</canvas>
</div>
Method
new Vue({
el: "#app",
data: {
loadModal: false,
},
methods: {
runModal(){
this.loadModal = true;
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.arc(95, 50, 40, 0, 2 * Math.PI);
ctx.stroke();
}
}
})
Try with v-show and with class instead id, so you can select all divs:
new Vue({
el: "#app",
data: {
loadModal: false,
},
methods: {
runModal(){
this.loadModal = true;
const c = document.querySelectorAll("canvas");
c.forEach(can => {
let ctx = can.getContext("2d");
ctx.beginPath();
ctx.arc(95, 50, 40, 0, 2 * Math.PI);
ctx.stroke();
})
}
}
})
Vue.config.productionTip = false
Vue.config.devtools = false
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
li {
margin: 8px 0;
}
h2 {
font-weight: bold;
margin-bottom: 15px;
}
del {
color: rgba(0, 0, 0, 0.3);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<button #click="runModal()">
Click Me
</button>
<br><br>
<div v-show="loadModal == true">
<canvas class="canvas" id="myCanvas" width="200" height="100" style="border:3px solid #d3d3d3; color:red;">
</canvas>
</div>
<canvas class="canvas" id="myCanvas" width="200" height="100" style="border:3px solid #d3d3d3; color:red;">
</canvas>
</div>
The problem is runModal() sets loadModal to true and immediately tries to reference the <canvas> inside the conditionally rendered <div v-if="loadModal">, but the <div> (and its <canvas>) is still not rendered yet. The effect of the loadModal change is not complete until the next render cycle. The <canvas> outside the <div> "loads" correctly because it's not conditionally rendered.
One solution is to await the next render cycle with the $nextTick() callback before trying to access the <canvas>:
new Vue({
methods: {
async runModal() {
this.loadModal = true;
// await next render cycle
await this.$nextTick();
// <canvas id="myCanvas"> is available here
var c = document.getElementById("myCanvas");
⋮
}
}
})
updated fiddle
Alternatively, using <div v-show="loadModal"> (as described in another answer) also works because the <canvas> is already rendered in the document and thus available to query. If you rather prefer to lazily render the <canvas>, stick with v-if="loadModal".

trying to show and edit some boxes with jquery

i am trying to create divs that are boxes and do the following on them
1) change the background color
2) make them look like a circle
3) create more boxes(divs)
each has a individual button to fire the events but the boxes wont show and the only the second button works,with the console.log and the console doesnt show any errors at all
here is the html code and style
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js" >
</script>
<script src="Query_script.js"></script>
<div class= "packages">
<div></div>
<div></div>
</div>
<button id = "change">Turn Colors on/off</button><br>
<button id = "R-border">Rounded Corners on/off</button><br>
<button id = "create">Add an extra box </button> <br>
<style>
.packages{
border-color: black;
border-width: 5px;
height: 75 px;
width: 75 px;
}
</style>
</body>
</html>
and here is the js and query
let pack=document.getElementById("packages");
let rad= document.getElementById("R-border");
let Adder=document.getElementById("create");
let checker=true;
$(document).ready(function() {
$("#changer").click(function(){
console.log("clicked1");
if (checker==true){
$('.pack').css('background-color','red');
checker=false;
}
else{
$('.packa>div').css('background-color','white');
checker=true;
}
});
});
$(document).ready(function() {
$("#R-border").click(function(){
if(checker==true){
console.log("clicked2");
$('.pack').css("border-radius","50%");
checker=false;
}
else{
$('.pack').css("border-radius");
}
});
});
$(document).ready(function() {
$("#Adder").click(function(){
console.log("clicked3");
$('.pack').append("<div>");
});
});
Maintain CSS selector names properly
I have done some modifications to HTML and javascript. Try this... It's working properly.
let pack = document.getElementById("packages");
let rad = document.getElementById("R-border");
let Adder = document.getElementById("create");
let checker = true;
$(document).ready(function () {
$("#change").click(function () {
console.log("clicked1");
if (checker == true) {
$('.packages').css('background-color', 'red');
checker = false;
} else {
$('.packages > div').css('background-color', 'white');
checker = true;
}
});
});
$(document).ready(function () {
$("#R-border").click(function () {
console.log("clicked2");
if (checker == true) {
$('.packages').css("border-radius", "50%");
checker = false;
} else {
$('.packages').css("border-radius");
}
});
});
$(document).ready(function () {
$("#create").click(function () {
console.log("clicked3");
$('.packages').append("<div>");
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="Query_script.js"></script>
<div class="packages">
<div></div>
<div></div>
</div>
<button id="change">Turn Colors on/off</button>
<br>
<button id="R-border">Rounded Corners on/off</button>
<br>
<button id="create">Add an extra box</button>
<br>
<style>
.packages {
border-color: black;
border-width: 5px;
height: 75px;
width: 75px;
}
</style>

Fabric.js beta2 – text underline options

How can we exactly get and set the underline, overline etc. properties now for text, iText and Textbox in the 2.x beta? Is there some documentation available?
var canvas = new fabric.Canvas('canvas');
var text = new fabric.Text('FabricJS is Awsome.',{
fontSize:'30',
left:50,
top:50,
underline:true
});
canvas.add(text);
//text.setSelectionStyles({overline:true},0,5);
canvas.renderAll();
function changeStyle(val){
text[val] = !text[val];
text.dirty = true;
canvas.renderAll();
}
canvas {
border: 2px dotted green;
}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<button onclick=changeStyle('underline')>underline</button>
<button onclick=changeStyle('overline')>overline</button>
<button onclick=changeStyle('linethrough')>linethrough</button><br>
<canvas id="canvas" width="400" height="400"></canvas>
Same as other property set/get from object. fabric.Text

fabric.js adding multiple text using button click

I want to add multiple text on my canvas using click of a button but as i click the button again it reload s the canvas and as loaded my first text again here is my code....is there any better way to do it.???
function text()
{
var m,n;
m=150;
n=60;
var tex=document.getElementById("tex");
var tex1=document.getElementById("tex1");
var te=tex.value;
var te1=tex1.value;
var canvas=new fabric.Canvas('can');
var text=new fabric.Text( te ,{
top: m,
left: n
});
canvas.add(text);
}
function text2()
{
var m,n;
m=150;
n=60;
var tex1=document.getElementById("tex1");
var te1=tex1.value;
var canvas=new fabric.Canvas('can');
var text1=new fabric.Text( te1 ,{
top: m,
left: n
});
canvas.add(text1);
}
finally i got it i dont know where i was making mistake but finally this code of piece is working for me but still can any body tell me my mistake
<script>
$(document).ready(function(e) {
var can=new fabric.Canvas('can');
$("#d").click(function(e) {
rect=new fabric.Text('New Text',{
top:Math.floor(Math.random()*350+1),
left:Math.floor(Math.random()*250+1),
fill:'red'
});
can.add(rect);
});
});
</script>
<body>
<canvas id="can" width="700" height="500" style=" border:0.2em solid #000;" > </canvas>
<div class="controls">
<button id="d" onclick="text()">ADD TEXT</button>
</div>

Categories