基于HTML5的Drag and Drop生成图片Base64信息

HTML5的Drag and Drop是很不错的功能,网上使用例子较多如 http://html5demos.com/drag ,但这些例子大部分没实际用途,本文将搞个有点使用价值的例子,通过Drag and Drop生成图片的Base64的字符串信息。

使用Base64方式的图片有诸多好处,可将多个图片信息整合到单个js文件避免多次http请求,可以避免WebGL例子跨域访问的安全限制无法本地文件运行等好处,当然弊端也不少例如不能有效利用浏览器图片缓存机制等。使用HT for Web的朋友会发现HT的例子很多注册图片都采用Base64的方式,这主要是为了方便用户直接本地文件打开HT的手册即可操作浏览,无需构建web服务器发布进行访问,用户常问然后将图片转出Base64信息,我们使用的就是本文介绍的小工具。

该工具由一个列表、一个拓扑图和一个文本框三部分组成,用户任意拖拽本地多图片文件到任意页面部分,HT自动将图片信息生成对应的DataModel数据模型,列表显示图片效果、名称和宽高信息,拓扑显示图片、修改时间和文件大小等信息,文本框生成对应注册到htDefault.setImage函数的代码片段,用户直接可以将文本框内的代码拷贝到自己的工程的js文件进行使用。

function init(){                                                                 
    dataModel = new ht.DataModel();                                                                             
    listView = new ht.widget.ListView(dataModel); 
    graphView = new ht.graph.GraphView(dataModel);
    splitView = new ht.widget.SplitView(listView, graphView);
    textArea = new ht.widget.TextArea(); 
    textArea.getElement().style.wordWrap = 'normal';
    textArea.getElement().style.color = '#777';
    textArea.setEditable(false);
    new ht.widget.SplitView(splitView, textArea, 'v').addToDOM();    
    new ht.layout.ForceLayout(graphView).start();                            
    listView.setRowHeight(50);   
    listView.drawRowBackground = function(g, data, selected, x, y, width, height){
        if(this.isSelected(data)){
            g.fillStyle = '#87A6CB';
        }
        else if(this.getRowIndex(data) % 2 === 0){
            g.fillStyle = '#F1F4F7';
        }
        else{
            g.fillStyle = '#FAFAFA';
        }
        g.beginPath();
        g.rect(x, y, width, height);
        g.fill();
    };

    ht.Default.setImage('icon', {
        width: 50,
        height: 50,
        clip: function(g, width, height) {   
            g.beginPath();
            g.arc(width/2, height/2, Math.min(width, height)/2-3, 0, Math.PI * 2, true);
            g.clip();                        
        },
        comps: [
            {
                type: 'image',
                stretch: 'uniform',
                rect: [0, 0, 50, 50],
                name: {func: 'getImage'}
            }
        ]
    });
    listView.setIndent(60);  
    listView.setVisibleFunc(function(data){
        return data instanceof ht.Node;
    });
    listView.getIcon = function(data){
        return 'icon';
    };                                  
    listView.getLabel = function(data){
        var name = data.getName(name);
        var image = ht.Default.getImage(name);
        if(image){
            name += ' ( ' + image.width + ' X ' + image.height + ' )';
        }
        return name;
    };
    window.addEventListener("dragenter", dragEnter, false);
    window.addEventListener("dragexit", dragExit, false);
    window.addEventListener("dragover", dragOver, false);
    window.addEventListener("drop", drop, false);                                             
}

function dragEnter(evt) {
    evt.stopPropagation();
    evt.preventDefault();
}

function dragExit(evt) {
    evt.stopPropagation();
    evt.preventDefault();
}

function dragOver(evt) {
    evt.stopPropagation();
    evt.preventDefault();
}

function drop(evt) {
    evt.stopPropagation();
    evt.preventDefault();

    dataModel.clear();
    textArea.setText("");
    lastNode = null;                

    var files = evt.dataTransfer.files;
    var count = files.length;                
    for (var i = 0; i < count; i++) {
        var file = files[i];
        var reader = new FileReader();
        reader.onloadend = handleReaderLoadEnd;
        reader.file = file;
        reader.readAsDataURL(file);
    }
}

