Canvas - delete drawimages - image

In my canvas adds 2 images. 1 images is "background canvas". 2 image is cut from 1 image and add to background.
Add background (1 images):
img.onload = function() {
img2= new Image();
img2.src=e.target.result;
canvas.width = this.width;
canvas.height = this.height;
context.drawImage(img2,0,0);
}
Add 2 images:
var c=document.getElementById('obrazek');
var ctx = c.getContext("2d");
var img1 = new Image();
img1.src =$('#blur').getCanvasImage();
img1.onload = function(){
ctx.translate(xStart,yStart);
ctx.beginPath();
context.arc(0, 0, d, 0, 2 * Math.PI, false);
ctx.clip();
ctx.drawImage(img1,-xStart,-yStart);
}
I need clean background. I want delete 2 image and load again background.
My clean:
context.drawImage(img2,0,0);
After cleaning background, I see:
2 image is wrong removed, why?

You need to clear your clipping region or else all further draws will be restricted to your circle.
save the unclipped context
do your clipped drawing
restore the context to its unclipped state
Like this:
function drawAll(backgroundImage,topImage,xStart,yStart,d){
// clear the whole canvas of all images
ctx.clearRect(0,0,c.width,c.height);
// save the unclipped context
ctx.save()
// draw the background image (not clipped)
ctx.drawImage(backgroundImage,0,0);
// create a clipping circle
ctx.arc(xStart,yStart,d,0,Math.PI*2);
ctx.clip();
// draw the top image restricted to the clipping circle
ctx.drawImage(topImage,xStart-topImage.width/2,yStart-topImage.height/2);
// restore the context (clears the clipping circle)
ctx.restore();
}

The issue is that you need to clear your context before you redraw
See related issue:
How to clear the canvas for redrawing

This too work:
ctx.clearRect(0,0, c.width, c.height);
var w = c.width;
c.width = 1;
c.width = w;
context.clearRect ( 0 , 0 , canvas.width , canvas.height );
context.drawImage(img2,0,0);

Related

Three.js raycaster intersection with sprites is completely off to the left

I have sprites with text on screen, placed in spherical pattern and I want to allow user to click on individual words and highlight them.
Now the problem is that when I do raycasting and do raycaster.intersectObjects() it returns sprites that are somewhere completely different where the click happened (usually it highlights words that are to the left of the words clicked). For debugging purposes I actually drew the rays from the raycaster object, and they are pretty much going trough the words I clicked.
In this picture I clicked the words "emma", "universe" and "inspector legrasse", but the words that got highlighted are in the red, I also rotated the camera so we can see the lines.
here is the relevant code:
Sprite creation:
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
canvas.height = 256;
canvas.width = 1024;
...
context.fillStyle = "rgba(0, 0, 0, 1.0)";
context.fillText(message, borderThickness, fontsize + borderThickness);
var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
var spriteMaterial = new THREE.SpriteMaterial({map: texture});
var sprite = new THREE.Sprite(spriteMaterial);
sprite.scale.set(400, 100, 1.0);
Individual sprites are then added to "sprites" array, and then added to the scene.
Click detection:
function clickOnSprite(event) {
mouse.x = ( event.clientX / renderer.domElement.clientWidth ) * 2 - 1;
mouse.y = -( event.clientY / renderer.domElement.clientHeight ) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
drawRaycastLine(raycaster);
var intersects = raycaster.intersectObjects(sprites);
if (intersects.length > 0) {
intersects[0].object.material.color.set(0xff0000);
console.log(intersects[0]);
}
}
I am using perspective camera with orbit controls.
I came to the conclusion, that this cannot be currently done with sprites (at least not currently).
As suggested in the comments, I ended up using plane geometries instead of sprites.

Rotate image on its own center kineticJS

