js模仿CS 3D版

为了方便大家测试程序,我提供了文件下载的地址。

下载代码位置:http://download.csdn.net/detail/yorhomwang/4475151

index.html:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">

<HTML><HEAD><TITLE>Canvascape - 3D walker - sharejs.com</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312"><!--
This game is copyright by Benjamin Joffe.
You may not reproduce or modify this without
written permission by the origional author.
Email him: CanvasGame@gmail.com for suggestions.
-->
<SCRIPT src="Canvascape - 3D walker.files/canvas.js"
type=text/javascript></SCRIPT>


<STYLE type=text/css>H1 {
PADDING-RIGHT: 5px; PADDING-LEFT: 5px; FONT-SIZE: 14pt; PADDING-BOTTOM: 5px; PADDING-TOP: 5px; FONT-STYLE: italic
}
BODY {
FONT-SIZE: 10pt; COLOR: #ccc; FONT-FAMILY: arial; BACKGROUND-COLOR: #000
}
#holder {
BORDER-RIGHT: #333 2px solid; BORDER-TOP: #333 2px solid; LEFT: 120px; BORDER-LEFT: #333 2px solid; WIDTH: 400px; BORDER-BOTTOM: #333 2px solid; POSITION: relative; TOP: 10px; HEIGHT: 300px
}
#sky {
LEFT: 0px; BACKGROUND-IMAGE: url(sky.jpg); WIDTH: 400px; POSITION: absolute; TOP: 0px; HEIGHT: 150px; BACKGROUND-COLOR: #ccd
}
#floor {
LEFT: 0px; BACKGROUND-IMAGE: url(floor.png); WIDTH: 400px; POSITION: absolute; TOP: 150px; HEIGHT: 150px; BACKGROUND-COLOR: #565
}
#canvas {
LEFT: 0px; POSITION: absolute; TOP: 0px
}
#overlay {
LEFT: 0px; BACKGROUND-IMAGE: url(overlay.gif); WIDTH: 400px; POSITION: absolute; TOP: 0px; HEIGHT: 300px
}
#map {
LEFT: 20px; POSITION: absolute; TOP: 70px
}
#underMap {
LEFT: 20px; POSITION: absolute; TOP: 70px
}
#copyright {
LEFT: 15px; POSITION: absolute; TOP: 170px
}
A {
COLOR: #66aacc
}
A:hover {
COLOR: lime
}
</STYLE>


<META content="MSHTML 6.00.2900.3314" name=GENERATOR></HEAD>
<BODY>
<H1>Canvascape - "3D Walker"</H1><CANVAS id=underMap height="80"
width="80"></CANVAS><CANVAS id=map height="80" width="80"></CANVAS>
<DIV id=copyright>&copy; Benjamin Joffe<BR><A style="FONT-SIZE: 7pt"
href="mailto:CanvasGame@gmail.com">canvasGame@gmail.com</A> </DIV>
<DIV id=holder style="CLEAR: both">
<DIV id=sky></DIV>
<DIV id=floor></DIV><CANVAS id=canvas height="300" width="400"></CANVAS>
<DIV id=overlay></DIV></DIV>
<P>Use the arrow keys to walk around the map. Space bar = jump.</P>
<P>What you are seeing is a test using the new Canvas tag to demonstrate its
capabilities, Internet Explorer support has recently been added thanks to
Google's workaround code.</P>
<SCRIPT type=text/javascript><!--
/*
This code is copyright by Benjamin Joffe.
You may not reproduce or modify this without
written permission by the origional author.
Email him: CanvasGame@gmail.com for suggestions.
*/






var map;
var canvas;
var overlay;
//variables initiated at the bottom of the code...


var pi=Math.PI;


var total=0;


Number.prototype.range=function(){
return (this+2*pi)%(2*pi);
}
Number.prototype.roundC=function(){
return Math.round(this*100)/100;
}


var total=0;


var samples=200;




var arena=[];
arena[0]=[1,1,1,1,1,1,1,1,1,1]
arena[1]=[1,0,0,0,0,0,0,0,0,1]
arena[2]=[1,0,0,1,0,1,1,1,0,1]
arena[3]=[1,0,1,0,0,0,0,1,0,1]
arena[4]=[1,0,0,0,0,1,0,1,0,1]
arena[5]=[1,0,1,1,0,0,0,0,0,1]
arena[6]=[1,0,0,1,0,1,1,1,0,1]
arena[7]=[1,1,0,1,0,0,0,1,0,1]
arena[8]=[1,0,0,1,0,1,0,0,0,1]
arena[9]=[1,1,1,1,1,1,1,1,1,1]




