Get top,left position of the cursor in draftjs - reactjs

How to get the cursor position(top, left) value in Draft.js. I have already seen this question, but it gives only the line number, but I want the top, left value.

This is working for my needs (NB: not tested on multi-platform/multi-browser, but at least it works great on Chrome/Firefox on Windows). The idea is to consider the caret as a mere window selection, and not as a draftjs selection. Hope it'll help.
function FindCaretPosition() {
let selection = window.getSelection();
let selectionRange = selection.getRangeAt(0).cloneRange();
selectionRange.collapse(false);
//-----
let caretMarker = document.createElement("span");
caretMarker.id = "__caret";
selectionRange.insertNode(caretMarker);
let caretPosition = document.querySelector("#__caret").getBoundingClientRect();
//-----
selectionRange.deleteContents();
return { x: caretPosition.left, y: caretPosition.bottom }
}

editorState.getSelection().getAnchorOffset();
you can get the position of cursor like that

Related

I'm trying to update the row values in MUI datagrid, i'm using processRowUpdate property.But, I'm only getting recent updated cell value only

Here **Skills ** will have the array of objects which includes the values Which I'm updating.
const handleProcessRowUpdate = (newRow, oldRow) => {
console.log("update called", newRow, oldRow);
let skills = assignedskillList;
let result = skills.map((item) => {
if (item.skill_id == params.skill_id) {
console.log("ids", params.skill_id, item.skill_id);
if (item.skill_level !== newRow.skill_level) {
item.skill_level = newRow.skill_level;
}
if ((item.target_level = newRow.target_level)) {
item.target_level = newRow.target_level;
}
console.log("idsss", item.skill_level, item.target_level); // here for first column edit //I'm getting current edited value only, for the second col edit getting only second column //value.the first value is resetting
}
setUpdatedVal(result); //I'm setting this in a new array to use this for post to API
return item;
});
tried onCellEdit commit , but, thats not worked. any other solutions ?
or correct me if I'm setting the value wrongly.
Thanks In advance.....
Finally, I found it.
Hope it might be helpful for someone in future
instead of updating the value inside the map. I've just defined a result array outside and assigned the map to that, Now I can get all updated values..
Thank you...

How to optimize mouseover function's current logic to improve performance

I have 2 series (lines) displayed as shown in demo. I can have up to 30 series (lines) in one go.
What is implemented is, as soon as I move the mouse, it should update the current value (for all series (lines) - remember I can have up to 30 series in one go) in the grid shown right below stock chart. It is working as expected.
Pls find working demo : https://stackblitz.com/edit/react-ts-qcsum9?file=stockchart%2Fstockchart.js,constants%2Fzoom-level.js,stockchart%2FchartOptions.js
FYI: You can focus on only mouseOver function rather than looking in to all other files as demo has so many files.
Problem : Problem related to performance
As I told you I can have up to 30 series (lines) in one go. In given demo, there are two series(lines) and when you select 30 days, you have to move your mouse slowly in other to see updated or current hovered value in the gird. If you move your mouse speedily, it will not update the value immediately (I think that is obvious).
But the problem is on each mouse move, I'm looping through all available lines multiple times and perform some logic. I know it is a bit complex logic as shown in below code snippet. It runs every time when mouse is moved for each hovered point for all the lines. This is very bad way of updating the current value.
I know this is not the correct implementation but I really have NO IDEA how to optimize it. Any help would be greatly appreciated.
Code: Select all
point: {
events: {
mouseOver: (e) => {
const xAxisValue = e.target.x;
const chart = e.target.series.chart;
const series = chart.yAxis[0].series;
const totalGridSeries = [...stockGrid];
for (let i = 0; i < series.length; i++) {
const name = series[i].name || series[i].name;
const foundSeries = totalGridSeries.find(
(x) => x.name === name
);
if (foundSeries) {
if (xAxisValue) {
const foundPoint = series[i].points.find(
(t) => t.x === xAxisValue
);
if (foundPoint && foundPoint.y) {
foundSeries.currentValue = foundPoint.y;
} else {
foundSeries.currentValue = undefined;
}
} else {
foundSeries.currentValue = undefined;
}
}
}
setStockGrid(totalGridSeries);
},
},
}

Swift - Update and store position of a multiple programmatically created buttons

I have a button which creates other buttons based on the class Clip seen below. Those newly created buttons are added to an array and stored in a plist.
class Clip: Encodable, Decodable {
var name: String = ""
var xCoordinate: Int = 100
var yCoordinate: Int = 300
// more parameter will be added later on e.g color, scale etc..
}
Each button can be moved around the view and the new x & y coordinates are stored in a plist.
#objc func handlePan(sender: UIPanGestureRecognizer){
let uIViewSelected = sender.view!
switch sender.state {
case .began, .changed :
moveViewWithPan(view: uIViewSelected, sender: sender)
break
case .ended:
//Finds the position when the button is no longer being dragged
let x = Int(uIViewSelected.center.x)
let y = Int(uIViewSelected.center.y)
//clipArray[0] need to be the corresponding clicked button e.g clipArray[2]
clipArray[0].xCoordinate = x
clipArray[0].yCoordinate = y
saveData()
break
default:
break
}
}
The above works only if I create one button. When more buttons are added, the above lines only change the first clip from the array. I need a way to update the value to the correct button clicked.
How can identify the array position of the click button as I am creating all them programmatically? At the moment I am placing at value 0 of the clipArray.
clipArray[0].xCoordinate = x
clipArray[0].yCoordinate = y
I am not even sure if using a plist is the best way to store the buttons in the first place.
Any help or documentation would be much appreciated.
Thanks
Following from dfd response, I added tags to each button which are created and it solved the issue for now.
let x = Int(uIViewSelected.center.x)
let y = Int(uIViewSelected.center.y)
//clipArray.append(clip)
var tagNo = uIViewSelected.tag
clipArray[tagNo].xCoordinate = x
clipArray[tagNo].yCoordinate = y