I'm trying to rotate an image added to my canvas using KineticJS.
I got it almost working.
I know I need to set the offset to 'move' the rotation point, that part is working.
But it is also moving to that location of the offset.
After doing some rotating I can drag my image to another location in the canvas and continue rotating around its own center.
I don't want to rotate the whole canvas, because I have multiple images on a layer.
The relevant code:
function rotateLayer() {
// Rotate bird image
var rotation = 15;
// Set rotation point:
imageDict[1].setOffsetX(imageDict[1].width() / 2);
imageDict[1].setOffsetY(imageDict[1].height() / 2);
// rotation in degrees
imageDict[1].rotate(rotation);
imageDict[1].getLayer().draw();
}
A working demo is on jsfiddle: http://jsfiddle.net/kp61vcfg/1/
So in short I want the rotation but not the movement.
How you want to rotate without movement?
KineticJS rotate objects relative it's "start point" . For example for Kinetic.Rect start points is {0, 0} - top left corner. You may move such "start point" to any position with offset params.
After a lot of trail and error I found the solution.
The trick is to set the offset during load to the half width and height to set the rotation point to the middle of the image AND don't call image.cache:
function initAddImage(imgId, imgwidth, imgheight) {
var imageObj = new Image();
imageObj.src = document.getElementById(imgId).src;
imageObj.onload = function () {
var image = new Kinetic.Image({
image: imageObj,
draggable: true,
shadowColor: '#787878',
shadowOffsetX: 2,
shadowOffsetY: 2,
width: imgwidth,
height: imgheight,
x: 150, // half width of container
y: 150, // half height of container
offset : {x : imgwidth / 2, y : imgheight / 2}, // Rotation point
imgId: imgId
});
layer.add(image);
//image.cache();
layer.draw();
imageDict[currentLayerHandle] = image;
currentLayerHandle++;
};
}
I've updated my demo to a working version:
http://jsfiddle.net/kp61vcfg/2/

How do I get rid of default opacity in HTML5 canvas?

I am trying to draw 2 black lines in HTML5 canvas:
JSFiddle: http://jsfiddle.net/KFNt5/
Javascript:
var canvas = document.createElement('canvas');
canvas.height = 150;
canvas.width = 150;
var canvasContext = canvas.getContext('2d');
canvasContext.beginPath();
// Draw the red line.
canvasContext.strokeStyle = '#000';
canvasContext.moveTo(10, 0);
canvasContext.lineTo(10, 100);
canvasContext.stroke();
// Draw the green line.
canvasContext.moveTo(50, 0);
canvasContext.lineTo(50, 100);
canvasContext.stroke();
document.body.appendChild(canvas);​
However, the line to the right is gray, implying that it is semitransparent. How do I ensure that the default opacity is 100 (not transparent at all)?
The second line is lighter due to anti-aliasing. You can include the following line to ensure that you render each line once and avoid the anti-aliasing effect.
canvasContext.translate(0.5, 0.5);
http://jsfiddle.net/bagWQ/
Your first line is darker because you drew it twice, once for each call to stroke(). The second call to stroke() draws both lines because you didn't start a new path.

Fill & Stoke width issue in html 5 canvas

I want to draw a closed shape(Using paths) & my stroke width is 10.
Now,i want to fill that shape,i can fill it using fill() function of context.
But,when i want to change alpha of my shape,then stroke & fill area overlap at border of shape.
I want only fill the area of shape that remains black after my stroke.
I have attached image of explaining my problem.
Click here to show shape with stork & fill bug.
As you can see in jsfiddle,
-- Color of overlapping area are composite color. That i don't want.
I want it to be exactly same as in border(or stroke color with alpha).
-- i am not enable to specify fill area of closed path.(there is no method of contexx.)
-- I can't use "glabalCompositeOperation",because i am drawing more than 1 shapes in 1 canvas in my application.
The effect you are getting seems to be a property of how canvas draws lines round a shape. Half the thickness of the line is drawn inside the shape and half outside the shape. One way round it is to draw the filled shape and the border as seperate paths. The changes to do this for your example are shown below. This will be more difficult with irregular shapes.
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var topLeftCornerX = 188;
var topLeftCornerY = 50;
var width = 200;
var height = 100;
var linewidth = 10;
context.globalAlpha = 0.5;
context.beginPath();
context.moveTo(topLeftCornerX, topLeftCornerY);
context.lineTo(topLeftCornerX+width,topLeftCornerY);
context.lineTo(topLeftCornerX+width,topLeftCornerY+height);
context.lineTo(topLeftCornerX,topLeftCornerY+height);
context.closePath();
context.fillStyle = "#FF0000";
context.fill();
context.beginPath();
context.moveTo(topLeftCornerX-linewidth/2, topLeftCornerY-linewidth/2);
context.lineTo(topLeftCornerX+width+linewidth/2,topLeftCornerY-linewidth/2);
context.lineTo(topLeftCornerX+width+linewidth/2,topLeftCornerY+height+linewidth/2);
context.lineTo(topLeftCornerX-linewidth/2,topLeftCornerY+height+linewidth/2);
context.closePath();
context.lineWidth = linewidth;
context.strokeStyle = "#00FF00";
context.stroke();

