HTML5 canvas 画逼真的简单铅笔
HTML5 canvas paint realistic simple pencil
我如何创建逼真的简单铅笔工具,而不像在 MS windows 绘图程序中那样。我需要这样的结果:
如果我尝试不透明的纯色,我会像在 MS 中一样 windows 绘画程序不是逼真的铅笔,如果我尝试添加不透明度,我会看到圆圈,这太不现实了:
如何获得第一张图片中的铅笔工具?我的尝试示例:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var previousMouseX = null;
var previousMouse = null;
var isDrawing = false;
var lineWidth = 10;
var brush = 1;
var myColor = "#FF0000";
function getMousePosition(canvas, evt) {
var rect = canvas.getBoundingClientRect();
if (evt.clientX !== undefined && evt.clientY !== undefined) {
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
}
/* BUTTONS */
$("#btn1").on("click", function() {
ctx.globalAlpha = "0.2";
});
$("#btn2").on("click", function() {
ctx.globalAlpha = "1";
});
$("#change-color").on("click", function() {
ctx.strokeStyle = "#009933";
});
$("#canvas").on("mousedown", function(e) {
isDrawing = true;
var pos = getMousePosition(canvas, e);
move(pos.x, pos.y);
});
$("#canvas").on("mousemove", function(e) {
if(isDrawing) {
var pos = getMousePosition(canvas, e);
stroke(pos.x, pos.y);
}
});
$("#canvas").on("mouseup", function() {
isDrawing = false;
});
function stroke(mouseX, mouseY) {
ctx.globalCompositeOperation = "source-over";
ctx.lineJoin = ctx.lineCap = "round";
ctx.lineWidth = 10;
ctx.beginPath();
ctx.moveTo(previousMouseX, previousMouseY);
ctx.lineTo(mouseX, mouseY);
ctx.closePath();
ctx.stroke();
move(mouseX, mouseY);
}
function move(mouseX, mouseY) {
previousMouseX = mouseX;
previousMouseY = mouseY;
}
canvas {
border: 1px solid #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="button" id="btn1" value="Transparent">
<input type="button" id="btn2" value="Solid">
<input type="button" id="change-color" value="Green color"><br />
<canvas id="canvas" width="500" height="500">
这是否接近您想要的效果?
使用透明的铅笔绘制,线宽 10,然后使用较小的线宽 (8) 在实线上绘制。也许您可以通过在 7、8 和 9 之间随机改变第二条线宽来获得更多变化?
EDIT 还可以在 1 和 0.8 之间随机设置第二行的不透明度!
在第一行永久设置不透明度并将此代码添加到函数 stroke()
ctx.globalAlpha = "1";
ctx.lineWidth = 6;
ctx.beginPath();
ctx.moveTo(previousMouseX, previousMouseY);
ctx.lineTo(mouseX, mouseY);
ctx.closePath();
ctx.stroke();
已更改代码段
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var previousMouseX = null;
var previousMouse = null;
var isDrawing = false;
var lineWidth = 10;
var brush = 1;
var myColor = "#FF0000";
function getMousePosition(canvas, evt) {
var rect = canvas.getBoundingClientRect();
if (evt.clientX !== undefined && evt.clientY !== undefined) {
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
}
/* BUTTONS */
$("#btn1").on("click", function() {
ctx.globalAlpha = "0.2";
});
$("#btn2").on("click", function() {
ctx.globalAlpha = "1";
});
$("#change-color").on("click", function() {
ctx.strokeStyle = "#009933";
});
$("#canvas").on("mousedown", function(e) {
isDrawing = true;
var pos = getMousePosition(canvas, e);
move(pos.x, pos.y);
});
$("#canvas").on("mousemove", function(e) {
if(isDrawing) {
var pos = getMousePosition(canvas, e);
stroke(pos.x, pos.y);
}
});
$("#canvas").on("mouseup", function() {
isDrawing = false;
});
function stroke(mouseX, mouseY) {
ctx.globalCompositeOperation = "source-over";
ctx.lineJoin = ctx.lineCap = "round";
ctx.lineWidth = 10;
ctx.globalAlpha = "0.2"; //NOTE ALWAYS SET TO 'TRANSPARENT' needs variable if you want to switch to solid.
ctx.beginPath();
ctx.moveTo(previousMouseX, previousMouseY);
ctx.lineTo(mouseX, mouseY);
ctx.closePath();
ctx.stroke();
ctx.globalAlpha = "1";
ctx.lineWidth = 6;
ctx.beginPath();
ctx.moveTo(previousMouseX, previousMouseY);
ctx.lineTo(mouseX, mouseY);
ctx.closePath();
ctx.stroke();
move(mouseX, mouseY);
}
function move(mouseX, mouseY) {
previousMouseX = mouseX;
previousMouseY = mouseY;
}
canvas {
border: 1px solid #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="button" id="btn1" value="Transparent">
<input type="button" id="btn2" value="Solid">
<input type="button" id="change-color" value="Green color"><br />
<canvas id="canvas" width="500" height="500">
这是铅笔效果。
改编自 Mohamed Moustafa 制作的精美粉笔效果:http://codepen.io/mmoustafa/pen/gmEdk
示例代码和演示:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw,ch;
var $canvas=$("#canvas");
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var scrollX=$canvas.scrollLeft();
var scrollY=$canvas.scrollTop();
var isDown=false;
var startX,startY,mouseX,mouseY;
var xLast = 0;
var yLast = 0;
var brushDiameter=2;
var fill1='rgba(255,255,255,0.5)';
var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/pad.jpg";
function start(){
cw=canvas.width=img.width;
ch=canvas.height=img.height;
ctx.fillStyle = fill1;
ctx.strokeStyle = fill1;
ctx.lineWidth = brushDiameter;
ctx.lineCap = 'round';
ctx.drawImage(img,0,0);
$("#canvas").mousedown(function(e){handleMouseDown(e);});
$("#canvas").mousemove(function(e){handleMouseMove(e);});
$("#canvas").mouseup(function(e){handleMouseUp(e);});
$("#canvas").mouseout(function(e){handleMouseOut(e);});
}
function handleMouseDown(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
getOffset();
xLast=mouseX=parseInt(e.clientX-offsetX);
yLast=mouseY=parseInt(e.clientY-offsetY);
isDown=true;
draw(mouseX+1, mouseY+1);
}
function handleMouseUp(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
isDown=false;
}
function handleMouseOut(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
isDown=false;
}
function handleMouseMove(e){
if(!isDown){return;}
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
getOffset();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
draw(mouseX,mouseY);
}
//252,254,171
function draw(x,y){
ctx.strokeStyle = 'rgba(0,0,0,'+(0.4+Math.random()*0.2)+')';
ctx.beginPath();
ctx.moveTo(xLast, yLast);
ctx.lineTo(x, y);
ctx.stroke();
// Chalk Effect
var length = Math.round(Math.sqrt(Math.pow(x-xLast,2)+Math.pow(y-yLast,2))/(5/brushDiameter));
var xUnit = (x-xLast)/length;
var yUnit = (y-yLast)/length;
for(var i=0; i<length; i++ ){
var xCurrent = xLast+(i*xUnit);
var yCurrent = yLast+(i*yUnit);
var xRandom = xCurrent+(Math.random()-0.5)*brushDiameter*1.2;
var yRandom = yCurrent+(Math.random()-0.5)*brushDiameter*1.2;
ctx.clearRect( xRandom, yRandom, Math.random()*2+2, Math.random()+1);
}
xLast = x;
yLast = y;
}
function getOffset(){
var BB=canvas.getBoundingClientRect();
offsetX=BB.left;
offsetY=BB.top;
}
body{ background-color:ivory; }
#canvas{border:1px solid red; background:white;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Drag to draw pencil line on the pad</h4>
<canvas id="canvas" width=300 height=300></canvas>
我如何创建逼真的简单铅笔工具,而不像在 MS windows 绘图程序中那样。我需要这样的结果:
如果我尝试不透明的纯色,我会像在 MS 中一样 windows 绘画程序不是逼真的铅笔,如果我尝试添加不透明度,我会看到圆圈,这太不现实了:
如何获得第一张图片中的铅笔工具?我的尝试示例:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var previousMouseX = null;
var previousMouse = null;
var isDrawing = false;
var lineWidth = 10;
var brush = 1;
var myColor = "#FF0000";
function getMousePosition(canvas, evt) {
var rect = canvas.getBoundingClientRect();
if (evt.clientX !== undefined && evt.clientY !== undefined) {
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
}
/* BUTTONS */
$("#btn1").on("click", function() {
ctx.globalAlpha = "0.2";
});
$("#btn2").on("click", function() {
ctx.globalAlpha = "1";
});
$("#change-color").on("click", function() {
ctx.strokeStyle = "#009933";
});
$("#canvas").on("mousedown", function(e) {
isDrawing = true;
var pos = getMousePosition(canvas, e);
move(pos.x, pos.y);
});
$("#canvas").on("mousemove", function(e) {
if(isDrawing) {
var pos = getMousePosition(canvas, e);
stroke(pos.x, pos.y);
}
});
$("#canvas").on("mouseup", function() {
isDrawing = false;
});
function stroke(mouseX, mouseY) {
ctx.globalCompositeOperation = "source-over";
ctx.lineJoin = ctx.lineCap = "round";
ctx.lineWidth = 10;
ctx.beginPath();
ctx.moveTo(previousMouseX, previousMouseY);
ctx.lineTo(mouseX, mouseY);
ctx.closePath();
ctx.stroke();
move(mouseX, mouseY);
}
function move(mouseX, mouseY) {
previousMouseX = mouseX;
previousMouseY = mouseY;
}
canvas {
border: 1px solid #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="button" id="btn1" value="Transparent">
<input type="button" id="btn2" value="Solid">
<input type="button" id="change-color" value="Green color"><br />
<canvas id="canvas" width="500" height="500">
这是否接近您想要的效果?
使用透明的铅笔绘制,线宽 10,然后使用较小的线宽 (8) 在实线上绘制。也许您可以通过在 7、8 和 9 之间随机改变第二条线宽来获得更多变化?
EDIT 还可以在 1 和 0.8 之间随机设置第二行的不透明度!
在第一行永久设置不透明度并将此代码添加到函数 stroke()
ctx.globalAlpha = "1";
ctx.lineWidth = 6;
ctx.beginPath();
ctx.moveTo(previousMouseX, previousMouseY);
ctx.lineTo(mouseX, mouseY);
ctx.closePath();
ctx.stroke();
已更改代码段
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var previousMouseX = null;
var previousMouse = null;
var isDrawing = false;
var lineWidth = 10;
var brush = 1;
var myColor = "#FF0000";
function getMousePosition(canvas, evt) {
var rect = canvas.getBoundingClientRect();
if (evt.clientX !== undefined && evt.clientY !== undefined) {
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
}
/* BUTTONS */
$("#btn1").on("click", function() {
ctx.globalAlpha = "0.2";
});
$("#btn2").on("click", function() {
ctx.globalAlpha = "1";
});
$("#change-color").on("click", function() {
ctx.strokeStyle = "#009933";
});
$("#canvas").on("mousedown", function(e) {
isDrawing = true;
var pos = getMousePosition(canvas, e);
move(pos.x, pos.y);
});
$("#canvas").on("mousemove", function(e) {
if(isDrawing) {
var pos = getMousePosition(canvas, e);
stroke(pos.x, pos.y);
}
});
$("#canvas").on("mouseup", function() {
isDrawing = false;
});
function stroke(mouseX, mouseY) {
ctx.globalCompositeOperation = "source-over";
ctx.lineJoin = ctx.lineCap = "round";
ctx.lineWidth = 10;
ctx.globalAlpha = "0.2"; //NOTE ALWAYS SET TO 'TRANSPARENT' needs variable if you want to switch to solid.
ctx.beginPath();
ctx.moveTo(previousMouseX, previousMouseY);
ctx.lineTo(mouseX, mouseY);
ctx.closePath();
ctx.stroke();
ctx.globalAlpha = "1";
ctx.lineWidth = 6;
ctx.beginPath();
ctx.moveTo(previousMouseX, previousMouseY);
ctx.lineTo(mouseX, mouseY);
ctx.closePath();
ctx.stroke();
move(mouseX, mouseY);
}
function move(mouseX, mouseY) {
previousMouseX = mouseX;
previousMouseY = mouseY;
}
canvas {
border: 1px solid #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="button" id="btn1" value="Transparent">
<input type="button" id="btn2" value="Solid">
<input type="button" id="change-color" value="Green color"><br />
<canvas id="canvas" width="500" height="500">
这是铅笔效果。
改编自 Mohamed Moustafa 制作的精美粉笔效果:http://codepen.io/mmoustafa/pen/gmEdk
示例代码和演示:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw,ch;
var $canvas=$("#canvas");
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var scrollX=$canvas.scrollLeft();
var scrollY=$canvas.scrollTop();
var isDown=false;
var startX,startY,mouseX,mouseY;
var xLast = 0;
var yLast = 0;
var brushDiameter=2;
var fill1='rgba(255,255,255,0.5)';
var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/pad.jpg";
function start(){
cw=canvas.width=img.width;
ch=canvas.height=img.height;
ctx.fillStyle = fill1;
ctx.strokeStyle = fill1;
ctx.lineWidth = brushDiameter;
ctx.lineCap = 'round';
ctx.drawImage(img,0,0);
$("#canvas").mousedown(function(e){handleMouseDown(e);});
$("#canvas").mousemove(function(e){handleMouseMove(e);});
$("#canvas").mouseup(function(e){handleMouseUp(e);});
$("#canvas").mouseout(function(e){handleMouseOut(e);});
}
function handleMouseDown(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
getOffset();
xLast=mouseX=parseInt(e.clientX-offsetX);
yLast=mouseY=parseInt(e.clientY-offsetY);
isDown=true;
draw(mouseX+1, mouseY+1);
}
function handleMouseUp(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
isDown=false;
}
function handleMouseOut(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
isDown=false;
}
function handleMouseMove(e){
if(!isDown){return;}
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
getOffset();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
draw(mouseX,mouseY);
}
//252,254,171
function draw(x,y){
ctx.strokeStyle = 'rgba(0,0,0,'+(0.4+Math.random()*0.2)+')';
ctx.beginPath();
ctx.moveTo(xLast, yLast);
ctx.lineTo(x, y);
ctx.stroke();
// Chalk Effect
var length = Math.round(Math.sqrt(Math.pow(x-xLast,2)+Math.pow(y-yLast,2))/(5/brushDiameter));
var xUnit = (x-xLast)/length;
var yUnit = (y-yLast)/length;
for(var i=0; i<length; i++ ){
var xCurrent = xLast+(i*xUnit);
var yCurrent = yLast+(i*yUnit);
var xRandom = xCurrent+(Math.random()-0.5)*brushDiameter*1.2;
var yRandom = yCurrent+(Math.random()-0.5)*brushDiameter*1.2;
ctx.clearRect( xRandom, yRandom, Math.random()*2+2, Math.random()+1);
}
xLast = x;
yLast = y;
}
function getOffset(){
var BB=canvas.getBoundingClientRect();
offsetX=BB.left;
offsetY=BB.top;
}
body{ background-color:ivory; }
#canvas{border:1px solid red; background:white;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Drag to draw pencil line on the pad</h4>
<canvas id="canvas" width=300 height=300></canvas>