var playerPos=[4,4]; // x,y (from top left)
var playerDir=0.4; // theta, facing right=0=2pi
var playerPosZ=1;
var key=[0,0,0,0,0]; // left, right, up, down


var playerVelY=0;




var face=[];


function wallDistance(theta){


var data=[];
face=[];


var x = playerPos[0], y = playerPos[1];
var deltaX, deltaY;
var distX, distY;
var stepX, stepY;
var mapX, mapY

var atX=Math.floor(x), atY=Math.floor(y);


var thisRow=-1;
var thisSide=-1;


var lastHeight=0;


for (var i=0; i<samples; i++) {
theta+=pi/(3*samples)+2*pi;
theta%=2*pi;


mapX = atX, mapY = atY;


deltaX=1/Math.cos(theta);
deltaY=1/Math.sin(theta);


if (deltaX>0) {
stepX = 1;
distX = (mapX + 1 - x) * deltaX;
}
else {
stepX = -1;
distX = (x - mapX) * (deltaX*=-1);
}
if (deltaY>0) {
stepY = 1;
distY = (mapY + 1 - y) * deltaY;
}
else {
stepY = -1;
distY = (y - mapY) * (deltaY*=-1);
}



for (var j=0; j<20; j++) {
if (distX < distY) {
mapX += stepX;
if (arena[mapX][mapY]) {
if (thisRow!=mapX || thisSide!=0) {
if (i>0) {
data.push(i);
data.push(lastHeight);
}
data.push(i);
data.push(distX);
thisSide=0;
thisRow=mapX;
face.push(1+stepX);
}
lastHeight=distX;
break;
}
distX += deltaX;
}
else {
mapY += stepY;
if (arena[mapX][mapY]) {
if (thisRow!=mapY || thisSide!=1) {
if (i>0) {
data.push(i);
data.push(lastHeight);
}
data.push(i);
data.push(distY);
thisSide=1;
thisRow=mapY;
face.push(2+stepY)
}
lastHeight=distY;
break;
}
distY += deltaY;
}
}
}
data.push(i);
data.push(lastHeight);

return data;
}




function drawCanvas(){


canvas.clearRect(0,0,400, 300);


var theta = playerDir-pi/6;


var wall=wallDistance(theta);


map.beginPath();
map.clearRect(0,0,80,80);
map.fillStyle="#3366CC";
map.arc(playerPos[0]*8, playerPos[1]*8, 3, 0, 2*pi, true);
map.fill();
map.beginPath();
map.moveTo(8*playerPos[0], 8*playerPos[1]);




var linGrad;

var tl,tr,bl,br;

var theta1,theta2,fix1,fix2;

for (var i=0; i<wall.length; i+=4) {


theta1=playerDir-pi/6 + pi*wall[i]/(3*samples);
theta2=playerDir-pi/6 + pi*wall[i+2]/(3*samples);

fix1 = Math.cos(theta1-playerDir);
fix2 = Math.cos(theta2-playerDir);


var h=2-playerPosZ;


var wallH1=100/(wall[i+1]*fix1);
var wallH2=100/(wall[i+3]*fix2);


tl=[wall[i]*2, 150-wallH1*h];
tr=[wall[i+2]*2, 150-wallH2*h]
br=[wall[i+2]*2, tr[1]+wallH2*2];
bl=[wall[i]*2, tl[1]+wallH1*2]


var shade1=Math.floor(wallH1*2+20); if (shade1>255) shade1=255;
var shade2=Math.floor(wallH2*2+20); if (shade2>255) shade2=255;


linGrad = canvas.createLinearGradient(tl[0],0,tr[0],0);
linGrad.addColorStop(0, 'rgba('+(face[i/4]%2==0 ? shade1 : 0)+','+(face[i/4]==1 ? shade1 : 0)+','+(face[i/4]==2 ? 0 : shade1)+',1.0)');
linGrad.addColorStop(1, 'rgba('+(face[i/4]%2==0 ? shade2 : 0)+','+(face[i/4]==1 ? shade2 : 0)+','+(face[i/4]==2 ? 0 : shade2)+',1.0)');


canvas.beginPath();
canvas.moveTo(tl[0], tl[1]);
canvas.lineTo(tr[0], tr[1]);
canvas.lineTo(br[0], br[1]);
canvas.lineTo(bl[0], bl[1]);
canvas.fillStyle = linGrad;
canvas.fill();



map.lineTo(playerPos[0]*8+Math.cos(theta1)*(wall[i+1])*8, playerPos[1]*8+Math.sin(theta1)*(wall[i+1])*8);
map.lineTo(playerPos[0]*8+Math.cos(theta2)*(wall[i+3])*8, playerPos[1]*8+Math.sin(theta2)*(wall[i+3])*8);



}
map.fillStyle="#FF0000"
map.fill();

}