Move around an image in processing

Is it possible to move an image (or image object) without clearing the whole background?
I wish to create an app that allows the user to "paint", using a device that is not the mouse. I would like to have a cursor to follow the users movement with the input device, without having to clear the already painted picture.
Is this possible? And how?
It depends how you handle drawing.
I would suggest using PImage as a canvas to draw into and another PImage to store the pixels of your brush. The 'brush' can be a loaded image, or at the start of your sketch you could make the brush using drawing commands, then store those as a PImage using get().
You will need to clear everything because you want to draw your cursor, but you will also draw your canvas, and you'll store 'brush strokes' only when the mouse is pressed (or some device specific method) by using the copy() or the blend() function (depending on your brush PNG - with or without transparency, etc.)
Here's a quick sketch to illustrate this:
PImage canvas;
PImage brush;
void setup(){
size(800,800);
stroke(128);
smooth();
canvas = createImage(width,height,ARGB);
brush = loadImage("brush.png");
}
void draw(){
background(255);
image(canvas,0,0);
//draw cursor
line(mouseX-5,mouseY-5,mouseX+5,mouseY+5);
line(mouseX+5,mouseY-5,mouseX-5,mouseY+5);
//blend brush pixels into canvas if mouse is pressed
if(mousePressed) canvas.blend(brush, 0, 0, brush.width, brush.width, (int)(mouseX-brush.width*.5), (int)(mouseY-brush.height*.5), brush.width, brush.width,MULTIPLY);
}
Note that you need an image into your sketch's data folder.
You can try it here:
You can run a javascript version bellow:
var canvas;
var brush;
function setup(){
createCanvas(800,800);
stroke(128);strokeWeight(3);
smooth();
canvas = createImage(width,height);
brush = getGradientImg(64,64,random(360),random(100),85);
}
function draw(){
background(255);
image(canvas,0,0);
//draw cursor
line(mouseX-5,mouseY-5,mouseX+5,mouseY+5);
line(mouseX+5,mouseY-5,mouseX-5,mouseY+5);
//blend brush pixels into canvas if mouse is pressed
if(isMousePressed) canvas.blend(brush, 0, 0, brush.width, brush.width, (int)(mouseX-brush.width*.5), (int)(mouseY-brush.height*.5), brush.width, brush.width,MULTIPLY);
//image(brush,mouseX,mouseY);
}
//*
function getGradientImg(w,h,hue,satMax,brightness){
push();//isolate drawing styles such as color Mode
colorMode(HSB,360,100,100);
var gradient = createImage(w,h);//create an image with an alpha channel
var np = w * h;//total number of pixels
var np4 = np*4;
var cx = floor(gradient.width * 0.5);//center on x
var cy = floor(gradient.height * 0.5);//center on y
gradient.loadPixels();
for(var i = 0 ; i < np4; i+=4){//for each pixel
var id4 = floor(i * .25);
var x = id4%gradient.width;//compute x from pixel index
var y = floor(id4/gradient.width);//compute y from pixel index
var d = dist(x,y,cx,cy);//compute distance from centre to current pixel
//map the saturation and transparency based on the distance to centre
gradient.pixels[i] = hue;
gradient.pixels[i+1] = map(d,0,cx,satMax,0);
gradient.pixels[i+2] = brightness;
gradient.pixels[i+3] = map(d,0,cx,255,0);
}
gradient.updatePixels();//finally update all the pixels
pop();
console.log(gradient);
return gradient;
}
//*/
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.4/p5.min.js"></script>

Resources