Canvas添加了橡皮擦工具的画板项目和只能画圆的源码

简介: Canvas添加了橡皮擦工具的画板项目和只能画圆的源码

原项目链接:

项目文件预览 - CanvasStudy - GitCode

<!DOCTYPE html>
<!--
- Copyright (C) 2012 David Geary. This code is from the book
- Core HTML5 Canvas, published by Prentice-Hall in 2012.
-
- License:
-
- Permission is hereby granted, free of charge, to any person
- obtaining a copy of this software and associated documentation files
- (the "Software"), to deal in the Software without restriction,
- including without limitation the rights to use, copy, modify, merge,
- publish, distribute, sublicense, and/or sell copies of the Software,
- and to permit persons to whom the Software is furnished to do so,
- subject to the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- The Software may not be used to create training material of any sort,
- including courses, books, instructional videos, presentations, etc.
- without the express written consent of David Geary.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
-->
 
<html>
<head>
    <title>Erasing with the Clipping Region</title>
 
    <style>
        body {
            background: #eeeeee;
        }
 
        #controls {
            position: absolute;
            left: 25px;
            top: 25px;
        }
 
        #canvas {
            background: #ffffff;
            cursor: pointer;
            margin-left: 10px;
            margin-top: 10px;
            -webkit-box-shadow: 4px 4px 8px rgba(0,0,0,0.5);
            -moz-box-shadow: 4px 4px 8px rgba(0,0,0,0.5);
            box-shadow: 4px 4px 8px rgba(0,0,0,0.5);
        }
    </style>
</head>
 
<body>
<canvas id='canvas' width='950' height='600'>
    Canvas not supported
</canvas>
 
<div id='controls'>
    Stroke color: <select id='strokeStyleSelect'>
    <option value='red'>red</option>
    <option value='green'>green</option>
    <option value='blue'>blue</option>
    <option value='orange'>orange</option>
    <option value='cornflowerblue'>cornflowerblue</option>
    <option value='goldenrod'>goldenrod</option>
    <option value='navy' selected>navy</option>
    <option value='purple'>purple</option>
    <option value='purple'>purple</option>
</select>
 
    Fill color: <select id='fillStyleSelect'>
    <option value='rgba(255,0,0,0.5)'>semi-transparent red</option>
    <option value='green'>green</option>
    <option value='rgba(0,0,255,0.5)'>semi-transparent blue</option>
    <option value='orange'>orange</option>
    <option value='rgba(100,140,230,0.5)'>semi-transparent cornflowerblue</option>
    <option value='goldenrod' selected>goldenrod</option>
    <option value='navy'>navy</option>
    <option value='purple'>purple</option>
</select>
 
    Draw  <input id='drawRadio' name='drawEraserRadios' type='radio' checked/>
    Erase <input id='eraserRadio' name='drawEraserRadios' type='radio'/>
 
    Eraser: <select id='eraserShapeSelect'>
    <option value='circle'>circle</option>
    <option value='square'>square</option>
</select>
 
    Eraser width: <select id='eraserWidthSelect'>
    <option value=25>25</option>
    <option value=50>50</option>
    <option value=75>75</option>
    <option value=100>100</option>
    <option value=125>125</option>
    <option value=150>150</option>
    <option value=175>175</option>
    <option value=200>200</option>
</select>
</div>
 
