I want to reveal the background image on mouse move on the front image. I have tried it using fabricjs but it seems the pattern image offset is updated on mouse up.
I have also tried it using the making the pixels transparent of image on mouse move but there are performance issue on slow devices. Can you suggest any better solution.
HTML
<canvas id="container"></canvas>
JS
var canvasWidth = window.innerWidth;
var canvasHeight = window.innerHeight;
var backgroundUrl = "http://www.keenthemes.com/preview/metronic/theme/assets/global/plugins/jcrop/demos/demo_files/image2.jpg";
var frontUrl = "http://tofurious.wpengine.netdna-cdn.com/images/textures/texture-8.jpg";
var canvas = new fabric.Canvas('container', {
width:canvasWidth,
height:canvasHeight,
isDrawingMode: true
});
fnDrawImage(backgroundUrl);
drawPattern()
function fnDrawImage(_url){
var Image = fabric.Image.fromURL(_url, function(oImg) {
oImg.width = canvasWidth;
oImg.height = canvasHeight;
oImg.selectable = false;
canvas.add(oImg);
});
}
function drawPattern(){
var img = new Image();
img.src = frontUrl;
img.onload = function(){
img.width = canvasWidth;
img.height = canvasHeight;
fnTexturePattern(img);
//fnStartFreeDrawing(img);
}
}
function fnTexturePattern(_img){
var texturePatternBrush = new fabric.PatternBrush(canvas);
texturePatternBrush.source = _img;
canvas.freeDrawingBrush = texturePatternBrush;
canvas.freeDrawingBrush.width = 30;
}
JSFiddle - http://jsfiddle.net/3qp5y9jb/
Related
I'm trying to load an image on my HTML5 canvas. I'm following a tutorial and I've done everything precisely.
My console prints "image loaded", so I know that it has found the png file. However, nothing shows up on screen.
I have tried resizing the canvas, and trying to make the image appear on different coordinates, to no avail.
<body>
<canvas id="my_canvas"></canvas>
</body>
<script>
var canvas = null;
var context = null;
var basicImage = null;
var setup = function() {
// Set up canvas
canvas = document.getElementById("my_canvas");
context = canvas.getContext('2d'); // lets us modify canvas visuals later
canvas.width = window.innerWidth; // 1200
canvas.height = window.innerHeight; // 720
// Load an image
basicImage = new Image();
basicImage.src = "bb8.png";
basicImage.onload = onImageLoad();
}
var onImageLoad = function() {
console.log("image loaded");
context.drawImage(basicImage, 0, 0);
}
setup();
</script>
Rather than drawing the image on basicImage.onload, try it on window.onload
var setup = function() {
// Set up canvas
canvas = document.getElementById("my_canvas");
context = canvas.getContext('2d'); // lets us modify canvas visuals later
canvas.width = window.innerWidth; // 1200
canvas.height = window.innerHeight; // 720
// Load an image
basicImage = new Image();
basicImage.src = "bb8.png";
}
window.onload = function() {
console.log("image loaded");
context.drawImage(basicImage, 0, 0);
}
setup();
I'd like to use a hitArea to capture click events in my EaselJS project, but the hitArea Shape I've assigned doesn't seem to be respected.
jsFiddle Example
var stage = new createjs.Stage($("#game")[0]);
// This will be a big button
var container = new createjs.Container();
stage.addChild(container);
// This defines the hit area of the button
var hitArea = new createjs.Shape();
var hitAreaGraphics = hitArea.graphics;
// A 1x1 black square, centered about the origin
hitAreaGraphics.beginFill("#000").drawRect(-0.5, -0.5, 1, 1).endFill();
// Assign the hitArea
container.hitArea = hitArea;
// container.addChild(hitArea);
container.onTick = function() {
var canvas = container.getStage().canvas;
container.x = canvas.width / 2;
container.y = canvas.height / 2;
container.scaleX = canvas.width;
container.scaleY = canvas.height;
};
container.onPress = function() {
alert("Eureka!");
};
// Run the simulation
updater = {
tick: function() { stage.update(); }
};
createjs.Ticker.addListener(updater);
If I add the hitArea shape as a child of the container object, the click events work fine.
I've modified a page where I can drag and drop images onto a canvas. It does everything I want except for one. I've tried multiple methods (including scripts, e.g. Kinetic and Raphael, which I still think may be the route to go) but have dead ended:
Once the image is dropped, I can't drag it on the canvas to a new position.
function drag(e)
{
//store the position of the mouse relativly to the image position
e.dataTransfer.setData("mouse_position_x",e.clientX - e.target.offsetLeft );
e.dataTransfer.setData("mouse_position_y",e.clientY - e.target.offsetTop );
e.dataTransfer.setData("image_id",e.target.id);
}
function drop(e)
{
e.preventDefault();
var image = document.getElementById( e.dataTransfer.getData("image_id") );
var mouse_position_x = e.dataTransfer.getData("mouse_position_x");
var mouse_position_y = e.dataTransfer.getData("mouse_position_y");
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// the image is drawn on the canvas at the position of the mouse when we lifted the mouse button
ctx.drawImage( image , e.clientX - canvas.offsetLeft - mouse_position_x , e.clientY - canvas.offsetTop - mouse_position_y );
}
function convertCanvasToImage() {
var canvas = document.getElementById('canvas');
var image_src = canvas.toDataURL("image/png");
window.open(image_src);
}
Here is a JSFiddle that I used as my initial start point - http://fiddle.jshell.net/gael/GF96n/4/ (drag the JSFiddle logo onto the canvas and then try to move it). I've since added CSS, tabs, content, etc. to my almost working page. The function I don't want to lose is the ability to drag the single image multiple times (clone) onto the canvas.
Any ideas/examples/pointers on how to create this functionality?
You need to do a couple of changes to your code, instead of drawing the image immediately to the canvas, you need to keep track of all images dropped. imagesOnCanvas will be filled with all images dropped.
var imagesOnCanvas = [];
function drop(e)
{
e.preventDefault();
var image = document.getElementById( e.dataTransfer.getData("image_id") );
var mouse_position_x = e.dataTransfer.getData("mouse_position_x");
var mouse_position_y = e.dataTransfer.getData("mouse_position_y");
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
imagesOnCanvas.push({
context: ctx,
image: image,
x:e.clientX - canvas.offsetLeft - mouse_position_x,
y:e.clientY - canvas.offsetTop - mouse_position_y,
width: image.offsetWidth,
height: image.offsetHeight
});
}
You also need an animation loop, which will go through all images in imagesOnCanvas and draw them sequentially. requestAnimationFrame is used to achieve this.
function renderScene() {
requestAnimationFrame(renderScene);
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.clearRect(0,0,
canvas.width,
canvas.height
);
for(var x = 0,len = imagesOnCanvas.length; x < len; x++) {
var obj = imagesOnCanvas[x];
obj.context.drawImage(obj.image,obj.x,obj.y);
}
}
requestAnimationFrame(renderScene);
Next you will have to monitor mousedown events on canvas, and if the event occurs on an image the startMove action can be called
canvas.onmousedown = function(e) {
var downX = e.offsetX,downY = e.offsetY;
// scan images on canvas to determine if event hit an object
for(var x = 0,len = imagesOnCanvas.length; x < len; x++) {
var obj = imagesOnCanvas[x];
if(!isPointInRange(downX,downY,obj)) {
continue;
}
startMove(obj,downX,downY);
break;
}
}
The isPointInRange function returns true if the mouse event occurred on an image object
function isPointInRange(x,y,obj) {
return !(x < obj.x ||
x > obj.x + obj.width ||
y < obj.y ||
y > obj.y + obj.height);
}
Once 'move mode' is active, the x/y coordinates of the object are changed to reflect the new mouse position
function startMove(obj,downX,downY) {
var canvas = document.getElementById('canvas');
var origX = obj.x, origY = obj.y;
canvas.onmousemove = function(e) {
var moveX = e.offsetX, moveY = e.offsetY;
var diffX = moveX-downX, diffY = moveY-downY;
obj.x = origX+diffX;
obj.y = origY+diffY;
}
canvas.onmouseup = function() {
// stop moving
canvas.onmousemove = function(){};
}
}
Working example here:
http://jsfiddle.net/XU2a3/41/
I know it's been like 2 years, but I'll give it a try... In the answer provided by #lostsource, the dataTransfer object is not supported in Opera browser, and the jsfiddle is not working. I desperately need that answer, that's what I've been looking for, but it's not working!
Was wondering if any of you could help me
I've got to create an advert and want to have text flying in from the right.
So far I've managed to do it, but cannot clear the canvas for reanimation.
Here's my code so far:
<canvas id="canvas" width="800" height="200">Your browser doesn't support the canvas. <br/> I appologise for any inconvenience.
</canvas>
<script type = "text/javascript">
//Set up the canvas
var the_canvas_element = document.getElementById("canvas");
var the_canvas = the_canvas_element.getContext("2d");
//Start Variables
var x = 800;
//Start animation timing
var int = setInterval(draw,10);
var ljmulogo = new Image ();
{
ljmulogo.src = 'C:\Users\Chad\Documents\My Web Sites\CWK 2\Part A\Images\ljmu_logo.png'
setInterval (draw,100)
}
function draw()
{
//Clear canvas
the_canvas.clearRect(0,0,800,200);
//Draw text
the_canvas.fillStyle = "#000000";
the_canvas.font = "24pt arial";
the_canvas.fillText("Welcome to:",x,30);
the_canvas.fillStyle = "#000000";
the_canvas.font = "bold 24pt arial";
the_canvas.fillText("Liverpool John Moores University",x,70);
the_canvas.fillStyle = "#000000";
the_canvas.font = "32pt arial";
the_canvas.fillText("Computer Forensics",x,150);
//Check if at the end
if (x<=20)
{
//End animation
int = clearInterval(int);
}
else
{
//bring text in further
x = x -2;
}
}
</script>
Thanks a lot for any help, much appreciated :)
I'm not sure what's going on here, it doesn't look valid:
var ljmulogo = new Image ();
{
ljmulogo.src = 'C:\Users\Chad\Documents\My Web Sites\CWK 2\Part A\Images\ljmu_logo.png'
setInterval (draw,100)
}
To create a new image, try this:
//This code outside the draw loop
var ljmulogo = new Image();
ljmulogo.src = 'ljmu_logo.png';
//This code inside the draw loop
ctx.drawImage(ljmulogo, 0, 0);
(and remove the setInterval (draw,100) as you already have a setInterval + that 100 value is pretty high).
EDIT: Below is the original post, but I have figured out the problem. It appears the problem was with using a decimal number as the Y coordinate (destY). I sorted this out by rounding:
var rand = {
destX: Math.round(Math.random()*main.canvas.width),
destY: Math.random()*main.canvas.height
}
I have included images to show the difference between Firefox and Chrome. As you can see the images I have blended onto the canvas are skewed. Has anyone experienced this before? Is it a problem with context blender, or Webkits canvas in general?
var main;
$(document).ready(function(){
var canvas = document.getElementById('canvas');
main = canvas.getContext('2d');
main.canvas.width = $(window).width();
main.canvas.height = $(window).height()/2;
});
$(window).load(function(){
var array = new Array();
$('img').each(function(){
var temp = document.createElement('canvas');
var ctx = temp.getContext('2d');
ctx.canvas.width = this.width;
ctx.canvas.height = this.height;
ctx.drawImage(this,0,0);
var rand = {
destX: Math.random()*main.canvas.width,
destY: Math.random()*main.canvas.height
}
ctx.blendOnto(main,'multiply',rand);
});
});