html5 编写贝塞尔曲线,HTML5 Canvas笔记——编写可编辑和拖动的贝塞尔曲线

HTML5 Canvas编写拖动和编辑图形的程序——贝塞尔曲线

2-28.js

var canvas = document.getElementById("canvas"),

context = canvas.getContext("2d"),

eraseAllButton = document.getElementById("eraseAllButton"),

strokeStyleSelect = document.getElementById("strokeStyleSelect"),

fillStyleSelect = document.getElementById("fillStyleSelect"),

fillCheckbox = document.getElementById("fillCheckbox"),

editCheckbox = document.getElementById('editCheckbox'),

sidesSelect = document.getElementById('sidesSelect'),

mousedown = {},

rubberbandRect = {},

dragging = false,

draggingOffsetX,

draggingOffsetY,

sides = 8,

startAngle = 0,

guidewires = true,

editing = false,

polygons = [];

//Function..................................................................

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);

}

//Draw a polygon...........................................................

function drawPolygon(polygon) {

context.beginPath();

polygon.createPath(context);

polygon.stroke(context);

if (fillCheckbox.checked) {

polygon.fill(context);

}

}

//Rubber bands.............................................................

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, sides, startAngle) {

var polygon = new Polygon(mousedown.x, mousedown.y,

rubberbandRect.width,

parseInt(sidesSelect.value),

(Math.PI/180)* parseInt(startAngleSelect.value),

context.strokeStyle,

context.fillStyle,

fillCheckbox.checked);

drawPolygon(polygon);

if(!dragging) {

polygons.push(polygon);

}

}

function updateRubberband(loc, sides, startAngle) {

updateRubberbandRectangle(loc);

drawRubberbandShape(loc, sides, startAngle);

}

//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();

}

function drawPolygons() {

polygons.forEach(function (polygon) {

drawPolygon(polygon);

});

}

//Dragging..............................................................

function startDragging (loc) {

saveDrawingSurface();

mousedown.x = loc.x;

mousedown.y = loc.y;

}

function startEditing() {

canvas.style.cursor = "pointer";

editing = true;

}

function stopEditing() {

canvas.style.cursor = "crosshair";

editing = false;

}

//Event handlers...........................................................

canvas.onmousedown = function (e) {

var loc = windowToCanvas(e.clientX, e.clientY);

e.preventDefault();

if (editing) {

polygons.forEach( function (polygon) {

polygon.createPath(context);

if (context.isPointInPath(loc.x, loc.y)){

startDragging(loc);

dragging = polygon;

draggingOffsetX = loc.x - polygon.x;

draggingOffsetY = loc.y - polygon.y;

return;

}

});

}

else {

startDragging(loc);

dragging = true;

}

};

canvas.onmousemove = function (e) {

var loc = windowToCanvas(e.clientX, e.clientY);

e.preventDefault();

if (editing && dragging) {

dragging.x = loc.x - draggingOffsetX;

dragging.y = loc.y - draggingOffsetY;

context.clearRect(0, 0, canvas.width,canvas.height);

drawPolygons();

}

else {

if(dragging) {

restoreDrawingSurface();

updateRubberband(loc, sides, startAngle);

if (guidewires) {

drawGuidewires(mousedown.x, mousedown.y);

}

}

}

};

canvas.onmouseup = function (e) {

var loc = windowToCanvas(e.clientX, e.clientY);

dragging = false;

if (editing) {

}

else {

restoreDrawingSurface();

updateRubberband(loc);

}

};

eraseAllButton.onclick = function (e) {

context.clearRect (0, 0, canvas.width, canvas.height);

saveDrawingSurface();

};

strokeStyleSelect.onchange = function (e) {

context.strokeStyle = strokeStyleSelect.value;

};

fillStyleSelect.onchange = function (e) {

context.fillStyle = fillStyleSelect.value;

};

editCheckbox.onchange = function (e) {

if (editCheckbox.checked){

startEditing();

}

else {

stopEditing();

}

};

//Initialization............................................................

context.strokeStyle = strokeStyleSelect.value;

context.fillStyle = fillStyleSelect.value;

context.shadowColor = 'rgba(0,0,0,0.4)';

context.shadowOffsetX = 2;

context.shadowOffsetY = 2;

context.shadowBlur = 4;

2-29.html

可编辑的贝塞尔曲线