<script src = 'example.js'></script>
</body>
<script>
    /*
 * Copyright (C) 2012 David Geary. This code is from the book
 * Core HTML5 Canvas, published by Prentice-Hall in 2012.
 *
 * License:
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation files
 * (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * The Software may not be used to create training material of any sort,
 * including courses, books, instructional videos, presentations, etc.
 * without the express written consent of David Geary.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
*/
 
    var canvas = document.getElementById('canvas'),
        context = canvas.getContext('2d'),
        strokeStyleSelect = document.getElementById('strokeStyleSelect'),
        fillStyleSelect = document.getElementById('fillStyleSelect'),
        drawRadio = document.getElementById('drawRadio'),
        eraserRadio = document.getElementById('eraserRadio'),
        eraserShapeSelect = document.getElementById('eraserShapeSelect'),
        eraserWidthSelect = document.getElementById('eraserWidthSelect'),
 
        ERASER_LINE_WIDTH = 1,
 
        ERASER_SHADOW_COLOR = 'rgb(0,0,0)',
        ERASER_SHADOW_STYLE = 'blue',
        ERASER_STROKE_STYLE = 'rgb(0,0,255)',
        ERASER_SHADOW_OFFSET = -5,
        ERASER_SHADOW_BLUR = 20,
 
        GRID_HORIZONTAL_SPACING = 10,
        GRID_VERTICAL_SPACING = 10,
        GRID_LINE_COLOR = 'lightblue',
        drawingSurfaceImageData,
 
        lastX,
        lastY,
        mousedown = {},
        rubberbandRect = {},
        dragging = false,
        guidewires = true;
 
    // General-purpose functions.....................................
 
    function drawGrid(color, stepx, stepy) {
        context.save()
 
        context.strokeStyle = color;
        context.fillStyle = '#ffffff';
        context.lineWidth = 0.5;
        context.fillRect(0, 0, context.canvas.width, context.canvas.height);
 
        for (var i = stepx + 0.5; i < context.canvas.width; i += stepx) {
            context.beginPath();
            context.moveTo(i, 0);
            context.lineTo(i, context.canvas.height);
            context.stroke();
        }
 
        for (var i = stepy + 0.5; i < context.canvas.height; i += stepy) {
            context.beginPath();
            context.moveTo(0, i);
            context.lineTo(context.canvas.width, i);
            context.stroke();
        }
 
        context.restore();
    }
 
    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)
        };
    }
 
    // Save and restore drawing surface..............................
 
    function saveDrawingSurface() {
        drawingSurfaceImageData = context.getImageData(0, 0,
            canvas.width,
            canvas.height);
    }
 
    function restoreDrawingSurface() {
        context.putImageData(drawingSurfaceImageData, 0, 0);
    }
 
    // Rubberbands...................................................
 
    function updateRubberbandRectangle(loc) {
        rubberbandRect.width  = Math.abs(loc.x - mousedown.x);
        rubberbandRect.height = Math.abs(loc.y - mousedown.y);
 
        if (loc.x > mousedown.x) rubberbandRect.left = mousedown.x;
        else                     rubberbandRect.left = loc.x;
 
        if (loc.y > mousedown.y) rubberbandRect.top = mousedown.y;
        else                     rubberbandRect.top = loc.y;
    }
 
    function drawRubberbandShape(loc) {
        var angle = Math.atan(rubberbandRect.height/rubberbandRect.width),
            radius = rubberbandRect.height / Math.sin(angle);
 
        if (mousedown.y === loc.y) {
            radius = Math.abs(loc.x - mousedown.x);
        }
 
        context.beginPath();
        context.arc(mousedown.x, mousedown.y, radius, 0, Math.PI*2, false);
        context.stroke();
        context.fill();
    }
 
    function updateRubberband(loc) {
        updateRubberbandRectangle(loc);
        drawRubberbandShape(loc);
    }
 
    // Guidewires....................................................
 
    function drawHorizontalLine (y) {
        context.beginPath();
        context.moveTo(0,y+0.5);
        context.lineTo(context.canvas.width,y+0.5);
        context.stroke();
    }
 
    function drawVerticalLine (x) {
        context.beginPath();
        context.moveTo(x+0.5,0);
        context.lineTo(x+0.5,context.canvas.height);
        context.stroke();
    }
 
    function drawGuidewires(x, y) {
        context.save();
        context.strokeStyle = 'rgba(0,0,230,0.4)';
        context.lineWidth = 0.5;
        drawVerticalLine(x);
        drawHorizontalLine(y);
        context.restore();
    }
 
    // Eraser........................................................
 
    function setDrawPathForEraser(loc) {
        var eraserWidth = parseFloat(eraserWidthSelect.value);
 
        context.beginPath();
 
        if (eraserShapeSelect.value === 'circle') {
            context.arc(loc.x, loc.y,
                eraserWidth/2,
                0, Math.PI*2, false);
        }
        else {
            context.rect(loc.x - eraserWidth/2,
                loc.y - eraserWidth/2,
                eraserWidth, eraserWidth);
        }
        context.clip();
    }
 
    function setErasePathForEraser() {
        var eraserWidth = parseFloat(eraserWidthSelect.value);
 
        context.beginPath();
 
        if (eraserShapeSelect.value === 'circle') {
            context.arc(lastX, lastY,
                eraserWidth/2 + ERASER_LINE_WIDTH,
                0, Math.PI*2, false);
        }
        else {
            context.rect(lastX - eraserWidth/2 - ERASER_LINE_WIDTH,
                lastY - eraserWidth/2 - ERASER_LINE_WIDTH,
                eraserWidth + ERASER_LINE_WIDTH*2,
                eraserWidth + ERASER_LINE_WIDTH*2);
        }
        context.clip();
    }
 
    function setEraserAttributes() {
        context.lineWidth     = ERASER_LINE_WIDTH;
        context.shadowColor   = ERASER_SHADOW_STYLE;
        context.shadowOffsetX = ERASER_SHADOW_OFFSET;
        context.shadowOffsetY = ERASER_SHADOW_OFFSET;
        context.shadowBlur    = ERASER_SHADOW_BLUR;
        context.strokeStyle   = ERASER_STROKE_STYLE;
    }
 
    function eraseLast() {
        context.save();
 
        setErasePathForEraser();
        drawGrid(GRID_LINE_COLOR,
            GRID_HORIZONTAL_SPACING,
            GRID_VERTICAL_SPACING);
 
        context.restore();
    }
 
    function drawEraser(loc) {
        context.save();
 
        setEraserAttributes();
        setDrawPathForEraser(loc);
        context.stroke();
 
        context.restore();
    }
 
    // Canvas event handlers.........................................
 
    canvas.onmousedown = function (e) {
        var loc = windowToCanvas(e.clientX, e.clientY);
 
        e.preventDefault(); // prevent cursor change
 
        if (drawRadio.checked) {
            saveDrawingSurface();
        }
 
        mousedown.x = loc.x;
        mousedown.y = loc.y;
 
        lastX = loc.x;
        lastY = loc.y;
 
        dragging = true;
    };
 
    canvas.onmousemove = function (e) {
        var loc;
 
        if (dragging) {
            e.preventDefault(); // prevent selections
 
            loc = windowToCanvas(e.clientX, e.clientY);
 
            if (drawRadio.checked) {
                restoreDrawingSurface();
                updateRubberband(loc);
 
                if(guidewires) {
                    drawGuidewires(loc.x, loc.y);
                }
            }
            else {
                eraseLast();
                drawEraser(loc);
            }
            lastX = loc.x;
            lastY = loc.y;
        }
    };
 
    canvas.onmouseup = function (e) {
        loc = windowToCanvas(e.clientX, e.clientY);
 
        if (drawRadio.checked) {
            restoreDrawingSurface();
            updateRubberband(loc);
        }
 
        if (eraserRadio.checked) {
            eraseLast();
        }
 
        dragging = false;
    };
 
    // Controls event handlers.......................................
 
    strokeStyleSelect.onchange = function (e) {
        context.strokeStyle = strokeStyleSelect.value;
    };
 
    fillStyleSelect.onchange = function (e) {
        context.fillStyle = fillStyleSelect.value;
    };
 
    // Initialization................................................
 
    context.strokeStyle = strokeStyleSelect.value;
    context.fillStyle = fillStyleSelect.value;
    drawGrid(GRID_LINE_COLOR,
        GRID_HORIZONTAL_SPACING,
        GRID_VERTICAL_SPACING);
 
 