SceneKit ARKit glowing effect

Hi I'm trying to have a glowing effect around a node.
I used the SCNNode filters property and set to an array of CIFilter.
It works and renders only when the node has no node behind it which I don't understand. I tried to set the rendering order and the readDepth options without success. I'm really stuck at this point and would appreciate your input!
Please see the screenshot for an example and the code sample.
func addBloom() -> [CIFilter]? {
let bloomFilter = CIFilter(name:"CIBloom")!
bloomFilter.setValue(10.0, forKey: "inputIntensity")
bloomFilter.setValue(30.0, forKey: "inputRadius")
return [bloomFilter]
}
Calling this using:
myNode.filters = addBloom()
A final note, I noticed that for CIFilter to work with Metal the antiAliasing needs to be set to .none
arSceneView.antialiasingMode = .none
Thanks a lot!
Adrien
Have you tried setting the writesToDepthBuffer to false for those nodes which you aren't apply the filters to?
For your information writesToDepthBuffer refers to:
SceneKit’s rendering process uses a depth buffer to determine the
ordering of rendered surfaces relative to the viewer. The default
value of this property is YES, specifying that SceneKit saves depth
information for each rendered pixel for use by later rendering passes.
Typically, you disable writing to the depth buffer when rendering
semitransparent objects, because later stages of the rendering process
may require depth information about the opaque objects behind them.
This example seems to be working fine:
/// Generates An SCNPlane & A Red & Green SCNSphere
func generateNodes(){
let planeNode = SCNNode(geometry: SCNPlane(width: 1, height: 0.5))
planeNode.geometry?.firstMaterial?.diffuse.contents = UIColor.black
planeNode.position = SCNVector3(0, 0, -1)
let redSphereNode = SCNNode(geometry: SCNSphere(radius: 0.1))
redSphereNode.geometry?.firstMaterial?.diffuse.contents = UIColor.red
redSphereNode.position = SCNVector3(-0.3, 0, -1)
redSphereNode.filters = addBloom()
let greenSphereNode = SCNNode(geometry: SCNSphere(radius: 0.1))
greenSphereNode.geometry?.firstMaterial?.diffuse.contents = UIColor.green
greenSphereNode.position = SCNVector3(0.3, 0, -1)
greenSphereNode.filters = addBloom()
self.augmentedRealityView.scene.rootNode.addChildNode(planeNode)
self.augmentedRealityView.scene.rootNode.addChildNode(redSphereNode)
self.augmentedRealityView.scene.rootNode.addChildNode(greenSphereNode)
planeNode.geometry?.firstMaterial?.writesToDepthBuffer = false
}
/// Creates An Array Of CIBloom Filters
///
/// - Returns: [CIFilter]?
func addBloom() -> [CIFilter]? {
let bloomFilter = CIFilter(name:"CIBloom")!
bloomFilter.setValue(10.0, forKey: "inputIntensity")
bloomFilter.setValue(30.0, forKey: "inputRadius")
return [bloomFilter]
}
One thing to note however, which I did notice was that if I used an image with a transparent background for the contents of the SCNPlane it didn't work, although with another image it was fine.
Hope it points you in the right direction...

