I am trying to display text on the screen and it's not working for me.
Here is some of my code you give you an idea on what I made:
duck.js
class duck {
constructor (canvas, logs = false, start = () => {}, update = () => {}) {
document.documentElement.style.overflowX = 'hidden';
self.canvas = canvas;
self.ctx = self.canvas.getContext('2d');
self.logs = logs;
self.keys = {};
window.onkeyup = (e) => self.keys[e.keyCode] = false;
var dpi = window.devicePixelRatio;
var style_height = +getComputedStyle(self.canvas).getPropertyValue("height").slice(0, -2);
var style_width = +getComputedStyle(self.canvas).getPropertyValue("width").slice(0, -2);
self.canvas.setAttribute('height', style_height * dpi);
self.canvas.setAttribute('width', style_width * dpi);
self.init = () => {
var a;
self.logs ? console.info('Duck initialized!') : a = 0;
};
self.init.call();
start();
setInterval(update, 1);
};
rect (x = 0, y = 0, w = 1, h = 1, color = "#FFFFFF", fill = true) {
self.ctx.fillStyle = color;
fill ? self.ctx.fillRect(x, y, w, h): self.ctx.strokeRect(x, y, w, h);
}
fill (color = "#000000") {
self.ctx.fillStyle = color;
self.ctx.fillRect(0, 0, canvas.width, canvas.height);
}
text (x = 0, y = 0, text = 'Hello world!', align='left', font = '16px Verdana', color = '#000000') {
self.ctx.font = font;
console.log(self.ctx.font)
self.ctx.fillStyle = color;
console.log(self.ctx.fillStyle);
self.ctx.textAlign = align;
console.log(self.ctx.textAlign)
self.ctx.fillText(text, x, y);
}
get getWidth() {
return canvas.width;
}
get getHeight() {
return canvas.height;
}
screenshot() {
var image = self.canvas.toDataURL('image/png').replace("image/png", "image/octet-stream");
window.location.href = image;
}
keyDown(key = 'q') {
if (self.keys[key]) {return true} else {return false};
}
}
index.js
let duck_core = new duck(document.getElementById('main'), true, start, update);
function start() {
console.log('test');
}
function update() {
duck_core.fill('#FFFFFF');
duck_core.rect(0, 0, duck_core.getWidth, 10, '#222222');
duck_core.text(0, 0);
if (duck_core.keyDown('q')) {
duck_core.screenshot();
}
}
The reason why it wasn't showing is that the text has the center point on the bottom left corner and not the top right corner. To fix this, I added t the y position the size of my text, in this case, 16px.
Change self to this inside your duck class. In JavaScript, the global self variable is a reference to the window object, meaning it doesn't point to the instance of your class:
MDN
EDIT
You also have to update these parts:
get getWidth() {
return this.canvas.width; // added "this"
}
get getHeight() {
return this.canvas.height; // added "this"
}
Related
I have a canvas element with multiple images being displayed. I am trying to achieve is that when I click on a button it should move 200 position in X coordinates. I managed to move the second image, but the first image is not moving. And the images must move with respective to their current position. I am here by attaching my javascript for the same.
$(window).on('load', function () {
imageContent(200);
});
function imageContent(x) {
var posX = x;
var imgArray = ['http://via.placeholder.com/200x200?text=first', 'http://via.placeholder.com/200x200?text=second'];
$.each(imgArray, function (i, l) {
var img = new Image();
img.onload = function () {
var x = 0;
myCanvas(img, i * posX);
};
img.src = l;
});
}
function myCanvas(img, x) {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var last_ts = -1
var speed = 0.1
function renderScene() {
ctx.beginPath();
ctx.drawImage(img, x, 0);
}
function fly(ts) {
if (last_ts > 0) {
x += speed * (ts - last_ts)
}
last_ts = ts
if (x < 200) {
imageContent(x);
requestAnimationFrame(fly);
}
}
renderScene();
$('#movebutton').click(function () {
x = 0;
requestAnimationFrame(fly);
});
}
Here is the codepen. It would be greatful if anyone could help me.
Edit: Modified to achieve side by side movement
I modified your code a little, and removed jQuery. See if it is the effect you are trying to achieve:
var imgArr = [],
c = document.getElementById("myCanvas"),
ctx = c.getContext("2d"),
last_ts = -1,
speed = 0.1,
x = 0
window.onload = function() {
[
'http://via.placeholder.com/200x200?text=first',
'http://via.placeholder.com/200x200?text=second'
].forEach(function(obj, idx) {
var img = new Image()
img.onload = function() {
drawImage(img, idx * 200, 0)
}
img.src = obj
imgArr.push(img)
})
}
function drawImages(x) {
ctx.clearRect(0, 0, c.width, c.height)
imgArr.forEach(function(obj, idx) {
drawImage(obj, x + idx*200, 0)
})
}
function drawImage(img, x, y) {
ctx.beginPath()
ctx.drawImage(img, x, y)
}
function fly(ts) {
if (last_ts > 0) {
x += speed * (ts - last_ts)
}
last_ts = ts
if (x < 200) {
drawImages(x)
requestAnimationFrame(fly)
}
}
document
.getElementById('movebutton')
.addEventListener('click', function() {
x = 0
fly()
}, false)
canvas {
border: 1px solid red;
}
<canvas id="myCanvas" width="960" height="600"></canvas>
<button id="movebutton">Move</button>
I want to access an object but I don't know how.
I want to access 'ctx', but using base.ctx always returns null (is this a closure?).
window.base = function () {
var c = null,
ctx = null;
window.addEventListener("load", function(){
c = document.getElementById("canvas");
ctx = c.getContext("2d");
}
}
I found the solution was to call a function in base that returned ctx.
window.base = function () {
var c = null,
ctx = null;
window.addEventListener("load", function(){
c = document.getElementById("canvas");
ctx = c.getContext("2d");
}
return {
ctx: function(){return ctx;}
};
}
Then I can access ctx, but now all my accesses need to be:
base.ctx().setStyle = "white";
Rather than what I'd like which is:
base.ctx.setStyle = "white";
Is it possible? I'm thinking there's a possible solution with 'this'/scope or something, but I don't know enough JavaScript yet.
base is a function.
use it like this:
base().ctx()
I would write your code in this way:
window.addEventListener('load', function () {
var base = function () {
return document.getElementById("canvas").getContext("2d");
}
// Do something with base()
});
You can also drop the function and just use the context:
window.addEventListener('load', function () {
var base = document.getElementById("canvas").getContext("2d");
// Do something
});
The answer for me was to store the values in an object called "inter", and then update the contents of that object - the changes were then visible to other code.
So then I could use:
base.ctx.fillStyle = "white";
I have no idea why the other way didn't work!
var base = function () {
var fps = 60,
canvasWidth = 300,
canvasHeight = 200,
scaling = 1;
function updateCanvas(){
ctx.putImageData(imageData, 0, 0);
}
var c = null,
cStyle = null,
updateGraphicsCallBack = null;
function initialiseCanvas(canvasName, theCallBack){
updateGraphicsCallBack = theCallBack;
c = document.getElementById(canvasName);
cStyle = c.style;
inter.ctx = c.getContext("2d");
inter.imageData = inter.ctx.getImageData(0, 0, canvasWidth, canvasHeight);
inter.imageArray = inter.imageData.data;
inter.buff8 = new Uint8ClampedArray(inter.imageArray.buffer);
inter.buff32 = new Uint32Array(inter.imageArray.buffer);
cStyle.width = canvasWidth * scaling + "px";
cStyle.height = canvasHeight * scaling + "px";
c.width = canvasWidth;
c.height = canvasHeight;
inter.ctx.imageSmoothingEnabled = true;
inter.ctx.fillStyle="#909090";
//mouse = (typeof window.mouseInit !== "undefined") ? window.mouseInit(c) : null;
//if(typeof window.db !== "undefined") window.db.setOutput("debugOutput");
requestAnimationFrame(drawLoop);
}
var oldTimeStamp = 0, timeTweak = 0;
function drawLoop(currentTimeStamp) {
currentTime = currentTimeStamp;
if(typeof timeChart !== "undefined") timeChart.start();
setTimeout(
function() {
requestAnimationFrame(drawLoop);
}, (1000 - ((currentTimeStamp - oldTimeStamp) - timeTweak)) / fps);
updateGraphicsCallBack(currentTimeStamp);
if(typeof timeChart !== "undefined") {
timeChart.end();
if(timeChart.currentFrameCount() > -1){
var difference = timeChart.currentFrameCount() - fps;
timeTweak += difference;
if(timeTweak<-10000) timeTweak = -10000;
if(timeTweak>10000) timeTweak = 10000;
}
inter.timeTweak = timeTweak;
}
oldTimeStamp = currentTimeStamp;
}
var inter = {
updateCanvas: updateCanvas,
ctx: null,//function(){return ctx;},
canvasWidth: canvasWidth,
canvasHeight: canvasHeight,
fps: fps,
scaling: scaling,
imageData: null,
imageArray: null,
buff8: null,
buff32: null,
timeTweak: timeTweak,
initialiseCanvas: initialiseCanvas
};
return inter;
}();
I can't understand why my code isn't working,
the circle is being drawn but not in the centre of the canvas,
and it's much bigger than it should be and pix-elated.
Any suggestions, help greatly appreciated.
// safe code:
(function(global, library){
var spaceTime = function(container){
// if container is global object
if (typeof container === "object"){
var cHeight = container.innerHeight;
var cWidth = container.innerWidth;
}
// if container is a div box
else {
var cHeight = container.style.height;
var cWidth = container.style.width;
}
console.log("container is an "+typeof container);
// return unique instance each time sT is called
return new spaceTime.init(cHeight, cWidth);
}
// function constructor
spaceTime.init = function(height, width) {
this.height = height;
this.width = width;
}
// methods: override the default prototype property
spaceTime.prototype = {
checkDimensions: function() {
console.log(this.height + this.width);
console.log(this);
return this;
},
sequence: function(divide) {
// var getSize = this.getCentre(divide);
var grow = this.expand(200);
var box = this.setCanvas();
// box.classList.add("box");
document.body.appendChild(box);
// nest this in a requestAnimationFrame and pass
// the grow function to warp radius
this.drawCircle(box, grow);
return this;
},
// expands each unique instance.
expand: function(i) {
i += 1;
return i;
},
getCentre: function(axis) {
// width axis
if(axis === "x"){
console.log(this.height / 2);
return this.height / 2;
}
// height axis
else if(axis === "y"){
return this.width / 2;
}
// if undefined or the string doesn't match
else{
throw "please input an x or y axis to be proccessed";
}
},
// canvas context object and it's api methods
drawCircle: function(c, radius) {
var ctx = c.getContext("2d");
var x = this.getCentre("x");
var y = this.getCentre("y");
console.log(x);
console.log(y);
// define the arc path
ctx.beginPath();
ctx.arc(x, y, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'green';
ctx.fill();
// stroke it
ctx.StrokeStyle = "#aaa";
ctx.stroke();
console.log(ctx);
console.log(radius);
},
// set up the canvas element
setCanvas: function() {
var c = document.createElement("canvas");
c.style.height = this.height + "px";
c.style.width = this.width + "px";
console.log("new canvas element created");
return c;
}
}
// override the prototype object with our own one.
spaceTime.init.prototype = spaceTime.prototype;
// reference and expose library to be invoked.
global.sT = spaceTime;
}(window));
// instance 1 of wormhole library
var inst1 = sT(this);
// method chaining
inst1.checkDimensions().sequence();
Didn't you confused x and y axises here?
getCentre: function(axis) {
if(axis === "x"){
return this.height / 2;
}
else if(axis === "y"){
return this.width / 2;
}
...
},
drawCircle: function(c, radius) {
...
var x = this.getCentre("x"); // will return this.height / 2
var y = this.getCentre("y"); // will return this.width / 2
console.log(x);
console.log(y);
...
}
Eh, probably, you shouldn't use style attribute when defining canvas size. Look here
I need to know when my mouse pointer is over a certain image, and while in that image, it goes over a very specific colour. Is this possible and how can I do it?
Just wrote this :
Basically, it does what #nepeo told you to do.
+ it cleans up the canvas and reset the original image after calculations.
+ I also added a customized cursor that you can disable.
Usage : Set your own callback function in colorPicker.callback, then attach the colorPicker.init function on the mouseover event of desired image.
N.B : You will have to host the images on your own server or to convert them to base64 in order to use this script.
var colorPicker = function() {};
//Settings
colorPicker.radius = 1, //square px
colorPicker.customCursor = true;
colorPicker.cursorColor = '#FFF';
//the fomatting for color return : "hex" || "rgba" || "array"
// !! hex is upperCase and returns "transparent" if opacity == 0; rgba is 'rgba(r,g,b,a)'; array is '[r,g,b,a]'
colorPicker.colorFormat = "hex";
//What to do with that color? Edit this to whatever you want
colorPicker.callback = function (color) {
var res = document.getElementById('ColorPickerResult');
res.style.backgroundColor = color;
res.style.color = invertHex(color);
res.innerHTML = color;
//Here I'm searching for some Hex color
if (color == '#FC771F') {
res.innerHTML = '!!! Found some orange !!!';
}
}
//What to do when we leave the image (Additionally to reset the original image)
colorPicker.callbackOut = function(){
var res = document.getElementById('ColorPickerResult');
res.innerHTML = '';
}
//END Settings
//This is optional
colorPicker.setCursor = function (canvas) {
if (!colorPicker.setCursor) return;
var can = document.createElement('canvas');
can.width = colorPicker.radius;
can.height = colorPicker.radius;
var ctx = can.getContext('2d');
ctx.strokeStyle = colorPicker.cursorColor;
ctx.rect(0, 0, colorPicker.radius, colorPicker.radius);
ctx.stroke();
canvas.style.cursor = 'url("' + can.toDataURL("image/png") + '"),default';
}
colorPicker.Init = function () {
var img = this;
var can = document.createElement('canvas');
can.id = 'ColorPicker';
can.width = img.width;
can.height = img.height;
can.ori = img;
can.oridisp = img.style.display;
var ctx = can.getContext('2d');
ctx.drawImage(img, 0, 0);
can.addEventListener('mousemove', colorPicker.pick);
can.addEventListener('mouseout', colorPicker.out);
colorPicker.setCursor(can);
img.parentNode.insertBefore(can, img);
img.style.display = 'none';
};
colorPicker.pick = function (evt) {
var rect = this.getBoundingClientRect();
ctx = this.getContext('2d'),
imageData = ctx.getImageData(evt.clientX - rect.left, evt.clientY - rect.top, colorPicker.radius, colorPicker.radius);
data = imageData.data;
r = 0, g = 0, b = 0, a = 0;
for (i = 0; i < data.length; i++) {
r += data[i];
g += data[++i];
b += data[++i];
a += data[++i];
}
var p = data.length / 4;
var mR = function (i) {
return Math.round(i);
};
r = mR(r/p);
g = mR(g/p);
b = mR(b/p);
a = (mR((a/p)/255 * 100)/100).toFixed(2);
if(colorPicker.colorFormat === "hex"){
var color = colorPicker.toHex(r,g,b,a);
}
else if(colorPicker.colorFormat === "rgba"){
var color = 'rgba('+r+', '+g+', '+b+', '+a+')';
}
else if(colorPicker.colorFormat === "array"){
var color = [r, g, b, a];
}
colorPicker.callback(color);
}
colorPicker.out = function () {
this.ori.style.display = this.oridisp;
this.parentNode.removeChild(this);
colorPicker.callbackOut();
}
//toHex function originally posted by http://stackoverflow.com/users/10474/felipec in http://stackoverflow.com/a/19765382/3702797
colorPicker.toHex= function(r,g,b,a){
if(a=="0.00") return "transparent";
var rgb = b | (g << 8) | (r << 16);
return '#' + (0x1000000 + rgb).toString(16).slice(1).toUpperCase()
}
// END colorPicker \\
// Just an example of external function beeing called
function invertHex(c){
if(c==="transparent") return "#000000";
c = c.replace('#', '');
var reqHex = "#";
for(var i=0;i<6;i++){
reqHex = reqHex + (15-parseInt(c[i],16)).toString(16);
}
return reqHex;
}
//Attach the function to whatever images you want
document.getElementsByTagName('img')[0].addEventListener('mouseover', colorPicker.Init);
body {
background: #175;
}
<img src="data:image/png;base64,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" />
<span id="ColorPickerResult"></span>
Here I made an attempt. In this example the script searches for the color #FF0000, as passed in the options object. http://jsfiddle.net/2sw3pzs4/
var ColorChecker = function( options ) {
var canvas, ctx, output;
this.init = function() {
canvas = document.getElementById('canvas');
output = document.getElementById('output');
ctx = canvas.getContext("2d");
color = this.hexToRGB(options.searchedColor);
this.drawOnCanvas();
canvas.addEventListener('mousemove', function(e) {
if(e.offsetX) {
mouseX = e.offsetX;
mouseY = e.offsetY;
}
else if(e.layerX) {
mouseX = e.layerX;
mouseY = e.layerY;
}
var c = ctx.getImageData(mouseX, mouseY, 1, 1).data;
var foundColor = [c[0], c[1], c [2]];
var is_identical = foundColor.join() === color.join();
var message = is_identical == true ? 'red found' : 'not found';
output.innerHTML = message;
});
}
this.drawOnCanvas = function() {
ctx.fillStyle = "#FF0000";
ctx.fillRect(0,0, 20, 20);
}
this.hexToRGB = function( hex ) {
var r = parseInt((this.cutHex(hex)).substring(0,2),16);
var g = parseInt((this.cutHex(hex)).substring(2,4),16);
var b = parseInt((this.cutHex(hex)).substring(4,6),16);
return [r,g,b];
}
this.cutHex = function( hex ) {
return hex.replace("#",'');
}
this.init();
}
var colorChecker = new ColorChecker({
searchedColor: "#FF0000",
});
If you want to use an image just use putImageData() to draw the image on the canvas. You can use the function drawOnCanvas in my code to draw whatever you want inside the canvas, or resize it or other stuff.
Use a canvas instead of the image, resize the canvas to the size of the image and draw the image into the canvas.
Then you can get the pixel location of the cursor using the canvas.onmousemove event. Canvas may have something in it's api for querying the colour at a location(can't remember at this moment) but otherwise you can use getImageData to get the rgba data for every pixel and do a look up during the event. Ta da!
So I want to create a drawing app, and I did, I am able to change brush size and brush color, however, I want to save the stuff I draw including the brush size and the brush color. I am able to store the point I have drawn on the canvas now, but not the brush size and color.
var canvas;
var context;
var color = "black";
var brushSize = 13;
var mouseDown = false;
window.onload = function init() {
//Brush Size
var bigBrushSize = document.getElementById("bigBrush");
bigBrushSize.onclick = handleBigBrushclicked;
var mediumBrushSize = document.getElementById("mediumBrush");
mediumBrushSize.onclick = handleMediumBrushclicked;
var smallBrushSize = document.getElementById("smallBrush");
smallBrushSize.onclick = handleSmallBrushclicked;
//Brush Color
var redBrushColor = document.getElementById("red");
redBrushColor.onclick = handleRedBrushColorclicked;
var blueBrushColor = document.getElementById("blue");
blueBrushColor.onclick = handleBlueBrushColorclicked;
var yellowBrushColor = document.getElementById("yellow");
yellowBrushColor.onclick = handleYellowBrushColorclicked;
var greenBrushColor = document.getElementById("green");
greenBrushColor.onclick = handleGreenBrushColorclicked;
//Clear Button
var clearButton = document.getElementById("clearButton");
clearButton.onclick = handleClearButton;
canvas = document.getElementById("myCanvas");
context = canvas.getContext("2d");
canvas.onmousedown = handleMouseDown;
canvas.onmouseup = handleMouseUp;
canvas.onmousemove = handleMouseMove;
var coords = localStorage["coords"];
if (coords) {
coords = JSON.parse(coords);
for (var i = 0; i < coords.length; i = i + 2) {
paintToCanvas(coords[i], coords[i + 1]);
}
}
}
function handleClearButton() {
context.clearRect(0, 0, canvas.width, canvas.height);
localStorage.removeItem("coords");
}
function handleMouseDown(event) {
paintFromMouse(event);
mouseDown = true;
}
function handleMouseUp(event) {
mouseDown = false;
}
function handleMouseMove(event) {
if (mouseDown) {
paintFromMouse(event);
}
}
// Bursh Size Start
function handleBigBrushclicked() {
brushSize = 32;
}
function handleMediumBrushclicked() {
brushSize = 16;
}
function handleSmallBrushclicked() {
brushSize = 6;
}
// Brush Size Ends
function paintFromMouse(event) {
var x = event.clientX - canvas.offsetLeft;
var y = event.clientY - canvas.offsetTop;
paintToCanvas(x, y);
var coords = localStorage["coords"];
if (coords) {
coords = JSON.parse(coords);
} else {
coords = [];
}
coords.push(x);
coords.push(y);
localStorage.setItem("coords", JSON.stringify(coords));
}
//color change starts
function handleRedBrushColorclicked() {
color = "red";
}
function handleBlueBrushColorclicked() {
color = "blue";
}
function handleGreenBrushColorclicked() {
color = "green";
}
function handleYellowBrushColorclicked() {
color = "yellow";
}
// color change ends
function paintToCanvas(x, y) {
context.fillStyle = color;
context.fillRect(x - brushSize / 2, y - brushSize / 2, brushSize, brushSize);
So here I used the local storage to store brush size and color, the alert shows it seems to work, but I still don't know how to actually store them, which means, if I refresh my page, nothing changes on my canvas.
var storeColorAndBrush = [color " ", brushSize]
var store = storeColorAndBrush
localStorage.setItem("store",store)
alert(localStorage.store);
}
Thank you very much, I am a beginner.
This is how I would do it: I would add a "save" button which, when clicked, stores the whole image and the current brush size and color. When you load the page you draw the stored image in the canvas and set the brush size and color:
$('.save').on('click',function() {
var data = context.getImageData(x, y, img.width, img.height).data;
localStorage.setItem('image', data); // save image data
localStorage.setItem('brushSize', brushSize);
localStorage.setItem('color', color);
});
on load:
brushSize = localStorage.getItem('brushSize');
color = localStorage.getItem('color');
var picture = localStorage.getItem('image');
context.putImageData(picture, 0, 0);