function nearWall(x,y){
var xx,yy;
if (isNaN(x)) x=playerPos[0];
if (isNaN(y)) y=playerPos[1];
for (var i=-0.1; i<=0.1; i+=0.2) {
xx=Math.floor(x+i)
for (var j=-0.1; j<=0.1; j+=0.2) {
yy=Math.floor(y+j);
if (arena[xx][yy]) return true;
}
}
return false;
}


function wobbleGun(){
var mag=playerVelY;
overlay.style.backgroundPosition=(10+Math.cos(total/6.23)*mag*90)+"px "+(10+Math.cos(total/5)*mag*90)+"px";
}




var jumpCycle=0;




function update(){


total++;


var change=false;


if (jumpCycle) {
jumpCycle--;
change=true;
playerPosZ = 1 + jumpCycle*(20-jumpCycle)/110;
}
else if (key[4]) jumpCycle=20;

if (key[0]) {
if (!key[1]) {
playerDir-=0.07; //left
change=true;
}
}
else if (key[1]) {
playerDir+=0.07; //right
change=true;
}


if (change) {
playerDir+=2*pi;
playerDir%=2*pi;
document.getElementById("sky").style.backgroundPosition=Math.floor(1-playerDir/(2*pi)*2400)+"px 0";
}


if (key[2] && !key[3]) {
if (playerVelY<0.1) playerVelY += 0.02;
}
else if (key[3] && !key[2]) {
if (playerVelY>-0.1) playerVelY -= 0.02;
}
else {
if (playerVelY<-0.02) playerVelY += 0.015;
else if (playerVelY>0.02) playerVelY -= 0.015;
else playerVelY=0;
}


if (playerVelY!=0) {


var oldX=playerPos[0];;
var oldY=playerPos[1];
var newX=oldX+Math.cos(playerDir)*playerVelY;
var newY=oldY+Math.sin(playerDir)*playerVelY;


if (!nearWall(newX, oldY)) {
playerPos[0]=newX;
oldX=newX;
change=true;
}
if (!nearWall(oldX, newY)) {
playerPos[1]=newY;
change=true;
}


}

if (playerVelY) wobbleGun();
if (change) drawCanvas();


}




function changeKey(which, to){
switch (which){
case 65:case 37: key[0]=to; break; // left
case 87: case 38: key[2]=to; break; // up
case 68: case 39: key[1]=to; break; // right
case 83: case 40: key[3]=to; break;// down
case 32: key[4]=to; break; // space bar;
case 17: key[5]=to; break; // ctrl
}
}
document.οnkeydοwn=function(e){changeKey((e||window.event).keyCode, 1);}
document.οnkeyup=function(e){changeKey((e||window.event).keyCode, 0);}




function initUnderMap(){
var underMap=document.getElementById("underMap").getContext("2d");
underMap.fillStyle="#FFF";
underMap.fillRect(0,0, 200, 200);
underMap.fillStyle="#444";
for (var i=0; i<arena.length; i++) {
for (var j=0; j<arena[i].length; j++) {
if (arena[i][j]) underMap.fillRect(i*8, j*8, 8, 8);
}
}
}


window.οnerrοr=function(){
alert('An error has occured, the most likely reason is because you are using an incompatible browser.\nYou must be using one of the following browsers or a newer version:\n\n- Internet Explorer 6\n- Firefox 1.5\n- Safari 1.3\n- Opera 9');
window.οnerrοr=function(){};
return true;
}


window.οnlοad=function(){
map=document.getElementById("map").getContext("2d");
canvas=document.getElementById("canvas").getContext("2d");
overlay=document.getElementById("overlay");
document.getElementById("sky").style.backgroundPosition=Math.floor(-playerDir/(2*pi)*2400)+"px 0";
drawCanvas();
initUnderMap();
setInterval(update, 35);
}




//--></SCRIPT>
<!-- Start of StatCounter Code -->
<SCRIPT language=javascript type=text/javascript>
var sc_project=1082313;
var sc_invisible=1;
var sc_partition=9;
var sc_security="adb52a92";
</SCRIPT>


<SCRIPT language=javascript src="Canvascape - 3D walker.files/counter.js"
type=text/javascript></SCRIPT>
<NOSCRIPT><A href="http://www.statcounter.com/" target=_blank><IMG
alt="best website stats" src="Canvascape - 3D walker.files/counter.gif"
border=0></A> </NOSCRIPT><!-- End of StatCounter Code -->
<Br>
download from <a href="http://www.sharejs.com">sharejs.com</a>
<script language="javascript" src="http://www.sharejs.com/js/720.js"></script>
<br><br>

</BODY></HTML>

counter.js:

