JSDM

HTML

2
 
1
        <canvas id="drawing_canvas"></canvas>
2

CSS

xxxxxxxxxx
16
 
1
body {
2
    background-color: #222;
3
    margin: 0;
4
}
5
6
#drawing_canvas {
7
    position: absolute;
8
    margin: auto;
9
    width: 512px;
10
    height: 512px;
11
    top: 0;
12
    bottom: 0;
13
    left: 0;
14
    right: 0;
15
    border: 1px solid #555
16
}
? ?
? ?
必须是有效的URL
+ 添加另一个资源

JS

212
 
1
// canvas settings
2
var viewWidth = 512,
3
    viewHeight = 512,
4
    centerX = viewWidth * 0.5,
5
    centerY = viewHeight * 0.5,
6
    drawingCanvas = document.getElementById("drawing_canvas"),
7
    ctx,
8
    timeStep = (1/30),
9
    time = 0;
10
11
var ribbon,
12
    frontGradient,
13
    backGradient;
14
15
function initDrawingCanvas() {
16
    drawingCanvas.width = viewWidth;
17
    drawingCanvas.height = viewHeight;
18
    ctx = drawingCanvas.getContext('2d');
19
20
    ctx.translate(0.5, 0.5);
21
22
    frontGradient = ctx.createLinearGradient(0, 0, viewWidth, 0);
23
    frontGradient.addColorStop(0.0, '#999');
24
    frontGradient.addColorStop(0.5, '#fff');
25
    frontGradient.addColorStop(1.0, '#999');
26
27
    backGradient = ctx.createLinearGradient(0, 0, viewWidth, 0);
28
    backGradient.addColorStop(0.0, '#555');
29
    backGradient.addColorStop(0.5, '#777');
30
    backGradient.addColorStop(1.0, '#555');
31
}
32
33
function initCurves() {
34
35
    var curves = [],
36
        rotations = 12,
37
        dy = (viewHeight + 84) / rotations;
38
39
    for (var i = 0; i <= rotations; i++) {
40
        var c,
41
            startX = centerX,
42
            startY = viewHeight - dy * i + 84,
43
            controlX = (i % 2) * viewWidth,
44
            controlY = startY;
45
46
        c = new Curve(
47
            new Point(startX, startY),
48
            new Point(controlX, controlY),
49
            new Point(controlX, controlY - dy),
50
            new Point(startX, startY - dy)
51
        );
52
53
        curves.push(c);
54
    }
55
56
    ribbon = new BezierRibbon(curves, 42);
57
}
58
59
function update() {
60
//    ribbon.updateTime(timeStep);
61
    ribbon.currentTime = Math.min(time, ribbon.totalTime);
62
    ribbon.startOffset = Math.max(time - 1.5, 0);
63
64
    time %= (ribbon.totalTime + 1.5);
65
66
//    console.log(time % (ribbon.totalTime));
67
//    ribbon.currentTime = Math.min(time, ribbon.totalTime);
68
//    ribbon.startOffset = Math.max(ribbon.currentTime - 3, 0);
69
}
70
71
function draw() {
72
//    ctx.fillStyle = '#000';
73
    ctx.clearRect(0, 0, viewWidth, viewHeight);
74
75
    ribbon.draw();
76
}
77
78
window.onload = function() {
79
    initDrawingCanvas();
80
    initCurves();
81
    requestAnimationFrame(loop);
82
};
83
84
function loop() {
85
    update();
86
    draw();
87
    time += timeStep;
88
    requestAnimationFrame(loop);
89
}
90
91
////////////////////////////
92
// class and utils
93
////////////////////////////
94
BezierRibbon = function(curves, width) {
95
    this.curves = curves;
96
    this.width = width;
97
    this.halfWidth = this.width * 0.5;
98
    this.totalTime = curves.length; // 1.0 per curve
99
    this.currentTime = 0;
100
    this.startOffset = 0;
101
102
    // point cache
103
    this.tp0 = new Point();
104
    this.tp1 = new Point();
105
    this.tp2 = new Point();
106
    this.tp3 = new Point();
107
};
108
BezierRibbon.prototype = {
109
    draw:function() {
110
        // debug draw
111
//        this.curves.forEach(function(c) {
112
//            c.draw();
113
//        });
114
115
        var step = 1e-2,
116
            index = 0,
117
            dx,
118
            curve;
119
120
        for (var t = this.startOffset; t < this.currentTime; t += step) {
121
            index = t | 0;
122
            curve = this.curves[index];
123
            curve.interpolate(t - index, this.tp0);
124
            curve.interpolate(t + step - index, this.tp1);
125
126
            this.tp0.translate(0, -this.halfWidth);
127
            this.tp1.translate(0, -this.halfWidth);
128
            this.tp2.copy(this.tp1).translate(0, this.width);
129
            this.tp3.copy(this.tp0).translate(0, this.width);
130
131
            dx = this.tp1.x - this.tp0.x;
132
133
            ctx.strokeStyle = ctx.fillStyle = dx >= 0 ? frontGradient : backGradient;
134
            ctx.globalCompositeOperation = dx >= 0 ? 'source-over' : 'destination-over';
135
            ctx.lineWidth = 1.5;
136
137
            ctx.beginPath();
138
            ctx.moveTo(this.tp0.x, this.tp0.y);
139
            ctx.lineTo(this.tp1.x, this.tp1.y);
140
            ctx.lineTo(this.tp2.x, this.tp2.y);
141
            ctx.lineTo(this.tp3.x, this.tp3.y);
142
            ctx.closePath();
143
            ctx.fill();
144
            ctx.stroke();
145
        }
146
    }
147
};
148
149
Curve = function(p0, p1, p2, p3) {
150
    this.p0 = p0;
151
    this.p1 = p1;
152
    this.p2 = p2;
153
    this.p3 = p3;
154
};
155
Curve.prototype = {
156
    interpolate:function(t, p) {
157
        p = p || new Point();
158
159
        var nt = (1 - t);
160
161
        p.x = nt * nt * nt * this.p0.x + 3 * nt * nt * t * this.p1.x + 3 * nt * t * t * this.p2.x + t * t * t * this.p3.x;
162
        p.y = nt * nt * nt * this.p0.y + 3 * nt * nt * t * this.p1.y + 3 * nt * t * t * this.p2.y + t * t * t * this.p3.y;
163
164
        return p;
165
    },
166
    draw:function() {
167
        ctx.strokeStyle = "#f00";
168
        ctx.beginPath();
169
        ctx.moveTo(this.p0.x, this.p0.y);
170
        ctx.bezierCurveTo(this.p1.x, this.p1.y, this.p2.x, this.p2.y, this.p3.x, this.p3.y);
171
        ctx.stroke();
172
    },
173
    clone:function(offsetX, offsetY) {
174
        offsetX = offsetX || 0;
175
        offsetY = offsetY || 0;
176
177
        return new Curve(
178
            this.p0.clone(offsetX, offsetY),
179
            this.p1.clone(offsetX, offsetY),
180
            this.p2.clone(offsetX, offsetY),
181
            this.p3.clone(offsetX, offsetY)
182
        );
183
    }
184
};
185
186
Point = function(x, y) {
187
    this.x = x || 0;
188
    this.y = y || 0;
189
};
190
Point.prototype = {
191
    clone:function(offsetX, offsetY) {
192
        offsetX = offsetX || 0;
193
        offsetY = offsetY || 0;
194
195
        return new Point(this.x + offsetX, this.y + offsetY);
196
    },
197
    copy:function(p) {
198
        this.x = p.x;
199
        this.y = p.y;
200
201
        return this;
202
    },
203
    translate:function(dx, dy) {
204
        dx = dx || 0;
205
        dy = dy || 0;
206
207
        this.x += dx;
208
        this.y += dy;
209
210
        return this;
211
    }
212
};
必须是有效的URL
+ 添加另一个资源
Close

文件管理 点击文件查看URL

图片

  1. 暂无文件

CSS

  1. 暂无文件

JavaScript

  1. 暂无文件

其他

  1. 暂无文件
拖动文件到上面的区域或者:
加载中 ..................