Canvas - When i put <canvas> in div does not work - javascript

I want a draw something canvas tag , when i put in div it doesnt work. I taked this code from github. it isnot working within div.
github url => https://github.com/GeekLaunch/simple-drawing-web-app
how can i do this ? actually i dont know canvas library. but this codes enough for me. In my project i use bootstrap css library.
var canvas, ctx,
brush = {
x: 0,
y: 0,
color: '#000000',
size: 10,
down: false,
},
strokes = [],
currentStroke = null;
function redraw() {
ctx.clearRect(0, 0, canvas.width(), canvas.height());
ctx.lineCap = 'round';
for (var i = 0; i < strokes.length; i++) {
var s = strokes[i];
ctx.strokeStyle = s.color;
ctx.lineWidth = s.size;
ctx.beginPath();
ctx.moveTo(s.points[0].x, s.points[0].y);
for (var j = 0; j < s.points.length; j++) {
var p = s.points[j];
ctx.lineTo(p.x, p.y);
}
ctx.stroke();
}
}
function init() {
canvas = $('#draw');
ctx = canvas[0].getContext('2d');
function mouseEvent(e) {
brush.x = e.pageX;
brush.y = e.pageY;
currentStroke.points.push({
x: brush.x,
y: brush.y,
});
redraw();
}
canvas.mousedown(function (e) {
brush.down = true;
currentStroke = {
color: brush.color,
size: brush.size,
points: [],
};
strokes.push(currentStroke);
mouseEvent(e);
}).mouseup(function (e) {
brush.down = false;
mouseEvent(e);
currentStroke = null;
}).mousemove(function (e) {
if (brush.down)
mouseEvent(e);
});
$('#save-btn').click(function () {
window.open(canvas[0].toDataURL());
});
$('#undo-btn').click(function () {
strokes.pop();
redraw();
});
$('#clear-btn').click(function () {
strokes = [];
redraw();
});
$('#color-picker').on('input', function () {
brush.color = this.value;
});
$('#brush-size').on('input', function () {
brush.size = this.value;
});
}
$(init);
body {
margin: 0;
}
.top-bar {
display: flex;
flex-direction: row;
background-color: #3af;
border-bottom: 2px solid black;
position: absolute;
width: 100%;
}
.top-bar * {
margin: 5px 10px;
}
#draw {
display: block;
}
:<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="top-bar">
<button id="save-btn">Save</button>
<button id="undo-btn">Undo</button>
<button id="clear-btn">Clear</button>
<input type="color" id="color-picker"></input>
<input type="range" id="brush-size" min="1" nax="50" value="10"></input>
</div>
<div style="border:1px solid red;width:500px;height:500px;margin:auto;">
<canvas id="draw" style="border:1px solid red;"></canvas>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="draw.js"></script>
</body>
</html>

From my observation, the save button is not working on chrome. Because apparently Google Chrome has removed support for top-frame navigation, you can see more informations here: https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/GbVcuwg_QjM
You may try to render the canvas data to an iFrame.
Add below function to your draw.js file:
function debugBase64(base64URL){
var win = window.open();
win.document.write('<iframe src="' + base64URL + '" frameborder="0" style="border:0; top:0px; left:0px; bottom:0px; right:0px; width:100%; height:100%;" allowfullscreen></iframe>');
}
Now run the function when click event occurred.
$('#save-btn').click(function () {
debugBase64(canvas[0].toDataURL());
});
Hope it works !

Related

Weird bug occurring for Event listeners( I think)

