How can I select the cropped image in fabric js - html

<html>
<head>
<style type="text/css">
canvas{
border:1px solid #ccc;
}
.canvas-container{
float: left;
left: 20px;
}
</style>
</head>
<body>
<canvas id='canvas' width='500' height='600' ></canvas>
<canvas id='C2' width='500' height='600'></canvas>
<script type="text/javascript" src="fabric.js"></script>
<script>
(function() {
var canvas = this.__canvas = new fabric.Canvas('canvas');
fabric.Object.prototype.transparentCorners = false;
var radius = 300;
fabric.Image.fromURL('./images/Chrysanthemum.jpg', function(img) {
img.scale(0.4).set({
left: 10,
top: 100,
angle: 0,
clipTo: function (ctx) {
ctx.rect(-250, -250, 400, 400);
}
});
canvas.add(img).setActiveObject(img);
console.log(canvas.getActiveObject());
});
})();
</script>
</body>
----------
</html>
//the code above;
Now the active object size is the same as the image which has not been cropped;
But if there is any way to make the cropped image to be selected.Means the smaller size which will be selected in a smaller size.
thx!

Clip is not meant for that effect:
If you desire some cropping better go with pattern trick if your cropping differs from what the attribute preserverveAspectRatio allows you.
(basically crop in center, crop left crop right, both for x and y axis).
As you see instead of image i create a rect with desired dimensions, then i use the img loaded to create a pattern that will fill the rect.
You can then use offsetX and offsetY on pattern to modify the part of image visible.
offsets are accessible trought:
rect.fill.offsetX
rect.fill.offsetY
(function() {
var canvas = this.__canvas = new fabric.Canvas('canvas');
fabric.Object.prototype.transparentCorners = false;
var radius = 300;
fabric.Image.fromURL('http://fabricjs.com/assets/pug.jpg', function(img) {
var rect = new fabric.Rect({width: 400, height: 400});
var pattern = new fabric.Pattern({source: img.getElement(), offsetX: -20, offsetY: -50});
rect.scale(0.4).set({
left: 10,
top: 100,
angle: 0,
fill: pattern,
});
canvas.add(rect).setActiveObject(rect);
});
})();
canvas{
border:1px solid #ccc;
}
.canvas-container{
float: left;
left: 20px;
}
<canvas id='canvas' width='500' height='600' ></canvas>
<canvas id='C2' width='500' height='600'></canvas>
<script type="text/javascript" src="http://fabricjs.com/lib/fabric.js"></script>

Related

Scroll bars - KineticJS

I have a canvas defined in a div. I have set the option the oveflow option in div to scroll. when I set any content in the canvas. I'm able to scroll. How can I have the same affect using KineticJS ?
Scrollbars in KineticJS
Same concept really!
Wrap the kineticJS container in a wrapper div:
<div id="wrapper">
<div id="container"></div>
</div>
Next set the wrapper div to your desired smaller size (with overflow:scroll):
#wrapper{ overflow:scroll; width:300px; height:350px;}
And then just set your kinetic stage size to your large-as-life size:
var stage = new Kinetic.Stage({
container: 'container',
width: 740,
height: 463
});
Here's code and a Fiddle: http://jsfiddle.net/m1erickson/j4RGL/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://www.html5canvastutorials.com/libraries/kinetic-v4.3.3-beta.js"></script>
<style>
#container{
border:solid 1px #ccc;
margin-top: 10px;
}
#wrapper{ overflow:scroll; width:300px; height:350px; border:2px solid blue; }
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 740,
height: 463
});
var layer = new Kinetic.Layer();
stage.add(layer);
var image=new Image();
image.onload=function(){
var kImg=new Kinetic.Image({
image:image,
id:99,
x:0,
y:0,
width:740,
height:463,
draggable:false
});
layer.add(kImg);
layer.draw();
}
image.src="http://www.mrwallpaper.com/wallpapers/Colorful-New-York-City.jpg";
}); // end $(function(){});
</script>
</head>
<body>
<div id="wrapper">
<div id="container"></div>
</div>
</body>
</html>