</script>
</html>
相关文章
|
定位技术 API
基于Leaflet.draw的自定义绘制实战
本文介绍了如何基于leaflet.draw进行自定义绘制,同时获取对象的bbox和geojson信息。
629 0
基于Leaflet.draw的自定义绘制实战
|
9天前
|
移动开发 前端开发 HTML5
Canvas画布之100个小球弹射源码
Canvas画布之100个小球弹射源码
|
2月前
|
前端开发 小程序
微信小程序canvas画布绘制;canvas画布图片保存
微信小程序canvas画布绘制;canvas画布图片保存
60 0
|
11月前
|
Java 图形学
JavaSwing矩形绘制教程
JavaSwing矩形绘制教程 矩形是计算机图形学中最基本的图形,JavaSwing也提供了绘制矩形的功能。本教程将介绍如何使用JavaSwing绘制矩形。
163 0
|
11月前
|
前端开发
前端 SVG 与 Canvas 框架案例 (画线、矩形、箭头、文字 ....)
前端 SVG 与 Canvas 框架案例 (画线、矩形、箭头、文字 ....)
121 0
|
12月前
|
前端开发
canvas画布实现代码雨
canvas画布实现代码雨
76 0
|
移动开发 前端开发 JavaScript
利用Canvas进行网上绘图
利用Canvas进行网上绘图
179 0
|
前端开发 JavaScript
教你如何利用canvas画布绘制哆啦A梦
订阅专栏 教你如何利用canvas画布绘制哆啦A梦 最近一直在练习使用canvas画布标签,今天教大家如何使用canvas画布绘制哆啦A梦。如图: HTML代码: <canvas id="my_canvas"></canvas> 1 CSS代码: canvas { display:block; margin:0 auto; background: pink } 1 2 3 4 5 JavaScript代码: var oCanvas = document.getEleme
教你如何利用canvas画布绘制哆啦A梦
|
前端开发
Canvas绘制圆形头像
Canvas绘制圆形头像
208 0
Canvas绘制圆形头像
|
存储 Python
海龟编程 python绘图工具turtle库的用法 turtle库使用方法大全,画笔设置 画布设置 绘图设置,画笔粗细,画笔颜色, 画笔速度。
海龟编程 Python绘图工具trutle库的使用方法 trutle库命令大全,总结了常用命令,学会这些命令,玩转turtle库