TML5 的 canvas 元素使用 JavaScript 在網頁上繪制圖像。
畫布是一個矩形區域,您可以控制其每一像素。
canvas 擁有多種繪制路徑、矩形、圓形、字符以及添加圖像的方法。
下面是一個用 HTML5 的 canvas 繪制的 3D 玫瑰花。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>3D玫瑰花</title>
<meta name="Generator" content="EditPlus">
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta name="Description" content="">
</head>
<body>
<div id="demo" style="width:520; height:500px;"><canvas id="c" height="500" width="500"></canvas></div>
<script>
var b = document.body;
var c = document.getElementsByTagName('canvas')[0];
var a = c.getContext('2d');
var canvas = document.getElementsByTagName('canvas')[0];
var ctx = canvas.getContext('2d');
document.body.clientWidth;
with(m=Math)C=cos,S=sin,P=pow,R=random;
c.width=c.height=f=500;h=-250;
function p(a,b,c){
if(c>60)
return[S(a*7)*(13+5/(.2+P(b*4,4)))-S(b)*50,b*f+50,625+C(a*7)*(13+5/(.2+P(b*4,4)))+b*400,a*1-b/2,a];
A=a*2-1;
B=b*2-1;
if(A*A+B*B<1){
if(c>37){
n=(j=c&1)?6:4;o=.5/(a+.01)+C(b*125)*3-a*300;
w=b*h;
return[o*C(n)+w*S(n)+j*610-390,o*S(n)-w*C(n)+550-j*350,1180+C(B+A)*99-j*300,.4-a*.1+P(1-B*B,-h*6)*.15-a*b*.4+C(a+b)/5+P(C((o*(a+1)+(B>0?w:-w))/25),30)*.1*(1-B*B),o/1e3+.7-o*w*3e-6]
}
if(c>32){
c=c*1.16-.15;o=a*45-20;w=b*b*h;z=o*S(c)+w*C(c)+620;
return[o*C(c)-w*S(c),28+C(B*.5)*99-b*b*b*60-z/2-h,z,(b*b*.3+P((1-(A*A)),7)*.15+.3)*b,b*.7]
}
o=A*(2-b)*(80-c*2);
w=99-C(A)*120-C(b)*(-h-c*4.9)+C(P(1-b,7))*50+c*2;z=o*S(c)+w*C(c)+700;
return[o*C(c)-w*S(c),B*99-C(P(b, 7))*50-c/3-z/1.35+450,z,(1-b/1.2)*.9+a*.1, P((1-b),20)/4+.05]
}
}
var draw = setInterval('for(i=0;i<1e4;i++)if(s=p(R(),R(),i%46/.74)){z=s[2];x=~~(s[0]*f/z-h);y=~~(s[1]*f/z-h);if(!m[q=y*f+x]|m[q]>z)m[q]=z,a.fillStyle="rgb("+~(s[3]*h)+","+~(s[4]*h)+","+~(s[3]*s[3]*-80)+")",a.fillRect(x,y,1,1)}',0);
var demo = document.getElementById('demo');
function redraw(){
/*
var d_c = document.createElement("canvas");
d_c.setAttribute("id","c");
d_c.setAttribute("width","520");
d_c.setAttribute("height","500");
demo.appendChild(d_c);
*/
draw = setInterval('for(i=0;i<1e4;i++)if(s=p(R(),R(),i%46/.74)){z=s[2];x=~~(s[0]*f/z-h);y=~~(s[1]*f/z-h);if(!m[q=y*f+x]|m[q]>z)m[q]=z,a.fillStyle="rgb("+~(s[3]*h)+","+~(s[4]*h)+","+~(s[3]*s[3]*-80)+")",a.fillRect(x,y,1,1)}',0);
//alert(d_c);
}
function clear_canvas()
{
ctx.clearRect(0,0,520,500);
//canvas.parentNode.removeChild(canvas); //刪除
}
function stop_draw(obj){
clearInterval(obj);
}
</script>
</body>
</html>
周在給學生講授JavaScript課程中setInterval方法時,想到了我們在網上看到的各類GIF動圖比較有意思,就將其引入到教學中,教學內容設計如果通過HTML5與JavaScript實現網頁類似GIF效果的動態圖。于是在網上搜集了部分gif格式動圖,將每一個Gif動圖分解為一組jpg格式圖片,再采用setInterval與html5 Canvas進行動畫的實現。通過學習可以讓學生進一步了解canvas動畫實現的過程與原理。并將其發布到頭條,也希望對有興趣的初學者了解HTML5 Canvas等有所幫助。圖片分組圖片素材如下:
素材一
實現動畫的素材我們已經給出,主要通過gif動圖導出一組圖片,下面對html5動畫實現過程進行簡單說明。
實現其動畫的基本思路是通過HTML5提供的canvas元素進行圖片的繪制與展示,借助setInterval方法實現間隔指定時間調用新的圖片實現重新繪圖。其中繪圖主要使用drawImage方法進行繪圖,最終通過圖片依次重繪實現動畫效果。具體實現過程如下:
在頁面body部分添加Canva標簽,設置其id屬性為canv,寬度為600,高度為400,編寫代碼描述如下圖:
添加畫布元素
canvas瀏覽效果
使用Canvas借助JavaScript提供的drawImage方法進行繪圖,需要提供要繪制的圖片資源即繪圖的坐標位置。該方法原型如下:
drawImage方法原型
因此我們需要加載圖片資源,本例由于需要調用多個img實現定時不同圖片的繪制,因此我們可以使用數組存儲所加載的圖片資源。本例圖片數量為14,因此我們數組長度為14。使用素組存儲圖片實現代碼如下:
加載圖片資源代碼
本例設計在頁面加載時自動播放動畫,因此需要在JavaScript腳本中添加頁面onload事件,在事件中編寫繪圖相關代碼,主要代碼包括獲取畫布canva與實例化繪圖對象context。部分代碼描述如下:
onload事件及繪圖初始化
使用setInterval方法實現動畫主要需要定義回調函數與回調函數觸發執行的周期,本例中我們使用匿名函數作為回調函數,觸發周期設置為100毫秒。setInterval函數定義如下:
setInterval函數
在定義完函數之后可在其匿名函數函數體部分寫入繪圖方法dramImage(),實現周期調用不同圖片資源進行繪圖,最終展示出動畫效果。為了保證循環調用14張圖片,我們需要設置一計數全局變量i,由于我們圖片采用數組存儲,下標為數組,且從0-13進行編號,因此當計數值小于13時自動+1,指向下一數組下標,當為13時,設置計數值為0,回到數組第一元素,最終實現數組訪問下標的循環。setInterval實現完整代碼如下:
setInterval完整代碼
HTML動畫效果展示
本頭條號長期關注編程資訊分享;編程課程、素材、代碼分享及編程培訓。如果您對以上方面有興趣或代碼錯誤、建議與意見,可以聯系作者,共同探討。期待大家關注!如需案例完整代碼請關注并私信,往期前端設計文章鏈接如下:
提示:目前提供兩種在網頁中瀏覽編輯CAD圖紙方案,詳細說明見:https://help.mxdraw.com/?pid=46
提示:MxDraw云圖API教程:https://demo.mxdraw3d.com:3562/mxdrawcloud/index.html
提示:MxDraw云圖github:https://github.com/mxcad
全新在線CAD平臺,基于JavaScript、WebGL、C++、Node.js、Three.js技術,前臺使用html5方式,在線處理二維、三維CAD圖紙。可用于圖紙管理、交流、批注、信息提取、三維展示等場景,支持dwg,dxf,dwf等文件格式,后臺使用高效C++程序開發,異步多線程、多進程架構。平臺前后臺都提供js語言開發接口,開發人員就只需要會JS語言,就可以快速搭建自己的在線CAD繪圖平臺。該系統可以在Windows、Linux、Android、iOS等系統上使用,真正一份代碼,全平臺支持。
1)在線演示網址1:
https://www.mxdraw3d.com/sample/vuebrowse/
2)CAD與GIS結合演示網址,請使用chrome,或edge瀏覽器:
https://www.mxdraw3d.com/sample/mx-vuemap/?cmd=Mx_CADGISDemo
3)MxCAD云圖:
https://www.mxdraw3d.com/
4)MxCAD云圖圖庫:
https://www.mxdraw3d.com/drawinglibrary.html
5)MxDraw npm 包在線幫助:
https://mxcadx.gitee.io/mxdraw_docs/start/abstract.html#%E6%A6%82%E8%BF%B0
6)MxCAD npm 包在線幫助:
https://mxcadx.gitee.io/mxcad_docs/zh/
MxDraw與MxCAD區別:
MxDraw包主要用來瀏覽CAD圖紙,如果不需要編輯CAD圖紙使用MxDraw包
MxCAD包主是在MxDraw的基礎上,增加了編輯功能,它相對于MxDraw更加復雜,如果需要在線編輯CAD圖紙,就需要使用MxCAD包。
支持AutoCAD R14 到AutoCAD 2021的所有dwg圖紙格式,未來也將支持新出現的AutoCAD文件格式。
三維支持:創建錐、柱、環等基本幾何體, 對幾何體進行布爾操作(相加、相減、相交運算)、倒角、斜切、鏤空、偏移、掃視,、幾何空間關系計算(法線、點積、叉積、投影、擬合等)、幾何體分析(質心、體積、曲率等)、空間變換(平移、縮放、旋轉)等功能。
二維支持:CAD圖紙信息搜索提取、測距離、算面積、批注、捕捉、正交、曲線離散、偏移、打斷、陣列、擴展數據讀寫、擴展記錄讀寫、構造選擇集、動畫、自定義實體、組、超連接、Undo、Redo、字典、圖層、標注樣式、線型樣式、文字樣式、視口、布局、用戶坐標系、系統變量、圖紙比較、動態提示等。
主要實體有:直線、圓弧、Polyline、樣條線、圓、橢圓、橢圓弧、IMAGE、點、塊引用、外部塊參照、射線、云線、文本、多行文本、對齊標注、旋轉標注、半徑標注、直徑標注、角度標注、布局、視口、圖層、線型、文字樣式、命名字典、標注、自定義實體、代理實體、反應器等。
主要編輯有:移動、夾點拉伸、偏移、刪除、復制、粘貼、旋轉、縮放、鏡向、離散、圖案填充、實心填充、打碎、計算曲線長、面積、最近點、交點、導角、文字變線條等。
幾何運算:面積、夾角、向量、矩陣、旋轉、縮放、最近點、最近距離、垂足、參數、鏡向、平移、交點、打斷、延伸、最短路徑、最長路徑。
點擊 http://www.mxdraw.com/download.html下載開發包,界面如下圖所示:
下載后的文件是安裝程序,雙擊按照提示安裝開發包,默認安裝位置在: C:\Users\MxDraw\Documents\MxKd\MxDrawCloudServer
注意:開發包的內容很多,安裝需要很長時間,請耐心等待!
安裝目錄內容如下:
雙擊桌面快捷方式:
啟動開始程序,界面如下:
按照界面操作,從上到下,點擊三個按鈕,啟動服務。
注意:在啟動前,關閉360殺毒軟件,它會誤報和攔截我們服務器程序訪問網絡。
注意:一定要防火墻允許我們的服務程序訪問網絡。
設置防火墻,允許這兩個程序能訪問網格:Bin\Release\node.exe和SRC\TsWeb\nodejs\node.exe,如下圖:
啟動后的效果如下:
1. 后臺網站服務程序,如果用戶有自己網站服務,可以不需要啟動該程序。
2. MxDrawNodeJS服務,后臺保存文件 ,和上傳文件 ,文件格式轉換的服務
3. MxCAD文件上傳保存服務,CAD圖紙編輯后,保存到服務器的服務
4. 前臺演示效果:
5. 選擇文件后:
6. 打開DWG圖紙:
7. Browse模式運行效果:
8. MxCAD運行效果:
9. MxGIS運行效果:
10. Mx3D運行效果:
在線看CAD圖紙的原理是:CAD圖紙文件上傳到服務后臺后,調用我們的格式轉換程序,把CAD圖紙文件轉換成我們的CAD瀏覽格式wgh文件,然后把該文件傳給前臺JS程序加載顯示CAD圖紙。
為了對大的CAD圖紙異步加載,CAD文件會轉換成多個wgh文件。
DWG文件格式轉換有兩個方法:
方法1:調用我們后面服務轉換,詳細參考:https://help.mxdraw.com/?pid=115
方法2:調用MxFileConvert.exe轉換,軟件安裝目錄下:C:\Users\MxDraw\Documents\MxKd\MxDrawCloudServer\Bin\Release\MxFileConvert.exe有一個MxFileConvert.exe程序,使用它對CAD圖紙做格式轉換。
調用命令:
MxFileConvert.exe {"srcpath":"E:/1.dwg"} 或 MxFileConvert.exe "E:/1.dwg"
或使用nodejs調用:
windows: node.exe mxconvert.js e:/1.dwg 或 node.exe mxconvert.js convert file=e:/1.dwg
linux: ./node mxconvert.js /tmp/1.dwg 或 ./node mxconvert.js convert file=/tmp/1.dwg
后臺JAVA程序如何調用MxFileConvert.exe轉換CAD文件格式,代碼如下:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
public class MyTest {
// 后面java程序,調用我們exe程序轉換dwg文件格式.
public static String CallMxFileConvert(String sDwgFile){
// 我們轉所程序路徑.
String command = "C:/Users/MxDrawDEV/Documents/MxKd/MxDrawCloudServer/Bin/Release/MxFileConvert.exe";
Runtime rn = Runtime.getRuntime();
Process process = null;
// 轉換參數。
String sJsonParam = "{\"srcpath\":\"" + sDwgFile + "\"}";
String [] sRetJson = new String[1];
try {
// 啟動一個進程序,調用轉換程序。
process = rn.exec(new String[]{command,sJsonParam});
final InputStream ins = process.getInputStream();
final InputStream errs = process.getErrorStream();
//確保子進程與主進程之間inputStream不阻塞
new Thread() {
@Override
public void run() {
BufferedReader inb = null;
String line = null;
try {
inb = new BufferedReader(new InputStreamReader(ins,"gbk"));
while ((line = inb.readLine()) != null) {
sRetJson[0] = line;
//System.out.println("executeMxExe - InputStream : " + line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(null != inb)
inb.close();
if(null != ins){
ins.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}.start();
//確保子進程與主進程之間ErrorStream不阻塞
new Thread() {
@Override
public void run() {
BufferedReader errb = null;
String line = null;
try {
errb = new BufferedReader(new InputStreamReader(errs,"gbk"));
while ((line = errb.readLine()) != null) {
System.out.println("executeMxExe - ErrorStream : " + line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(null!=errb)
errb.close();
if(null != errs){
errs.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}.start();
int retCode = process.waitFor();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally{
if(null !=process ){
OutputStream out = process.getOutputStream();
if(null != out){
try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
process.destroy();
}
}
// 返回轉換結果。
return sRetJson[0];
}
public static void main(String[] args) {
String sDwg = "e:/1.dwg";
String sRetJson = CallMxFileConvert(sDwg);
System.out.println(sRetJson);
}
};
后臺JAVA程序調用代碼:https://demo.mxdraw3d.com:3562/MxFileConvert.java.7z
Node.js后臺調用代碼如下:
/* POST upload listing. */router.post('/', upload.single('file'), function (req, res, next) {
// 得到上傳文件
var file = req.file;
// MxFileConvert.exe在服務器的路徑
var pathConvertExt = '"' + __dirname + "/../../../Bin/Release/MxFileConvert.exe" + '"';
// 準備調用參數,json格式,srcpath是dwg在服務器上的路徑.
var cmdparam = '{"srcpath":"' + file.path + '"}';
var cmd = pathConvertExt + " " + cmdparam;
const exec = child_process.exec;
//調用MxFileConvert.exe進程,進行文件格式轉換.
exec(cmd, (err, stdout, stderr) => {
if (err) {
res.json('{"code": 1, "message": "exec cmd failed"}');
}
else {
// 轉換成功,通過命令輸出json格式字符串.
res.json(stdout);
}
});
});
比如: D:/test/test.dwg 轉換后,生成文件: D:/test/buf/$test.dwg.xxx.wgh1,2.. 文件,如下圖:
把這些生成的文件放到java的Web服務的目錄下,必須前臺網頁可以直接下載這些文件,如下效果:http://localhost:3000/test/buf/$test.dwg.mxb1.wgh
到目前為止,后臺的工作已經準備完成。
接下來如何在前臺加載CAD圖紙:
A.新建一個Vue工程
詳細見:https://help.mxdraw.com/?pid=107
B.安裝mxdraw npm插件
yarn add mxdraw 或 npm install mxdraw
C. 修改main.ts加載,初始化MxDraw插件
import { loadCoreCode } from "mxdraw"loadCoreCode()
如下圖:
*請認真填寫需求信息,我們會在24小時內與您取得聯系。