function handleReaderLoadEnd(evt) {
    var reader = evt.target;  
    var file = reader.file;
    var name = file.name;
    name = name.substr(0, name.length - 4);
    var text = "ht.Default.setImage('" + name + "', '" + reader.result + "');\n";
    textArea.setText(textArea.getText() + text);                 
    ht.Default.setImage(name, reader.result); 

    var note = 'Date: ' + file.lastModifiedDate.toLocaleString() + '\n'
            + 'Name: ' + file.name + '\n'
            + 'Size: ' + file.size + '\n'
            + 'Type: ' + file.type;

    var node = new ht.Node();
    node.setName(name);
    node.setImage(name);
    node.s({
        'note': note,
        'note.position': 3
    });
    dataModel.add(node);

    if(lastNode){
        var edge = new ht.Edge(lastNode, node);
        dataModel.add(edge);                    
    }
    lastNode = node;                
}

该代码主要对window添加了dragenter、dragexit、dragover和drop的拖拽处理,大部分都是通过e.stopPropagation();和evt.preventDefault();阻止默认行为,我们仅需在最后的drop事件中通过e.dataTransfer.files得到所有当前拖拽文件信息,构建FileReader进行加载,然后对加载的信息构建对应DataModel中的ht.Node对象和属性就完事了。

最后代码中还有几处使用HT for Web的技术细节值得提到,左侧list列表通过自定义矢量图标,并且在定义矢量时采用了clip的功能,这样列表的图标就会显示成clip裁剪后的圆形效果。重载了listView.drawRowBackground函数,实现隔行变色的列表效果。重载了listView.getLabel显示了更多的动态文本信息。通过listView.setVisibleFunc过滤不显示连线信息在列表中。

以下为该Base64转换工具的操作效果视频和抓图供参考:http://v.youku.com/v_show/id_XODUxNzY3OTA4.html

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序员互动联盟

Android Metro风格的Launcher开发系列第二篇

前言: 各位小伙伴们请原谅我隔了这么久才开始写这一系列的第二篇博客,没办法忙新产品发布,好了废话不说了,先回顾一下:在我的上一篇博客 Android Metro...

2926
来自专栏用户2442861的专栏

PyQt中如何结合Qt设计师进行开发

Qt设计师是Qt的所见即所得的界面设计工具,通过拖拉方式设计界面,但它并不能产生任何代码。

741
来自专栏JarvanMo的IT专栏

基于ExoPlayer的ExoVideoView

本人之前写过一篇名为基于ExoPlayer的ExoPlayerVideoView的文章,近日发现竟然被盗用了。

1042
来自专栏ml

C/C++ 如何来自动优雅的涮别银家的贴子

  被涮屏涮烦了,就分享一下如何用低调的c/c++来涮别人家的屏吧! 此处埋下三颗雷! 这不是啥新知识,也不是什么浅显的代码。下面,来淘淘这份经验,呼呼 我们要...

3395
来自专栏林德熙的博客

WPF 修改图片颜色

在 WPF 可以使用很多图片处理的方法,本文告诉大家的是一个图片处理,可以把处理的图片保存在文件。

611
来自专栏向治洪

android的消息通知栏

在android的应用层中,涉及到很多应用框架,例如:Service框架,Activity管理机制,Broadcast机制,对话框框架,标题栏框架,状态栏框架,...

3627
来自专栏Android干货园

Android高仿微信照片选择器+预览+显示照片

版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/lyhhj/article/details/49...

542
来自专栏我杨某人的青春满是悔恨

在 iPhone 上使用 Popover Segue

iOS 系统提供了4种基本的转场方式:Show、Show Detail、Present Modally、Present as Popover。我们平常用的最多的...

875
来自专栏陈满iOS

iOS学习资源大集合(转)

vim插件:https://github.com/Valloric/YouCompleteMe

893
来自专栏小蠢驴iOS专题

使用Category+runtime简单解决高德地图定位问题

1705

扫码关注云+社区