网页前端后台技巧(CSS+HTML)【HTML+CSS】

HTML5 Canvas笔记——橡皮筋式绘图二

2020-04-22  本文已影响0人  没昔

编程实现:橡皮筋式绘图。

参考书目:《HTML5 Canvas核心技术 图形、动画与游戏开发》

html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
        body {
            background: #dddddd;
        }
        
        #canvas {
            margin-left: 10px;
            margin-top: 10px;
            cursor: pointer;
            background: #ffffff;
            -webkit-webkit: box shadow 4px;
            -moz-webkit: box shadow 4px;
            -ms-webkit: box shadow 4px;
            -o-webkit: box shadow 4px;
            box-shadow: 4px 4px 8px raga(0, 0, 0, 0.5);
        }
    </style>
</head>

<body>
    <canvas id="canvas" width="600" height="400">Canvas not suported!</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">navy</option>
            <option value="purple">purple</option>
        </select> Draw shape:
        <select id='strokeShapeSelect'>
            <option value="circle">circle</option>
            <option value="line">line</option>
            <option value="rect">rect</option>
        </select> Line style:
        <select id='lineStyleSelect'>
            <option value="solid">solid</option>
            <option value="virtual">virtual</option>
        </select>Gide wires:
        <input type="checkbox" checked id="guidewireCheckbox">
        <input type="button" value="Erase all" id="eraseAllButton">
    </div>

    <script src="2-16.js"></script>
</body>

</html>

2-16.js

var canvas = document.getElementById("canvas")
var context = canvas.getContext("2d")
var eraseAllButton = document.getElementById('eraseAllButton')
var guidewireCheckbox = document.getElementById('guidewireCheckbox')
var strokeStyleSelect = document.getElementById('strokeStyleSelect')
var strokeShapeSelect = document.getElementById('strokeShapeSelect')
var lineStyleSelect = document.getElementById('lineStyleSelect')
var strokeShape = strokeShapeSelect.value;
var lineStyle = lineStyleSelect.value;
var drawingSurfaceImageData;
var mousedown = {}
var rubberbandRect = {}
var dragging = false
var guidewires = guidewireCheckbox.checked

function drawGrid(color, stepx, stepy) {
    context.save()
    context.setLineDash([])
    context.strokeStyle = color;
    context.lineWidth = 0.5;

    for (var i = stepx + 0.5; i < canvas.width; i += stepx) {
        context.beginPath();
        context.moveTo(i, 0);
        context.lineTo(i, canvas.height);
        context.stroke();
    }
    for (var i = stepy + 0.5; i < canvas.height; i += stepy) {
        context.beginPath();
        context.moveTo(0, i);
        context.lineTo(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)
    }
}

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

function restoreDrawingSurface() {
    context.putImageData(drawingSurfaceImageData, 0, 0);
}

function updateLocation(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 drawLine(loc) { //画线条
    context.beginPath();
    context.moveTo(mousedown.x, mousedown.y);
    context.lineTo(loc.x, loc.y);
    context.stroke();
}

function drawRect(loc) { //画矩形
    context.beginPath();
    context.rect(mousedown.x, mousedown.y, loc.x - mousedown.x, loc.y - mousedown.y);
    context.stroke();
}

function drawCircle(loc) { //画圆
    context.beginPath();
    X = (loc.x - mousedown.x);
    Y = (loc.y - mousedown.y);
    context.arc(mousedown.x + X / 2, mousedown.y + Y / 2, Math.sqrt(X * X + Y * Y) / 2, 0, Math.PI * 2);
    context.stroke();
}

function updateRubberband(loc) {
    updateLocation(loc);
    switch (strokeShape) {
        case "line":
            drawLine(loc);
            break;
        case "rect":
            drawRect(loc);
            break;
        case "circle":
            drawCircle(loc);
            break;
        default:
            break;
    }
}

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.setLineDash([])
    context.strokeStyle = 'rgba(0.0,20,0.4)';
    context.lineWidth = 0.5;
    drawVerticalLine(x);
    drawHorizontalLine(y);
    context.restore();
}

canvas.onmousedown = function(e) {
    var loc = windowToCanvas(e.clientX, e.clientY);

    e.preventDefault();
    saveDrawingSurface();
    mousedown.x = loc.x;
    mousedown.y = loc.y;
    dragging = true;
}

canvas.onmousemove = function(e) {
    var loc;

    if (dragging) {
        e.preventDefault();

        loc = windowToCanvas(e.clientX, e.clientY);
        restoreDrawingSurface();
        updateRubberband(loc);

        if (guidewires) {
            drawGuidewires(loc.x, loc.y);
        }
    }
}

canvas.onmouseup = function(e) {
    loc = windowToCanvas(e.clientX, e.clientY);
    restoreDrawingSurface();
    updateRubberband(loc);
    dragging = false;
}

eraseAllButton.onclick = function() {
    context.clearRect(0, 0, canvas.width, canvas.height);
    saveDrawingSurface();
    drawGrid('lightgray', 10, 10);
}

strokeStyleSelect.onchange = function() {
    context.strokeStyle = strokeStyleSelect.value;
}

strokeShapeSelect.onchange = function() {
    strokeShape = strokeShapeSelect.value;
}

lineStyleSelect.onchange = function() {
    lineStyle = lineStyleSelect.value;
    if (lineStyle == "virtual") {
        context.setLineDash([8, 8])
    } else {
        context.setLineDash([])
    }
}

guidewireCheckbox.onchange = function() {
    guidewires = guidewireCheckbox.checked;
}

drawGrid('lightgray', 10, 10);
context.strokeStyle = strokeStyleSelect.value;

效果如图:

QQ图片20200422111854.png
上一篇 下一篇

猜你喜欢

热点阅读