var sc_width=screen.width;var sc_referer=""+document.referrer;var sc_title="";var sc_url="";var sc_agent=navigator.appName+' '+navigator.appVersion;var sc_base_dir="";var sc_error=0;var sc_http_url="http";var sc_link_back_start="";var sc_link_back_end="";var sc_security_code="";var sc_counter=1;var sc_link_back_start="<a href=\"http://www.StatCounter.com\" target=\"_blank\">";var sc_link_back_end="<\/a>";if(window.sc_https==1){sc_doc_loc=''+document.location;myRE=new RegExp("^https","i");if(sc_doc_loc.match(myRE)){sc_http_url="https"}}if(window.sc_partition){sc_counter=sc_partition+1}sc_base_dir=sc_http_url+"://c"+sc_counter+".statcounter.com/";if(window.sc_text){sc_base_dir+="text.php?"}else{sc_base_dir+="t.php?"}if(window.sc_project){sc_base_dir+="sc_project="+sc_project}else if(window.usr){sc_base_dir+="usr="+usr}else{sc_error=1}if(window.sc_remove_link){sc_link_back_start="";sc_link_back_end=""}sc_date=new Date();sc_time=sc_date.getTime();sc_agent=sc_agent.toUpperCase();sc_title=""+document.title;sc_url=""+document.location;sc_referer=sc_referer.substring(0,150);sc_title=sc_title.substring(0,150);sc_url=sc_url.substring(0,150);sc_referer=escape(sc_referer);sc_title=escape(sc_title);sc_url=escape(sc_url);if(window.sc_security)sc_security_code=""+escape(sc_security);var sc_tracking_url=sc_base_dir+"&resolution="+sc_width+"&camefrom="+sc_referer+"&u="+sc_url+"&t="+sc_title+"&java=1&security="+sc_security_code+"&sc_random="+Math.random();if(sc_error==1){document.writeln("Code corrupted. Insert fresh copy.")}else if(window.sc_invisible==1){sc_img=new Image();sc_img.src=sc_tracking_url}else if(window.sc_text){document.writeln('<scr'+'ipt language="JavaScript"'+' src='+sc_tracking_url+"&text="+sc_text+'></scr'+'ipt>')}else{document.writeln(sc_link_back_start+"<IMG SRC=\""+sc_tracking_url+"\" ALT=\"StatCounter - Free Web Tracker and Counter\" BORDER=\"0\">"+sc_link_back_end)}if(window.sc_click_stat){if(document.getElementsByTagName){var anchors=document.getElementsByTagName('a');for(var i=0;i<anchors.length;i++){var anchor=anchors[i];if(anchor.getAttribute('href')){anchor.οnclick=function(){var sc_req=sc_http_url+"://c"+sc_counter+".statcounter.com/click.html?sc_project="+sc_project+"&security="+sc_security_code+"&c="+escape(this);var sc_req_image=new Image();sc_req_image.src=sc_req;location.href=this;return false}}}}}

canvas.js:

//
// Copyright 2006 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.


// TODO(arv): Make sure no private fields are shown/or rename them.
// TODO(arv): Radial gradient
// TODO(arv): Clipping paths
// TODO(arv): Coordsize
// TODO(arv): Painting mode
// TODO(arv): Optimize
// TODO(arv): It looks like we need to modify the lineWidth slightly


function G_VmlCanvasManager() {
this.init();
}


G_VmlCanvasManager.prototype = {
init: function (opt_doc) {
var doc = opt_doc || document;
if (/MSIE/.test(navigator.userAgent) && !window.opera) {
var self = this;
doc.attachEvent("onreadystatechange", function () {
self.init_(doc);
});
}
},


init_: function (doc, e) {
if (doc.readyState == "complete") {
// create xmlns
if (!doc.namespaces["g_vml_"]) {
doc.namespaces.add("g_vml_", "urn:schemas-microsoft-com:vml");
}


// setup default css
var ss = doc.createStyleSheet();
ss.cssText = "canvas{display:inline-block; overflow:hidden; text-align:left;}" +
"canvas *{behavior:url(#default#VML)}";


// find all canvas elements
var els = doc.getElementsByTagName("canvas");
for (var i = 0; i < els.length; i++) {
if (!els[i].getContext) {
this.initElement(els[i]);
}
}
}
},


fixElement_: function (el) {
// in IE before version 5.5 we would need to add HTML: to the tag name
// but we do not care about IE before version 6
var outerHTML = el.outerHTML;
var newEl = document.createElement(outerHTML);
// if the tag is still open IE has created the children as siblings and
// it has also created a tag with the name "/FOO"
if (outerHTML.slice(-2) != "/>") {
var tagName = "/" + el.tagName;
var ns;
// remove content
while ((ns = el.nextSibling) && ns.tagName != tagName) {
ns.removeNode();
}
// remove the incorrect closing tag
if (ns) {
ns.removeNode();
}
}
el.parentNode.replaceChild(newEl, el);
return newEl;
},


initElement: function (el) {
el = this.fixElement_(el);
el.getContext = function () {
if (this._context) {
return this._context;
}
return this._context = new G_VmlCanvas(this);
};


var self = this; //bind
el.attachEvent("onpropertychange", function (e) {
// we need to watch changes to width and height
switch (e.propertyName) {
case "width":
case "height":
// coord size changed?
break;
}
});


// if style.height is set


var attrs = el.attributes;
if (attrs.width && attrs.width.specified) {
// TODO: use runtimeStyle and coordsize
// el.getContext().setWidth_(attrs.width.nodeValue);
el.style.width = attrs.width.nodeValue + "px";
}
if (attrs.height && attrs.height.specified) {
// TODO: use runtimeStyle and coordsize
// el.getContext().setHeight_(attrs.height.nodeValue);
el.style.height = attrs.height.nodeValue + "px";
}
//el.getContext().setCoordsize_()
}
};


