wangyuheng's Blog

time for change

svgjs 本身提供了绘制图形的函数。

为了实现鼠标点击、绘制的功能,需要监听鼠标事件

  1. mousedown 修改绘画状态位,开始画图
  2. mousemove 修改图形大小,绘制图形
  3. mouseup 修改绘画状态位,结束画图

拓展了一个函数,获取鼠标点击时相对画布左上角的相对坐标

根据svgjs提供的函数,将图形的透明度设置为0.0全透明,可以修改边框和高度,后期可以根据上面的按钮关联修改。

现在默认绘制矩形,需要向上封装,实现按钮与图形绘制的绑定。

github地址: https://github.com/wangyuheng/painter

DEMO地址: http://painter.crick.wang/

扩展Doc,获取相对坐标

(function() {
    SVG.extend(SVG.Doc, {
            transformPoint : function( event ){
                event = event || window.event;
                var touches = event.changedTouches && event.changedTouches[0] || event;
                var node = this.node;
                var point = node.createSVGPoint();
                point.x = touches.pageX-window.scrollX;
                point.y = touches.pageY-window.scrollY;
                var matrix = node.getScreenCTM().inverse();
                return point.matrixTransform( matrix );
            }
        });
})();

通过事件监听,绘制矩形

if (!SVG.supported) {
    alert('SVG not supported');
}
var svgDraw = SVG( "svgPanel" ).size('100%', 600);
var svgDoc = svgDraw.doc();
var drawing = false;
var element = null;
var startPoint = null;
var parent = null;
function mousemove(event) {
    console.log('rect mousemove');
    if (drawing) {
        var svgPoint = svgDoc.transformPoint(event);
        var x = svgPoint.x;
        var y = svgPoint.y;
        var newWidth = x - startPoint.x;
        var newHeight = y - startPoint.y;
        var startX = startPoint.x;
        var startY = startPoint.y;
        if (newWidth < 0) {
            startX += newWidth;
        }
        if (newHeight < 0) {
            startY += newHeight;
        }
        newWidth = Math.abs(newWidth);
        newHeight = Math.abs(newHeight);
        element.x(startX).y(startY).width(newWidth).height(newHeight);
    }
};
function mousedown(event) {
    console.log('rect mousedown');
    drawing = true;
    startPoint = svgDoc.transformPoint(event);
    element = parent.rect(0, 0).style("fill-opacity", '0.0').stroke({
        width: '2',
        color: '#000000'
    });
}
function mouseup(event) {
    console.log('rect mouseup ' + element);
    drawing = false;
}
var listener = {
    mousedown: mousedown,
    mousemove: mousemove,
    mouseup: mouseup,
};
var Tool = {};
Tool.Rect = function (parentEle) {
    parent = parentEle;
    var l =listener;
    svgDoc.on( 'mousedown', l.mousedown );
    svgDoc.on( 'mousemove', l.mousemove );
    svgDoc.on( 'mouseup',   l.mouseup );
};
Tool.Rect(svgDraw);

提到画图,现在的首选印象可能是canvas,但在技术选型上,为什么选择了svg而弃用Canvas?

  1. svg为矢量图,Canvas基于像素,依赖分辨率
  2. Canvas发生变化时,整个场景都会重新绘制
  3. svg以dom形式,方便进行数据传递与通信 (结构过度复杂可能会导致性能下降)
  4. svg支持事件处理器

基于以上几点,选用svg作为绘图技术,采用开源的svgjshttps://github.com/wout/svg.js进行绘画开发。

github地址: https://github.com/wangyuheng/painter

DEMO地址: http://painter.crick.wang/

svg参考文档:http://documentup.com/wout/SVG.js

现象

idea创建的spring4允许单元测试时报错

java.lang.NoClassDefFoundError: javax/servlet/SessionCoo

servlet为2.5,Spring版本为4.1.1,tomcat 6

原因

Spring Reference中提到,虽然Spring4仍然支持2.5,但它的主要目标是Servlet3.0及以上版本。如果你用Spring MVC Test Framework进行测试,则必须添加
兼容Servlet3.0的jar包(即3.0以上的servlet的jar包),

解决方法

在pom.xml中添加依赖

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>test</scope>
</dependency>

限制scope为test即可。

附录

https://jira.spring.io/browse/SPR-11292

现象

java程序报错

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)

原因

未扫描xml所在包路径

解决方法

一般的原因是Mapper interface和xml文件的定义对应不上,需要检查包名,namespace,函数名称等能否对应上,需要比较细致的对比。