body {

background: #eeeeee;

}

.floatingControls {

position: absolute;

left: 150px;

top: 100px;

width: 300px;

padding: 20px;

border: thin solid rgba(0, 0, 0, 0.3);

background: rgba(0, 0, 200, 0.1);

color: blue;

font: 14px Arial;

-webkit-box-shadow: rgba(0, 0, 0, 0.2) 6px 6px 8px;

-moz-box-shadow: rgba(0, 0, 0, 0.2) 6px 6px 8px;

box-shadow: rgba(0, 0, 0, 0.2) 6px 6px 8px;

display: none;

}

.floatingControls p {

margin-top: 0px;

margin-bottom: 20px;

}

#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);

}

Canvas not supported

Stroke color:

red

green

blue

orange

cornflowerblue

goldenrod

navy

purple

Guidewires:

拖动贝塞尔曲线的锚点和控制点以改变曲线的形状

当你完成曲线形状的编辑后,点击曲线外的一点,以完成此图像

value='不再提示'/>

2-30.js

var canvas = document.getElementById('canvas'),

context = canvas.getContext('2d'),

eraseAllButton = document.getElementById('eraseAllButton'),

strokeStyleSelect = document.getElementById('strokeStyleSelect'),

guidewireCheckbox = document.getElementById('guidewireCheckbox'),

instructions = document.getElementById('instructions'),

instructionsOkayButton = document.getElementById('instructionsOkayButton'),

instructionsNoMoreButton = document.getElementById('instructionsNoMoreButton'),

showInstructions = true,

GRID_STROKE_STYLE = 'lightblue',

GRID_SPACING = 10,

CONTROL_POINT_RADIUS = 5,

CONTROL_POINT_STROKE_STYLE = 'blue',

CONTROL_POINT_FILL_STYLE = 'rgba(255, 255, 0, 0.5)',

END_POINT_STROKE_STYLE = 'navy',

END_POINT_FILL_STYLE = 'rgba(0, 255, 0, 0.5)',

GUIDEWIRE_STROKE_STYLE = 'rgba(0,0,230,0.4)',

drawingImageData,

mousedown = {},

rubberbandRect = {},

dragging = false,

draggingPoint = false,

endPoints = [{}, {}],

controlPoints = [{}, {}],

editing = false,

guidewires = guidewireCheckbox.checked;

//Function……