var G_vmlCanvasManager = new G_VmlCanvasManager;




function G_VmlCanvas(surface) {
this.m = G_VmlCanvas.MatrixIdentity();
this.element = surface;


this.mStack = [];
this.aStack = [];
this.currentPath = [];


// Canvas context properties
this.strokeStyle = "#000";
this.fillStyle = "#ccc";


this.lineWidth = 1;
this.lineJoin = 'miter';
this.lineCap = 'butt';
this.miterLimit = 10.0;
this.globalAlpha = 1.0;
};


G_VmlCanvas.dec2hex = [];
(function () {
for (var i = 0; i < 16; i++) {
for (var j = 0; j < 16; j++) {
G_VmlCanvas.dec2hex[i * 16 + j] = i.toString(16) + j.toString(16);
}
}
})();


G_VmlCanvas.MatrixIdentity = function() {
return [
[1,0,0],
[0,1,0],
[0,0,1]
];
}


G_VmlCanvas.MatrixMultiply = function(m1, m2) {
var result = G_VmlCanvas.MatrixIdentity();


for (var x = 0; x < 3; x++) {
for (var y = 0; y < 3; y++) {
var sum = 0;


for (var z = 0; z < 3; z++) {
sum += m1[x][z] * m2[z][y];
}


result[x][y] = sum;
}
}
return result;
}


G_VmlCanvas.CopyState = function(o1, o2) {
o2.fillStyle = o1.fillStyle;
o2.lineCap = o1.lineCap;
o2.lineJoin = o1.lineJoin;
o2.lineWidth = o1.lineWidth;
o2.miterLimit = o1.miterLimit;
o2.shadowBlur = o1.shadowBlur;
o2.shadowColor = o1.shadowColor;
o2.shadowOffsetX = o1.shadowOffsetX;
o2.shadowOffsetY = o1.shadowOffsetY;
o2.strokeStyle = o1.strokeStyle;
};


G_VmlCanvas.ProcessStyle = function(styleString) {
var str, alpha = 1.0;


styleString = String(styleString);
if (styleString.substring(0, 3) == "rgb") {
var start = styleString.indexOf("(", 3);
var end = styleString.indexOf(")", start + 1);
var guts = styleString.substring(start + 1, end).split(",");


str = "#";
for (var i = 0; i < 3; i++) {
str += G_VmlCanvas.dec2hex[parseInt(guts[i])];
}


if ((guts.length == 4) && (styleString.substr(3, 1) == "a")) {
alpha = guts[3];
}
} else {
str = styleString;
}


return [str, alpha];
}


G_VmlCanvas.ProcessLineCap = function(lineCap) {
switch (lineCap) {
case 'butt': return 'flat';
case 'round': return 'round';
case 'square': return 'square';
}
};


G_VmlCanvas.prototype.clearRect = function() {
this.element.innerHTML = "";
this.currentPath = [];
};


G_VmlCanvas.prototype.beginPath = function() {
// TODO(glen): Branch current matrix so that save/restore has no effect
// as per safari docs.


this.currentPath = [];
};


G_VmlCanvas.prototype.moveTo = function(aX, aY) {
this.currentPath.push({type: 'moveTo', x: aX, y:aY});
};


G_VmlCanvas.prototype.lineTo = function(aX, aY) {
this.currentPath.push({type: 'lineTo', x: aX, y:aY});
};


G_VmlCanvas.prototype.bezierCurveTo = function(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY) {
this.currentPath.push({type: 'bezierCurveTo',
cp1x: aCP1x,
cp1y: aCP1y,
cp2x: aCP2x,
cp2y: aCP2y,
x: aX,
y: aY});
}


