Skip to content

Commit df40385

Browse files
committed
initial revision !strict
git-svn-id: http://svn.dojotoolkit.org/src/demos/trunk@27165 560b804f-0ae3-0310-86f3-f6aa0a117693
1 parent f5176f2 commit df40385

File tree

5 files changed

+371
-0
lines changed

5 files changed

+371
-0
lines changed

bezier/README

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
-------------------------------------------------------------------------------
2+
Bezier Playground - An interactive Bezier curve editor
3+
-------------------------------------------------------------------------------
4+
Authors: Patrick Ruzand
5+
-------------------------------------------------------------------------------
6+
Demo description
7+
8+
This demo allows the creation of Bezier curves interactively. It demonstrates
9+
the dojox.gfx Path API and how shapes definition can be dynamically redefined. It
10+
also illustrates how user interaction can be easily handled.
11+
Press the left mouse button to add a new point. Release the button to keep the default control points, or:
12+
Drag the mouse to adjust the control points position.
13+
Double-click to commit the curve.
14+
15+
-------------------------------------------------------------------------------
16+
Dependencies:
17+
18+
Dojo Core (dom, on, mouse)
19+
DojoX Gfx
20+
21+
-------------------------------------------------------------------------------
22+
Installation instructions
23+
24+
Simply run the included demo.html
25+
26+
-------------------------------------------------------------------------------
27+
@rank:752

bezier/demo.css

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
body {
2+
font-family:sans-serif;
3+
}
4+
5+
.canvas {
6+
margin-top:10px;
7+
background-color:#ececec;
8+
border-width:2px;
9+
border-color:gray;
10+
border-style:solid;
11+
-moz-border-radius: 10px;
12+
border-radius: 10px;
13+
width:300px;
14+
height:300px;
15+
display:block;
16+
}
17+
18+
.toolbar{
19+
display:inline-block;
20+
width:80px;
21+
22+
}
23+
24+
p, ul, li {
25+
font-size:10pt;
26+
margin-bottom:2px;
27+
margin-top:2px;
28+
}
29+
input {
30+
-webkit-user-select: none;
31+
}

bezier/demo.html

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
2+
"http://www.w3.org/TR/html4/strict.dtd">
3+
<html>
4+
<head>
5+
<title>GFX Bezier Playground</title>
6+
<link rel="stylesheet" href="demo.css">
7+
<script type="text/javascript" src="../../dojo/dojo.js" charset="utf-8" djConfig="isDebug: true, async:true"></script>
8+
<script type="text/javascript" src="src.js" charset="utf-8"></script>
9+
</head>
10+
<body>
11+
<h1>GFX Bezier Playground Demo</h1>
12+
<p>
13+
Instructions:
14+
<ul>
15+
<li>Press the left mouse button to add a new point. Release the button to keep the default control points, or:</li>
16+
<li>Drag the mouse to adjust the control points position.</li>
17+
<li>Double-click to commit the curve.</li>
18+
</ul>
19+
</p>
20+
<div id="surface" class="canvas">
21+
</div>
22+
<div id="controls" class="toolbar">
23+
<input type="button" value="Clear" id="clear"/>
24+
</div>
25+
</body>
26+
</html>

bezier/demo.profile.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
dependencies = {
2+
layers: [
3+
{
4+
name: "../demos/bezier/src.js",
5+
resourceName: "demos.bezier.src",
6+
dependencies: [
7+
"demos.bezier.src"
8+
]
9+
}
10+
],
11+
12+
prefixes: [
13+
[ "dijit", "../dijit" ],
14+
[ "dojox", "../dojox" ],
15+
[ "demos", "../demos" ]
16+
]
17+
}

