Html Canvas add Text Or Image in Rendered Image - html5-canvas

i am trying to add add text (water mark) in canvas generated image
here is my code.
html2canvas($("#frame"), {
onrendered: function (canvas) {
$("#outputImage").html(canvas);
}
what i should add in this code to add watermark mark in generated image

Inside the handler do the following:
html2canvas($("#frame"), {
onrendered: function (canvas) {
var ctx = canvas.getContext("2d"); // get 2D context of canvas
ctx.textBaseline = "top"; // start with drawing text from top
ctx.font = "20px sans-serif"; // set a font and size
ctx.fillStyle = "red"; // set a color for the text
ctx.fillText("WATERMARK", 20, 20); // draw the text at some position (x, y)
$("#outputImage").html(canvas);
}
}
There is also alignment modes using:
ctx.textAlign = "center"; // default: "start" = left-to-right/right-to-left
// depending on language, override with "left" or "right"

Check out Canvas.globalCompositeOperation. If you set it to the string 'lighter', it will lighten the pixels drawn by the next drawing command (such as fillText()). Here's a sample
<canvas id='canvas'></canvas>
<script>
var img = new Image();
img.src = 'http://www.javascripture.com/pic.jpg';
img.onload = function() {
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.drawImage(img, 0, 0, canvas.width, canvas.height);
// Draw the Watermark
context.font = '48px sans-serif';
context.globalCompositeOperation = 'lighter';
context.fillStyle = '#444';
context.textAlign = 'center';
context.textBaseline = 'middle';
context.fillText('watermark', canvas.width / 2, canvas.height / 2);
};
</script>

Related

Loading image in Canvas with mouse follow

I am struggling to make an image appear in a Canvas animated card. I can get text and drawn images to show up, but I can't seem to load the image and still have the ball follow the mouse. Why is that? I'm sure it's something super easy but I keep trying different things and am getting no where!
<script>
var canvas = document.querySelector("#myCanvas");
var context = canvas.getContext("2d");
var canvasPos = getPosition(canvas);
var mouseX = 525;
var mouseY = 325;
canvas.addEventListener("mousemove", setMousePosition, false);
function setMousePosition(e) {
mouseX = e.clientX - canvasPos.x;
mouseY = e.clientY - canvasPos.y;
}
function getPosition(el) {
var xPosition = 0;
var yPosition = 0;
while (el) {
xPosition += (el.offsetLeft - el.scrollLeft + el.clientLeft);
yPosition += (el.offsetTop - el.scrollTop + el.clientTop);
el = el.offsetParent;
}
return {
x: xPosition,
y: yPosition
};
}
function loadTeacher() {
var myImage = new Image();
myImage.src = 'images/teacher.jpg';
myImage.addEventListener("load", loadImage, false);
function loadImage(e) {
context.drawImage(myImage, 0, 75, 500, 350);
}
} loadTeacher();
function update() {
context.clearRect(0, 0, canvas.width, canvas.height);
//write text
context.font = "bold 12pt Helvetica, Ariel, sans-serif";
context.textAlign = "center";
context.fillStyle = "black";
context.fillText("This teacher needs an apple now! Drag the apple to her mouth.", 250, 50);
//draw circle
context.beginPath();
context.arc(mouseX, mouseY, 15, 0, 2 * Math.PI, true);
context.fillStyle = "red";
context.fill();
requestAnimationFrame(update);
}
update();
</script>

How to have foreground text with repeat pattern on canvas?

I am trying to have a repeated background image with the text foreground but when I add pattern on canvas the text is not visible, here is me code:
HTML
<canvas id="canvas"></canvas>
JavaScript
var canvas = document.getElementById("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var ctx = canvas.getContext("2d");
var img = new Image();
img.src = "https://cdn.pixabay.com/photo/2019/03/03/20/23/flowers-4032775__340.png";
img.height = 10;
img.onload = function(){
ctx.font = "30px Calibri";
ctx.fillText("DEXIE", 10, 50);
ctx.drawImage(img, 0, 0);
var ptrn = ctx.createPattern(img, 'repeat');
ctx.fillStyle = ptrn;
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
Draw the text after drawing the pattern. Changing the fillStyle to what color you want the text to be.
canvas.width = innerWidth;
canvas.height = innerHeight;
var ctx = canvas.getContext("2d");
var img = new Image();
img.src = "https://cdn.pixabay.com/photo/2019/03/03/20/23/flowers-4032775__340.png";
img.onload = function(){
img.height = 10;
ctx.drawImage(img, 0, 0); // Do you really want to draw the image on the canvas????
var ptrn = ctx.createPattern(img, 'repeat');
// Draw pattern first
ctx.fillStyle = ptrn;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Draw text on top
ctx.font = "30px Calibri";
ctx.fillStyle = "Black"; // <<== Set text color
ctx.fillText("DEXIE", 10, 50);
}

how to set canvas size propertly for canvasTexture in threejs

This is how I set in my code
createText(text = 'example') {
const canvas = document.createElement('canvas');
// canvas.width = 256;
// canvas.height = 64;
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#796e8c';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.font='120px Arial';
ctx.fillStyle = '#000000';
ctx.fillText(text, 0, 120);
const canvasTexture = new THREE.CanvasTexture(canvas);
const spriteMaterail = new THREE.SpriteMaterial({
map: canvasTexture,
color: 0xffffff
});
const sprite = new THREE.Sprite(spriteMaterail);
return sprite;
}
but the context is clipped
if I set canvas size like:
canvas.width = 256
canvas.width = 64
the result is like this:

Three js - the best way to draw text and line

after gone through three.js docs, I found it is quite hard to draw line with stroke width, and text.
For the line with stroke width I have to draw an rectange and adjust it to look likes a thick line
For the text, there only two option, one is using font loader, which I found it very hard to handle the promise of font loader, and it become slower if I have so many text.
But if I use canvas to draw the text then use sprite to add that canvas, then I got my texts keep rotates whenever I rotate my camera
so it is 2018, is there any way to make life more easier with three js.
Thanks all
my code to create a thick curve line
function curveLine(start, mid, end, width) {
var curveLine = new THREE.Shape();
curveLine.moveTo(start.x, start.y + width);
curveLine.quadraticCurveTo(mid.x, mid.y + width, end.x, end.y + width);
curveLine.lineTo(end.x, end.y);
curveLine.quadraticCurveTo(mid.x, mid.y, start.x, start.y);
curveLine.lineTo(start.x, start.y);
return curveLine;
}
var line = curveLine({x:0,y:0}, {x:120,y:80}, {x:240,y:0}, 20);
var lineGeo = new THREE.ExtrudeGeometry(line, extrudeSettings);
var lineMesh = new THREE.Mesh(lineGeo, new THREE.MeshBasicMaterial({color: 'red'}));
scene.add(lineMesh);
And this my code to draw text, current using canvas to draws
function text2D(text, params) {
var canvas = document.createElement('canvas');
canvas.width = params.radius * 4;
canvas.height = params.radius * 2;
var context = canvas.getContext('2d');
context.font = '20px Verdana';
var metrics = context.measureText(text);
var textWidth = metrics.width;
context.fillStyle = params.color;
context.fillText(text, (canvas.width - textWidth) / 2, params.radius);
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(canvas.width, canvas.height, 1);
return sprite;
}
and then whenever i rotate the camera, the text keep face the camera. is there any way to prevent that
Cheers all

WebGL single frame "screenshot" of webGL

tried searching for something like this, but I've had no luck. I'm trying to open a new tab with a screenshot of the current state of my webgl image. Basically, it's a 3d model, with the ability to change which objects are displayed, the color of those objects, and the background color. Currently, I am using the following:
var screenShot = window.open(renderer.domElement.toDataURL("image/png"), 'DNA_Screen');
This line succeeds in opening a new tab with a current image of my model, but does not display the current background color. It also does not properly display the tab name. Instead, the tab name is always "PNG 1024x768".
Is there a way to change my window.open such that the background color is shown? The proper tab name would be great as well, but the background color is my biggest concern.
If you open the window with no URL you can access it's entire DOM directly from the JavaScript that opened the window.
var w = window.open('', '');
You can then set or add anything you want
w.document.title = "DNA_screen";
w.document.body.style.backgroundColor = "red";
And add the screenshot
var img = new Image();
img.src = someCanvas.toDataURL();
w.document.body.appendChild(img);
Well it is much longer than your one liner but you can change the background color of the rectangle of the context.
printCanvas (renderer.domElement.toDataURL ("image/png"), width, height,
function (url) { window.open (url, '_blank'); });
// from THREEx.screenshot.js
function printCanvas (srcUrl, dstW, dstH, callback)
{
// to compute the width/height while keeping aspect
var cpuScaleAspect = function (maxW, maxH, curW, curH)
{
var ratio = curH / curW;
if (curW >= maxW && ratio <= 1)
{
curW = maxW;
curH = maxW * ratio;
}
else if (curH >= maxH)
{
curH = maxH;
curW = maxH / ratio;
}
return { width: curW, height: curH };
}
// callback once the image is loaded
var onLoad = function ()
{
// init the canvas
var canvas = document.createElement ('canvas');
canvas.width = dstW;
canvas.height = dstH;
var context = canvas.getContext ('2d');
context.fillStyle = "black";
context.fillRect (0, 0, canvas.width, canvas.height);
// scale the image while preserving the aspect
var scaled = cpuScaleAspect (canvas.width, canvas.height, image.width, image.height);
// actually draw the image on canvas
var offsetX = (canvas.width - scaled.width ) / 2;
var offsetY = (canvas.height - scaled.height) / 2;
context.drawImage (image, offsetX, offsetY, scaled.width, scaled.height);
// notify the url to the caller
callback && callback (canvas.toDataURL ("image/png")); // dump the canvas to an URL
}
// Create new Image object
var image = new Image();
image.onload = onLoad;
image.src = srcUrl;
}

Resources