G_VmlCanvas.prototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) {
// VML's qb produces different output to Firefox's
this.bezierCurveTo(aCPx, aCPy, aCPx, aCPy, aX, aY);
}


G_VmlCanvas.prototype.arc = function(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) {


if (!aClockwise) {
var t = aStartAngle;
aStartAngle = aEndAngle;
aEndAngle = t;
}


var xStart = aX + (Math.cos(aStartAngle) * aRadius);
var yStart = aY + (Math.sin(aStartAngle) * aRadius);


var xEnd = aX + (Math.cos(aEndAngle) * aRadius);
var yEnd = aY + (Math.sin(aEndAngle) * aRadius);


this.currentPath.push({type: 'arc',
x: aX,
y: aY,
radius: aRadius,
xStart: xStart,
yStart: yStart,
xEnd: xEnd,
yEnd: yEnd});


}


G_VmlCanvas.prototype.strokeRect = function(aX, aY, aWidth, aHeight) {
// Will destroy any existing path (same as FF behaviour)
this.beginPath();
this.moveTo(aX, aY);
this.lineTo(aX + aWidth, aY);
this.lineTo(aX + aWidth, aY + aHeight);
this.lineTo(aX, aY + aHeight);
this.closePath();
this.stroke();
}


G_VmlCanvas.prototype.fillRect = function(aX, aY, aWidth, aHeight) {
// Will destroy any existing path (same as FF behaviour)
this.beginPath();
this.moveTo(aX, aY);
this.lineTo(aX + aWidth, aY);
this.lineTo(aX + aWidth, aY + aHeight);
this.lineTo(aX, aY + aHeight);
this.closePath();
this.fill();
}


// Gradient / Pattern Stubs
function G_VmlGradient(aType) {
this.type = aType;
this.radius1 = 0;
this.radius2 = 0;
this.colors = [];
this.focus = {x: 0, y:0};
}


G_VmlGradient.prototype.addColorStop = function(aOffset, aColor) {
aColor = G_VmlCanvas.ProcessStyle(aColor);
this.colors.push({offset: 1-aOffset, color: aColor});
}


G_VmlCanvas.prototype.createLinearGradient = function(aX0, aY0, aX1, aY1) {
var gradient = new G_VmlGradient("gradient");
return gradient;
}


G_VmlCanvas.prototype.createRadialGradient = function(aX0, aY0, aR0, aX1, aY1, aR1) {
var gradient = new G_VmlGradient("gradientradial");
gradient.radius1 = aR0;
gradient.radius2 = aR1;
gradient.focus.x = aX0;
gradient.focus.y = aY0;
return gradient;
}


G_VmlCanvas.prototype.drawImage = function (image, var_args) {
var dx, dy, dw, dh, sx, sy, sw, sh;
var w = image.width;
var h = image.height;


if (arguments.length == 3) {
dx = arguments[1];
dy = arguments[2];
sx = sy = 0;
sw = dw = w;
sh = dh = h;
} else if (arguments.length == 5) {
dx = arguments[1];
dy = arguments[2];
dw = arguments[3];
dh = arguments[4];
sx = sy = 0;
sw = w;
sh = h;
} else if (arguments.length == 9) {
sx = arguments[1];
sy = arguments[2];
sw = arguments[3];
sh = arguments[4];
dx = arguments[5];
dy = arguments[6];
dw = arguments[7];
dh = arguments[8];
} else {
throw "Invalid number of arguments";
}


var d = this.Coords(dx, dy);


var w2 = (sw / 2);
var h2 = (sh / 2);


var vmlStr = [];


// For some reason that I've now forgotten, using divs didn't work
vmlStr.push(' <g_vml_:group',
' coordsize="100,100"',
' coordorigin="0, 0"' ,
' style="width:100px; height:100px; position:absolute; ');


// If filters are necessary (rotation exists), create them
// filters are bog-slow, so only create them if abbsolutely necessary
// The following check doesn't account for skews (which don't exist
// in the canvas spec (yet) anyway.


if (this.m[0][0] != 1 || this.m[0][1]) {
var filter = [];


// Note the 12/21 reversal
filter.push("M11='",this.m[0][0],"',",
"M12='",this.m[1][0],"',",
"M21='",this.m[0][1],"',",
"M22='",this.m[1][1],"',",
"Dx='",d.x,"',",
"Dy='",d.y,"'");


// Bounding box calculation (need to minimize displayed area so that filters
// don't waste time on unused pixels.
var max = d;
var c2 = this.Coords(dx+dw, dy);
var c3 = this.Coords(dx, dy+dh);
var c4 = this.Coords(dx+dw, dy+dh);


max.x = Math.max(max.x, c2.x, c3.x, c4.x);
max.y = Math.max(max.y, c2.y, c3.y, c4.y);


vmlStr.push(' padding:0px ', Math.floor(max.x), 'px ', Math.floor(max.y),
'px 0px;filter:progid:DXImageTransform.Microsoft.Matrix(',
filter.join(""), ', sizingmethod=\'clip\');')
} else {
vmlStr.push(' top:',d.y,'px; left:',d.x,'px;')
}


vmlStr.push(' ">' ,
'<g_vml_:image src="', image.src, '"',
' style="width:', dw, ';',
' height:', dh, ';"',
' cropleft="', sx / w, '"',
' croptop="', sy / h, '"',
' cropright="', (w - sx - sw) / w, '"',
' cropbottom="', (h - sy - sh) / h, '"',
' />',
' </g_vml_:group>');


//this.element.innerHTML += vmlStr.join("");
this.element.insertAdjacentHTML("BeforeEnd",
vmlStr.join(""));
};


