Open toannguyendts opened 3 years ago
I have the same problem @jnschulze @toannguyendts
Scrolling works for me but in order to debug this, you can do a quick check if the problem is on the Dart or the native side.
This plugin uses the Listener widget on the Dart side for detecting scroll events. You might set up a Listener
and see if it fires scroll events (using onPointerSignal
).
@jnschulze you can move your mouse to this area and scroll it. It cannot scroll box inside. It is working only outside
Hi @toannguyendts, you can help me to setup this package in my project? You can provide your current version flutter. Because I have error in my project. You can show more error in this link: #41
Scrolling works for me but in order to debug this, you can do a quick check if the problem is on the Dart or the native side.
This plugin uses the Listener widget on the Dart side for detecting scroll events. You might set up a
Listener
and see if it fires scroll events (usingonPointerSignal
).
I checked on my widget for using "onPointerSignal",the scroll events in widget worked,but in the webview's page,the scroll event doesn't worked
Scrolling works for me but in order to debug this, you can do a quick check if the problem is on the Dart or the native side.
This plugin uses the Listener widget on the Dart side for detecting scroll events. You might set up a Listener and see if it fires scroll events (using onPointerSignal).
So the scrolling does work, but the only places where it doesn't work (as expected) is when there are smaller containers in the webpage which are scrollable.
Expected Behaviour: When the mouse is placed on / hovered on the (webpage) container and scrolled, the scroll bar inside the smaller container should be considered and not the main page scroll bar (if it exists)
Current Behaviour: The mouse location doesn't really seem to matter, it will always interact with the main page (largest) scrollbar.
I am having the same issue with ESRI Map in webview, Zoom and zoom out by scrolling doesn't work. I am using the latest version. I can see code reach
return _methodChannel.invokeMethod('setScrollDelta', [dx, dy]);
But after that I believe we need to run in native to debug
Any update on this?
Update: I end up creating own Listener widget and update the same listener in web content as well.
@tashi146 , could you describe exactly what you did to workaround the issue? I debugged the case and the line setScrollDelta is called when scrolling a small container with scrollbar. Which listener did you update in web content? Thanky you!
any updates?
Scrolling works for me but in order to debug this, you can do a quick check if the problem is on the Dart or the native side.
This plugin uses the Listener widget on the Dart side for detecting scroll events. You might set up a Listener and see if it fires scroll events (using onPointerSignal).
So the scrolling does work, but the only places where it doesn't work (as expected) is when there are smaller containers in the webpage which are scrollable.
Expected Behaviour: When the mouse is placed on / hovered on the (webpage) container and scrolled, the scroll bar inside the smaller container should be considered and not the main page scroll bar (if it exists)
Current Behaviour: The mouse location doesn't really seem to matter, it will always interact with the main page (largest) scrollbar.
Did you solve it.
同样的问题,无法与网页小滚动条交互,始终是与最外层的滚动条交互。有解决问题的麻烦回复我下谢谢,514435771@qq.com
I have solution for this. You must custom onPointerSignal of lib. By my way, I dont use _controller._setScrollDelta
. I will use postMessage to my web apps. Then my webapps can capture event scroll. Finally, you can control event scroll by your self.
*Flutter Side: Go to webview_windows.dart Add function below
String postMouseEvent(String mouseEvent,dynamic data)
{
return jsonEncode({"mouse_event" : mouseEvent,"data" : data});
}
Then override onPotinerSignal
onPointerSignal: (signal) {
if (signal is PointerScrollEvent) {
String mouse_event = postMouseEvent("scroll",{"scroll_delta_dx":-signal.scrollDelta.dx,"scroll_delta_dy":-signal.scrollDelta.dy});
_controller.postWebMessage(mouse_event);
// _controller._setScrollDelta(
// -signal.scrollDelta.dx, -signal.scrollDelta.dy);
}
},
Web App
document.getElementsByTagName("body")[0].addEventListener("mousemove", (e) => {
this.element = document.elementFromPoint(e.x, e.y);
// this.mousePos = { x: e.x, y: e.y };
});
if (typeof window.chrome.webview !== "undefined") {
window.chrome.webview.removeEventListener("message");
window.chrome.webview.addEventListener("message", this.handleMessage);
}
handleMessage(message) { let direction = message.data.data.scroll_delta_dy > 0 ? -1 : 1; let distance = 40; if(this.getScrollDiv(this.element)) { let classList = this.getScrollDiv(this.element).classList; let queryString = ""; for(let i = 0; i < classList.length; i++) { queryString += ('.' + classList[i]); } let elems = document.querySelectorAll(queryString); if (elems && elems[0]) { elems.forEach((elem) => { elem.scrollTop += direction * distance; }); } } }, getScrollDiv(el) { while (el && el.parentNode) { if(el.style.overflow == "auto" || el.style.overflow == "scroll" || el.style.overflowY == "auto" || el.style.overflowY == "scroll") { return el; } el = el.parentNode; } return null; },
We solved it in a similar fashion, here is the source code for reference:
Future<void> scrollWebview(double mouseX, double mouseY, double dx, double dy) {
return _windowsController.executeScript("""
function eleCanScroll(ele) {
if (ele.scrollTop > 0) { return ele; }
else {
ele.scrollTop++;
const top = ele.scrollTop;
top && (ele.scrollTop = 0);
if(top > 0){
return ele;
} else {
return eleCanScroll( ele.parentElement);
}
}
}
var el = document.elementFromPoint($mouseX,$mouseY);
var el2 = eleCanScroll(el);
el2.scrollBy($dx,$dy);
""");
}
// ... inside your body use:
return Listener(
onPointerPanZoomUpdate: (event) {
final Offset panDelta = event.panDelta;
final Offset position = event.position;
scrollWebview(position.dx, position.dy, panDelta.dx, panDelta.dy);
},
onPointerSignal: (signal) {
if (signal is PointerScrollEvent) {
final Offset scrollDelta = signal.scrollDelta;
final Offset position = signal.position;
scrollWebview(position.dx, position.dy, scrollDelta.dx, scrollDelta.dy);
}
},
child: Stack(
children: [
webview_windows.Webview(
_windowsController,
),
StreamBuilder<webview_windows.LoadingState>(
stream: _windowsController.loadingState,
builder: (context, snapshot) {
if (snapshot.hasData && snapshot.data == webview_windows.LoadingState.loading) {
return const LinearProgressIndicator();
} else {
return const SizedBox();
}
},
),
],
),
);
我们以类似的方式解决了这个问题,下面是源代码供参考:
Future<void> scrollWebview(double mouseX, double mouseY, double dx, double dy) { return _windowsController.executeScript(""" function eleCanScroll(ele) { if (ele.scrollTop > 0) { return ele; } else { ele.scrollTop++; const top = ele.scrollTop; top && (ele.scrollTop = 0); if(top > 0){ return ele; } else { return eleCanScroll( ele.parentElement); } } } var el = document.elementFromPoint($mouseX,$mouseY); var el2 = eleCanScroll(el); el2.scrollBy($dx,$dy); """); } // ... inside your body use: return Listener( onPointerPanZoomUpdate: (event) { final Offset panDelta = event.panDelta; final Offset position = event.position; scrollWebview(position.dx, position.dy, panDelta.dx, panDelta.dy); }, onPointerSignal: (signal) { if (signal is PointerScrollEvent) { final Offset scrollDelta = signal.scrollDelta; final Offset position = signal.position; scrollWebview(position.dx, position.dy, scrollDelta.dx, scrollDelta.dy); } }, child: Stack( children: [ webview_windows.Webview( _windowsController, ), StreamBuilder<webview_windows.LoadingState>( stream: _windowsController.loadingState, builder: (context, snapshot) { if (snapshot.hasData && snapshot.data == webview_windows.LoadingState.loading) { return const LinearProgressIndicator(); } else { return const SizedBox(); } }, ), ], ), );
用了你的方法,发现能解决嵌套滚动的问题了,但鼠标放大的效果不起作用。请问中间有图表放大的问题如何解决呢? 例如以下网址图表需要滚动放大:https://ait0.goingmerry.hk/#/tradingview?symbol=W2405&resultSymbol=CBOT_W2405
We solved it in a similar fashion, here is the source code for reference:
Future<void> scrollWebview(double mouseX, double mouseY, double dx, double dy) { return _windowsController.executeScript(""" function eleCanScroll(ele) { if (ele.scrollTop > 0) { return ele; } else { ele.scrollTop++; const top = ele.scrollTop; top && (ele.scrollTop = 0); if(top > 0){ return ele; } else { return eleCanScroll( ele.parentElement); } } } var el = document.elementFromPoint($mouseX,$mouseY); var el2 = eleCanScroll(el); el2.scrollBy($dx,$dy); """); } // ... inside your body use: return Listener( onPointerPanZoomUpdate: (event) { final Offset panDelta = event.panDelta; final Offset position = event.position; scrollWebview(position.dx, position.dy, panDelta.dx, panDelta.dy); }, onPointerSignal: (signal) { if (signal is PointerScrollEvent) { final Offset scrollDelta = signal.scrollDelta; final Offset position = signal.position; scrollWebview(position.dx, position.dy, scrollDelta.dx, scrollDelta.dy); } }, child: Stack( children: [ webview_windows.Webview( _windowsController, ), StreamBuilder<webview_windows.LoadingState>( stream: _windowsController.loadingState, builder: (context, snapshot) { if (snapshot.hasData && snapshot.data == webview_windows.LoadingState.loading) { return const LinearProgressIndicator(); } else { return const SizedBox(); } }, ), ], ), );
Thanks, this worked for me.
I only need to adjust the scrollWebview function because my webview isn't filling all the space on the view. So I need to convert the x and y mouse positions to the widget's correct size.
Future<void> scrollWebview(
double mouseX, double mouseY, double dx, double dy) {
// get relative position from window
final RenderBox renderBox = context.findRenderObject() as RenderBox;
final Offset localOffset = renderBox.localToGlobal(Offset.zero);
mouseX -= localOffset.dx;
mouseY -= localOffset.dy;
return _windowsController.executeScript("""
function eleCanScroll(ele) {
if (ele.scrollTop > 0) { return ele; }
else {
ele.scrollTop++;
const top = ele.scrollTop;
top && (ele.scrollTop = 0);
if(top > 0){
return ele;
} else {
return eleCanScroll( ele.parentElement);
}
}
}
var el = document.elementFromPoint($mouseX,$mouseY);
var el2 = eleCanScroll(el);
el2.scrollBy($dx,$dy);
""");
}
None of the solution mentioned above seem to allow to zoom in into an interactive plot like the one displayed in the html file below.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Bokeh Plot</title>
<style>
html, body {
box-sizing: border-box;
height: 100%;
margin: 0;
padding: 0;
}
</style>
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-3.1.0.min.js"></script>
<script type="text/javascript">
Bokeh.set_log_level("info");
</script>
</head>
<body>
<div id="f51afd3d-72f3-4292-9b9b-95295add4f5a" data-root-id="p1128" style="display: contents;"></div>
<script type="application/json" id="p1257">
{"e91e631c-e1f0-4cd3-8907-4f155d1fc643":{"version":"3.1.0","title":"Bokeh Application","defs":[],"roots":[{"type":"object","name":"Figure","id":"p1128","attributes":{"x_range":{"type":"object","name":"DataRange1d","id":"p1130"},"y_range":{"type":"object","name":"DataRange1d","id":"p1129"},"x_scale":{"type":"object","name":"LinearScale","id":"p1142"},"y_scale":{"type":"object","name":"LinearScale","id":"p1144"},"title":{"type":"object","name":"Title","id":"p1131","attributes":{"text":"Simple Line Plot"}},"renderers":[{"type":"object","name":"GlyphRenderer","id":"p1181","attributes":{"data_source":{"type":"object","name":"ColumnDataSource","id":"p1175","attributes":{"selected":{"type":"object","name":"Selection","id":"p1176","attributes":{"indices":[],"line_indices":[]}},"selection_policy":{"type":"object","name":"UnionRenderers","id":"p1177"},"data":{"type":"map","entries":[["x",[1,2,3,4]],["y",[4,7,2,5]]]}}},"view":{"type":"object","name":"CDSView","id":"p1182","attributes":{"filter":{"type":"object","name":"AllIndices","id":"p1183"}}},"glyph":{"type":"object","name":"Line","id":"p1178","attributes":{"x":{"type":"field","field":"x"},"y":{"type":"field","field":"y"},"line_color":"#1f77b4","line_width":2}},"nonselection_glyph":{"type":"object","name":"Line","id":"p1179","attributes":{"x":{"type":"field","field":"x"},"y":{"type":"field","field":"y"},"line_color":"#1f77b4","line_alpha":0.1,"line_width":2}},"muted_glyph":{"type":"object","name":"Line","id":"p1180","attributes":{"x":{"type":"field","field":"x"},"y":{"type":"field","field":"y"},"line_color":"#1f77b4","line_alpha":0.2,"line_width":2}}}}],"toolbar":{"type":"object","name":"Toolbar","id":"p1137","attributes":{"tools":[{"type":"object","name":"PanTool","id":"p1160"},{"type":"object","name":"WheelZoomTool","id":"p1161"},{"type":"object","name":"BoxZoomTool","id":"p1162","attributes":{"overlay":{"type":"object","name":"BoxAnnotation","id":"p1163","attributes":{"syncable":false,"level":"overlay","visible":false,"left_units":"canvas","right_units":"canvas","bottom_units":"canvas","top_units":"canvas","line_color":"black","line_alpha":1.0,"line_width":2,"line_dash":[4,4],"fill_color":"lightgrey","fill_alpha":0.5}}}},{"type":"object","name":"SaveTool","id":"p1164"},{"type":"object","name":"ResetTool","id":"p1165"},{"type":"object","name":"HelpTool","id":"p1166"},{"type":"object","name":"WheelZoomTool","id":"p1186"}],"active_scroll":{"id":"p1186"}}},"left":[{"type":"object","name":"LinearAxis","id":"p1153","attributes":{"ticker":{"type":"object","name":"BasicTicker","id":"p1156","attributes":{"mantissas":[1,2,5]}},"formatter":{"type":"object","name":"BasicTickFormatter","id":"p1154"},"axis_label":"y","major_label_policy":{"type":"object","name":"AllLabels","id":"p1155"}}}],"below":[{"type":"object","name":"LinearAxis","id":"p1146","attributes":{"ticker":{"type":"object","name":"BasicTicker","id":"p1149","attributes":{"mantissas":[1,2,5]}},"formatter":{"type":"object","name":"BasicTickFormatter","id":"p1147"},"axis_label":"x","major_label_policy":{"type":"object","name":"AllLabels","id":"p1148"}}}],"center":[{"type":"object","name":"Grid","id":"p1152","attributes":{"axis":{"id":"p1146"}}},{"type":"object","name":"Grid","id":"p1159","attributes":{"dimension":1,"axis":{"id":"p1153"}}},{"type":"object","name":"Legend","id":"p1184","attributes":{"items":[{"type":"object","name":"LegendItem","id":"p1185","attributes":{"label":{"type":"value","value":"Test"},"renderers":[{"id":"p1181"}]}}]}}]}}],"callbacks":{"type":"map"}}}
</script>
<script type="text/javascript">
(function() {
const fn = function() {
Bokeh.safely(function() {
(function(root) {
function embed_document(root) {
const docs_json = document.getElementById('p1257').textContent;
const render_items = [{"docid":"e91e631c-e1f0-4cd3-8907-4f155d1fc643","roots":{"p1128":"f51afd3d-72f3-4292-9b9b-95295add4f5a"},"root_ids":["p1128"]}];
root.Bokeh.embed.embed_items(docs_json, render_items);
}
if (root.Bokeh !== undefined) {
embed_document(root);
} else {
let attempts = 0;
const timer = setInterval(function(root) {
if (root.Bokeh !== undefined) {
clearInterval(timer);
embed_document(root);
} else {
attempts++;
if (attempts > 100) {
clearInterval(timer);
console.log("Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing");
}
}
}, 10, root)
}
})(window);
});
};
if (document.readyState != "loading") fn();
else document.addEventListener("DOMContentLoaded", fn);
})();
</script>
</body>
</html>
I try to use mouse scroll . But It is not affected. I have tested it on WPF. It is working perfectly. Anh Touch support only click. Cannot move. Thank!
I tested it on https://joltfly.com/mouse-test/