按以下步骤一一执行

  1. 检查xml文件所在的package名称是否和interface对应的package名称一一对应
  2. 检查xml文件的namespace是否和xml文件的package名称一一对应
  3. 检查函数名称能否对应上
  4. 去掉xml文件中的中文注释
  5. 随意在xml文件中加一个空格或者空行然后保存

转载请注明出处WangYuheng’s Blog

现象

CentOS7 tomcat启动后外网无法访问

原因

网络防火墙

解决方法

关闭防火墙

centos 7

停止

systemctl stop firewalld.service 

禁用

systemctl disable firewalld.service 

之前的版本

停止

service iptables stop

禁用

chkconfig iptables off

转载请注明出处WangYuheng’s Blog

现象

将radio表单元素放在隐藏的div中,利用显示的label for 试图改变radio的值

IE8下不起作用

原因

IE8无法通过label for 修改隐藏的表单元素值

解决方法

利用input hidden 通过js监听label的click事件并改变hidden表单元素的值

转载请注明出处WangYuheng’s Blog

现象

利用js记录路由值,抽象面包屑导航模块,导致业务复杂度上升

原因

每个导航菜单都包含多个参数,利用js记录每个来源请求的地址+参数, 但抽象能力不足,导致设计过分复杂,而且是无用功。

解决方法

在每个页面中写静态导航

附录为失败的导航js

var breadcrumb = {
    _cachekey: 'breadcrumbs',
    _breadcrumbs: [],
    init: function() {
        this.clearBreadcrumb();
    },
    courseIndexInit: function() {
        if (breadcrumb._breadcrumbs.length == 0) {
            breadcrumb._breadcrumbs = WName.get(breadcrumb._cachekey);
            for (var i = 0; i < breadcrumb._breadcrumbs.length; i++) {
                var _thisBreadcrumb = breadcrumb._breadcrumbs[i];
                $("#breadCrumbMenu #" + _thisBreadcrumb.name).length == 0 && $('#breadCrumbMenu').append(_thisBreadcrumb.htmlTxt);
                $("#breadCrumbMenu #" + _thisBreadcrumb.name).on("click", _thisBreadcrumb.fn);
            }
        }
    },
    refreshWNCache: function() {
        WName.get(breadcrumb._cachekey) && WName.remove(breadcrumb._cachekey);
        WName.put(breadcrumb._cachekey, breadcrumb._breadcrumbs);
    },
    refresh: function() {
        this.refreshWNCache();
        $('#breadCrumbMenu').children().remove();
        for (var i = 0; i < breadcrumb._breadcrumbs.length; i++) {
            var _thisBreadcrumb = breadcrumb._breadcrumbs[i];
            $("#breadCrumbMenu #" + _thisBreadcrumb.name).length == 0 && $('#breadCrumbMenu').append(_thisBreadcrumb.htmlTxt);
            $("#breadCrumbMenu #" + _thisBreadcrumb.name).on("click", _thisBreadcrumb.fn);
        }
    },
    fillBreadcrumb: function(vName, vFoo, vIndex) {
        var _thisBreadcrumb = this.breadcrumbTemplate[vName];
        $("#breadCrumbMenu #" + vName).length == 0 && $('#breadCrumbMenu').append(_thisBreadcrumb.htmlTxt);
        if (vFoo) {
            _thisBreadcrumb.fn = vFoo;
        }
        this._breadcrumbs[_thisBreadcrumb.seq] = _thisBreadcrumb;
        this._breadcrumbs.splice(1 + _thisBreadcrumb.seq, this._breadcrumbs.length);
        $("#breadCrumbMenu #" + vName).on("click", _thisBreadcrumb.fn);
        this.refresh();
    },
    clearBreadcrumb: function() {
        this._breadcrumbs = [];
        $('#breadCrumbMenu').children().remove();
        WName.put(breadcrumb._cachekey, null);
        WName.get(breadcrumb._cachekey) && WName.remove(breadcrumb._cachekey);
    },
    breadcrumbTemplate: {
        courseList: { name: 'courseList', htmlTxt: '<span><b>/</b><a href="#courseList" id="courseList">课程列表</a></span>', seq: 0 },
        course: { name: 'course', htmlTxt: '<span><b>/</b><a href="#course" id="course">课程首页</a></span>', seq: 1 },
        user: { name: 'user', htmlTxt: '<span><b>/</b><a href="#userBase" id="user">电子档案</a></span>', seq: 0, fn: function() { user.forupdateinfo() } }
    }
}

转载请注明出处WangYuheng’s Blog

现象

调用toString()时死循环

原因

在toString()方法中使用了this关键字和+
String 后面的+后调用自动类型转换, 将this转换为String,而转换方法就是toString(),导致递归

解决方法

toString()禁用this关键字

0%