Im developing a react image editor, and I want to draw lines on the canvas, to do this I have a class that i add to the canvas elements array (this stores all the diferent elements, text, images and lines that the canvas redraws every frame).
But when i do this:
let pos = this.stageRef.current.getPointerPosition()
let new_line = (<Line
key={this.state.itemArray.length}
stroke={'#df4b26'}
strokeWidth={5}
globalCompositeOperation={'source-over'}
points={[pos.x, pos.y]}
/>)
this.state.itemArray.push(new_line)
this.setState({isDrawing: true})
console.log(new_line)
I get this object:
This object it's located inside the itemsArray, all the items are rendered on the main render here:
And it's rendered correctly, but all it's props are read-only and i can't call any methods of the object, what i need it's the "real" React object, the one you get when you call a reference.
(I want to add more points to the line object onMoveMouse event)
this:
Is there any way I can get the Line object (i just created) accesing to the itemsArray object instead of using the ref?
I don't know how can i create a Line object directly and call it's methods without a Ref ¿Do I really need a ref to an object i just created 2 lines above?.
Related
I am using canvas2Html where you i pass the ref of element to take image of element. i am dynamically assigning the refs to take image of particular divs. The code runs but i am getting the Provided element is not within a Document. In Devconsole refs are not appearing too.
I am really stuck on this one. Any suggestions
https://codesandbox.io/embed/rlo3mmo5zp?fontsize=14
I want the image of signature and initial as output. I am currently getting error. :/
Do not forget that if you use :ref inside v-for then it becomes an Array - so you should change your code
async takeimage(name) {
let el = this.$refs[name][0]; // <--- use an Array
Sandbox: https://codesandbox.io/s/8292lmypz2
I'm trying to measure the absolute position some divs. I'm accessing the DOM node of the div through a forwarded ref (React.forwardRef()) to the div I'm interested in. In the constructor of my parent component, I'm populating an array with React.createRef()s, which I then assign to each divs ref iteratively as they're being rendered. Finally, I log the return value of getBoundingClientRect() for each div. The problem is that - in spite of the fact that each div has a unique position relative to the next one - the same data is returned every single time. It's as if I was getting the getBoundingClientRect() data for the same div eight times. What gives?
A very basic issue in your case is that in order to create the array of refs, you are using Array.fill method, which initialises all the values in the array with the same reference of the React.createRef, and hence when you try assign refs to the divs, all ref properties will refer to the last div being assigned the ref instance
A simple way to fix this is to use Map instead of fill like
constructor(props) {
super(props);
this.refArray = Array.apply(null, { length: props.number.length}).map(() => React.createRef());
}
Working demo
In my TypeScript class I can load an array of type HTMLCanvasElement - but when I iterate over this array with ngFor - I only see text on the page for each canvas object loaded: "[object HTMLCanvasElement]".
The gist of my template code:
<div>*ngFor="#cvs of canvases">
{{cvs}} </div>
Relevant Class code:
canvases:HTMLCanvasElement[]=[]
var canvas = document.createElement("canvas");
//here I take an image and drawimage via context -- this part works
//then......
this.canvases.push(canvas);
My assumption is probably wrong-headed: but, if you can append a canvas object to a node (which I can do) - then why can you not place the canvas object onto the window "directly" inside a div using *ngFor?
Create a componenet with image and other options required as #Input()
Move your canvas creation code in the component
In the component you have shown make canvases an array of objects that contains the information for each canvas
In ngFor render the canvas component you created by passing info to your component
Your code is not working because you are trying to stringify the HTMLCanvasElement inside ngFor using interpolation {{}}
Here is the working Plunker
https://plnkr.co/edit/1ho41z
Instead of push html objects around use javascript objects.
Let HTML create HTML elements instead of using document.createElement
Avoid using document.getElementById inside Angular component
See usage of View Child to get hold of components
There is still scope of improvements in the plunker, but you get the gist of creating a component in Angular with the plunk above
I created small component thats going through all select elements and creating unordered lists from it so that i can style it easily. Everything works just like i wanted. Here is the script:
https://github.com/goranefbl/softdrop
You fire it like this:
SoftDrop.init({
selector:'input_select',
mobile:true
});
and its looping through every "input_select" element and creating new nodes for it. But that is all one single object, and i dont have a way to access for example specific select element, if i want to push an item to it, or to close it with some public method.
For every element, i am adding data-softdrop="i" to it, so this way i could easily target it with:
document.querySelectorAll("[data-softdrop='i']")
and it works. But if i want to do this from within component, something like this:
var selects = SoftDrop.init({
selector:'input_select',
mobile:true
});
selects.data('something').open();
How would i go with doing this? I would create some array of objects at the top and during forEach call, push it there, then access it how ? To be able to have public methods on specific select elements.
Thanks
One way to achieve this would be to create a data object inside your component and add each entry as property to this object, e.g. like this:
data['something'] = myElement;
Then, later, you could access the element again and invoke methods on it, e.g.
data['something'].open();
Is that what you have in mind?
I'd like to be able to figure out what React component is associated with a certain DOM element.
For example, say I have a div, and I'm rendering my entire application using React. The div has to be rendered by a React component - but which one?
I know that React supplies the method "getDOMNode" to get the DOM node associated with a React component, but I'd like to do the opposite.
Is this possible?
No.
A central concept in React is that you don't actually have a control in the DOM. Instead, your control is that factory function. What's in the DOM is the current render of the control.
If you actually need this, you can keep an object as a global variable, whose keys are the string representations of the names of factory functions, and whose values are the factory functions, then on your renderable div, keep an attribute containing the name of the factory function.
But chances are this is a question of the XY problem (needing X, seeing a way with Y, then asking how to do Y.) Probably if you'd explain your goal there's a better way that better fits React's top-down conceptual model.
Generally speaking, asking to get access to the control from its render is like asking to get access to an SVG from its cached PNG render. It's possible, but it's usually a red flag that something else is conceptually wrong.
Here's what I use, with React 15.3.0:
window.FindReact = function(dom) {
for (var key in dom) {
if (key.startsWith("__reactInternalInstance$")) {
var compInternals = dom[key]._currentElement;
var compWrapper = compInternals._owner;
var comp = compWrapper._instance;
return comp;
}
}
return null;
};
And then to use it:
var someElement = document.getElementById("someElement");
FindReact(someElement).setState({test1: test2});
If your situtation demands getting react element from DOM node, here is an approach, "Communicate via event and call back"
You shall fire a custom event on DOM element and have event listener for that custom event in React component. This will map DOM element back to react component.