zoukankan      html  css  js  c++  java
  • Canvas:橡皮筋线条绘制

    Canvas:橡皮筋线条绘制

    效果演示

    实现要点

    事件监听

    【说明】:

    在Canvas中检测鼠标事件是非常简单的,可以在canvas中添加一个事件监听器,当事件发生时,浏览器就会调用这个监听器。

    我们可以使用绑定事件属性:

    canvas.onmousedown = function(e)
    {
       //.....
    }  

    此外,也可以使用更为通用的addEventListener()方法来注册监听器:

    canvas.addEventListener('mousedown',function(e){
       //..... 
    })  

    注意:使用onmouseXXX更为简单,但是addEventListener()可以向某个事件注册多个监听器。

    鼠标坐标转换为canvas坐标

    【说明】

      浏览器通过事件对象传递给监听器的鼠标坐标,是窗口坐标,而不是相对于canvas自身的坐标。大部分情况下,我们需要知道的是发生鼠标事件的点相对于canvas的位置,而不是在整个窗口中的坐标,所以必须进行坐标转换

    【实例】:转换代码

        function windowToCanvas(x, y) {
            var bbox = canvas.getBoundingClientRect();
            return {
                x: (x - bbox.left)*(canvas.width / bbox.width),
                y: (y - bbox.top)*(canvas.height / bbox.height)
            };
        }
    

    注意:为什么最后要乘(canvas.width / bbox.width),我们简单说明一下,canvas存在元素大小与绘图表面大小两套尺寸,我们的图像是显示在绘图表面上的,但是如果canvas元素大小较大的话,浏览器就会对绘图表面上的图像进行缩放以适应canvas元素大小,我们要避免这种缩放就要除去缩放比例

    我们用element表示canvas元素,用canvas表示绘图表面,src表示绘制的内容,dest表示展示的内容

    缩放规则为:dest.size = src.size * (element.size / canvas.size)

    所以,src=dest.size*(canvas.size/element.size)

     绘制表面的保存与恢复

    【说明】:

      使用getImageData与putImageData方法来保存与恢复绘图环境的绘图表面数据。

    【实例】:保存和恢复数据

        function saveDrawingSurface() {
            drawingSurfaceImageData = context.getImageData(0, 0, canvas.width, canvas.height);
        }
    
        function restoreDrawingSurface() {
            context.putImageData(drawingSurfaceImageData, 0, 0);
        }  

    实现代码

    <canvas id="canvas">
        </canvas>
        <script>
            var canvas = document.getElementById("canvas");
            var context = canvas.getContext("2d");
            var drawingSufraceData;
            var mousedown ={};
            var dragging = false;
    
            //绝对坐标转相对坐标
            function windowToCanvas(x, y) {
                var bbox = canvas.getBoundingClientRect();
                return {
                    x: (x - bbox.left)* (canvas.width / bbox.width),
                    y: (y - bbox.top)* (canvas.height / bbox.height)
                };
            }
    
            //绘图表面的保存与恢复
            function saveDrawingSurface()
            {
                drawingSufraceData = context.getImageData(0,0,canvas.width,canvas.height);
            }
            function restoreDrawingSurface()
            {
                context.putImageData(drawingSufraceData,0,0);
            }
    
            function drawingLine(loc)
            {
                context.beginPath();
                context.moveTo(mousedown.x,mousedown.y);
                context.lineTo(loc.x,loc.y);
                context.stroke()
            }
    
    
            //鼠标按下
            canvas.onmousedown = function (e) {
                mousedown = windowToCanvas(e.x,e.y);
                saveDrawingSurface();
                dragging =true;
            }
    
            //鼠标移动
            canvas.onmousemove = function (e) {
                var loc =  windowToCanvas(e.x,e.y);
                if(dragging)
                {
                    restoreDrawingSurface();
                    drawingLine(loc);
                }
            }
            //鼠标松开
            canvas.onmouseup =function (e) {
                dragging=false;
            }
        </script>
  • 相关阅读:
    Ubantu 安装Redis
    传说中的WCF(5):数据协定(a)
    传说中的WCF(4):发送和接收SOAP头
    传说中的WCF(3):多个协定
    传说中的WCF(2):服务协定的那些事儿
    传说中的WCF(1):这东西难学吗?
    Linq教程
    Installutil.exe的位置和路径
    uni-app中对输入框的判断与提示(密码格式为6-12位,必须有大小写字母和数字组成)
    uni-app系列回顾总结----项目国际化
  • 原文地址:https://www.cnblogs.com/MrSaver/p/10011453.html
Copyright © 2011-2022 走看看