您的解決方案實際上是一個有點複雜,因爲下面的問題!
問題:
- 你需要一個KineticJS形狀對象繪製自定義形狀。
- Shape在其drawFunc中只允許1個單獨的context.beginPath。
- Html Canvas只允許您爲每個beginPath設置1個fillStyle(填充顏色)。
- 這意味着你僅限於填充1個藍色 - 而不是你的10個藍色。
解決方案:
- 你可以讓你形狀的裁剪區域。
- 然後使用另一個背景畫布顯示通過裁剪後的形狀。
- 背景畫布將用於高效地繪製您的所有藍色陰影中的單個像素!
要繪製隨機像素,並且仍然覆蓋所有的像素中,創建一個「映射」數組:
- 用在舞臺上的每個像素的索引#創建的陣列。 (randomPixels [])
- 隨機化數組。
- 使用包含每個像素索引的隨機數組一次一個地繪製隨機像素。
這是創建地圖陣列功能:
// make an array with elements from 0 to shapeWidth*shapeHeight in random order
function initPixelArray(shapeWidth,shapeHeight){
var array=[];
var i;
var countdown;
var temp;
// Must be a better way to fill an array with
// a sequential group of numbers, just in random order
// Anyone got some magic for this ????????????
// fill array with sequential numbers representing each pixel;
for(var i=0;i<shapeWidth*shapeHeight;i++){ array.push(i); }
// randomize the array
countdown=array.length;
while (countdown > 0) {
i = (Math.random() * countdown--) | 0;
temp = array[countdown];
array[countdown] = array[i];
array[i] = temp;
}
//
return array;
}
接着創建自定義KineticJS形狀:
- 定義自定義形狀作爲剪輯區域(在drawFunc )
- DrawImage背景畫布(將包含不斷更新的像素)
- 由於它被剪切,背景畫布只會在您的自定義形狀內部可見。
此使用的形狀,剪切路徑到畫布背景
var shape = new Kinetic.Shape({
drawFunc: function(canvas){
var context = canvas.getContext();
context.beginPath();
context.moveTo(0, 50);
context.lineTo(220, 80);
context.quadraticCurveTo(100, 100, 60, 170);
context.closePath();
context.clip();
context.drawImage(this.backgroundCanvas,0,0);
canvas.fillStroke(this);
},
x: x,
y: y,
stroke: "lightgray",
strokeWidth: 8,
draggable:true
});
爲了通過像素
- 增量動畫的10種顏色到您的形狀像素創建自定義動力學形狀用你的彩色像素填充背景畫布。
- 由於背景畫布是「內置的」動態形狀,所以您只需在畫布上繪製像素,然後調用layer.draw以使形狀中的變化可見。
此功能將使用10個藍色
// add pixels to the background canvas
// after layer.draw the new pixels will be visible in the shape
function updatePattern(){
// add 10 pixels of each type of blue (100px total)
for(var n=0;n<shapeWidth/8;n++){
// set a blue color
tempCtx.fillStyle=color[n];
tempCtx.beginPath();
// draw 10 random pixels in that blue
for(var b=0;b<10;b++){
// get next random pixel
var i=randomPixels[nextPixel]
// calculate x/y from i
var y=Math.floor(i/shapeWidth);
var x=(i-y*shapeWidth)-1;
// draw
tempCtx.rect(x,y,1,1);
// increment array index and do bounds check
if(++nextPixel>=randomPixels.length){return;}
}
// done filling with this blue--do the fill()
tempCtx.fill();
}
}
一注隨機放置像素的背景批:保持高性能---也讓觀衆的耐心,我畫(!)一批像素。
藍色陰影的適當組合保持不變。
當然,你會喜歡你的口味。
這裏是代碼和一個小提琴:http://jsfiddle.net/m1erickson/zhatS/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.1.min.js"></script>
<style>
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:300px;
height:300px;
}
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 300,
height: 300
});
var layer = new Kinetic.Layer();
stage.add(layer);
// the KineticJS shape
var myShape;
//
var shapeWidth=stage.getWidth();
var shapeHeight=stage.getHeight();
// temporary canvas to create/update the pattern for the Shape
var tempCanvas=document.createElement("canvas");
var tempCtx=tempCanvas.getContext("2d");
tempCanvas.width=shapeWidth;
tempCanvas.height=shapeHeight;
// an array of pixel references from 0 to shapeWidth*shapeHeight
// used to draw individual pixels randomly
var randomPixels=initPixelArray(shapeWidth,shapeHeight);
var nextPixel=0;
// shades of colors to fill with
var color;
var colors={
blues:["#0000ff","#2b60de","#4863a0","#2554c7","#000080","#afdcec","#c6deff","#6698ff","#c2dfff","#79baec"],
reds:["#ff0000","#f4c3c2","#fd5c5c","#fe2625","#ff3030","#ff6666","#fa8072","#efc3bf","#ff6347","#ef7942"]
}
// Create a KineticJS shape
function kShape(x,y){
var shape = new Kinetic.Shape({
drawFunc: function(canvas){
var context = canvas.getContext();
context.beginPath();
context.moveTo(0, 50);
context.lineTo(220, 80);
context.quadraticCurveTo(100, 100, 60, 170);
context.closePath();
context.clip();
context.drawImage(this.backgroundCanvas,0,0);
canvas.fillStroke(this);
},
x: x,
y: y,
stroke: "lightgray",
strokeWidth: 8,
draggable:true
});
// let the shape keep a reference to the background canvas
shape.backgroundCanvas=tempCanvas;
layer.add(shape);
layer.draw();
return(shape);
}
// make an array with elements from 0 to shapeWidth*shapeHeight in random order
function initPixelArray(shapeWidth,shapeHeight){
var array=[];
var i;
var countdown;
var temp;
// Must be a better way to fill an array with
// a sequential group of numbers, just in random order
// Anyone got some magic for this ????????????
// fill array with sequential numbers representing each pixel;
for(var i=0;i<shapeWidth*shapeHeight;i++){ array.push(i); }
// randomize the array
countdown=array.length;
while (countdown > 0) {
i = (Math.random() * countdown--) | 0;
temp = array[countdown];
array[countdown] = array[i];
array[i] = temp;
}
//
return array;
}
// add pixels to the pattern
function updatePattern(){
// add 10 pixels of each type of blue (100px total)
for(var n=0;n<shapeWidth/8;n++){
// set a blue color
tempCtx.fillStyle=color[n];
tempCtx.beginPath();
// draw 10 random pixels in that blue
for(var b=0;b<10;b++){
// get next random pixel
var i=randomPixels[nextPixel]
// calculate x/y from i
var y=Math.floor(i/shapeWidth);
var x=(i-y*shapeWidth)-1;
// draw
tempCtx.rect(x,y,1,1);
// increment array index and do bounds check
if(++nextPixel>=randomPixels.length){return;}
}
// done filling with this blue--do the fill()
tempCtx.fill();
}
}
// great cross-browser animation shim by Paul Irish
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000/60);
};
})();
// animate filling of pixels
var fps = 60;
function animate() {
setTimeout(function() {
requestAnimationFrame(animate);
if(nextPixel>=randomPixels.length){return;}
updatePattern();
layer.draw();
}, 1000/fps);
}
////////////////// ACTION STARTS HERE
var myShape=kShape(20,20);
$("#blues").click(function(){
color=colors.blues;
nextPixel=0;
animate();
});
$("#reds").click(function(){
color=colors.reds;
nextPixel=0;
animate();
});
}); // end $(function(){});
</script>
</head>
<body>
<div id="container"></div>
<button id="blues">Fill blues</button>
<button id="reds">Fill reds</button>
</body>
</html>
哇!這真是太神奇了!這正是我想要做的。我也學到了很多東西,你也可以閱讀你的答案。謝謝。 – RadiantHex