首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >锈蚀gloo_events :嵌套事件侦听器

锈蚀gloo_events :嵌套事件侦听器
EN

Stack Overflow用户
提问于 2022-11-24 12:18:14
回答 1查看 38关注 0票数 1

所以,几个月前,我踏上了锈病和WASM的旅程。目标是建立新一代免费软件WASM CMS,建立网站,实现加密和分散联网。(见Fermyon Bartholomew,Locutus (Freenet的锈版),Holochain)。我想建立一个业务围绕这一点,所以我不会放弃这个项目。对那些有兴趣的人来说,帮助是受欢迎的。

不管怎么说,几个星期以来我一直被困在这个问题上,而且我真的要为此疯狂了。以下是问题所在:

现在,我正在尝试制作一个矩形选择工具,只需在我的画布上绘制空矩形。

机制如下,只有三个嵌套的事件侦听器:

第一个是onmousedown,注册鼠标单击的x/y位置,然后添加第二个eventlistener

  • The是onmousemove,如果没有添加第三个事件侦听器,然后绘制/重新绘制矩形

  • ,第三个是oumouseup,将点设置为None,然后删除自身和onmousemove侦听器

您可以在https://github.com/MojoMotion/canvas_rectangle_drawing_example上获得该项目(欢迎推送请求)。

下面是main.rs:

代码语言:javascript
复制
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();
}

以下是错误:

代码语言:javascript
复制
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::Streamfutures::channel::mpscstd::pin::Pinstd::task::{Context, Poll})在https://docs.rs/gloo-events/latest/gloo_events/struct.EventListener.html的官方文档,但因为我不是很有经验的javascript,我真的失去了尝试连接锈菌和javascript.

现在,我正在努力使javascript中的代码位更好地理解js行为和回调.我永远不会投降,但同时我很乐意得到一些帮助.此外,我认为这是一个非常酷的项目,所以如果我们可以分享免费的解决方案,我认为这很好。帮帮我!

EN

回答 1

Stack Overflow用户

发布于 2022-11-24 14:02:30

您正在传递对引用计数值的引用,如果这句话看起来有点多余,那是因为它是多余的。

换句话说,Rc<T>已经是对T的引用。

如果需要多个并传递克隆值,只需.clone() Rc<T>即可。

代码语言:javascript
复制
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 p1
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74560666

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档