Whenever I click either 'Reset', 'Color Black', or 'Erase' randomly the entire grid will color in black. If that happens and I click Erase I can clear them off and then sometimes randomly the excess black that was randomly created will disappear. Not really sure what the issue is. I THINK it may be an issue with how the Event Listeners are set up, but this is the only configuration of them that gets the buttons to work. Any ideas what the issue might be?
let blackBtn = document.querySelector('#black');
let eraseBtn = document.querySelector('#eraser');
let resetBtn = document.querySelector('#reset');
let resize = document.querySelector('.resize');
let value = 16; // For default 16x16 grid size
//Create grid
function createGrid(size = value) {
grid.style["grid-template-rows"] = `repeat(${size}, 1fr)`;
grid.style["grid-template-columns"] = `repeat(${size}, 1fr)`;
for (let i = 0; i < size * size; i++) {
const block = document.createElement('div');
block.className = 'block';
grid.appendChild(block);
}
grid.addEventListener("mouseover", colorBlack);
resize.addEventListener("click", resizeGrid);
resetBtn.addEventListener("click", clearGrid);
eraseBtn.addEventListener("click", eraseColor);
blackBtn.addEventListener("click", blackPaint);
}
//Resize the grid
function resizeGrid() {
const newSize = parseInt(prompt("New Size: ", 16));
grid.innerHTML = '';
resize.removeEventListener("click", resizeGrid);
grid.removeEventListener("mouseover", colorBlack);
createGrid(newSize);
}
//Fill in background color of black
function colorBlack(e) {
if (e.target.className !== "block") return false;
e.target.style.backgroundColor = 'black';
}
//Clear background color from grid
function clearGrid(size, newSize) {
grid.innerHTML = '';
resize.removeEventListener("click", resizeGrid);
grid.removeEventListener("mouseover", colorBlack);
createGrid();
}
//Colors divs black after clicking 'Color Black'
function blackPaint(e) {
grid.removeEventListener("mouseover", eraseColor);
grid.addEventListener("mouseover", (e) => {
e.target.style.backgroundColor = 'black';
})
}
//Colors over black divs with white to 'erase' it
function eraseColor(e) {
grid.removeEventListener("mouseover", colorBlack);
grid.addEventListener("mouseover", (e) => {
e.target.style.backgroundColor = 'white';
})
}
createGrid();
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
#grid {
width: 20rem;
height: 20rem;
border: 1px solid #333;
display: grid;
flex-wrap: grid;
}
.block {
border: 1px solid black;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Etch-A-Sketch</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<p>Etch-A-Sketch</p>
</header>
<div class="gameBoard">
<div id="actions">
<button class="resize">Resize</button>
<button id="reset">Reset</button>
<button id="black">Color Black</button>
<button id="eraser">Eraser</button>
</div>
<div id='grid'></div>
<div class="block"></div>
</div>
<script src="script.js"></script>
</body>
</html>
When you click on Black or Erase, you add event listeners that call anonymous functions. These can't be removed with removeEventListener() when you switch modes. So these old event listeners continue to run, erasing and filling in elements.
You should have two functions, colorBlack() and colorWhite(), and switch between them in the mouseover event listener. Also, when you reset or resize, you should go back to black.
The problem with Clear is that it calls createGrid(), which adds all the event listeners again. You remove some of the old listeners before you call it, but not all, so you get duplication. You should separate creating the grid and adding the event listeners, so you don't repeat the listeners, and then you wouldn't need to remove them.
let blackBtn = document.querySelector('#black');
let eraseBtn = document.querySelector('#eraser');
let resetBtn = document.querySelector('#reset');
let resize = document.querySelector('.resize');
let value = 16; // For default 16x16 grid size
//Create grid
function createGrid(size = value) {
grid.style["grid-template-rows"] = `repeat(${size}, 1fr)`;
grid.style["grid-template-columns"] = `repeat(${size}, 1fr)`;
for (let i = 0; i < size * size; i++) {
const block = document.createElement('div');
block.className = 'block';
grid.appendChild(block);
}
}
function addListeners() {
grid.addEventListener("mouseover", colorBlack);
resize.addEventListener("click", resizeGrid);
resetBtn.addEventListener("click", clearGrid);
eraseBtn.addEventListener("click", eraseColor);
blackBtn.addEventListener("click", blackPaint);
}
//Resize the grid
function resizeGrid() {
const newSize = parseInt(prompt("New Size: ", 16));
grid.innerHTML = '';
createGrid(newSize);
blackPaint();
}
//Fill in background color of black
function colorBlack(e) {
if (e.target.className !== "block") return false;
e.target.style.backgroundColor = 'black';
}
//Fill in background color of white
function colorWhite(e) {
if (e.target.className !== "block") return false;
e.target.style.backgroundColor = 'white';
}
//Clear background color from grid
function clearGrid(size, newSize) {
grid.innerHTML = '';
createGrid();
blackPaint();
}
//Colors divs black after clicking 'Color Black'
function blackPaint(e) {
grid.removeEventListener("mouseover", colorWhite);
grid.addEventListener("mouseover", colorBlack);
}
//Colors over black divs with white to 'erase' it
function eraseColor(e) {
grid.removeEventListener("mouseover", colorBlack);
grid.addEventListener("mouseover", colorWhite);
}
createGrid();
addListeners();
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
#grid {
width: 20rem;
height: 20rem;
border: 1px solid #333;
display: grid;
flex-wrap: grid;
}
.block {
border: 1px solid black;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Etch-A-Sketch</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<p>Etch-A-Sketch</p>
</header>
<div class="gameBoard">
<div id="actions">
<button class="resize">Resize</button>
<button id="reset">Reset</button>
<button id="black">Color Black</button>
<button id="eraser">Eraser</button>
</div>
<div id='grid'></div>
<div class="block"></div>
</div>
<script src="script.js"></script>
</body>
</html>

Store draggable DIV's position in HTML Table to MySQL database

I'd like to know if/how i will be able to store the position of where I move a draggable div to on the table, so when the page is reloaded, it will return to were it was left (from MySQL database).
i read some articles about that but it was all about using jquery (event, ui) with AJAX.
here's my code :
var p = document.getElementsByTagName('p');
var choice = document.getElementsByClassName('choice');
var dragItem = null;
for(var i of p){
i.addEventListener('dragstart', dragStart);
i.addEventListener('dragend', dragEnd);
}
function dragStart(){
dragItem = this;
setTimeout(()=>this.style.display = "none", 0);
}
function dragEnd(){
setTimeout(()=>this.style.display = "block", 0);
dragItem = null;
}
for(j of choice){
j.addEventListener('dragover', dragOver);
j.addEventListener('dragenter', dragEnter);
j.addEventListener('dragleave', dragLeave);
j.addEventListener('drop', Drop);
}
function Drop(){
this.append(dragItem);
}
function dragOver(e){
e.preventDefault();
this.style.border = "2px dotted cyan";
}
function dragEnter(e){
e.preventDefault();
}
function dragLeave(e){
this.style.border = "none";
}
section{
width: 1000px;
height: 360px;
margin: 100px auto;
display: flex;
justify-content: space-around;
}
h1{
text-align: center;
}
div{
width: 200px;
height: 90%;
padding: 20px;
margin: 10px;
background: #fafafa;
box-sizing: border-box;
}
p{
font-weight: bold;
border-radius: 5px;
padding: 5px;
color: white;
background: red;
}
table, th, td {
border:1px solid black;
}
button{
width: 100px;
height: 15px;
padding: 15px;
margin: 10px;
background: gray;
box-sizing: border-box;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>test drag & drop </title>
</head>
<body>
<h1> it's just a test for js </h1>
<section>
<div2>
<table style="width:100%">
<tr>
<th>time</th>
<th>DIM</th>
<th>LUN</th>
</tr>
<tr>
<td>8:00 - 9:00</td>
<td><div class="choice"></div> S1-1</td>
<td><div class="choice"></div>S1-2</td>
</tr>
<tr>
<td>9:00 - 10:00</td>
<td><div class="choice"></div>S2-1</td>
<td><div class="choice"></div>S2-2</td>
</tr>
</table>
<button>save</button>
</div2>
<div class="choice">
<p draggable="true">MODULE 1</p>
<p draggable="true">MODULE 2</p>
<p draggable="true">MODULE 3</p>
<p draggable="true">MODULE 4</p>
<p draggable="true">MODULE 5</p>
</div>
</section>
</body>
</html>
This may be an overcomplicated answer. But I feel the best way to go about this is to store an array of module objects inside your javascript. Each module would have a position attribute that would need to be updated every time a module is moved. You could also use the data html attribute to store the position of the element on the element itself(https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes). Here is my code:
Javascript:
var dragItem = null;
let modules = loadDataFromServer();
//Initial UI
updateUI(modules);
function dragStart() {
console.log("Start")
dragItem = this;
setTimeout(() => this.style.display = "none", 0);
}
function dragEnd() {
console.log("End")
setTimeout(() => this.style.display = "block", 0);
dragItem = null;
}
function Drop() {
console.log("Drop")
console.log(dragItem)
this.append(dragItem);
moveModuleTo(modules.length - 1, modules[dragItem.dataset.position])
}
function dragOver(e) {
e.preventDefault();
this.style.border = "2px dotted cyan";
}
function dragEnter(e) {
e.preventDefault();
}
function dragLeave(e) {
this.style.border = "none";
}
//Added Code
function loadDataFromServer() {
//return an array of modules
return [
{
title: "Module 1",
position: 0
},
{
title: "Module 2",
position: 1
},
{
title: "Module 3",
position: 2
},
{
title: "Module 4",
position: 3
},
{
title: "Module 5",
position: 4
},
]
}
function moveModuleTo(position, module) {
if (module.position < position) {
//Module is moving down the list
console.log(position)
console.log(module.position)
for (let i = module.position; i < position; i++) {
modules[i] = modules[i + 1];
modules[i].position = i
}
} else {
//Module is moving up the list
for (let i = module.position - 1; i > position; i--) {
modules[i] = modules[i - 1]
modules[i].position = i + 1;
}
}
modules[position] = module
modules[position].position = position
console.log(modules)
//Update UI and database
updateUI(modules)
}
function updateUI(modules) {
let choice = document.getElementsByClassName('choice');
//Remove old Modules
const draggableContainer = document.getElementById("draggableContainer")
while (draggableContainer.firstChild) {
draggableContainer.removeChild(draggableContainer.lastChild)
}
//Add updated Modules
modules.forEach(item => {
console.log("yeet")
let newDraggableItem = document.createElement('p')
newDraggableItem.innerHTML = `${item.title}`
newDraggableItem.draggable = true
newDraggableItem.dataset.position = item.position
draggableContainer.appendChild(newDraggableItem);
});
//ReAdd Event listeners
var p = document.getElementsByTagName('p');
for (var i of p) {
i.addEventListener('dragstart', dragStart);
i.addEventListener('dragend', dragEnd);
}
for (j of choice) {
j.addEventListener('dragover', dragOver);
j.addEventListener('dragenter', dragEnter);
j.addEventListener('dragleave', dragLeave);
j.addEventListener('drop', Drop);
}
}
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="main.css">
<title>test drag & drop </title>
</head>
<body>
<h1> it's just a test for js </h1>
<section>
<div2>
<table style="width:100%">
<tr>
<th>time</th>
<th>DIM</th>
<th>LUN</th>
</tr>
<tr>
<td>8:00 - 9:00</td>
<td>
<div class="choice"></div> S1-1
</td>
<td>
<div class="choice"></div>S1-2
</td>
</tr>
<tr>
<td>9:00 - 10:00</td>
<td>
<div class="choice"></div>S2-1
</td>
<td>
<div class="choice"></div>S2-2
</td>
</tr>
</table>
<button>save</button>
</div2>
<div class="choice" id="draggableContainer"></div>
</section>
<script src="app.js"></script>
</body>
</html>
For updating a database you could make a write database call every time you move a module. Then every time the page is loaded just sort the array based on the position value. Hope this helps!

how to reset color grid?

I am creating a simple etch-a-sketch game. currently on hover it colors in black. I am trying to use a button to reset the colors back to white. However, i can't get the button to function with an event listener, if i add an alert it displays the alert but nothing else. Please guide me and supply a documentation that I can reference as I want to learn and fixing it without explaining will be counterproductive at this point.
Thank you !
const containerGrid = document.getElementById("mainGrid");
function makeGrid(col) {
for (let i = 0; i < col * col; i++) {
const gridAdd = document.createElement("div");
gridAdd.classList.add("box");
gridAdd.textContent = "";
containerGrid.appendChild(gridAdd);
}
}
makeGrid(16); // make grid 16*16
const btnClear = document.getElementById("clear");
//mouseover event black - need to link to button (well done :)
const boxes = document.querySelectorAll('.box').forEach(item => {
item.addEventListener('mouseover', event => {
item.style.backgroundColor = "black";
})
});
btnClear.addEventListener("click", () => {
boxes.style.backgroundColor = "white";
});
const changeGrid = document.getElementById(".sizechange");
/*clearBtn.forEach.addEventListener("click", function () {
clearBtn.style.color ="white";
});
*/
/*const randomBtn = document.getElementById("randomgen").addEventListener('click',(e) => {
console.log(this.classname)
console.log(e.currentTarget === this)
}) */
//change color
#mainGrid {
display: grid;
justify-content: center;
align-items: center;
grid-template-columns: repeat(16, 1fr);
grid-template-rows: auto;
margin-left: 150px;
width: 200px;
}
.box {
color: black;
border: 3px solid;
height: 10px;
width: 10px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Etch-a-Sketch</title>
<link type="text/css" rel="stylesheet" href="styles.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<div id="colorContainer">
<input type="radio" id="blackchoice" value="color" name="black" class="defaultbtn">
<label for="defaultcolor">black</label>
<input type="radio" id="randomgen" class="hey">
<label for="randomchoice">random</label>
</div>
<div id="changeGrid">
<button id="clear">clear</button>
</div>
<div id="mainGrid"></div>
<script src="app.js"></script>
</body>
</html>
A couple of related problems:
The variable boxes is undefined. It looks as though it was required to be the set elements with class box. When it is being defined this is indeed done, but then made undefined by the forEach attached to it. Separate out these two things and boxes will become the collection of all elements with class box.
Then when the clear is clicked you need to step through each of these boxes making their background color white, so again use a forEach.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Etch-a-Sketch</title>
<link type="text/css" rel="stylesheet" href="styles.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style>
#mainGrid {
display: grid;
justify-content: center;
align-items: center;
grid-template-columns: repeat(16, 1fr);
grid-template-rows: auto;
margin-left: 150px;
width: 200px;
}
.box {
color: black;
border: 3px solid;
height: 10px;
width: 10px;
}
</style>
</head>
<body>
<div id="colorContainer">
<input type="radio" id="blackchoice" value="color" name="black" class="defaultbtn">
<label for="defaultcolor">black</label>
<input type="radio" id="randomgen" class="hey">
<label for="randomchoice">random</label>
</div>
<div id="changeGrid">
<button id="clear">clear</button>
</div>
<div id="mainGrid"></div>
<script src="app.js"></script>
<script>
const containerGrid = document.getElementById("mainGrid");
function makeGrid(col) {
for (let i = 0; i < col * col; i++) {
const gridAdd = document.createElement("div");
gridAdd.classList.add("box");
gridAdd.textContent = "";
containerGrid.appendChild(gridAdd);
}
}
makeGrid(16); // make grid 16*16
const btnClear = document.getElementById("clear");
//mouseover event black - need to link to button (well done :)
const boxes = document.querySelectorAll('.box');
boxes.forEach(box => {
box.addEventListener('mouseover', event => {
box.style.backgroundColor = "black";
})
});
btnClear.addEventListener("click", () => {
boxes.forEach(box => {
box.style.backgroundColor = "white";
});
});
const changeGrid = document.getElementById(".sizechange");
/*clearBtn.forEach.addEventListener("click", function () {
clearBtn.style.color ="white";
});
*/
/*const randomBtn = document.getElementById("randomgen").addEventListener('click',(e) => {
console.log(this.classname)
console.log(e.currentTarget === this)
}) */
//change color
</script>
</body>
</html>
Simplify your CSS
Use a SELECT element for your colors
Define the gridTemplateColumns in JS, not in CSS.
Use simpler functions
Use global variables to store the current grid size and color
Don't forget to clear your grid before changing the size
Assign the mouseenter Event on each cell on creation!
Add a boolean variable isPenDown for a better user experience!
const NewEL = (sel, prop) => Object.assign(document.createElement(sel), prop);
const EL_grid = document.querySelector("#grid");
const EL_clear = document.querySelector("#clear");
const EL_color = document.querySelector("[name=color]");
const EL_size = document.querySelector("[name=size]");
let size = parseInt(EL_size.value, 10);
let color = "black";
let isPenDown = false;
function makeGrid() {
EL_grid.innerHTML = ""; // Clear current grid!
for (let i = 0; i < size ** 2; i++) {
EL_grid.style.gridTemplateColumns = `repeat(${size}, 1fr)`;
EL_grid.append(NewEL("div", {
className: "box",
onmousedown() { isPenDown = true; paint(this); },
onmouseup() { isPenDown = false; },
onmouseenter() { if (isPenDown) paint(this); },
}));
}
};
function paint(EL) {
EL.style.backgroundColor = color;
}
EL_clear.addEventListener("click", () => {
const tmp_color = color; // Remember current color
color = "transparent"; // Temporarily set it to transparent
EL_grid.querySelectorAll(".box").forEach(paint); // Paint all cells as transparent
color = tmp_color; //* Reset as it was before.
});
EL_color.addEventListener("change", () => {
color = EL_color.value;
if (color === "random") color = `hsl(${~~(Math.random() * 360)}, 80%, 50%)`;
});
EL_size.addEventListener("change", () => {
size = parseInt(EL_size.value, 10);
makeGrid();
});
// INIT!
makeGrid();
#grid {
display: inline-grid;
margin: 10px 0;
}
#grid .box {
border: 1px solid;
height: 10px;
width: 10px;
margin: 0;
user-select: none;
}
<div>
<label>
Size:
<input type="number" name="size" value="16">
</label>
<label>
Color:
<select name="color">
<option value="black">black</option>
<option value="white">white</option>
<option value="red">red</option>
<option value="yellow">yellow</option>
<option value="orange">orange</option>
<option value="fuchsia">fuchsia</option>
<option value="transparent">CLEAR (transparent)</option>
<option value="random">RANDOM COLOR</option>
</select>
</label>
<button id="clear">Clear canvas</button>
</div>
<div id="grid"></div>