Make a draggable HTML5 canvas curve area

If I have a canvas in which an image is drawn. The image has four points in the curve. I need to make this curve area draggable.
but without use of kinetic Js
Image attached.
HTML
<div id='curveAreaDrag' class="ui-widget-content" >
<div id="point1" class="ui-widget-content"></div>
<div id="point2" class="ui-widget-content"></div>
<div id="point3" class="ui-widget-content"></div>
<div id="point4" class="ui-widget-content"></div>
</div>
<canvas id="myCanvas" width="400px" height="400px"
style="border:1px solid #d3d3d3;top:0;left:0"></canvas>
jQuery
$("#curveAreaDrag").draggable({drag:function(){save();}});
Updated:
I have four points of bezier curve. i am also scaling each point then the light black area also scaling.
i need to drag the light black area. it is not an image. it is selected area by bezier curve.
[ Edited: To fit OP’s additional information ]
This code uses 2 Cubic Bezier Curves and 6 control handles to let you select the eyeball in your image.
The Red handles control the curve on the top part of the eye. The Blue handles control the curve on the bottom part of the eye. The White handles let you anchor on the corners of the eye. The Orange shows the resulting path (=2 curves).
Below is a picture of the app and here is a Fiddle of it in action: http://jsfiddle.net/m1erickson/98G9F/
Here is the code:
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.1/jquery-ui.js"></script>
<style>
body { font-family: arial; }
.anchor { background: #fff; position: absolute; display: block; height: 10px; width: 10px; border: 1px solid #333; border-radius:5px;}
.control { background: #fff; position: absolute; display: block; height: 20px; width: 20px; border: 1px solid #333; border-radius:10px;}
.p1, .p2 { background: red; z-index: 50; }
.p3, .p4 { background: blue; }
.pStart { background:white;}
.pEnd {background:white;}
.pStart { left: 54px; top: 166px; }
.pEnd { left: 346px; top: 189px; }
.p1 { left: 150px; top: 39px; }
.p2 { left: 276px; top: 97px; }
.p3 { left: 219px; top: 227px; }
.p4 { left: 147px; top: 224px; }
canvas { border: 1px solid #333;}
#start,#end2{color:green;}
#end1{color:purple;}
#c1,#c3{color:red;}
#c2,#c4{color:blue;}
</style>
</head>
<body>
<canvas height="400" width="400" id="canvas"></canvas>
<p>context.moveTo(
<span id="start"></span>);
</p>
<p>context.bezierCurveTo(
<span id="c1"></span>,
<span id="c2"></span>,
<span id="end1"></span>);
</p>
<p>context.bezierCurveTo(
<span id="c3"></span>,
<span id="c4"></span>,
<span id="end2"></span>);
</p>
<script>
var $p1,$p2,$codeMove,$codeBez1,$codeBez2;
$(function() {
var canvas=document.getElementById("canvas");
var ctx = canvas.getContext("2d");
$pStart=$(".pStart");
$pEnd=$(".pEnd");
$p1 = $(".p1");
$p2 = $(".p2");
$p3 = $(".p3");
$p4 = $(".p4");
$codeMove=$("code-move");
$codeBez1=$("code-bez1");
$codeBez2=$("code-bez2");
$(".pStart, .pEnd, .p1, .p2, .p3, .p4").draggable({
containment: 'parent',
drag: function(event, ui) { renderWrap(ctx); },
stop: function(){ renderWrap(ctx); }
});
var eyeImage=new Image();
eyeImage.onload=function(){
canvas.width=eyeImage.width*1.5;
canvas.height=eyeImage.height*1.5;
renderWrap(ctx);
}
eyeImage.src="http://i.stack.imgur.com/SbcL4.png";
function renderWrap(ctx) {
var pStart=$pStart.position();
var pEnd=$pEnd.position();
var p1 = $p1.position();
var p2 = $p2.position();
var p3 = $p3.position();
var p4 = $p4.position();
render({x:pStart.left, y:pStart.top}, {x:pEnd.left, y:pEnd.top}, {x:p1.left, y:p1.top}, {x:p2.left, y:p2.top}, {x:p3.left, y:p3.top}, {x:p4.left, y:p4.top} );
};
function render(start, end, p1, p2, p3, p4) {
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(eyeImage,0,0,eyeImage.width,eyeImage.height,0,0,eyeImage.width*1.5,eyeImage.height*1.5);
ctx.beginPath();
ctx.lineWidth = 2;
ctx.strokeStyle = "orange";
// start-->end
ctx.moveTo(start.x,start.y);
ctx.bezierCurveTo(p1.x,p1.y,p2.x,p2.y,end.x,end.y);
ctx.stroke();
// end-->start
ctx.bezierCurveTo(p3.x,p3.y,p4.x,p4.y,start.x,start.y);
ctx.stroke();
ctx.closePath();
// connectors
ctx.beginPath();
ctx.strokeStyle = "#999";
ctx.lineWidth = 1;
connector(start,p1);
connector(end,p2);
connector(end,p3);
connector(start,p4);
ctx.closePath();
// display code
$("#start").html(start.x+","+start.y);
$("#c1").html(p1.x+","+p1.y);
$("#c2").html(p2.x+","+p2.y);
$("#end1").html(end.x+","+end.y);
$("#c3").html(p3.x+","+p3.y);
$("#c4").html(p4.x+","+p4.y);
$("#end2").html(start.x+","+start.y);
}
function connector(pt1,pt2){
ctx.moveTo(pt1.x,pt1.y);
ctx.lineTo(pt2.x,pt2.y);
ctx.stroke();
}
});
</script>
</body>
</html>

transitionTo method of kineticJs not working on click event

I am using transitionTo method of kineticJS to show animated rotation of a shape on click event of mouse. It works fine if we click the shape first time but then on subsequent clicks it does not rotate the shape. I want to show transition(rotation) of the shape by some angle every time I click on it. Please let me know the mistake I am making and how can I correct it??
This is the code I am using
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
canvas {
border: 1px solid #9C9898;
}
</style>
<script src="http://www.html5canvastutorials.com/libraries/kinetic-v3.9.6.js"></script>
<script>
window.onload = function() {
var stage = new Kinetic.Stage({
container: "container",
width: 578,
height: 200
});
var layer = new Kinetic.Layer({
x:stage.getWidth()/3 ,
y: stage.getHeight()/3
});
var rect = new Kinetic.Rect({
x: 239,
y: 75,
width: 100,
height: 50,
fill: "#00D2FF",
stroke: "black",
strokeWidth: 4,
centerOffset: [50, 100]
});
// add the shape to the layer
layer.add(rect);
// add the layer to the stage
stage.add(layer);
rect.on("click", function() {
rect.transitionTo({
rotation:2*Math.PI,
duration:1
});
stage.draw();
});
};
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>
Try this:
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
canvas {
border: 1px solid #9C9898;
}
</style>
<script src="http://www.html5canvastutorials.com/libraries/kinetic-v3.10.0.js"></script>
<script>
window.onload = function() {
var angle = 0;
var stage = new Kinetic.Stage({
container: "container",
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var rect = new Kinetic.Rect({
x: 239,
y: 75,
width: 100,
height: 50,
fill: "#00D2FF",
stroke: "black",
strokeWidth: 4
});
layer.add(rect);
stage.add(layer);
rect.on("click", function() {
angle += 2;
rect.transitionTo({
rotation: Math.PI * angle,
duration:1
});
});
};
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>
The click was working just fine, however you were telling it to rotate to the same angel every time (why it only animates on the first click). I added a variable so that the angle increases 360 degrees every time you click on it.

jQuery - Follow the cursor with a DIV

How can I use jQuery to follow the cursor with a DIV?
You can't follow the cursor with a DIV, but you can draw a DIV when moving the cursor!
$(document).on('mousemove', function(e){
$('#your_div_id').css({
left: e.pageX,
top: e.pageY
});
});
That div must be off the float, so position: absolute should be set.
You don't need jQuery for this. Here's a simple working example:
<!DOCTYPE html>
<html>
<head>
<title>box-shadow-experiment</title>
<style type="text/css">
#box-shadow-div{
position: fixed;
width: 1px;
height: 1px;
border-radius: 100%;
background-color:black;
box-shadow: 0 0 10px 10px black;
top: 49%;
left: 48.85%;
}
</style>
<script type="text/javascript">
window.onload = function(){
var bsDiv = document.getElementById("box-shadow-div");
var x, y;
// On mousemove use event.clientX and event.clientY to set the location of the div to the location of the cursor:
window.addEventListener('mousemove', function(event){
x = event.clientX;
y = event.clientY;
if ( typeof x !== 'undefined' ){
bsDiv.style.left = x + "px";
bsDiv.style.top = y + "px";
}
}, false);
}
</script>
</head>
<body>
<div id="box-shadow-div"></div>
</body>
</html>
I chose position: fixed; so scrolling wouldn't be an issue.
This works for me. Has a nice delayed action going on.
var $mouseX = 0, $mouseY = 0;
var $xp = 0, $yp =0;
$(document).mousemove(function(e){
$mouseX = e.pageX;
$mouseY = e.pageY;
});
var $loop = setInterval(function(){
// change 12 to alter damping higher is slower
$xp += (($mouseX - $xp)/12);
$yp += (($mouseY - $yp)/12);
$("#moving_div").css({left:$xp +'px', top:$yp +'px'});
}, 30);
Nice and simples

An html5 canvas element in the background of my page?

Is it possible to have a full screen canvas element in the background of a webpage and "normal" markup elements like a table in front of it?
like the following snippet (if it wouldn't be used as alternative content):
<canvas id="imageView" width="100%" height="100%">
<table>...</table>
</canvas>
You could try setting a CSS style on the canvas where it has a position: fixed (or absolute as appropriate), and then any content that follows it (as opposed to container content as you've given in your example) should sit on top of it.
<html>
<style>
body {
margin:0;
padding:0;
}
canvas{
position:absolute;
left:0;
top:0;
z-index:-1;
}
div{
position:absolute;
z-index:0;
left:12px;
top:10px;
}
</style>
<body>
<canvas id="myCanvas" width="600" height="600" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
<div>hello is floating div</div>
<script type="text/javascript">
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var grd = ctx.createLinearGradient(0, 0, 600, 600);
grd.addColorStop(0, "#FF0000");
grd.addColorStop(1, "#00FF00");
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 600, 600);
</script>
</body>
</html>
I tried it for you with the following code. The div gets placed on top of the canvas element just as Matthew describes it. So should work for you:
<!DOCTYPE HTML>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Canvas demo</title>
<style type="text/css">
#canvasSection{ position:fixed;}
</style>
<script type="text/javascript">
function draw()
{
//paint the text
var canvas = document.getElementById('canvasSection');
var context = canvas.getContext('2d');
context.fillStyle = '#00f';
context.font = 'italic 30px sans-serif';
context.textBaseline = 'top';
context.font = 'bold 30px sans-serif';
context.strokeText('Your Text!!', 0, 0);
//paint the square
var canvasSquare = document.getElementById('canvasSquare');
var ctxSquare = canvas.getContext('2d');
ctxSquare.fillStyle='#FF0000';
ctxSquare.fillRect(0, 100,50,100);
}
</script>
</head>
<body onLoad="draw()">
<canvas id="canvasSection">Error, canvas is not supported</canvas>
<div>TestText</div>
</body>
</html>
You can use toDataURL() to have it in pure JS separated from HTML
var c = document.createElement('canvas'),
ctx = c.getContext('2d'),
size = c.width = c.height = 50;
for( var x = 0; x < size; x++ ){
for( var y = 0; y < size; y++ ){
ctx.fillStyle = 'hsl(0, 0%, ' + ( 100 - ( Math.random() * 15 ) ) + '%)';
ctx.fillRect(x, y, 1, 1);
}
}
document.body.style.background = 'url(' + c.toDataURL() + ')';
HTML on <b>canvas background</b>
Based on this CodePen