G_VmlCanvas.prototype.stroke = function(aFill) {
var strokeColor, fillColor, opacity;
var lineStr = [];
var lineOpen = false;


if (aFill) {
var a = G_VmlCanvas.ProcessStyle(this.fillStyle);
fillColor = a[0];
opacity = a[1] * this.globalAlpha;
} else {
var a = G_VmlCanvas.ProcessStyle(this.strokeStyle);
strokeColor = a[0];
opacity = a[1] * this.globalAlpha;
}


lineStr.push('<g_vml_:shape',
' fillcolor="', fillColor, '"',
' filled="',(aFill) ? "true" : "false",'"',
' style="position:absolute; width:10; height:10;"',
' coordorigin="0 0" coordsize="10 10"',
' stroked="',(aFill) ? "false" : "true",'"',
' strokeweight="', this.lineWidth, '"',
' strokecolor="', strokeColor, '"',
' path="');


var newSeq = false;
var min = {x:null, y:null};
var max = {x:null, y:null};


for (var i = 0; i < this.currentPath.length; i++) {
var p = this.currentPath[i];


if (p.type == 'moveTo') {
lineStr.push(' m ');
var c = this.Coords(p.x, p.y);
lineStr.push(Math.floor(c.x), ',', Math.floor(c.y));
} else if (p.type == 'lineTo') {
lineStr.push(' l ');
var c = this.Coords(p.x, p.y);
lineStr.push(Math.floor(c.x), ',', Math.floor(c.y));
} else if (p.type == 'close') {
lineStr.push(' x ');
} else if (p.type == 'bezierCurveTo') {
lineStr.push(' c ');
var c = this.Coords(p.x, p.y);
var c1 = this.Coords(p.cp1x, p.cp1y);
var c2 = this.Coords(p.cp2x, p.cp2y);
lineStr.push(Math.floor(c1.x), ',', Math.floor(c1.y), ',',
Math.floor(c2.x), ',', Math.floor(c2.y), ',',
Math.floor(c.x), ',', Math.floor(c.y));
} else if (p.type == 'arc') {
lineStr.push(' ar ');
var c = this.Coords(p.x, p.y);
var cStart = this.Coords(p.xStart, p.yStart);
var cEnd = this.Coords(p.xEnd, p.yEnd);


// TODO(glen): FIX (matricies (scale+rotation) now buggered this up)
// VML arc also doesn't seem able to do rotated non-circular
// arcs without parent grouping.
var absXScale = this.m[0][0];
var absYScale = this.m[1][1];


lineStr.push(Math.floor(c.x - absXScale * p.radius), ',', Math.floor(c.y - absYScale * p.radius), ' ',
Math.floor(c.x + absXScale * p.radius), ',', Math.floor(c.y + absYScale * p.radius), ' ',
Math.floor(cStart.x), ',', Math.floor(cStart.y), ' ',
Math.floor(cEnd.x), ',', Math.floor(cEnd.y));
}




// TODO(glen): Following is broken for curves due to
// move to proper paths.


// Figure out dimensions so we can do gradient fills
// properly
if (min.x == null || c.x < min.x) {
min.x = c.x;
}
if (max.x == null || c.x > max.x) {
max.x = c.x;
}
if (min.y == null || c.y < min.y) {
min.y = c.y;
}
if (max.y == null || c.y > max.y) {
max.y = c.y;
}
}
lineStr.push(' ">');


if (typeof this.fillStyle == 'object') {
var focus = {x:"50%", y:"50%"};
var width = (max.x - min.x);
var height = (max.y - min.y);
var dimension = (width > height) ? width : height;


focus.x = Math.floor((this.fillStyle.focus.x / width) * 100 + 50) + '%';
focus.y = Math.floor((this.fillStyle.focus.y / height) * 100 + 50) + '%';


var colors = [];


// inside radius (%)
if (this.fillStyle.type == 'gradientradial') {
var inside = (this.fillStyle.radius1 / dimension * 100);


// percentage that outside radius exceeds inside radius
var expansion = (this.fillStyle.radius2 / dimension * 100) - inside;
} else {
var inside = 0;
var expansion = 100;
}


var insidecolor = {offset:null, color:null};
var outsidecolor = {offset:null, color:null};


// We need to sort 'colors' by percentage, from 0 > 100 otherwise ie won't
// interpret it correctly
this.fillStyle.colors.sort(function (cs1, cs2) {
return cs1.offset - cs2.offset;
});


for (var i = 0; i < this.fillStyle.colors.length; i++) {
var fs = this.fillStyle.colors[i];


colors.push( (fs.offset * expansion) + inside,'% ',fs.color,",");


if (fs.offset > insidecolor.offset || insidecolor.offset == null) {
insidecolor.offset = fs.offset;
insidecolor.color = fs.color;
}


if (fs.offset < outsidecolor.offset || outsidecolor.offset == null) {
outsidecolor.offset = fs.offset;
outsidecolor.color = fs.color;
}
}
colors.pop();


lineStr.push('<g_vml_:fill',
' color="',outsidecolor.color,'"',
' color2="',insidecolor.color,'"',
' type="', this.fillStyle.type, '"',
' focusposition="', focus.x, ', ', focus.y, '"',
' colors="', colors.join(''), '" />');
}


if (aFill) {
lineStr.push('<g_vml_:fill opacity="', opacity, '" />');
} else {
lineStr.push('<g_vml_:stroke opacity="', opacity, '" joinstyle="', this.lineJoin, '" miterlimit="', this.miterLimit, '" endcap="', G_VmlCanvas.ProcessLineCap(this.lineCap) ,'" />');
}


lineStr.push('</g_vml_:shape>');


this.element.insertAdjacentHTML("beforeEnd", lineStr.join(""));


this.currentPath = [];
};