function drawGrid(color, stepX, stepY){

context.save()

context.strokeStyle = color;

context.lineWidth = 0.5;

context.clearRect(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 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 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(){

drawingImageData = context.getImageData(0, 0,

canvas.width, canvas.height);

};

function restoreDrawingSurface(){

context.putImageData(drawingImageData, 0, 0);

};

/**

* 绘制贝塞尔曲线

*/

function drawBezierCurve (){

context.beginPath();

context.moveTo(endPoints[0].x, endPoints[0].y);

context.bezierCurveTo(controlPoints[0].x, controlPoints[0].y,

controlPoints[1].x, controlPoints[1].y,

endPoints[1].x, endPoints[1].y);

context.stroke();

};

function updateEndAndControlPoints(){

endPoints[0].x = rubberbandRect.left;

endPoints[0].y = rubberbandRect.top;

endPoints[1].x = rubberbandRect.left + rubberbandRect.width;

endPoints[1].y = rubberbandRect.top + rubberbandRect.height

controlPoints[0].x = rubberbandRect.left;

controlPoints[0].y = rubberbandRect.top + rubberbandRect.height

controlPoints[1].x = rubberbandRect.left + rubberbandRect.width;

controlPoints[1].y = rubberbandRect.top;

};

function drawRubberbandShape(loc){

updateEndAndControlPoints();

drawBezierCurve();

};

function updateRubberband(loc){

updateRubberbandRectangle(loc);

drawRubberbandShape(loc);

};

//辅助线

function drawHorizontalGuidewire(y){

context.beginPath();

context.moveTo(0, y + 0.5);

context.lineTo(context.canvas.width, y + 0.5);

context.stroke();

};

function drawVerticalGuidewire(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 = GUIDEWIRE_STROKE_STYLE;

context.lineWidth = 0.5;

drawVerticalGuidewire(x);

drawHorizontalGuidewire(y);

context.restore();

};

//绘制锚点和控制点

function drawControlPoint(index){

context.beginPath();

context.arc(controlPoints[index].x, controlPoints[index].y,

CONTROL_POINT_RADIUS, 0, Math.PI * 2, false);

context.stroke();

context.fill();

};

function drawControlPoints(){

context.save();

context.strokeStyle = CONTROL_POINT_STROKE_STYLE;

context.fillStyle = CONTROL_POINT_FILL_STYLE;

drawControlPoint(0);

drawControlPoint(1);

context.stroke();

context.fill();

context.restore();

};

function drawEndPoint(index){

context.beginPath();

context.arc(endPoints[index].x, endPoints[index].y,

CONTROL_POINT_RADIUS, 0, Math.PI * 2, false);

context.stroke();

context.fill();

};

function drawEndPoints(){

context.save();

context.strokeStyle = END_POINT_STROKE_STYLE;

context.fillStyle = END_POINT_FILL_STYLE;

drawEndPoint(0);

drawEndPoint(1);

context.stroke();

context.fill();

context.restore();

};

function drawControlAndEndPoints(){

drawControlPoints();

drawEndPoints();

};

function cursorInEndPoint(loc){

var pt;

endPoints.forEach(function (point) {

context.beginPath();

context.arc(point.x, point.y,

CONTROL_POINT_RADIUS, 0, Math.PI * 2, false);

if (context.isPointInPath(loc.x, loc.y)) {

pt = point;

}

});

return pt;

};

function cursorInControlPoint(loc){

var pt;

controlPoints.forEach(function (point) {

context.beginPath();

context.arc(point.x, point.y,

CONTROL_POINT_RADIUS, 0, Math.PI * 2, false);

if (context.isPointInPath(loc.x, loc.y)) {

pt = point;

}

});

return pt;

};

function updateDraggingPoint(loc){

draggingPoint.x = loc.x;

draggingPoint.y = loc.y;

};

//事件

canvas.onmousedown = function(e){

//获取当前位置

var loc = windowToCanvas(e.clientX,e.clientY);

e.preventDefault();

if (!editing){

saveDrawingSurface();

mousedown.x =loc.x;

mousedown.y = loc.y;

updateRubberbandRectangle(loc);

dragging=true;

}

else{

draggingPoint = cursorInControlPoint(loc);

if (!draggingPoint){

draggingPoint=cursorInEndPoint(loc);

}

}

};

canvas.οnmοusemοve=function(e){

var loc = windowToCanvas(e.clientX,e.clientY);

if (dragging||draggingPoint){

e.preventDefault();

restoreDrawingSurface();

if (guidewires){

drawGuidewires(loc.x,loc.y);

}

}

if (dragging) {

updateRubberband(loc);

drawControlAndEndPoints();

}

else if (draggingPoint) {

updateDraggingPoint(loc);

drawControlAndEndPoints();

drawBezierCurve();

}

};

canvas.οnmοuseup=function(e){

var loc = windowToCanvas(e.clientX,e.clientY);

restoreDrawingSurface();

if (!editing) {

updateRubberband(loc);

drawControlAndEndPoints();

dragging = false;

editing = true;

if (showInstructions) {

instructions.style.display = 'inline';

}

}

else {

if (draggingPoint) drawControlAndEndPoints();

else editing = false;

drawBezierCurve();

draggingPoint = undefined;

}

}

// 给控件添加监听

eraseAllButton.onclick =function() {

context.clearRect(0, 0, canvas.width, canvas.height);

drawGrid(GRID_STROKE_STYLE, GRID_SPACING, GRID_SPACING);

saveDrawingSurface();

editing = false;

dragging = false;

draggingPoint = undefined;

};

strokeStyleSelect.onchange = function() {

context.strokeStyle = strokeStyleSelect.value;

};

guidewireCheckbox.onchange = function() {

guidewires = guidewireCheckbox.checked;

};

// 给介绍框添加监听

instructionsOkayButton.onclick = function() {

instructions.style.display = 'none';

};

instructionsNoMoreButton.onclick =function() {

instructions.style.display = 'none';

showInstructions = false;

};

// 初始化

//

context.strokeStyle = strokeStyleSelect.value;

drawGrid(GRID_STROKE_STYLE, GRID_SPACING, GRID_SPACING);

效果如图:

69de7f4525da

贝塞尔曲线

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值