Saving/Loading JSON on Page

I'd like to make a saver/loader for a single canvas, like on the Fabric.js example website (see JSON tab). I'm able to get, and load to a canvas, my JSON (kudos Durga) with this:
var canvas = new fabric.Canvas('canvas', {
backgroundColor: 'white',
centeredScaling: true,
isDrawingMode: true
});
var canvas1 = new fabric.Canvas('canvas1');
function loadOnCanvas(){
var json = canvas.toJSON();
console.log(json)
canvas1.loadFromJSON(json,canvas1.renderAll.bind(canvas1));
}
body {
}
canvas {
border-radius: 2px;
margin: 5px;
border:1px solid #000000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.min.js"></script>
<button onclick='loadOnCanvas()'>Load</button>
<canvas id="canvas" height="400" width="400"></canvas><br>
<canvas id="canvas1" height="400" width="400"></canvas>
How would I go about getting the JSON on the page so that I can save/load it like in the example?
For anyone coming across this post, I eventually got a solution (here's the JSFiddle) together:
$(function() {
var canvas = new fabric.Canvas('c', {
/* isDrawingMode: true */
});
$('#text').on('click', addtext);
function addtext() {
var text = new fabric.IText('Some Text!', {
left: 10,
top: 10
});
canvas.add(text);
}
// From Computer
document.getElementById('imgLoader').onchange = function handleImage(e) {
var reader = new FileReader();
reader.onload = function(event) {
console.log('fdsf');
var imgObj = new Image();
imgObj.src = event.target.result;
imgObj.onload = function() {
// start fabricJS stuff
var image = new fabric.Image(imgObj);
image.set({
left: 0,
top: 0,
angle: 20,
padding: 10,
cornersize: 10
});
//image.scale(getRandomNum(0.1, 0.25)).setCoords();
image.scale(0.2);
canvas.add(image);
// end fabricJS stuff
}
}
reader.readAsDataURL(e.target.files[0]);
}
//
var myImg = 'https://i.imgur.com/q2oGjQ9.jpg';
$('#addImage').on('click', addImg);
function addImg() {
fabric.Image.fromURL(myImg, function(oImg) {
oImg.scale(0.2);
canvas.add(oImg);
});
}
$("#canvas2json").click(function() {
var json = canvas.toJSON();
$("#myTextArea").text(JSON.stringify(json));
});
$("#loadJson2Canvas").click(function() {
canvas.loadFromJSON(
$("#myTextArea").val(),
canvas.renderAll.bind(canvas));
});
});
#myTextArea {
width: 200px;
height: 200px;
}
canvas {
border: 1px solid black
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<button id="text">Add Text</button>
<input type="button" id="addImage" value="Add Web IMG">
<input type="file" id="imgLoader">
<br/><br/>
<canvas id='c' width=500 height=500></canvas>
<br/>
<button id='canvas2json'>canvas2json</button>
<button id='loadJson2Canvas'>loadJson2Canvas</button>
<br/><br/>
<textarea id='myTextArea' onfocus="this.select();" onmouseup="return false;"></textarea>

Tootip event with JQuery and array with id

I found this snipplet online and altered it so I hoped it would work for me:
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
<style type="text/css">
#hint{
cursor:pointer;
}
.tooltip{
margin:8px;
padding:8px;
border:1px solid blue;
background-color:lightblue;
position: absolute;
z-index: 2;
}
</style>
</head>
<body>
<h1>Testpage</h1>
<label id="username">Username : </label><input type="text" / size="50">
<span id="hint">Tooltip</span>
<script type="text/javascript">
$(document).ready(function() {
var changeTooltipPosition = function(event) {
var tooltipX = event.pageX + 15;
var tooltipY = event.pageY - 20;
$('div.tooltip').css({top: tooltipY, left: tooltipX});
};
var testext = {
"hint_text": {
"attr1": "String1/1",
"attr2": "String1/2"
},
"username_text": {
"attr1": "String2/1",
"attr2": "String2/2"
}
};
var showTooltip = function(event, id) {
var outputid= id+"_text";
$('div.tooltip').remove();
$('<div class="tooltip">'+testext[$outputid]['attr2']+'</div>')
.appendTo('body');
changeTooltipPosition(event);
};
var hideTooltip = function() {
$('div.tooltip').remove();
};
$("span#hint,label#username'").bind({
mousemove : changeTooltipPosition,
mouseenter : showTooltip,
mouseleave: hideTooltip
});
});
</script>
</body>
</html>
I have for example the id "hint" and I want to use the hint_text/attr2 tooltip. So I take the id ( var showTooltip = function(event, id)) and append "_text" to it (var outputid= id+"_text";) and then use that to get the tooltip ($(''+testext[$outputid]['attr2']+'').appendTo('body');).
When I use a static value like testext['hint_text']['attr2'] it works but like this I can't get it done.
Where am I going wrong?
Any ideas?
Thanks in advance.
Hi Please try the following code ....
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
<style type="text/css">
#hint{
cursor:pointer;
}
.tooltip{
margin:8px;
padding:8px;
border:1px solid blue;
background-color:lightblue;
position: absolute;
z-index: 2;
}
</style>
</head>
<body>
<h1>Testpage</h1>
<label id="username">Username : </label><input type="text" / size="50">
<span id="hint">Tooltip</span>
<script type="text/javascript">
$(document).ready(function() {
var changeTooltipPosition = function(event) {
var tooltipX = event.pageX + 15;
var tooltipY = event.pageY - 20;
$('div.tooltip').css({top: tooltipY, left: tooltipX});
};
var testext = {
"hint_text": {
"attr1": "String1/1",
"attr2": "String1/2"
},
"username_text": {
"attr1": "String2/1",
"attr2": "String2/2"
}
};
var showTooltip = function(event, id) {
if(id!='document'){
var outputid= this.id+"_text";
$('div.tooltip').remove();
$('<div class="tooltip">'+testext[outputid]['attr2']+'</div>').appendTo('body');
changeTooltipPosition(event);
}
};
var hideTooltip = function() {
$('div.tooltip').remove();
};
$("span#hint,label#username").bind({
mousemove : changeTooltipPosition,
mouseenter : showTooltip,
mouseleave: hideTooltip
});
});
</script>

Categories