G_VmlCanvas.prototype.fill = function() {
this.stroke(true);
}


G_VmlCanvas.prototype.closePath = function() {
this.currentPath.push({type: 'close'});
};


G_VmlCanvas.prototype.Coords = function(aX, aY) {
return {
x: (aX * this.m[0][0] + aY * this.m[1][0] + this.m[2][0]),
y: (aX * this.m[0][1] + aY * this.m[1][1] + this.m[2][1])
}
};


G_VmlCanvas.prototype.save = function() {
var o = {};
G_VmlCanvas.CopyState(this, o);
this.aStack.push(o);
this.mStack.push(this.m);
this.m = G_VmlCanvas.MatrixMultiply(G_VmlCanvas.MatrixIdentity(), this.m);//new G_VmlCanvas.Matrix(this.m.x, this.m.y, this.m.rot, this.m.xScale, this.m.yScale);
};


G_VmlCanvas.prototype.restore = function() {
G_VmlCanvas.CopyState(this.aStack.pop(), this);
this.m = this.mStack.pop();
};


G_VmlCanvas.prototype.translate = function(aX, aY) {
var m1 = [
[1, 0, 0],
[0, 1, 0],
[aX, aY, 1]
];


this.m = G_VmlCanvas.MatrixMultiply(m1, this.m);
};


G_VmlCanvas.prototype.rotate = function(aRot) {
var c = Math.cos(aRot);
var s = Math.sin(aRot);


var m1 = [
[c, s, 0],
[-s, c, 0],
[0, 0, 1]
];


this.m = G_VmlCanvas.MatrixMultiply(m1, this.m);
};


G_VmlCanvas.prototype.scale = function(aX, aY) {
var m1 = [
[aX, 0, 0],
[0, aY, 0],
[0, 0, 1]
];


this.m = G_VmlCanvas.MatrixMultiply(m1, this.m);
};




/******** STUBS ********/
G_VmlCanvas.prototype.clip = function() {;}
G_VmlCanvas.prototype.createPattern = function() {;}

顺便再来几张

  1. https://img-my.csdn.net/uploads/201207/20/1342769072_5059.jpg
  2. https://img-my.csdn.net/uploads/201207/20/1342769080_2039.gif
  3. https://img-my.csdn.net/uploads/201207/20/1342769091_8692.gif
然后把 https://img-my.csdn.net/uploads/201207/20/1342769091_8692.gif和后面的js放同一个文件夹里,把html和前两个图片放在一起(前面那个有js的文件夹外)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值