所以,几个月前,我踏上了锈病和WASM的旅程。目标是建立新一代免费软件WASM CMS,建立网站,实现加密和分散联网。(见Fermyon Bartholomew,Locutus (Freenet的锈版),Holochain)。我想建立一个业务围绕这一点,所以我不会放弃这个项目。对那些有兴趣的人来说,帮助是受欢迎的。
不管怎么说,几个星期以来我一直被困在这个问题上,而且我真的要为此疯狂了。以下是问题所在:
现在,我正在尝试制作一个矩形选择工具,只需在我的画布上绘制空矩形。
机制如下,只有三个嵌套的事件侦听器:
第一个是onmousedown,注册鼠标单击的x/y位置,然后添加第二个eventlistener
您可以在https://github.com/MojoMotion/canvas_rectangle_drawing_example上获得该项目(欢迎推送请求)。
下面是main.rs:
use wasm_bindgen::JsCast;
use wasm_bindgen::UnwrapThrowExt;
//use gloo_console::log;
use gloo::events::EventListener;
use gloo_utils::document;
use web_sys::CanvasRenderingContext2d;
use web_sys::MouseEvent;
use std::cell::RefCell;
use std::rc::Rc;
struct Point {
x: f32,
y: f32,
}
fn main() {
let canvas = Rc::new(RefCell::new(document()
.get_element_by_id("canvas")
.unwrap()
.dyn_into::<web_sys::HtmlCanvasElement>()
.map_err(|_| ())
.unwrap()));
let context: CanvasRenderingContext2d = canvas
.borrow()
.get_context("2d")
.unwrap()
.unwrap()
.dyn_into::<CanvasRenderingContext2d>()
.unwrap();
let p1 = Rc::new(RefCell::new(None));
let p2 = Rc::new(RefCell::new(None));
let mouse_down = EventListener::new(&*canvas.borrow_mut(), "mousedown", |event| {
let event = event.dyn_ref::<MouseEvent>().unwrap_throw();
*p1.borrow_mut() = Some(Point { x: event.x() as f32, y: event.y() as f32 });
let mouse_move = EventListener::new(&*canvas.borrow_mut(), "mousemove", |event| {
let event = event.dyn_ref::<MouseEvent>().unwrap_throw();
*p2.borrow_mut() = Some(Point { x: event.x() as f32, y: event.y() as f32 });
let mouse_up = EventListener::new(&*canvas.borrow_mut(), "mouseup", |_event| {
*p1.borrow_mut() = None;
*p2.borrow_mut() = None;
//context.begin_path();
//context.move_to(125., 125.);
//context.line_to(125., 45.);
//context.line_to(45., 125.);
//context.close_path();
//context.stroke();
});
mouse_up.forget();
});
mouse_move.forget();
});
mouse_down.forget();
}以下是错误:
error[E0597]: `p1` does not live long enough
--> src/main.rs:40:10
|
38 | let mouse_down = EventListener::new(&*canvas.borrow_mut(), "mousedown", |event| {
| ------- value captured here
39 | let event = event.dyn_ref::<MouseEvent>().unwrap_throw();
40 | *p1.borrow_mut() = Some(Point { x: event.x() as f32, y: event.y() as f32 });
| ^^ borrowed value does not live long enough
...
46 | let mouse_up = EventListener::new(&*canvas.borrow_mut(), "mouseup", |_event| {
| ____________________________-
47 | | *p1.borrow_mut() = None;
48 | | *p2.borrow_mut() = None;
49 | |
... |
56 | |
57 | | });
| |______________- argument requires that `p1` is borrowed for `'static`
...
64 | }
| - `p1` dropped here while still borrowed
error[E0597]: `canvas` does not live long enough
--> src/main.rs:42:47
|
38 | let mouse_down = EventListener::new(&*canvas.borrow_mut(), "mousedown", |event| {
| ------- value captured here
...
42 | let mouse_move = EventListener::new(&*canvas.borrow_mut(), "mousemove", |event| {
| - ^^^^^^ borrowed value does not live long enough
| __________________________|
| |
43 | | let event = event.dyn_ref::<MouseEvent>().unwrap_throw();
44 | | *p2.borrow_mut() = Some(Point { x: event.x() as f32, y: event.y() as f32 });
45 | |
... |
58 | | mouse_up.forget();
59 | | });
| |__________- argument requires that `canvas` is borrowed for `'static`
...
64 | }
| - `canvas` dropped here while still borrowed
error[E0597]: `p2` does not live long enough
--> src/main.rs:44:14
|
38 | let mouse_down = EventListener::new(&*canvas.borrow_mut(), "mousedown", |event| {
| ------- value captured here
...
44 | *p2.borrow_mut() = Some(Point { x: event.x() as f32, y: event.y() as f32 });
| ^^ borrowed value does not live long enough
45 |
46 | let mouse_up = EventListener::new(&*canvas.borrow_mut(), "mouseup", |_event| {
| ____________________________-
47 | | *p1.borrow_mut() = None;
48 | | *p2.borrow_mut() = None;
49 | |
... |
56 | |
57 | | });
| |______________- argument requires that `p2` is borrowed for `'static`
...
64 | }
| - `p2` dropped here while still borrowed我猜问题来自于eventlistener.forget()方法调用,它将借来的变量抛出范围之外(我猜是使用了Futures )。
我试图通过理解生命周期来解决这个问题,并使用“静态生命周期Rc和RefCell”,这显然对事件侦听器来说还不够长。
我的猜测是,我应该使用eventlistener.callback()与未来的东西(futures::stream::Stream,futures::channel::mpsc,std::pin::Pin,std::task::{Context, Poll})在https://docs.rs/gloo-events/latest/gloo_events/struct.EventListener.html的官方文档,但因为我不是很有经验的javascript,我真的失去了尝试连接锈菌和javascript.
现在,我正在努力使javascript中的代码位更好地理解js行为和回调.我永远不会投降,但同时我很乐意得到一些帮助.此外,我认为这是一个非常酷的项目,所以如果我们可以分享免费的解决方案,我认为这很好。帮帮我!
发布于 2022-11-24 14:02:30
您正在传递对引用计数值的引用,如果这句话看起来有点多余,那是因为它是多余的。
换句话说,Rc<T>已经是对T的引用。
如果需要多个并传递克隆值,只需.clone() Rc<T>即可。
let p1: Rc<RefCell<Option<Point>>> = Rc::new(RefCell::new(None));
let mouse_down = {
let p1 = p1.clone();
EventListener::new(canvas.borrow(), "mousedown", move |event| {
let event = event.dyn_ref::<MouseEvent>().unwrap_throw();
*p1.borrow_mut() = Some(Point { x: event.x() as f32, y: event.y() as f32 });
// ...
})
};
// further uses of p1https://stackoverflow.com/questions/74560666
复制相似问题