first
This commit is contained in:
commit
59426d62fb
102 changed files with 42796 additions and 0 deletions
25
Controls/Paint/Tools/Bristle.js
Normal file
25
Controls/Paint/Tools/Bristle.js
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
//// © Microsoft. All rights reserved. ////
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
(function (AppNS) {
|
||||
'use strict';
|
||||
|
||||
// A Bristle simulates the bristle on a brush.
|
||||
var Bristle = WinJS.Class.define(
|
||||
|
||||
// Constructor
|
||||
function () {
|
||||
this.color = new AppNS.Painter.Graphics.Color(); // The color of the bristle
|
||||
this.width = 2; // The bristle width is 2px
|
||||
},
|
||||
|
||||
// Variables and Methods
|
||||
{}
|
||||
);
|
||||
|
||||
WinJS.Namespace.defineWithParent(AppNS, "Painter.Tools", {
|
||||
Bristle: Bristle
|
||||
});
|
||||
|
||||
})(Microsoft.Paint);
|
||||
176
Controls/Paint/Tools/Brush.js
Normal file
176
Controls/Paint/Tools/Brush.js
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
//// © Microsoft. All rights reserved. ////
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
(function (AppNS) {
|
||||
'use strict';
|
||||
|
||||
// The Brush tool simulates a PaintBrush, with color blending and paint loss over distance.
|
||||
var Brush = WinJS.Class.define(
|
||||
|
||||
// Constructor
|
||||
function () {
|
||||
this.blends = false; // Sets whether or not this brush blends with underlying color
|
||||
this.fade = 1000; // How quickly the brush fades, in pixels (0 = no fade)
|
||||
this.numBristles = 0; // Number of bristles on each side of the brush.
|
||||
this.bristles = []; // All of the Brush Bristles
|
||||
this.pxPerBristle = 3; // The width of each bristle
|
||||
this.maxA = 1.0; // Maximum beginning opacity
|
||||
this.minA = 0.8; // Minimum beginning opacity
|
||||
this.autoWidth = false; // Whether or not width is based on path touch-box data or manual width value
|
||||
this._width = 0;
|
||||
this.width = 20;
|
||||
},
|
||||
|
||||
// Variables and Methods
|
||||
{
|
||||
|
||||
// The width of the brush, to be approximated using bristles
|
||||
width: {
|
||||
get: function () {
|
||||
return this._width;
|
||||
},
|
||||
set: function (w) {
|
||||
this.numBristles = Math.floor(0.3 * w / this.pxPerBristle);
|
||||
if (this.numBristles <= 0) {
|
||||
this.numBristles = 0;
|
||||
}
|
||||
this._width = (2 * this.numBristles + 1) * this.pxPerBristle;
|
||||
}
|
||||
},
|
||||
|
||||
// Begins rendering the beginning of the path
|
||||
renderStart: function (path, painter) {
|
||||
var ctx = painter.canvas.context;
|
||||
ctx.shadowOffsetX = 0;
|
||||
ctx.shadowOffsetY = 0;
|
||||
ctx.shadowBlur = 0;
|
||||
ctx.globalCompositeOperation = "source-over";
|
||||
ctx.globalAlpha = 1.0;
|
||||
|
||||
var startColor = painter.color.copy();
|
||||
startColor.alpha = this.maxA;
|
||||
ctx.fillStyle = startColor.toString();
|
||||
|
||||
for (var i = -this.numBristles; i <= this.numBristles; i++) {
|
||||
this.bristles[i] = new AppNS.Painter.Tools.Bristle();
|
||||
this.bristles[i].color.fromColor(startColor);
|
||||
this.bristles[i].width = this.pxPerBristle + 0.5;
|
||||
}
|
||||
},
|
||||
|
||||
// Renders the given path using the current Marker style
|
||||
render: function (path, painter) {
|
||||
var ctx = painter.canvas.context;
|
||||
|
||||
// If just starting the path, draw semicircle
|
||||
if (path.starting) {
|
||||
path.calculateStartCurve(this.width / 2, this.width / 2, 3, this.width);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(path.pStart.x, path.pStart.y);
|
||||
ctx.bezierCurveTo(path.cpStart.x, path.cpStart.y, path.cpEnd.x, path.cpEnd.y, path.pEnd.x, path.pEnd.y);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
if (path.drawable) {
|
||||
|
||||
// Colors
|
||||
var blendColor = new AppNS.Painter.Graphics.Color();
|
||||
var oldColor = new AppNS.Painter.Graphics.Color();
|
||||
|
||||
// Draw each simulated bristle as a bezier curve
|
||||
for (var i = -this.numBristles; i <= this.numBristles; i++) {
|
||||
// The color at the beginning of the stroke segment
|
||||
oldColor.fromColor(this.bristles[i].color);
|
||||
|
||||
var offsetStart = i * this.pxPerBristle;
|
||||
var offsetEnd = i * this.pxPerBristle;
|
||||
path.calculateBezier(offsetStart, offsetEnd, Math.pow(oldColor.alpha, 2) * 0.25);
|
||||
|
||||
// Blend bristle's color with canvas color
|
||||
if (this.blends) {
|
||||
painter.canvas.getColorAt(blendColor, path.cpStart.x, path.cpStart.y);
|
||||
this.bristles[i].color.blendWith(blendColor);
|
||||
}
|
||||
|
||||
// Update opacity
|
||||
var currA = this.bristles[i].color.alpha;
|
||||
var perturb = 0;
|
||||
if (this.fade) { // Cause the brush to lose ink over distance
|
||||
perturb = Math.random() * -(Math.pow(0.2 * i / (this.numBristles + 1), 4) + path.dist / this.fade);
|
||||
currA = currA + perturb;
|
||||
} else { // Cause the brush to randomly gain or lose ink per bristle, within minA and maxA
|
||||
currA = Math.random() * (this.maxA - this.minA) + this.minA;
|
||||
}
|
||||
this.bristles[i].color.alpha = this.bristles[i].color.clipAlpha(currA);
|
||||
this.bristles[i].width = this.pxPerBristle + Math.pow(oldColor.alpha, 2) * 0.5;
|
||||
|
||||
// Create a linear gradient from the start of the stoke segment to the end,
|
||||
// giving a smooth transition of color.
|
||||
var gradient = ctx.createLinearGradient(path.pStart.x, path.pStart.y, path.pEnd.x, path.pEnd.y);
|
||||
gradient.addColorStop(0, oldColor.toString());
|
||||
gradient.addColorStop(1, this.bristles[i].color.toString());
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(path.pStart.x, path.pStart.y);
|
||||
ctx.bezierCurveTo(path.cpStart.x, path.cpStart.y, path.cpEnd.x, path.cpEnd.y, path.pEnd.x, path.pEnd.y);
|
||||
ctx.lineWidth = this.bristles[i].width;
|
||||
ctx.strokeStyle = gradient;
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Stops the path with the current style
|
||||
renderStop: function (path, painter) {
|
||||
var ctx = painter.canvas.context;
|
||||
|
||||
if (path.created || path.starting) {
|
||||
painter.canvas.drawCircle(path.p3.x, path.p3.y, this.width / 2);
|
||||
} else {
|
||||
// Colors
|
||||
var blendColor = new AppNS.Painter.Graphics.Color();
|
||||
var oldColor = new AppNS.Painter.Graphics.Color();
|
||||
|
||||
// Draw each simulated bristle as a bezier curve
|
||||
for (var i = -this.numBristles; i <= this.numBristles; i++) {
|
||||
var offsetStart = i * this.pxPerBristle;
|
||||
var offsetEnd = i * this.pxPerBristle;
|
||||
path.calculateEndBezier(offsetStart, offsetEnd, 20);
|
||||
|
||||
// The color at the beginning of the stroke segment
|
||||
oldColor.fromColor(this.bristles[i].color);
|
||||
|
||||
// Blend bristle's color with canvas color
|
||||
if (this.blends) {
|
||||
painter.canvas.getColorAt(blendColor, path.cpStart.x, path.cpStart.y);
|
||||
this.bristles[i].color.blendWith(blendColor);
|
||||
}
|
||||
|
||||
// Update opacity
|
||||
this.bristles[i].color.alpha = 0;
|
||||
|
||||
// Create a linear gradient from the start of the stoke segment to the end,
|
||||
// giving a smooth transition of color.
|
||||
var gradient = ctx.createLinearGradient(path.pStart.x, path.pStart.y, path.pEnd.x, path.pEnd.y);
|
||||
gradient.addColorStop(0, oldColor.toString());
|
||||
gradient.addColorStop(1, this.bristles[i].color.toString());
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(path.pStart.x, path.pStart.y);
|
||||
ctx.bezierCurveTo(path.cpStart.x, path.cpStart.y, path.cpEnd.x, path.cpEnd.y, path.pEnd.x, path.pEnd.y);
|
||||
ctx.lineWidth = this.bristles[i].width;
|
||||
ctx.strokeStyle = gradient;
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
WinJS.Namespace.defineWithParent(AppNS, "Painter.Tools", {
|
||||
Brush: Brush
|
||||
});
|
||||
|
||||
})(Microsoft.Paint);
|
||||
146
Controls/Paint/Tools/Crayon.js
Normal file
146
Controls/Paint/Tools/Crayon.js
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
//// © Microsoft. All rights reserved. ////
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
(function (AppNS) {
|
||||
'use strict';
|
||||
|
||||
// The crayon tool uses textures to generate a crayon/pencil/chalk like effect
|
||||
var Crayon = WinJS.Class.define(
|
||||
|
||||
// Constructor
|
||||
function () {
|
||||
this._density = 0.5; // The default density is 50% color
|
||||
this._color = new AppNS.Painter.Graphics.Color(0,0,0,255);
|
||||
this.autoWidth = false; // Whether or not width is based on path touch-box data or manual width value
|
||||
this.width = 30; // The default line manual width
|
||||
this.texture = null;
|
||||
},
|
||||
|
||||
// Variables and Methods
|
||||
{
|
||||
|
||||
density: {
|
||||
get: function () {
|
||||
return this._density;
|
||||
},
|
||||
set: function (d) {
|
||||
this._density = d;
|
||||
if (this.texture) {
|
||||
this.texture.update(this._color, this._density);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Starts rendering the given path using the current style
|
||||
renderStart: function (path, painter) {
|
||||
var ctx = painter.canvas.context;
|
||||
ctx.fillStyle = this.texture.texturePattern;
|
||||
ctx.shadowOffsetX = 0;
|
||||
ctx.shadowOffsetY = 0;
|
||||
ctx.shadowBlur = 0;
|
||||
ctx.globalCompositeOperation = "source-over";
|
||||
ctx.globalAlpha = 1.0;
|
||||
},
|
||||
|
||||
// Renders the given path using the current style
|
||||
render: function (path, painter) {
|
||||
var ctx = painter.canvas.context;
|
||||
|
||||
// Get start and end widths for the stroke part
|
||||
var wStart = this.width;
|
||||
var wEnd = this.width;
|
||||
if (this.autoWidth){
|
||||
path.calculateWidth();
|
||||
wStart = path.wStart;
|
||||
wEnd = path.wEnd;
|
||||
}
|
||||
|
||||
// If just starting the path, draw semicircle
|
||||
if (path.starting) {
|
||||
path.calculateStartCurve(wEnd / 2, wEnd / 2, 3, wEnd);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(path.pStart.x, path.pStart.y);
|
||||
ctx.bezierCurveTo(path.cpStart.x, path.cpStart.y, path.cpEnd.x, path.cpEnd.y, path.pEnd.x, path.pEnd.y);
|
||||
ctx.closePath();
|
||||
this.fillCrayon(ctx);
|
||||
}
|
||||
|
||||
if (path.drawable) {
|
||||
|
||||
// Start at first point of shape, then bezier to second
|
||||
ctx.beginPath();
|
||||
path.calculateBezier(wStart / 2, wEnd / 2);
|
||||
ctx.moveTo(path.pStart.x, path.pStart.y);
|
||||
ctx.bezierCurveTo(path.cpStart.x, path.cpStart.y, path.cpEnd.x, path.cpEnd.y, path.pEnd.x, path.pEnd.y);
|
||||
|
||||
// Line to third point of shape, then bezier to fourth, then close the path
|
||||
path.calculateBezier(-1 * wStart / 2, -1 * wEnd / 2);
|
||||
ctx.lineTo(path.pEnd.x, path.pEnd.y);
|
||||
ctx.bezierCurveTo(path.cpEnd.x, path.cpEnd.y, path.cpStart.x, path.cpStart.y, path.pStart.x, path.pStart.y);
|
||||
ctx.closePath();
|
||||
|
||||
// Set fill Style and fill shape
|
||||
this.fillCrayon(ctx);
|
||||
}
|
||||
},
|
||||
|
||||
// Renders the end of the path with the current style
|
||||
renderStop: function (path, painter) {
|
||||
var ctx = painter.canvas.context;
|
||||
|
||||
// Get start and end widths for the stroke part
|
||||
var wStart = this.width;
|
||||
var wEnd = this.width;
|
||||
if (this.autoWidth){
|
||||
path.calculateWidth();
|
||||
wStart = path.wStart;
|
||||
wEnd = path.wEnd;
|
||||
}
|
||||
|
||||
// If haven't drawn starting effect yet
|
||||
if (path.created || path.starting) {
|
||||
ctx.beginPath();
|
||||
ctx.arc(path.p3.x, path.p3.y, wEnd / 2, 0, Math.PI * 2, true);
|
||||
ctx.closePath();
|
||||
this.fillCrayon(ctx);
|
||||
} else { // Otherwise, draw a curve to end the path
|
||||
path.calculateStopCurve(wEnd / 2, wEnd / 2, 3, wEnd);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(path.pStart.x, path.pStart.y);
|
||||
ctx.bezierCurveTo(path.cpStart.x, path.cpStart.y, path.cpEnd.x, path.cpEnd.y, path.pEnd.x, path.pEnd.y);
|
||||
ctx.closePath();
|
||||
this.fillCrayon(ctx);
|
||||
}
|
||||
},
|
||||
|
||||
fillCrayon: function (ctx) {
|
||||
// Set fill Style and fill shape
|
||||
ctx.fillStyle = this.texturePattern;
|
||||
ctx.save();
|
||||
var rand = Math.random();
|
||||
ctx.rotate(rand * 2 * Math.PI);
|
||||
ctx.translate(rand * 10, rand * 10);
|
||||
ctx.fill();
|
||||
ctx.restore();
|
||||
},
|
||||
|
||||
update: function (painter) {
|
||||
this._color = painter.color.copy();
|
||||
if (this.texture) {
|
||||
this.texture.update(this._color, this._density);
|
||||
}
|
||||
},
|
||||
|
||||
setTexture: function (textureImage) {
|
||||
this.texture = new AppNS.Painter.Graphics.Texture(textureImage);
|
||||
this.texture.update(this._color, this._density);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
WinJS.Namespace.defineWithParent(AppNS, "Painter.Tools", {
|
||||
Crayon: Crayon
|
||||
});
|
||||
|
||||
})(Microsoft.Paint);
|
||||
101
Controls/Paint/Tools/Eraser.js
Normal file
101
Controls/Paint/Tools/Eraser.js
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
//// © Microsoft. All rights reserved. ////
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
(function (AppNS) {
|
||||
'use strict';
|
||||
|
||||
// The Marker tool is the simplest tool.
|
||||
// It simply connect users points smoothly with a solid color, usually slightly transparent.
|
||||
var Eraser = WinJS.Class.define(
|
||||
|
||||
// Constructor
|
||||
function () {
|
||||
this.autoWidth = false; // Whether or not width is based on path touch-box data or manual width value
|
||||
this.width = 20; // The default line manual width
|
||||
},
|
||||
|
||||
// Variables and Methods
|
||||
{
|
||||
|
||||
// Begins rendering the beginning of the path
|
||||
renderStart: function (path, painter) {
|
||||
var ctx = painter.canvas.context;
|
||||
ctx.shadowOffsetX = 0;
|
||||
ctx.shadowOffsetY = 0;
|
||||
ctx.shadowBlur = 0;
|
||||
ctx.globalCompositeOperation = "destination-out";
|
||||
ctx.globalAlpha = 1;
|
||||
ctx.fillStyle = "rgba(0,0,0,1)";
|
||||
|
||||
// Start effect
|
||||
var x = path.p3.x;
|
||||
var y = path.p3.y;
|
||||
painter.canvas.drawCircle(x, y, this.width / 2);
|
||||
},
|
||||
|
||||
// Renders the given path using the current Marker style
|
||||
render: function (path, painter) {
|
||||
if (path.drawable) {
|
||||
var ctx = painter.canvas.context;
|
||||
|
||||
// Get start and end widths for the stroke part
|
||||
var wStart = this.width;
|
||||
var wEnd = this.width;
|
||||
if (this.autoWidth) {
|
||||
path.calculateWidth();
|
||||
wStart = path.wStart;
|
||||
wEnd = path.wEnd;
|
||||
}
|
||||
|
||||
// Start at first point of shape, then bezier to second
|
||||
ctx.beginPath();
|
||||
path.calculateBezier(wStart / 2, wEnd / 2, 0.5);
|
||||
ctx.moveTo(path.pStart.x, path.pStart.y);
|
||||
ctx.bezierCurveTo(path.cpStart.x, path.cpStart.y, path.cpEnd.x, path.cpEnd.y, path.pEnd.x, path.pEnd.y);
|
||||
|
||||
// Line to third point of shape, then bezier to fourth, then close the path
|
||||
path.calculateBezier(-1 * wStart / 2, -1 * wEnd / 2, 0.5);
|
||||
ctx.lineTo(path.pEnd.x, path.pEnd.y);
|
||||
ctx.bezierCurveTo(path.cpEnd.x, path.cpEnd.y, path.cpStart.x, path.cpStart.y, path.pStart.x, path.pStart.y);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
}
|
||||
},
|
||||
|
||||
// Begins rendering the beginning of the path
|
||||
renderStop: function (path, painter) {
|
||||
var ctx = painter.canvas.context;
|
||||
|
||||
// Get start and end widths for the stroke part
|
||||
var wStart = this.width;
|
||||
var wEnd = this.width;
|
||||
if (this.autoWidth){
|
||||
path.calculateWidth();
|
||||
wStart = path.wStart;
|
||||
wEnd = path.wEnd;
|
||||
}
|
||||
|
||||
// Start at first point of shape, then bezier to second
|
||||
ctx.beginPath();
|
||||
path.calculateEndBezier(wStart / 2, wEnd / 2);
|
||||
ctx.moveTo(path.pStart.x, path.pStart.y);
|
||||
ctx.bezierCurveTo(path.cpStart.x, path.cpStart.y, path.cpEnd.x, path.cpEnd.y, path.pEnd.x, path.pEnd.y);
|
||||
|
||||
// Line to third point of shape, then bezier to fourth, then close the path
|
||||
path.calculateEndBezier(-1 * wStart / 2, -1 * wEnd / 2);
|
||||
ctx.lineTo(path.pEnd.x, path.pEnd.y);
|
||||
ctx.bezierCurveTo(path.cpEnd.x, path.cpEnd.y, path.cpStart.x, path.cpStart.y, path.pStart.x, path.pStart.y);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
|
||||
painter.canvas.drawCircle(path.p3.x, path.p3.y, this.width / 2);
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
WinJS.Namespace.defineWithParent(AppNS, "Painter.Tools", {
|
||||
Eraser: Eraser
|
||||
});
|
||||
|
||||
})(Microsoft.Paint);
|
||||
108
Controls/Paint/Tools/Marker.js
Normal file
108
Controls/Paint/Tools/Marker.js
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
//// © Microsoft. All rights reserved. ////
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
(function (AppNS) {
|
||||
'use strict';
|
||||
|
||||
// The Marker tool is the simplest tool.
|
||||
// It simply connect users points smoothly with a solid color, usually slightly transparent.
|
||||
var Marker = WinJS.Class.define(
|
||||
|
||||
// Constructor
|
||||
function () {
|
||||
this.opacity = 0.85; // The default opacity is 85%
|
||||
this.autoWidth = false; // Whether or not width is based on path touch-box data or manual width value
|
||||
this.width = 30; // The default line manual width is 1px
|
||||
},
|
||||
|
||||
// Variables and Methods
|
||||
{
|
||||
|
||||
// Renders the beginning of the path
|
||||
renderStart: function (path, painter) {
|
||||
var ctx = painter.canvas.context;
|
||||
ctx.shadowOffsetX = 0;
|
||||
ctx.shadowOffsetY = 0;
|
||||
ctx.shadowBlur = 0;
|
||||
ctx.globalCompositeOperation = "source-over";
|
||||
ctx.globalAlpha = this.opacity;
|
||||
ctx.fillStyle = painter.color.toString();
|
||||
},
|
||||
|
||||
// Renders the given path using the current Marker style
|
||||
render: function (path, painter) {
|
||||
var ctx = painter.canvas.context;
|
||||
|
||||
// Get start and end widths for the stroke part
|
||||
var wStart = this.width;
|
||||
var wEnd = this.width;
|
||||
if (this.autoWidth){
|
||||
path.calculateWidth();
|
||||
wStart = path.wStart;
|
||||
wEnd = path.wEnd;
|
||||
}
|
||||
|
||||
// If just starting the path, draw semicircle
|
||||
if (path.starting) {
|
||||
path.calculateStartCurve(wEnd / 2, wEnd / 2, 3, wEnd, Math.pow(this.opacity, 2) * 0.22);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(path.pStart.x, path.pStart.y);
|
||||
ctx.bezierCurveTo(path.cpStart.x, path.cpStart.y, path.cpEnd.x, path.cpEnd.y, path.pEnd.x, path.pEnd.y);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
if (path.drawable) {
|
||||
|
||||
// Start at first point of shape, then bezier to second
|
||||
ctx.beginPath();
|
||||
path.calculateBezier(wStart / 2, wEnd / 2, Math.pow(this.opacity, 2) * 0.22);
|
||||
ctx.moveTo(path.pStart.x, path.pStart.y);
|
||||
ctx.bezierCurveTo(path.cpStart.x, path.cpStart.y, path.cpEnd.x, path.cpEnd.y, path.pEnd.x, path.pEnd.y);
|
||||
|
||||
// Line to third point of shape, then bezier to fourth, then close the path
|
||||
path.calculateBezier(-1 * wStart / 2, -1 * wEnd / 2, Math.pow(this.opacity, 2) * 0.22);
|
||||
ctx.lineTo(path.pEnd.x, path.pEnd.y);
|
||||
ctx.bezierCurveTo(path.cpEnd.x, path.cpEnd.y, path.cpStart.x, path.cpStart.y, path.pStart.x, path.pStart.y);
|
||||
ctx.closePath();
|
||||
|
||||
// Set fill Style and fill shape
|
||||
ctx.fill();
|
||||
}
|
||||
},
|
||||
|
||||
// Renders the end of the path with the current style
|
||||
renderStop: function (path, painter) {
|
||||
var ctx = painter.canvas.context;
|
||||
|
||||
// Get start and end widths for the stroke part
|
||||
var wStart = this.width;
|
||||
var wEnd = this.width;
|
||||
if (this.autoWidth){
|
||||
path.calculateWidth();
|
||||
wStart = path.wStart;
|
||||
wEnd = path.wEnd;
|
||||
}
|
||||
|
||||
// If haven't drawn starting effect yet
|
||||
if (path.created || path.starting) {
|
||||
painter.canvas.drawCircle(path.p3.x, path.p3.y, wEnd / 2);
|
||||
} else {
|
||||
// Otherwise, draw a curve to end the path
|
||||
path.calculateStopCurve(wEnd / 2, wEnd / 2, 3, wEnd, Math.pow(this.opacity, 2) * 0.22);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(path.pStart.x, path.pStart.y);
|
||||
ctx.bezierCurveTo(path.cpStart.x, path.cpStart.y, path.cpEnd.x, path.cpEnd.y, path.pEnd.x, path.pEnd.y);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
WinJS.Namespace.defineWithParent(AppNS, "Painter.Tools", {
|
||||
Marker: Marker
|
||||
});
|
||||
|
||||
})(Microsoft.Paint);
|
||||
105
Controls/Paint/Tools/Neon.js
Normal file
105
Controls/Paint/Tools/Neon.js
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
//// © Microsoft. All rights reserved. ////
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
(function (AppNS) {
|
||||
'use strict';
|
||||
|
||||
// The Neon tool has a glow effect
|
||||
var Neon = WinJS.Class.define(
|
||||
|
||||
// Constructor
|
||||
function () {
|
||||
this.autoWidth = false; // Whether or not width is based on path touch-box data or manual width value
|
||||
this.width = 20; // The default line manual width
|
||||
this.glow = 20; // The amount of shadow blur used to generate the glow
|
||||
},
|
||||
|
||||
// Variables and Methods
|
||||
{
|
||||
// Begins rendering the beginning of the path
|
||||
renderStart: function (path, painter) {
|
||||
var ctx = painter.canvas.context;
|
||||
ctx.fillStyle = painter.color.toString();
|
||||
ctx.shadowColor = painter.color.toString();
|
||||
ctx.shadowOffsetX = 0;
|
||||
ctx.shadowOffsetY = 0;
|
||||
ctx.shadowBlur = this.glow;
|
||||
ctx.globalCompositeOperation = "source-over";
|
||||
ctx.globalAlpha = 1.0;
|
||||
},
|
||||
|
||||
// Renders the given path using the current style
|
||||
render: function (path, painter) {
|
||||
var ctx = painter.canvas.context;
|
||||
|
||||
// Get start and end widths for the stroke part
|
||||
var wStart = this.width;
|
||||
var wEnd = this.width;
|
||||
if (this.autoWidth) {
|
||||
path.calculateWidth();
|
||||
wStart = path.wStart;
|
||||
wEnd = path.wEnd;
|
||||
}
|
||||
|
||||
|
||||
// If just starting the path, draw semicircle
|
||||
if (path.starting) {
|
||||
path.calculateStartCurve(wEnd / 2, wEnd / 2, 3, wEnd);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(path.pStart.x, path.pStart.y);
|
||||
ctx.bezierCurveTo(path.cpStart.x, path.cpStart.y, path.cpEnd.x, path.cpEnd.y, path.pEnd.x, path.pEnd.y);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
if (path.drawable) {
|
||||
// Start at first point of shape, then bezier to second
|
||||
ctx.beginPath();
|
||||
path.calculateBezier(wStart / 2, wEnd / 2, 0.5);
|
||||
ctx.moveTo(path.pStart.x, path.pStart.y);
|
||||
ctx.bezierCurveTo(path.cpStart.x, path.cpStart.y, path.cpEnd.x, path.cpEnd.y, path.pEnd.x, path.pEnd.y);
|
||||
|
||||
// Line to third point of shape, then bezier to fourth, then close the path
|
||||
path.calculateBezier(-wStart / 2, -wEnd / 2, 0.5);
|
||||
ctx.lineTo(path.pEnd.x, path.pEnd.y);
|
||||
ctx.bezierCurveTo(path.cpEnd.x, path.cpEnd.y, path.cpStart.x, path.cpStart.y, path.pStart.x, path.pStart.y);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
}
|
||||
},
|
||||
|
||||
// Renders the end of the path with the current style
|
||||
renderStop: function (path, painter) {
|
||||
var ctx = painter.canvas.context;
|
||||
|
||||
// Get start and end widths for the stroke part
|
||||
var wStart = this.width;
|
||||
var wEnd = this.width;
|
||||
if (this.autoWidth){
|
||||
path.calculateWidth();
|
||||
wStart = path.wStart;
|
||||
wEnd = path.wEnd;
|
||||
}
|
||||
|
||||
// If haven't drawn starting effect yet
|
||||
if (path.created || path.starting) {
|
||||
painter.canvas.drawCircle(path.p3.x, path.p3.y, wEnd / 2);
|
||||
} else {
|
||||
// Otherwise, draw a curve to end the path
|
||||
path.calculateStopCurve(wEnd / 2, wEnd / 2, 3, wEnd);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(path.pStart.x, path.pStart.y);
|
||||
ctx.bezierCurveTo(path.cpStart.x, path.cpStart.y, path.cpEnd.x, path.cpEnd.y, path.pEnd.x, path.pEnd.y);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
WinJS.Namespace.defineWithParent(AppNS, "Painter.Tools", {
|
||||
Neon: Neon
|
||||
});
|
||||
|
||||
})(Microsoft.Paint);
|
||||
221
Controls/Paint/Tools/Pipe.js
Normal file
221
Controls/Paint/Tools/Pipe.js
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
//// © Microsoft. All rights reserved. ////
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
(function (AppNS) {
|
||||
'use strict';
|
||||
|
||||
// The Pipe tool has a 3D look to it
|
||||
var Pipe = WinJS.Class.define(
|
||||
|
||||
// Constructor
|
||||
function () {
|
||||
this.autoWidth = false; // Whether or not width is based on path touch-box data or manual width value
|
||||
this.width = 20; // The default line manual width
|
||||
this.height = 6; // The 'height' of the 3D pipe look, in pixels
|
||||
this.maxHeight = 6;
|
||||
this.numBristles = 0; // Number of bristles on each side of the pipe
|
||||
this.bristles = []; // All of the pipe bristles
|
||||
this.pxPerBristle = 1; // The width of each bristle in pixels
|
||||
this.middleBristle = new AppNS.Painter.Tools.Bristle();
|
||||
},
|
||||
|
||||
// Variables and Methods
|
||||
{
|
||||
|
||||
// Begins rendering the beginning of the path
|
||||
renderStart: function (path, painter) {
|
||||
var color = new AppNS.Painter.Graphics.Color();
|
||||
color.fromColor(painter.color);
|
||||
|
||||
// If the color is dark, we lighten it
|
||||
if (color.red + color.green + color.blue < 255 * 3 / 2) {
|
||||
color.lighten(0.2);
|
||||
}
|
||||
|
||||
// Inner Bristles
|
||||
this.numBristles = Math.floor(0.25 * this.width / this.pxPerBristle);
|
||||
if (this.numBristles <= 0) {
|
||||
this.numBristles = 1;
|
||||
}
|
||||
|
||||
for (var i = 0; i < this.numBristles; i++) {
|
||||
this.bristles[i] = new AppNS.Painter.Tools.Bristle();
|
||||
this.bristles[i].color.fromColor(color);
|
||||
this.bristles[i].color.scale(1 - ((i + 1) / this.numBristles) * (this.height / this.maxHeight));
|
||||
this.bristles[i].width = this.pxPerBristle;
|
||||
}
|
||||
|
||||
// Large inner bristle
|
||||
this.middleBristle.width = this.width - (this.numBristles * this.pxPerBristle * 2);
|
||||
this.middleBristle.color.fromColor(color);
|
||||
|
||||
var ctx = painter.canvas.context;
|
||||
ctx.shadowOffsetX = 0;
|
||||
ctx.shadowOffsetY = 0;
|
||||
ctx.shadowBlur = 0;
|
||||
ctx.globalCompositeOperation = "source-over";
|
||||
ctx.globalAlpha = 1.0;
|
||||
},
|
||||
|
||||
// Renders the given path using the current style
|
||||
render: function (path, painter) {
|
||||
var ctx = painter.canvas.context;
|
||||
|
||||
// Get start and end widths for the stroke part
|
||||
var wStart = this.width;
|
||||
var wEnd = this.width;
|
||||
if (this.autoWidth) {
|
||||
path.calculateWidth();
|
||||
wStart = path.wStart;
|
||||
wEnd = path.wEnd;
|
||||
}
|
||||
|
||||
var outerStart = this.middleBristle.width / 2;
|
||||
var outerEnd = this.middleBristle.width / 2;
|
||||
|
||||
if (path.starting) {
|
||||
|
||||
// Draw each simulated bristle as a bezier curve
|
||||
for (var i = this.numBristles - 1; i >= 0; i--) {
|
||||
var offsetStart = (i + 0.5) * this.pxPerBristle + this.middleBristle.width / 2;
|
||||
var offsetEnd = (i + 0.5) * this.pxPerBristle + this.middleBristle.width / 2;
|
||||
|
||||
ctx.strokeStyle = this.bristles[i].color.toString();
|
||||
ctx.fillStyle = this.bristles[i].color.toString();
|
||||
ctx.lineWidth = this.bristles[i].width;
|
||||
|
||||
// Draw the Bristle
|
||||
path.calculateStartCurve(offsetStart, offsetEnd, 3, wEnd);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(path.pStart.x, path.pStart.y);
|
||||
ctx.bezierCurveTo(path.cpStart.x, path.cpStart.y, path.cpEnd.x, path.cpEnd.y, path.pEnd.x, path.pEnd.y);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
// Draw middle
|
||||
path.calculateStartCurve(this.middleBristle.width / 2, this.middleBristle.width / 2, 3, wEnd);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(path.pStart.x, path.pStart.y);
|
||||
ctx.bezierCurveTo(path.cpStart.x, path.cpStart.y, path.cpEnd.x, path.cpEnd.y, path.pEnd.x, path.pEnd.y);
|
||||
ctx.closePath();
|
||||
ctx.fillStyle = this.middleBristle.color.toString();
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
if (path.drawable) {
|
||||
ctx.lineWidth = this.pxPerBristle + 0.5;
|
||||
|
||||
// Draw each simulated bristle as a bezier curve
|
||||
for (var i = this.numBristles - 1; i >= 0; i--) {
|
||||
var offsetStart = (i + 0.5) * this.pxPerBristle + outerStart;
|
||||
var offsetEnd = (i + 0.5) * this.pxPerBristle + outerEnd;
|
||||
var overlap = 1.5 * (1 - i / this.numBristles);
|
||||
|
||||
// Draw the middle bristle.
|
||||
// Start at first point of shape, then bezier to second.
|
||||
ctx.beginPath();
|
||||
path.calculateBezier(offsetStart, offsetEnd, overlap);
|
||||
ctx.moveTo(path.pStart.x, path.pStart.y);
|
||||
ctx.bezierCurveTo(path.cpStart.x, path.cpStart.y, path.cpEnd.x, path.cpEnd.y, path.pEnd.x, path.pEnd.y);
|
||||
|
||||
// Line to third point of shape, then bezier to fourth, then close the path
|
||||
path.calculateBezier(-offsetStart, -offsetEnd, overlap);
|
||||
ctx.lineTo(path.pEnd.x, path.pEnd.y);
|
||||
ctx.bezierCurveTo(path.cpEnd.x, path.cpEnd.y, path.cpStart.x, path.cpStart.y, path.pStart.x, path.pStart.y);
|
||||
ctx.closePath();
|
||||
|
||||
// Set fill Style and fill shape
|
||||
ctx.fillStyle = this.bristles[i].color.toString();
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
// Draw the middle bristle.
|
||||
// Start at first point of shape, then bezier to second.
|
||||
ctx.beginPath();
|
||||
path.calculateBezier(outerStart, outerEnd, 2);
|
||||
ctx.moveTo(path.pStart.x, path.pStart.y);
|
||||
ctx.bezierCurveTo(path.cpStart.x, path.cpStart.y, path.cpEnd.x, path.cpEnd.y, path.pEnd.x, path.pEnd.y);
|
||||
|
||||
// Line to third point of shape, then bezier to fourth, then close the path
|
||||
path.calculateBezier(-outerStart, -outerEnd, 2);
|
||||
ctx.lineTo(path.pEnd.x, path.pEnd.y);
|
||||
ctx.bezierCurveTo(path.cpEnd.x, path.cpEnd.y, path.cpStart.x, path.cpStart.y, path.pStart.x, path.pStart.y);
|
||||
ctx.closePath();
|
||||
|
||||
// Set fill Style and fill shape
|
||||
ctx.fillStyle = this.middleBristle.color.toString();
|
||||
ctx.fill();
|
||||
}
|
||||
},
|
||||
|
||||
// Renders the end of the path with the current style
|
||||
renderStop: function (path, painter) {
|
||||
var ctx = painter.canvas.context;
|
||||
|
||||
// Get start and end widths for the stroke part
|
||||
var wStart = this.width;
|
||||
var wEnd = this.width;
|
||||
if (this.autoWidth){
|
||||
path.calculateWidth();
|
||||
wStart = path.wStart;
|
||||
wEnd = path.wEnd;
|
||||
}
|
||||
|
||||
// If haven't drawn starting effect yet
|
||||
if (path.created || path.starting) {
|
||||
var x = path.p3.x;
|
||||
var y = path.p3.y;
|
||||
|
||||
// Draw bristles
|
||||
for (var i = this.numBristles - 1; i >= 0; i--) {
|
||||
var radius = (i + 0.5) * this.pxPerBristle + this.middleBristle.width / 2;
|
||||
|
||||
// Draw the Bristle
|
||||
ctx.fillStyle = this.bristles[i].color.toString();
|
||||
painter.canvas.drawCircle(x, y, radius);
|
||||
}
|
||||
|
||||
// Draw middle
|
||||
ctx.fillStyle = this.middleBristle.color.toString();
|
||||
painter.canvas.drawCircle(x, y, this.middleBristle.width / 2);
|
||||
|
||||
} else { // Otherwise, draw a curve to end the path
|
||||
|
||||
// Draw each simulated bristle as a bezier curve
|
||||
for (var i = this.numBristles - 1; i >= 0; i--) {
|
||||
var offsetStart = (i + 0.5) * this.pxPerBristle + this.middleBristle.width / 2;
|
||||
var offsetEnd = (i + 0.5) * this.pxPerBristle + this.middleBristle.width / 2;
|
||||
var overlap = 1.5 * (1 - i / this.numBristles);
|
||||
|
||||
ctx.fillStyle = this.bristles[i].color.toString();
|
||||
ctx.lineWidth = this.bristles[i].width;
|
||||
|
||||
// Draw the Bristle
|
||||
path.calculateStopCurve(offsetStart, offsetEnd, 3, wEnd, overlap);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(path.pStart.x, path.pStart.y);
|
||||
ctx.bezierCurveTo(path.cpStart.x, path.cpStart.y, path.cpEnd.x, path.cpEnd.y, path.pEnd.x, path.pEnd.y);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
// Draw middle
|
||||
path.calculateStopCurve(this.middleBristle.width / 2, this.middleBristle.width / 2, 3, wEnd, 2);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(path.pStart.x, path.pStart.y);
|
||||
ctx.bezierCurveTo(path.cpStart.x, path.cpStart.y, path.cpEnd.x, path.cpEnd.y, path.pEnd.x, path.pEnd.y);
|
||||
ctx.closePath();
|
||||
ctx.fillStyle = this.middleBristle.color.toString();
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
WinJS.Namespace.defineWithParent(AppNS, "Painter.Tools", {
|
||||
Pipe: Pipe
|
||||
});
|
||||
|
||||
})(Microsoft.Paint);
|
||||
Reference in a new issue