タイトルは魅力的な困難であり、最初の良いレンダリングを置きます
絵があなたにアピールすることができない場合は、私はに見るためには何もないと思います。
デモリンク: https://win7killer.github.io/demo_set/html_demo/canvas/can_demo/draw_roll_2.html
*************************************************
最後に、「レーダーチャート効果一日の見出し」逮捕され、漁獲データであることを光栄「物品」、という幸せではないすべてのリンクがリンクがデモにも名前が木材です、~~~ blablaを殺さなければなりません。
私は希望を参照する:見 http://www.cnblogs.com/ufex/p/6655336.html
*************************************************
クリエイティブのソース
GIFの効果を見て前に、この記事のために私は少しを見に行きました。iPadアプリ「Amaziograph」のように見えます。それは美しく、本当にクールに見えます
最初に自分の絵のマップと相まって:
手を引くことができない無効になって、私は笑いました。(携帯電話のブラウザのOH塗装)
DEMO讲解
1.効果分析
参照軸線 - 基準線を容易に制御するために、隠し示し、彼の単一のキャンバスを遂行は、すべての再描画されません。
ボディB塗装 - 効果(キャンバス線画)を塗装し、対称効果(回転キャンバス)
。Cの設定エリア - シンプルなDOM
ビューの簡単なポイントは、よく実現するのは簡単です
2.アウト開きます
1>座標系
実際には、いくつかの線を描くが、角度が均等に分割されます。他は、キャンバスを回転させながら、ライン均一に円の中心座標ながら、一つのアプローチは、各点を計算するために、その後発散の中心点から線を描くことです。キャンバスの絵はそうここに対処するために、均一のロータリーを回転させるために必要なので。
そこで、我々は、キャンバスの回転に対処する必要があります
1 function drawRotate(deg, fn, _ctx) {
2 _ctx = _ctx || ctx
3 _ctx.save();
4 _ctx.translate(_ctx.canvas.width / 2, _ctx.canvas.height / 2);
5 _ctx.rotate(deg);
6 fn && fn(_ctx);
7 _ctx.restore();
8 }
私は何度も試した後もちろん、この方法が書かれています。
図1に示すように、スタック状態記憶CTX、
図2に示すように、移動回転点、キャンバスの中心に(キャンバスは、原点座標)
図3に示すように、指定された回転角、
4、実行描画機能は、fnを
我々は、座標を使用して次回のでcanvaバック原点座標せ、影響を受けることになるので、メイン処理は、変換することである(を含むがこれのfillStyle、strokenStyle、翻訳、等が含まれていない)状態CTX内部スタックから取り出さ5、元の位置。
実際には、かなり比較的抽象周りが翻訳しています。。。私は鈍化する可能性が高いしています
次に、基準線の座標が描画されます
1 function baseLine() {
2 ctx_role.clearRect(0, 0, ctx_role.canvas.width, ctx_role.canvas.height);
3 var deg = 360 / pieace;
4 console.log(deg);
5 ctx_role.lineWidth = 1;
6 ctx_role.strokeStyle = 'rgba(0,0,0,.5)';
7 for (var i = 0, l = pieace; i < l; i ) {
8 drawRotate(i * deg / 180 * Math.PI, function(ctx_role) {
9 draw({
10 bx: can_role.width / 2,
11 by: can_role.width / 2,
12 ex: can_role.width / 2 can_role.width,
13 ey: can_role.width / 2
14 }, ctx_role);
15 }, ctx_role);
16 }
17 }
1 function draw(option, _ctx) {
2 _ctx = _ctx || ctx;
3 _ctx.beginPath();
4 _ctx.moveTo(option.bx - _ctx.canvas.width / 2, option.by - _ctx.canvas.height / 2);
5 _ctx.lineTo(option.ex - _ctx.canvas.width / 2, option.ey - _ctx.canvas.height / 2);
6 _ctx.stroke();
7 }
このように、基準線の描画が完了しました。
2>ボディーペインティング
まず、線を描画する一般的なプロセス。ムーブオーバーシュートのドラッグのような効果を有する2つの点を結ぶ線を描画されています。次のドラッグは直接コードに、学ぶために行くことができます理解していません
1 function bindPc() {
2 can.onmousedown = function(e) {
3 if (e.button != 0) {
4 return false;
5 }
6
7 var op = {};
8 op.ex = op.bx = e.clientX - can.parentElement.offsetLeft window.scrollX;
9 op.ey = op.by = e.clientY - can.parentElement.offsetTop window.scrollY;
10 drawFn(op);
11 document.onmousemove = function(e) {
12 document.body.style.cursor = 'pointer';
13 op.bx = op.ex;
14 op.by = op.ey;
15 op.ex = e.clientX - can.parentElement.offsetLeft window.scrollX;
16 op.ey = e.clientY - can.parentElement.offsetTop window.scrollY;
17 drawFn(op);
18 };
19 document.onmouseup = function() {
20 document.body.style.cursor = 'default';
21 document.onmouseup = document.onmousemove = null;
22 };
23 };
24 }
1 function drawFn(op) {
2 var deg = Math.floor(360 / pieace);
3 for (var i = 0, l = 360; i < l; i = deg) {
4 drawRotate(i / 180 * Math.PI, function(ctx) {
5 draw(op);
6 });
7 }
8 }
なお、e.buttonどのボタンマウスを決定するために使用される、左ボタンは0で
ここで再び、我々はフロントdrawRotateを使用して描画します。
************************************
この時点で、対称の線を描画することが可能です。
次は、ケーキの上のアイシングの事です
************************************
モバイル端末のサポート増加ドロー(恥じて、書かれていないどのように携帯端末を、より多くのアドバイスを歓迎)
1 function bindWp() {
2 can.addEventListener('touchstart', function(e) {
3 op = can.op = {};
4 op.ex = op.bx = e.touches[0].clientX - can.parentElement.offsetLeft window.scrollX;
5 op.ey = op.by = e.touches[0].clientY - can.parentElement.offsetTop window.scrollY;
6 drawFn(op);
7 can.addEventListener('touchmove', touchMoveFn);
8 can.addEventListener('touchend', touchEndFn);
9 });
10
11 function touchEndFn() {
12 document.body.style.cursor = 'default';
13 can.removeEventListener('touchmove', touchMoveFn);
14 can.removeEventListener('touchend', touchEndFn);
15 }
16
17 function touchMoveFn(e) {
18 op = can.op;
19 document.body.style.cursor = 'pointer';
20 op.bx = op.ex;
21 op.by = op.ey;
22 op.ex = e.touches[0].clientX - can.parentElement.offsetLeft window.scrollX;
23 op.ey = e.touches[0].clientY - can.parentElement.offsetTop window.scrollY;
24 drawFn(op);
25 return false;
26 }
27 }
3>設定など
ここでは、DOMは、それがスキップされ、比較的簡単です。彼は一つだけでは、言った地元のキャンバスに絵をダウンロード
最も簡単な、右セーブローカル画像を、しかし、あなたは確かにこの操作ああを知らない人、愚かな私を呼び出します。それについて少しはXをインストールしてきました
コードの行
1 function download() {
2 var data = can.toDataURL('image/png', 0.8);
3 var $a = document.createElement('a');
4 $a.download = imgName.value || 'default.png';
5 $a.target = '_blank';
6 $a.href = data;
7 $a.click();
8 }
(とき現金が戻って自分自身面倒、厄介な回り道を書くこのメソッドに直接ここで変更、手動./このブログを書きます)
重要な点は、ある a.downloadの、これはキャンバスの転送BASE64に入れ(canvas.toDataUrl方法、それはオーバークリアすることはできませんし、何度も繰り返し、次を理解するために、ここではそれらを繰り返すない)、ローカルキーああにダウンロードしたファイルで、かつ、財産
************************************************** ****
最後に、完全なコードを添付(および調整はまだ、トップのようなの少し外であってもよいです)
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<mtea author="[email protected]"></mtea>
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
p {
line-height: 15px;
font-size: 12px;
}
@media screen and (max-width: 768px) {
.wrapper {
width: auto;
position: relative;
overflow: hidden;
}
}
@media screen and (min-width: 769px) {
.wrapper {
width: 600px;
height: 600px;
margin: 100px auto 0;
position: relative;
overflow: hidden;
}
#panel_box {
position: fixed;
top: 20px;
right: 20px;
width: 200px;
}
}
canvas {
background: #fafafa;
display: block;
}
#can_role {
background: none;
position: absolute;
top: 0px;
left: 0px;
pointer-events: none;
}
#panel_box {
padding: 10px;
margin-top: 10px;
border: 1px solid rgba(10, 10, 10, .7);
box-shadow: 10px 7px 10px #999;
z-index: 100;
}
input {
width: 80px;
margin-left: 20px;
}
label {
text-align: justify;
}
</style>
</head>
<body>
<div class="wrapper" id="wrapper">
<canvas id="can_role"></canvas>
<canvas id="can"></canvas>
</div>
<div id="panel_box">
<p>
<label>画笔颜色<input id="color_val" type="color" value="#0099ff"/></label>
</p>
<p>
<label>画笔宽度<input type="number" id="line_width_val" min="1" max="20" value="2"/></label>
</p>
<p>
<label>扇形份数<input type="number" id="pieaceNum" min="1" max="200" value="12"/></label>
</p>
<p>
<label>参考线<input type="checkbox" id="onOff" checked="checked"/></label>
</p>
<p class="img_name_box">
<label>图片名称<input type="text" id="imgName" placeholder="ex:test.png"></label>
</p>
<p>
<a href="javascript:;" id="save_btn" target="">下载到本地</a>
</p>
</div>
<script>
var pieace = 6;
var ctx = can.getContext('2d');
var ctx_role = can_role.getContext('2d');
can.width = can.height = can_role.width = can_role.height = window.screen.width > 768 ? 600 : window.screen.width;
ctx_role.lineJoin = ctx.lineJoin = "round";
ctx_role.lineCap = ctx.lineCap = "round";
function drawFn(op) {
var deg = Math.floor(360 / pieace);
for (var i = 0, l = 360; i < l; i = deg) {
drawRotate(i / 180 * Math.PI, function(ctx) {
draw(op);
});
}
}
function draw(option, _ctx) {
_ctx = _ctx || ctx;
_ctx.beginPath();
_ctx.moveTo(option.bx - _ctx.canvas.width / 2, option.by - _ctx.canvas.height / 2);
_ctx.lineTo(option.ex - _ctx.canvas.width / 2, option.ey - _ctx.canvas.height / 2);
_ctx.stroke();
}
function drawRotate(deg, fn, _ctx) {
_ctx = _ctx || ctx
_ctx.save();
_ctx.translate(_ctx.canvas.width / 2, _ctx.canvas.height / 2);
_ctx.rotate(deg);
fn && fn(_ctx);
_ctx.restore();
}
function baseLine() {
ctx_role.clearRect(0, 0, ctx_role.canvas.width, ctx_role.canvas.height);
var deg = 360 / pieace;
ctx_role.lineWidth = 1;
ctx_role.strokeStyle = 'rgba(0,0,0,.5)';
for (var i = 0, l = pieace; i < l; i ) {
drawRotate(i * deg / 180 * Math.PI, function(ctx_role) {
draw({
bx: can_role.width / 2,
by: can_role.width / 2,
ex: can_role.width / 2 can_role.width,
ey: can_role.width / 2
}, ctx_role);
}, ctx_role);
}
}
function download() {
var data = can.toDataURL('image/png', 0.8);
var $a = document.createElement('a');
$a.download = imgName.value || 'default.png';
$a.target = '_blank';
$a.href = data;
$a.click();
// if (typeof MouseEvent === 'function') {
// var evt = new MouseEvent('click', {
// view: window,
// bubbles: true,
// cancelable: false
// });
// $a.dispatchEvent(evt);
// }
}
function bindPc() {
can.onmousedown = function(e) {
if (e.button != 0) {
return false;
}
var op = {};
op.ex = op.bx = e.clientX - can.parentElement.offsetLeft window.scrollX;
op.ey = op.by = e.clientY - can.parentElement.offsetTop window.scrollY;
drawFn(op);
document.onmousemove = function(e) {
document.body.style.cursor = 'pointer';
op.bx = op.ex;
op.by = op.ey;
op.ex = e.clientX - can.parentElement.offsetLeft window.scrollX;
op.ey = e.clientY - can.parentElement.offsetTop window.scrollY;
drawFn(op);
};
document.onmouseup = function() {
document.body.style.cursor = 'default';
document.onmouseup = document.onmousemove = null;
};
};
}
function bindWp() {
can.addEventListener('touchstart', function(e) {
op = can.op = {};
op.ex = op.bx = e.touches[0].clientX - can.parentElement.offsetLeft window.scrollX;
op.ey = op.by = e.touches[0].clientY - can.parentElement.offsetTop window.scrollY;
drawFn(op);
can.addEventListener('touchmove', touchMoveFn);
can.addEventListener('touchend', touchEndFn);
});
function touchEndFn() {
document.body.style.cursor = 'default';
can.removeEventListener('touchmove', touchMoveFn);
can.removeEventListener('touchend', touchEndFn);
}
function touchMoveFn(e) {
op = can.op;
document.body.style.cursor = 'pointer';
op.bx = op.ex;
op.by = op.ey;
op.ex = e.touches[0].clientX - can.parentElement.offsetLeft window.scrollX;
op.ey = e.touches[0].clientY - can.parentElement.offsetTop window.scrollY;
drawFn(op);
return false;
}
}
function bindSets() {
color_val.onchange = function() {
ctx.strokeStyle = color_val.value;
}
line_width_val.onchange = function() {
ctx.lineWidth = line_width_val.value;
}
pieaceNum.onchange = function() {
ctx.clearRect(0, 0, can.width, can.height);
reset();
}
onOff.onchange = function() {
if (this.checked == true) {
can_role.style.display = 'block';
} else {
can_role.style.display = 'none';
}
}
}
function bind() {
bindPc();
bindWp();
bindSets();
save_btn.onclick = download;
}
function reset() {
pieace = pieaceNum.value;
ctx.strokeStyle = 'rgba(100,100,100,.7)';
baseLine();
ctx.lineWidth = line_width_val.value;
ctx.strokeStyle = color_val.value;
}
function init() {
reset();
bind();
}
init();
</script>
</body>
</html>
**************密かに名を残す、抗キャッチブログパーク-fe豆***************
要約するとの姿勢を含み、
1.canvas_translate
2.canvas_rotate
3.canvas_toDataUrl
4.a.download && BASE64
それを考えるの残りの部分とそれを追加
最後に、自分の意見交換を表明することを歓迎、親指転載はさらに良いです。
マップを投げます
少し~~~次回お会いしましょう
**************** Shaoxiaは***************私はあなたに報酬を与えるだろう、ここで見ることができ、背後に滞在します
このデモでは、携帯端末で再生されている、ということを意味静電容量のペンがあり、それは偉大だったプロが- (脳死個々のブラウザについてのバック実行前後に~~します)することができます
いいえスタイラスプロは、最も確かに、と私たちは、このゲームをプレイすることはできません!!!
あなたがたは、高速静電容量のペンを行う(もちろん、そう簡単ではありません)
1.木製の鉛筆を探します
2.鉛筆を切り出します
3.鉛筆は斜めように研磨します
4.容量性スクリーンビデオの側に研磨(開始)
私の絵は鉛筆画を取ることです~~~上にあり
************************************
より専門的なフロントエンドの知識、作る [2048] APE www.mk2048.comを