This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 7 years ago.
function InfoImage(path,title){
this.path = path;
this.title = title;
this.color = undefined;
this.maxPixels = undefined;
this.init = function(){
var canvas = document.querySelector("canvas");
var img_Color = new Image_Processing_Color(canvas);
var img = new Image();
img.onload = function () {
img_Color.init(img);
this.color = img_Color.getDominantColor(); //this doesnt work
this.maxPixels = img_Color.getDominantColorPixels();
};
img.src = path;
};
this.init();
}
With this example, how can i save those variables as InfoImage variable? I know that using this there will affect Image and not InfoImage...
If I'm understanding you right, the usual answer is to use a variable to refer to this, which init then closes over:
function InfoImage(path,title){
this.path = path;
this.title = title;
this.color = undefined;
this.maxPixels = undefined;
this.init = function(){
var canvas = document.querySelector("canvas");
var img_Color = new Image_Processing_Color(canvas);
var img = new Image();
var infoimg = this; // <===
img.onload = function () {
img_Color.init(img);
infoimg.color = img_Color.getDominantColor(); // <===
infoimg.maxPixels = img_Color.getDominantColorPixels(); // <===
};
img.src = path;
};
}
You can also use Function#bind:
function InfoImage(path,title){
this.path = path;
this.title = title;
this.color = undefined;
this.maxPixels = undefined;
this.init = function(){
var canvas = document.querySelector("canvas");
var img_Color = new Image_Processing_Color(canvas);
var img = new Image();
img.onload = function () {
img_Color.init(img);
this.color = img_Color.getDominantColor();
this.maxPixels = img_Color.getDominantColorPixels();
}.bind(this); // <===
img.src = path;
};
}
With ES6, the next version of JavaScript, you'll be able to use an arrow function, because unlike normal functions, arrow functions inherit their this value from the context in which they're defined:
function InfoImage(path,title){
this.path = path;
this.title = title;
this.color = undefined;
this.maxPixels = undefined;
this.init = function(){
var canvas = document.querySelector("canvas");
var img_Color = new Image_Processing_Color(canvas);
var img = new Image();
img.onload = () => { // <===
img_Color.init(img);
this.color = img_Color.getDominantColor();
this.maxPixels = img_Color.getDominantColorPixels();
};
img.src = path;
};
}
You need the this and that pattern:
function InfoImage(path, title) {
var _this = this;
this.init = function(){
var img = new Image();
img.onload = function () {
_this.color = img_Color.getDominantColor();
};
};
};
function InfoImage(path,title){
var self = this;
this.path = path;
this.title = title;
this.color = undefined;
this.maxPixels = undefined;
this.init = function(){
var canvas = document.querySelector("canvas");
var img_Color = new Image_Processing_Color(canvas);
var img = new Image();
img.onload = function () {
img_Color.init(img);
self.color = img_Color.getDominantColor(); //this doesnt work
self.maxPixels = img_Color.getDominantColorPixels();
};
img.src = path;
};
this.init();
}
It's that easy. this is a keyword and depends on the function's binded calling context, but it can be stored to a variable just like anything else in JavaScript.
Related
I have seen people use this method for SVG-based NFTs:
function p5jsToImageURI(){
string memory baseURL = "data:image/svg+xml;base64,PUT-BASE64-HERE"
}
But, since I don't want to generate a fixed image how can I use my p5js script (that looks slightly different each time the js code runs)? Is there a way to just somehow pass the seed to my script and the script with the seed passed to it is stored on-chain?
var img,inpt,div
function convertImgToDataURLviaCanvas(url, callback, outputFormat){
var img = new Image();
img.crossOrigin = 'Anonymous';
img.onload = function(){
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var dataURL;
canvas.height = this.height;
canvas.width = this.width;
ctx.drawImage(this, 0, 0);
dataURL = canvas.toDataURL(outputFormat);
callback(dataURL);
canvas = null;
};
img.src = url;
}
function convertFileToDataURLviaFileReader(url, callback){
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = function() {
var reader = new FileReader();
reader.onloadend = function () {
callback(reader.result);
}
reader.readAsDataURL(xhr.response);
};
xhr.open('GET', url);
xhr.send();
}
function img2b64(imagefile){
var imageUrl = imagefile;
var convertType = 'Canvas';
var convertFunction = convertType === 'FileReader' ? convertFileToDataURLviaFileReader : convertImgToDataURLviaCanvas;
convertFunction(imageUrl, function(base64Img){
code='foto = "'+base64Img+'";'
inpt.value(code)
div.html('<img src="'+base64Img+'">');
});
}
function setup() {
but = createButton("CONVERT");
but.mousePressed(function () {
img2b64('nature100b.jpg');
});
inpt = createP('');
inpt = createElement("textarea",'');
inpt.elt.rows = 5;
inpt.elt.cols = 50;
div = createDiv('');
}
Try this
https://editor.p5js.org/josepssv/full/wsCZnJqkA
Here's the class and object:
class BDImage
{
constructor(path)
{
this.img = new Image();
this.img.src = path;
}
}
var myImage = new BDImage("path/to/image.png");
I want to access/use myImage's img member without typing myImage.img all the time. Instead just myImage and then I'm actually referring to myImage.img.
How?
extends ;)
class BDImage extends Image
{
constructor(path)
{
super()
this.src = path
}
}
var myImage = new BDImage("path/to/image.png");
console.log(myImage, myImage.src);
Object.defineProperty
class BDImage
{
constructor(path)
{
this.image = new Image()
this.image.src = path
Object.defineProperty(this, 'src', {
get(){
return this.image.src;
},
set(path){
this.image.src = path
}
})
}
}
myImage = new BDImage("path/to/image.png");
console.log(myImage, myImage.src);
myImage.image.src = "path/to/image2.png"
console.log(myImage, myImage.src);
myImage.src = "path/to/image3.png"
console.log(myImage, myImage.src);
Just cache the reference in a variable:
class BDImage
{
constructor(path)
{
this.img = new Image();
this.img.src = path;
}
}
var myImage = new BDImage("path/to/image.png");
var imgProp = myImage.img; // Now imgProp points to myImage.img
console.log(imgProp.src);
It looks like you need some Functional programming !
function BDImage(path) {
const img = new Image();
img.src = path;
return img;
};
const myImage = BDImage("path/img.png");
Hope it helps !
Hello me need get variable from function
me return in answer undefined
function etr() {
var img = new Image();
img.onload = paramsImg;
img.src = picFile.result;
function paramsImg() {
return img.height;
};
};
var vvvr = etr();
alert(vvvr);
function etr() {
var img = new Image();
img.onload = paramsImg;
img.src = picFile.result;
function paramsImg() {
return img.height;
};
};
In your function, you mentioned paramsImg before its even loaded, so its not visible to img.onload.
paramsImg is declared simply as function, its not have scope outside the object. You need to use this keyword or mention fn with prototype.
function etr(picFile){
this.paramsImg = function(){
return img.height;
};
var img = new Image();
img.onload = this.paramsImg;
img.src = picFile.result;
}
picfile = {
result: 10
}
var vvvr = new etr(picfile);
alert(vvvr.paramsImg());
Your function etr doesn't return anything. I see that you are trying to return from an event handler for onload, but that only returns from the paramsImg function and not from etr (which has already returned before the image loads). You should wither make etr accept a callback function or return a Promise so that you can alert the images height after the image has loaded. Here is an example with a Promise:
function etr() {
return new Promise( ( resolve, reject ) => {
var img = new Image();
img.onload = _ => resolve(img.height);
img.onerror = reject;
img.src = picFile.result;
} );
};
var picFile = { result: 'https://dummyimage.com/600x1234/000/fff' };
(async function ( ) {
var vvvr = await etr();
alert(vvvr);
})( );
Objekt.prototype.loadImg = function(pImg){
if(pImg!=null){
this.imgLoaded=false;
this.img = null;
this.img = new Image();
this.img.src = pImg;
this.img.onload = function(){
alert("!");
this.autoSize();
this.imgLoaded=true;
};
}
}
My Problem is that "this" is invalid in the "onload = function()"-function!
alert("!"); is executed, but not the Objekt.prototype.autoSize()-function for example!
What do I have to do to call my "class-intern"-functions (e.g. autoSize) ???
That's because the onload function isn't called with your objekt as receiver. So this, inside this callback, isn't the desired object.
You can do this to transmit this to the onload callback :
Objekt.prototype.loadImg = function(pImg){
if(pImg!=null){
this.imgLoaded=false;
this.img = null;
this.img = new Image();
this.img.src = pImg;
var _this = this;
this.img.onload = function(){
alert("!");
_this.autoSize();
_this.imgLoaded=true;
};
}
}
This is a jquery plugin that i've found, that creates an img element and appends it to a parent element.
$.fn.loadImg = function(src, f){ return this.each(function(){ var i = new Image(); i.src = src; i.onload = f; this.appendChild(i);}); }
How can i add paramaters attrName, attrVal to the function that would assign whatever attributes to the image before appending it?
This should work:
$.fn.loadImg = function(src, f, attrName, attrVal) {
return this.each(
function() {
var i = new Image();
i.src = src;
i.onload = f;
i[attrName] = attrVal;
// alternatively:
// i.setAttribute(attrName, attrVal);
this.appendChild(i);
}
);
}