dragAndDrop NOT working on Chrome

I am trying to perform a Drag and Drop operation on our Angular application using Protractor Jasmine. I am able to get hold of the source item but as the test runs, the source element gets selected but nothing happens thereafter; the drag and drop operation does not take place. There are no errors shown in the console.
An interesting thing about the destination container is that the items dropped here can be resized as per user wish. Also, there is no clearly marked place/area in the destination container where the dragged item will get dropped! But the container does have an ID; though that has still not helped here.
Here is the code:
let dragAndDrop = require('html-dnd').code;
.
.
.
function dragAndDropListItems(fdIndex: number): void {
let dragElement = element.all(by.repeater('listDefinition in lists')).get(fdIndex); // Select the first repeater corresponding to the first List Item in the list
let dragElementh5 = dragElement.all(by.css('a')).get(0); // Select the first List Item
let printFD = dragElementh5.getText().then((text: string) => {
console.log(text); // Print the innerHTML text from the chosen List Item to the Console
});
let finalDrop = element.all(by.css('[id="dashboardContainerDiv"]')).get(0);
dragElement.click();
browser.actions().dragAndDrop(dragElement, finalDrop).perform();
};
I have tried using coordinate based DragNDrop operation as well but the same in every case.
Other tried options include:
//browser.executeScript(dragAndDrop, dragElement, finalDrop); // Perform the drag and drop operation
//browser.driver.actions().dragAndDrop(dragElement, finalDrop).perform();
//browser.actions().dragAndDrop(dragElement, { x: 400, y: 400 }).perform();
// browser.driver.actions().mouseDown(dragElement).mouseMove(finalDrop).mouseUp(finalDrop).perform();
Kindly suggest a solution to this issue.
#FlorentB. I have attached the Code with your scripts imported.
let JS_DRAG_DROP = require('./drag-drop.js');
function dragAndDropListItems(fdIndex: number): void {
/*
let source = driver.find_element_by_css_selector("#drag")
target = driver.find_element_by_css_selector("#drop")
driver.execute_async_script(JS_DRAG_DROP, source, target)
# drag and drop an element by offset {x:500, y:200}
source = driver.find_element_by_css_selector("#drag")
driver.execute_async_script(JS_DRAG_DROP, source, None, 500, 200)
# drag and drop an element with a delay of 101ms before the drop
source = driver.find_element_by_css_selector("#drag")
target = driver.find_element_by_css_selector("#drop")
driver.execute_async_script(JS_DRAG_DROP, source, target, 0, 0, 101)
*/
let source = element.all(by.repeater('listDefinition in
lists')).get(fdIndex); // Select the first repeater corresponding to the
first List Item in the list
let dragElementh5 = source.all(by.css('a')).get(0); // Select the first List
Item
let printFD = dragElementh5.getText().then((text: string) => {
console.log(text); // Print the innerHTML text from the chosen List Item
to the Console
});
//browser.driver.switchTo().frame('dashboardContainerDiv');
/*
let finalDropClass = element.all(by.css('[class="dashboard mb10"]')).get(0);
let finalDropCon =
finalDropClass.all(by.css('[id="dashboardContainerDiv"]')).get(0);
let finalDrop =
finalDropCon.all(by.css('[id="dashboardContainerUl"]')).get(0);
*/
let target = element.all(by.css('[id="dashboardContainerDiv"]')).get(0);
//dragElement.click();
browser.executeScript(JS_DRAG_DROP, source, target); // Perform the drag and
drop operation
//browser.actions().dragAndDrop(dragElement, finalDrop).perform();
//browser.driver.actions().dragAndDrop(dragElement, finalDrop).perform();
//browser.actions().dragAndDrop(dragElement, { x: 400, y: 400 }).perform();
// browser.driver.actions().mouseDown(dragElement).mouseMove(finalDrop).mouseUp(finalDrop).perform();
};
Try
https://github.com/html-dnd/html-dnd
Installing it and using the typescript example worked for me.

Resources