用100行實現HTML5可存檔塗鴉版

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

這是開發工具程式時的副產品,整理成使用HTML5 Canvas實做手繪塗鴉板的範例(可適用IE9)。

程式結構分成四個主要部分: 第一部分在網頁加入八個不同背景顏色的20x20<div>,掛上click()事件當作點選後指定畫筆顏色的調色盤;第二部分則用同樣概念加入八個20x20的<div>,中央分別放入1x1, 2x2, 3x3, ..., 8x8大小的具背景色<div>小方塊,供使用者點選指定畫筆粗細,當調色盤切換顏色時,也會連動變換筆劃粗細小方塊的顏色。

第三部分建立一個300x300的<canvas>物件,利用getContext("2d")可以取得context(概念上context很像GDI+中的Graphics物件提供DrawLine、FillRectangle、DrawString等方法可以在上面繪製線條、形狀、輸出文字... 等等),然後在mousedown(), mousemove(), mouseup()事件加入落筆、劃線、起筆的對應邏輯。(介紹HTML5 Canvas的資源還蠻多的,例如: MDN Canvas教學、整個網站都在教Canvas的http://www.html5canvastutorials.com/...)

第四部分則是將<canvas>的繪製結果轉成圖檔,Javascript無法存取本機資源,所以很難直接產生檔案,而canvas提供了toDataURL()方法,可將canvas內容轉成png圖檔(或其他圖檔格式)的base64編碼字串(關於圖檔編碼字串可參考先前的Data URI的介紹文),再把它設定成<img>的src,就達到在網頁上顯示該圖檔的效果,使用者則可透過在圖檔按右鍵另存新檔的方式將檔案保存在本機上。

IE9+支援toDataURL(),故這個程式在IE9及Firefox、Chrome、Safari上均可順利執行。

依照慣例,這個陽春可匯出式塗鴉板範例遵HTML+Script不超過100行的優秀傳統,展現jQuery的簡潔~~

<!DOCTYPE html>

<html>

<head>

<title>HTML5 Canvas塗鴉板</title>

<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.4.js">

</script>

<style>

body,input { font-size: 9pt; }

#dCanvas,#dLine { clear: both; }

.option

{

float: left; width: 20px; height: 20px; border: 2px solid #cccccc;

margin-right: 4px; margin-bottom: 4px;

}

.active { border: 2px solid black; }

.lw { text-align: center; vertical-align: middle; }

img.output { border: 1px solid green; }

#cSketchPad { cursor: arrow; }

</style>

<script>

$(function () {

//產生不同顏色的div方格當作調色盤選項

var colors =

"red;orange;yellow;green;blue;indigo;purple;black;white".split(';');

var sb = [];

$.each(colors, function (i, v) {

sb.push("<div class='option' style='background-color:" + v + "'></div>");

});

$("#dPallete").html(sb.join("\n"));

//產生不同尺寸的方格當作線條粗細選項

sb = [];

for (var i = 1; i <= 9; i++)

sb.push("<div class='option lw'>" +

"<div style='margin-top:#px;margin-left:#px;width:%px;height:%px'></div></div>"

.replace(/%/g, i).replace(/#/g, 10 - i / 2));

$("#dLine").html(sb.join('\n'));

var clrs = ("#dPallete .option");

var lws = ("#dLine .option");

//點選調色盤時切換焦點並取得顏色存入p_color,

//同時變更線條粗細選項的方格的顏色

$clrs.click(function () {

$clrs.removeClass("active");

$(this).addClass("active");

p_color = this.style.backgroundColor;

$lws.children("div").css("background-color", p_color);

}).first().click();

//點選線條粗細選項時切換焦點並取得寬度存入p_width

$lws.click(function () {

$lws.removeClass("active");

$(this).addClass("active");

p_width =

$(this).children("div").css("width").replace("px", "");

}).eq(3).click();

//取得canvas context

var canvas = ("#cSketchPad");

var ctx = $canvas[0].getContext("2d");

ctx.lineCap = "round";

ctx.fillStyle = "white"; //整個canvas塗上白色背景避免PNG的透明底色效果

ctx.fillRect(0, 0, canvas.width(), canvas.height());

var drawMode = false;

//canvas點選、移動、放開按鍵事件時進行繪圖動作

$canvas.mousedown(function (e) {

ctx.beginPath();

ctx.strokeStyle = p_color;

ctx.lineWidth = p_width;

ctx.moveTo(e.pageX - canvas.position().left, e.pageY - canvas.position().top);

drawMode = true;

})

.mousemove(function (e) {

if (drawMode) {

ctx.lineTo(e.pageX - canvas.position().left, e.pageY - canvas.position().top);

ctx.stroke();

}

})

.mouseup(function (e) {

drawMode = false;

});

//利用.toDataqURL()將繪圖結果轉成圖檔

$("#bGenImage").click(function () {

$("#dOutput").html(

("\", { src: canvas[0].toDataURL(),

"class": "output"

}));

});

});

</script>

</head>

<body>

<div id="dPallete"></div>

<div id="dLine"></div>

<div id="dCanvas">

<canvas id="cSketchPad" width="300" height="300" style="border: 2px solid gray" />

</div>

<input type="button" id="bGenImage" value="Generate Image" />

<div id="dOutput"></div>

</body>

</html>

程式雖短,但已足以提供基本的手繪功能,我就用它復刻了小閃光的即興塗鴉作品:

按下"Generate Image",網頁的下方會出現當時<canvas>內容所轉換成的png圖檔,另存新檔就可以永久保存囉!

有興趣的人可以到線上展示親手玩看看~

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

相关推荐
程序员清洒5 分钟前
Flutter for OpenHarmony:Text — 文本显示与样式控制
开发语言·javascript·flutter
雨季66639 分钟前
Flutter 三端应用实战:OpenHarmony 简易“动态内边距调节器”交互模式深度解析
javascript·flutter·ui·交互·dart
会飞的战斗鸡1 小时前
JS中的链表(含leetcode例题)
javascript·leetcode·链表
方也_arkling2 小时前
别名路径联想提示。@/统一文件路径的配置
前端·javascript
qq_177767372 小时前
React Native鸿蒙跨平台剧集管理应用实现,包含主应用组件、剧集列表、分类筛选、搜索排序等功能模块
javascript·react native·react.js·交互·harmonyos
qq_177767372 小时前
React Native鸿蒙跨平台自定义复选框组件,通过样式数组实现选中/未选中状态的样式切换,使用链式调用替代样式数组,实现状态驱动的样式变化
javascript·react native·react.js·架构·ecmascript·harmonyos·媒体
web打印社区2 小时前
web-print-pdf:突破浏览器限制,实现专业级Web静默打印
前端·javascript·vue.js·electron·html
烬头88213 小时前
React Native鸿蒙跨平台采用了函数式组件的形式,通过 props 接收分类数据,使用 TouchableOpacity实现了点击交互效果
javascript·react native·react.js·ecmascript·交互·harmonyos
Amumu121383 小时前
Vuex介绍
前端·javascript·vue.js
2601_949809593 小时前
flutter_for_openharmony家庭相册app实战+相册详情实现
javascript·flutter·ajax