bezier/src.js

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
require([
2+
"dojo/ready",
3+
"dojo/on",
4+
"dojo/dom",
5+
"dojo/dom-geometry",
6+
"dojo/mouse",
7+
"dojo/_base/array",
8+
"dojo/_base/event",
9+
"dojox/gfx",
10+
"dojox/gfx/matrix",
11+
"dojox/gfx/utils",
12+
"dojox/gfx/Moveable"],
13+
function(ready, on, dom, domgeom, mouse, array, event, gfx, matrix, gutils, Moveable){
14+
15+
var surface, surfacePos, _dragging, _size, _points, _ptMarker, _ctrl1, _ctrl2, _lastX, _lastY, _ghost;
16+
17+
function _addPoint(p){
18+
if(_size > 1){
19+
_points[(++_size) - 1] = p;
20+
_points[(++_size) - 1] = p;
21+
_points[(++_size) - 1] = p;
22+
}else{
23+
_points[(++_size) - 1] = p; // start point
24+
_points[(++_size) - 1] = p; // start point
25+
}
26+
};
27+
function _react(p){
28+
if(_size > 3){
29+
// Updates the position of the control point.
30+
var prevp = _size - 3; // previous left handle
31+
var pivot = _size - 2; // previous end point
32+
_points[prevp] = _symmetric(_points[pivot], p);
33+
}
34+
};
35+
function toPos(e){
36+
return{
37+
x: e.pageX - surfacePos.x,
38+
y: e.pageY - surfacePos.y
39+
}
40+
};
41+
function onMouseDown(e){
42+
if(mouse.isLeft(e) && (_lastX !== e.clientX || _lastY !== e.clientY)){
43+
_dragging = true;
44+
_lastX = e.clientX;
45+
_lastY = e.clientY;
46+
if(!_points){
47+
_points = [];
48+
_size = 0;
49+
}
50+
var p = toPos(e);
51+
// Add the new point
52+
_addPoint(p);
53+
// ... and compute the control points
54+
_react(p);
55+
// update ghost
56+
_points[_size - 1] = p;
57+
addNewCurve();
58+
updateMarkerPos(p);
59+
event.stop(e);
60+
}
61+
};
62+
function onMouseMove(e){
63+
if(_size > 0 && _dragging){
64+
var p = toPos(e);
65+
if(_size == 1){
66+
// If user is dragging the starting point, add the second point.
67+
_addPoint(p);
68+
// and compute the control points
69+
_react(p);
70+
}else{
71+
// computes the control points position
72+
_react(p);
73+
_points[_size - 1] = p;
74+
}
75+
// update ghost
76+
updateCurveGhostPoints();
77+
event.stop(e);
78+
}
79+
};
80+
function onMouseUp(e){
81+
_dragging = false;
82+
};
83+
function onDoubleClick(e){
84+
if(_points != null){
85+
// Commit the action.
86+
commit(true);
87+
reset();
88+
event.stop(e);
89+
}
90+
};
91+
function _symmetric(pivot, p){
92+
return{
93+
"x": pivot.x - (p.x - pivot.x),
94+
"y": pivot.y - (p.y - pivot.y)
95+
};
96+
};
97+
98+
function reset(){
99+
_points = null;
100+
_size = 0;
101+
_dragging = false;
102+
_clearGhosts();
103+
_curveCount = 0;
104+
};
105+
function _clearGhosts(){
106+
_ctrl1.removeShape();
107+
_ctrl2.removeShape();
108+
_ptMarker.removeShape();
109+
_ctrlLine.removeShape();
110+
};
111+
function commit(slice){
112+
_ghost.setStroke({width:2, color: "black"});
113+
// remove last point added by dbl click
114+
if(slice){
115+
var val = _ghost.getShape().path;
116+
val = val.slice(0, val.lastIndexOf("C"));
117+
_ghost.setShape(val);
118+
}
119+
createGhost();
120+
};
121+
function createGhost(){
122+
_ghost = surface.createPath().setStroke({width: 2, color: "red"});
123+
};
124+
function initSurface(){
125+
surfacePos = domgeom.position(surface.rawNode, true);
126+
127+
on(dom.byId("surface"), "mousedown", onMouseDown);
128+
on(dom.byId("surface"), "mousemove", onMouseMove);
129+
on(dom.byId("surface"), "mouseup", onMouseUp);
130+
on(dom.byId("surface"), "dblclick", onDoubleClick);
131+
_ptMarker = surface.createCircle({
132+
r: 3
133+
}).setFill("black").removeShape();
134+
_ctrl1 = createControlPt().removeShape();
135+
_ctrl2 = createControlPt().removeShape();
136+
_ctrlLine = surface.createLine().setStroke({
137+
style: "dash",
138+
color: "black"
139+
}).removeShape();
140+
createGhost();
141+
};
142+
function createControlPt(){
143+
var ctrl = surface.createRect({
144+
width: 11,
145+
height: 11
146+
}).setStroke({
147+
width: 1,
148+
color: "black"
149+
});
150+
return ctrl;
151+
};
152+
function updateMarkerPos(p){
153+
surface.add(_ptMarker);
154+
_ptMarker.setShape({
155+
cx: p.x,
156+
cy: p.y
157+
});
158+
};
159+
function updateCurveGhostPoints(){
160+
var p;
161+
if(_curveCount > 0){
162+
var val, curveElt = _ghost.segments[2 * _curveCount - 1],
163+
i = (_curveCount - 1) * 3,
164+
x1 = _points[i].x,
165+
y1 = _points[i].y,
166+
x2 = _points[i + 3].x,
167+
y2 = _points[i + 3].y,
168+
c1x = _points[i + 1].x,
169+
c1y = _points[i + 1].y,
170+
c2x = _points[i + 2].x,
171+
c2y = _points[i + 2].y,
172+
cPt = {'x': c2x, 'y': c2y},
173+
to = {'x': x2, 'y': y2},
174+
s = ['C'];
175+
s.push(c1x);
176+
s.push(',');
177+
s.push(c1y);
178+
s.push(' ');
179+
s.push(c2x);
180+
s.push(',');
181+
s.push(c2y);
182+
s.push(' ');
183+
s.push(x2);
184+
s.push(',');
185+
s.push(y2);
186+
// remove the current curve (the last one in the path def)
187+
val = _ghost.getShape().path;
188+
// and add the updated curve
189+
val = val.slice(0, val.lastIndexOf("C")) + s.join("");
190+
_ghost.setShape(val);
191+
// ensure they are visible
192+
checkParented(_ctrl1, _ctrl2, _ctrlLine);
193+
// update control points markers
194+
p = _symmetric(to, cPt);
195+
x1 = cPt.x - 6;
196+
y1 = cPt.y - 6;
197+
x2 = p.x - 6;
198+
y2 = p.y - 6;
199+
_ctrl2.setShape({
200+
x: x1,
201+
y: y1
202+
});
203+
_ctrl1.setShape({
204+
x: x2,
205+
y: y2
206+
});
207+
_ctrlLine.setShape({
208+
x1: x1 + 5,
209+
y1: y1 + 5,
210+
x2: x2 + 5,
211+
y2: y2 + 5
212+
})
213+
} else if (_size > 1) {
214+
checkParented(_ctrl1, _ctrl2, _ctrlLine);
215+
p = {
216+
x: _points[1].x,
217+
y: _points[1].y
218+
};
219+
var p2 = _symmetric(_points[0], p);
220+
p.x -= 6;
221+
p.y -= 6;
222+
p2.x -= 6;
223+
p2.y -= 6;
224+
_ctrl1.setShape(p);
225+
_ctrl2.setShape(p2);
226+
_ctrlLine.setShape({
227+
x1: p.x + 5,
228+
y1: p.y + 5,
229+
x2: p2.x + 5,
230+
y2: p2.y + 5
231+
})
232+
}
233+
};
234+
function checkParented(){
235+
array.forEach(arguments, function(s){
236+
if(!s.getParent()){
237+
surface.add(s);
238+
}});
239+
};
240+
function addNewCurve(){
241+
if (_size > 4) {
242+
var i = _size - 4 - 1;
243+
var x1 = _points[i].x;
244+
var y1 = _points[i].y;
245+
var x2 = _points[i + 3].x;
246+
var y2 = _points[i + 3].y;
247+
var c1x = _points[i + 1].x;
248+
var c1y = _points[i + 1].y;
249+
var c2x = _points[i + 2].x;
250+
var c2y = _points[i + 2].y;
251+
if (_curveCount++ === 0) {
252+
_ghost.moveTo(x1, y1);
253+
}
254+
_ghost.curveTo(c1x, c1y, c2x, c2y, x2, y2);
255+
}
256+
};
257+
258+
ready(function(){
259+
var box = domgeom.getContentBox(dom.byId("surface"));
260+
surface = gfx.createSurface("surface", box.width, box.height);
261+
initSurface();
262+
reset();
263+
264+
on(dom.byId("clear"), "click", function(){
265+
surface.clear();
266+
reset();
267+
createGhost();
268+
});
269+
});
270+
});

0 commit comments

Comments
 (0)