Is there a way of adding e.g. circles or boxes to the html5 canvas by using konva.js? i tried it but somehow it doesn't work! What i want it e.g. one click is adding a circle with drag and drop, a doubleclick removes the circle.
This is how it works, maybe someone can use it!
$( document ).ready(function() {
var width = window.innerWidth;
var height = window.innerHeight;
var stage = new Konva.Stage({
container: 'container',
width: width,
height: height
});
var layer = new Konva.Layer();
var colors = ["red", "orange", "yellow", "green", "blue", "purple"];
var rect1 = new Konva.Rect({
x: 25,
y: 25,
width: width-50,
height: height-50,
opacity: 1,
fill: 'green',
stroke: 'black',
strokeWidth: 2
});
var circle = new Konva.Circle({
x: 230,
y: 100,
radius: 30,
fill: 'grey',
stroke: 'black',
strokeWidth: 1,
draggable: true,
id: 'Origin'
});
circle.on('mouseover', function() {
document.body.style.cursor = 'pointer';
});
circle.on('mouseout', function() {
document.body.style.cursor = 'default';
});
circle.on("dragstart", function () {
this.moveToTop();
layer.draw();
});
circle.on("dragmove", function () {
document.body.style.cursor = "pointer";
});
circle.on("dblclick dbltap", function (evt) {
evt.cancelBubble = true;
console.log("item dblclick");
this.destroy();
layer.draw();
});
circle.on("click tap", function (evt) {
evt.cancelBubble = true;
var node = evt.target;
if (node) {
// update tooltip
var mousePos = node.getStage().getPointerPosition();
console.log("item normal click " + node.getId() + " > node-x" + node.x() +" - fill " + node.getFill());
}
});
rect1.on('dblclick', function() {
var clone;
clone = circle.clone({
x:stage.getPointerPosition().x,
y:stage.getPointerPosition().y,
id: 'myCircle'
});
layer.add(clone);
layer.draw();
console.log('content click on rect1 ' + JSON.stringify(stage.getPointerPosition()));
});
circle.on("mouseover", function () {
document.body.style.cursor = "pointer";
});
circle.on("mouseout", function () {
document.body.style.cursor = "default";
});
layer.add(rect1);
layer.add(circle);
stage.add(layer);
});
<!doctype html>
<html lang="{{ app()->getLocale() }}">
<script src="https://cdn.rawgit.com/konvajs/konva/1.7.6/konva.min.js"></script>
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<meta charset="utf-8">
<title>Add/Remove</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #F0F0F0;
}
</style>
</head>
<body>
<div id="container"></div>
</body>
</html>
Related
I have few elements (triangles) and I want to be able to highlight(setShadow) them as I hover above each one (mouse:over/mouse:move), and reset highlight when mouse not over.
I tried this, but it doesn't do anything. Below is my code:
var canvas = new fabric.Canvas('canvas');
var petal1 = new fabric.Triangle({
width: 200,
height: 300,
fill: '#DBDBDB',
left: 500,
top: 350,
angle: 200,
strokeLineJoin: 'round',
strokeWidth: 20,
stroke: '#DBDBDB'
});
var petal2 = new fabric.Triangle({
// same options as above
});
var petal3 = new fabric.Triangle({
// same options as above
});
canvas.on('mouse:over', function(e) {
e.target.set('fill', 'red');
canvas.renderAll();
});
canvas.on('mouse:out', function(e) {
e.target.set('fill', 'green');
canvas.renderAll();
});
canvas.add(petal1, petal2, petal3);
I added console.log(e.target);, but it printed nothing.
Your snippet works and check target before setting property to it.
DEMO
var canvas = new fabric.Canvas('canvas');
var options = {
width: 100,
height: 200,
fill: '#DBDBDB',
strokeLineJoin: 'round',
strokeWidth: 20,
stroke: '#DBDBDB'
};
var petal1 = new fabric.Triangle(options);
var petal2 = new fabric.Triangle(options);
var petal3 = new fabric.Triangle(options);
canvas.on('mouse:over', function(e) {
if(e.target){
e.target.set('fill', 'red');
canvas.requestRenderAll();
}
});
canvas.on('mouse:out', function(e) {
if(e.target){
e.target.set('fill', 'green');
canvas.requestRenderAll();
}
});
canvas.add(petal1, petal2, petal3);
canvas{
border:1px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.7.0/fabric.js"></script>
<canvas id="canvas" width="300" height="300"></canvas>
I want to display an path in Fabric.JS, in svg file:
<g>
<path style="fill:none;stroke:#000000;stroke-miterlimit:10;"
d="M221.58-0.55 c17.5,31.22,4.77,57.16-8.14,88.46c-13.75,33.35,0.71,57.72,0.71,57.72"/>
</g>
And code in my Fabricjs
var Path_0_1 = new fabric.Path('M221.58-0.55 c17.5,31.22,4.77,57.16-8.14,88.46c-13.75,33.35,0.71,57.72,0.71,57.72', {
fill: 'none',
stroke: '#000000',
strokeMiterLimit: 10,
opacity: 1,
});
But result is not same:
Expected:
Path in FabricJS display same as in SVG file.
Here is my code:
var canvasObject = document.getElementById("editorCanvas");
// set canvas equal size with div
$(canvasObject).width($("#canvasContainer").width());
$(canvasObject).height($("#canvasContainer").height());
var canvas = new fabric.Canvas('editorCanvas', {
backgroundColor: 'white',
selectionLineWidth: 2,
width: $("#canvasContainer").width(),
height: $("#canvasContainer").height()
});
var Path_0_1 = new fabric.Path('M221.58-0.55 c17.5,31.22,4.77,57.16-8.14,88.46c-13.75,33.35,0.71,57.72,0.71,57.72', {
// fill : 'none',
stroke: '#000000',
strokeMiterLimit: 10,
opacity: 1,
});
canvas.add(Path_0_1);
canvas.moveTo(Path_0_1, 1);
setObjectCoords();
canvas.renderAll();
function setObjectCoords() {
canvas.forEachObject(function(object) {
object.setCoords();
});
}
#canvasContainer {
width: 100%;
height: 100vh;
background-color: gray;
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.3/fabric.js"></script>
<div id="canvasContainer">
<canvas id="editorCanvas"></canvas>
</div>
And here is my svg file:
https://svgur.com/s/Bw6
Set fill value '' || null || 'transparent', so on ctx.fill() it wont fill anything to the object.
DEMO
var canvasObject = document.getElementById("editorCanvas");
// set canvas equal size with div
$(canvasObject).width($("#canvasContainer").width());
$(canvasObject).height($("#canvasContainer").height());
var canvas = new fabric.Canvas('editorCanvas', {
selectionLineWidth: 2,
width: $("#canvasContainer").width(),
height: $("#canvasContainer").height()
});
var Path_0_1 = new fabric.Path('M221.58-0.55c17.5,31.22,4.77,57.16-8.14,88.46c-13.75,33.35,0.71,57.72,0.71,57.72', {
fill : null,
stroke: '#000000',
});
canvas.add(Path_0_1);
#canvasContainer {
width: 100%;
height: 100vh;
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.3/fabric.js"></script>
<div id="canvasContainer">
<canvas id="editorCanvas"></canvas>
</div>
I have a fabricJS editor with some large svg files, therefore, when I interactive with ( move / drag ) items on the editor I fill it very lag & heavy.
How to optimize using large svg files with fabricJS ?
big_image_1.svg: 4.4MB
big_image_2.svg: 6.1MB
big_image_3.svg: 4.1MB
big_image_4.svg: 13.6MB
Here is my code:
var canvas;
var canvasObject = document.getElementById("editorCanvas");
// set canvas equal size with div
$(canvasObject).width($("#canvasContainer").width());
$(canvasObject).height($("#canvasContainer").height());
canvas = new fabric.Canvas('editorCanvas', {
backgroundColor: 'white',
selectionLineWidth: 2,
width: $("#canvasContainer").width(),
height: $("#canvasContainer").height()
});
for (var i = 0; i < 4; i++) {
var bigImage = new fabric.Image();
bigImage.left = 10 * (i + 1);
bigImage.top = 10 * (i + 1);
bigImage["objectCaching"] = true;
canvas.add(bigImage);
bigImage.setSrc('https://futushigame.firebaseapp.com/big_image/big_image_' + (i + 1) + '.svg', function(imageObject) {
imageObject.set('dirty', true);
canvas.renderAll();
setObjectCoords();
});
}
function setObjectCoords() {
canvas.forEachObject(function(object) {
object.setCoords();
});
}
#canvasContainer {
width: 100%;
height: 100vh;
background-color: gray;
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.3/fabric.js"></script>
<div id="canvasContainer">
<canvas id="editorCanvas"></canvas>
</div>
Drag items are filling heavy & lag
You can rewrite needsItsOwnCache from fabric.Image class.
var canvasObject = document.getElementById("editorCanvas");
// set canvas equal size with div
$(canvasObject).width($("#canvasContainer").width());
$(canvasObject).height($("#canvasContainer").height());
canvas = new fabric.Canvas('editorCanvas', {
backgroundColor: 'white',
selectionLineWidth: 2,
width: $("#canvasContainer").width(),
height: $("#canvasContainer").height()
});
for (var i = 0; i < 4; i++) {
var bigImage = new fabric.Image();
bigImage.left = 10 * (i + 1);
bigImage.top = 10 * (i + 1);
// bigImage["objectCaching"] = true;
bigImage["ownCaching"] = true;
// bigImage["clipPath"] = [];
canvas.add(bigImage);
bigImage.setSrc('https://futushigame.firebaseapp.com/big_image/big_image_' + (i + 1) + '.svg', function(imageObject) {
//imageObject.set('dirty', true);
canvas.renderAll();
setObjectCoords();
});
}
function setObjectCoords() {
canvas.forEachObject(function(object) {
object.setCoords();
});
}
fabric.Image.prototype.needsItsOwnCache = function() {
return true
}
#canvasContainer {
width: 100%;
height: 100vh;
background-color: gray;
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.3/fabric.js"></script>
<div id="canvasContainer">
<canvas id="editorCanvas"></canvas>
</div>
I am new to nvd3 and d3 js.I am creating a line chart using nvd3. Now i want to rotate the text labels for the x Axis of the line chart.How to implement this?
I tried using
var xTicks = d3.selectAll('g.tick');
xTicks
.selectAll('text')
.attr('transform', function(d,i,j) { return ' rotate(-90 0,0)' }) ;
but was unsuccessful
My current code is
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="../build/nv.d3.css" rel="stylesheet" type="text/css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.2/d3.min.js" charset="utf-8"></script>
<script src="../build/nv.d3.js"></script>
<style>
text {
font: 12px sans-serif;
}
svg {
display: block;
}
html, body, #chart1, svg {
margin: 0px;
padding: 0px;
height: 100%;
width: 100%;
}
.dashed {
stroke-dasharray: 5,5;
}
</style>
<script type="text/javascript">
function download()
{
img = new Image(),
serializer = new XMLSerializer(),
svgStr = serializer.serializeToString(document.getElementById('svg'));
img.src = 'data:image/svg+xml;base64,'+window.btoa(svgStr);
// You could also use the actual string without base64 encoding it:
//img.src = "data:image/svg+xml;utf8," + svgStr;
var canvas = document.createElement("canvas");
var w=3000;
var h=3000;
canvas.width = w;
canvas.height = h;
canvas.getContext("2d").drawImage(img,0,0,w,h);
var imgURL = canvas.toDataURL("image/png");
var dlLink = document.createElement('a');
dlLink.download = "image";
dlLink.href = imgURL;
dlLink.dataset.downloadurl = ["image/png", dlLink.download, dlLink.href].join(':');
document.body.appendChild(dlLink);
dlLink.click();
document.body.removeChild(dlLink);
}
</script>
</head>
<body class='with-3d-shadow with-transitions'>
<div style="position:absolute; top: 0; left: 0;">
<button onclick="randomizeFillOpacity();">Randomize fill opacity</button>
<button onclick="expandLegend();">Expand/Contract Legend</button>
<script>
var expandLegend = function() {
var exp = chart.legend.expanded();
chart.legend.expanded(!exp);
chart.update();
}
</script>
</div>
<div id="chart1" width="100%" height='100%'></div>
<button onclick="download()">Download</button>
<script>
// Wrapping in nv.addGraph allows for '0 timeout render', stores rendered charts in nv.graphs, and may do more in the future... it's NOT required
var chart;
var data;
var randomizeFillOpacity = function() {
var rand = Math.random(0,1);
for (var i = 0; i < 100; i++) { // modify sine amplitude
data[4].values[i].y = Math.sin(i/(5 + rand)) * .4 * rand - .25;
}
data[4].fillOpacity = rand;
chart.update();
};
nv.addGraph(function() {
chart = nv.models.lineChart()
.options({
transitionDuration: 300,
useInteractiveGuideline: true
})
;
// chart sub-models (ie. xAxis, yAxis, etc) when accessed directly, return themselves, not the parent chart, so need to chain separately
chart.xAxis
.axisLabel("Time (s)")
.tickFormat(d3.format(',.1f'))
.staggerLabels(true)
;
chart.yAxis
.axisLabel('Voltage (v)')
.tickFormat(function(d) {
if (d == null) {
return 'N/A';
}
return d3.format(',.2f')(d);
})
;
data = sinAndCos();
d3.select('#chart1').append('svg')
.datum(data)
.attr("id","svg")
.attr("height","1000")
.attr("width","1000")
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
function sinAndCos() {
var /*sin = [],
sin2 = [],*/
cos = [],
/* rand = [],*/
rand2 = []
;
for (var i = 0; i < 100; i++) {
cos.push({x: i, y: .5 * Math.cos(i/10)});
rand2.push({x: i, y: Math.cos(i/10) + Math.random() / 10 })
}
return [
{
values: cos,
key: "Cosine Wave",
color: "#2ca02c"
},
{
values: rand2,
key: "Random Cosine",
color: "#667711",
strokeWidth: 3.5,
fillOpacity: .1,
classed: 'dashed',
area: true,
}
];
}
</script>
</body>
</html>
This will work:
chart.xAxis
.rotateLabels(-45)
Im still learning but it seems everything I do does not work in getting the images to also be rotated along with being scaled and dragged. Can someone please help me out with this. Here is the code I am working with...
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body onmousedown="return false;">
<div style="height:1024px; width: 1280px; background-image: url(http://www.designmyprofile.com/images/graphics/backgrounds/background0172.jpg)" id="container"></div>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.2.min.js"></script>
<script>
function update(activeAnchor) {
var group = activeAnchor.getParent();
var topLeft = group.get('.topLeft')[0];
var topRight = group.get('.topRight')[0];
var bottomRight = group.get('.bottomRight')[0];
var bottomLeft = group.get('.bottomLeft')[0];
var image = group.get('.image')[0];
var anchorX = activeAnchor.getX();
var anchorY = activeAnchor.getY();
// update anchor positions
switch (activeAnchor.getName()) {
case 'topLeft':
topRight.setY(anchorY);
bottomLeft.setX(anchorX);
break;
case 'topRight':
topLeft.setY(anchorY);
bottomRight.setX(anchorX);
break;
case 'bottomRight':
bottomLeft.setY(anchorY);
topRight.setX(anchorX);
break;
case 'bottomLeft':
bottomRight.setY(anchorY);
topLeft.setX(anchorX);
break;
}
image.setPosition(topLeft.getPosition());
var width = topRight.getX() - topLeft.getX();
var height = bottomLeft.getY() - topLeft.getY();
if(width && height) {
image.setSize(width, height);
}
}
function addAnchor(group, x, y, name) {
var stage = group.getStage();
var layer = group.getLayer();
var anchor = new Kinetic.Circle({
x: x,
y: y,
stroke: '#666',
fill: '#ddd',
strokeWidth: 2,
radius: 8,
name: name,
draggable: true,
dragOnTop: false
});
anchor.on('dragmove', function() {
update(this);
layer.draw();
});
anchor.on('mousedown touchstart', function() {
group.setDraggable(false);
this.moveToTop();
});
anchor.on('dragend', function() {
group.setDraggable(true);
layer.draw();
});
// add hover styling
anchor.on('mouseover', function() {
var layer = this.getLayer();
document.body.style.cursor = 'pointer';
this.setStrokeWidth(4);
layer.draw();
});
anchor.on('mouseout', function() {
var layer = this.getLayer();
document.body.style.cursor = 'default';
this.setStrokeWidth(2);
layer.draw();
});
group.add(anchor);
}
function loadImages(sources, callback) {
var images = {};
var loadedImages = 0;
var numImages = 0;
for(var src in sources) {
numImages++;
}
for(var src in sources) {
images[src] = new Image();
images[src].onload = function() {
if(++loadedImages >= numImages) {
callback(images);
}
};
images[src].src = sources[src];
}
}
function initStage(images) {
var stage = new Kinetic.Stage({
container: 'container',
width: 1280,
height: 1024
});
var darthVaderGroup = new Kinetic.Group({
x: 270,
y: 100,
draggable: true
});
var yodaGroup = new Kinetic.Group({
x: 100,
y: 110,
draggable: true
});
var layer = new Kinetic.Layer();
/*
* go ahead and add the groups
* to the layer and the layer to the
* stage so that the groups have knowledge
* of its layer and stage
*/
layer.add(darthVaderGroup);
layer.add(yodaGroup);
stage.add(layer);
// darth vader
var darthVaderImg = new Kinetic.Image({
x: 0,
y: 0,
image: images.darthVader,
width: 200,
height: 138,
name: 'image'
});
darthVaderGroup.add(darthVaderImg);
addAnchor(darthVaderGroup, 0, 0, 'topLeft');
addAnchor(darthVaderGroup, 200, 0, 'topRight');
addAnchor(darthVaderGroup, 200, 138, 'bottomRight');
addAnchor(darthVaderGroup, 0, 138, 'bottomLeft');
darthVaderGroup.on('dragstart', function() {
this.moveToTop();
});
// yoda
var yodaImg = new Kinetic.Image({
x: 0,
y: 0,
image: images.yoda,
width: 93,
height: 104,
name: 'image'
});
yodaGroup.add(yodaImg);
addAnchor(yodaGroup, 0, 0, 'topLeft');
addAnchor(yodaGroup, 93, 0, 'topRight');
addAnchor(yodaGroup, 93, 104, 'bottomRight');
addAnchor(yodaGroup, 0, 104, 'bottomLeft');
yodaGroup.on('dragstart', function() {
this.moveToTop();
});
stage.draw();
}
var sources = {
darthVader: 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg',
yoda: 'http://www.html5canvastutorials.com/demos/assets/yoda.jpg'
};
loadImages(sources, initStage);
</script>
</body>
</html>