对于freecodecamp部分笔记整理感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解.freecodecamp,并且为您提供关于16道JavaScript基础算法-freeCodeCam
对于free code camp部分笔记整理感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解.free code camp,并且为您提供关于16 道 JavaScript 基础算法 - freeCodeCamp、Beam Search、GREEDY DECODER、SAMPLING DECODER等解码器工作原理可视化、canvas 笔记整理、CSS部分1课件学习笔记整理的宝贵知识。
本文目录一览:- free code camp部分笔记整理(.free code camp)
- 16 道 JavaScript 基础算法 - freeCodeCamp
- Beam Search、GREEDY DECODER、SAMPLING DECODER等解码器工作原理可视化
- canvas 笔记整理
- CSS部分1课件学习笔记整理
free code camp部分笔记整理(.free code camp)
刷FCC的时候发现有一些东西遗忘,因此记录了下来,温故知新(2016.08,12整理,10,28上传)
一,bootstarp
l <div class=container-fluid></div>
container-fluid的width是100%。
而container的width是用媒体查询获得的动态尺寸。两者样式肯定是不一样的。并且由于padding的原因两者不可用嵌套,他们就是提供两种视觉风格。
l <imgimg-responsive'' src="/images/running-cat.jpg">
图片响应式
l 元素添加
居中
按钮风格:
<button class=”btn”>
1、btn-block:按钮变成块级元素。
2、btn-primary:深蓝色按钮
3、btn-info:浅蓝色按钮
4、btn-danger:红色按钮,表示警告
字体:
字体class text-danger: 警告红色字体
图标:
1、Font Awesome 是一个非常方便的图标库。这些图标都是矢量图形,被保存在 .svg 的文件格式中。这些图标就和字体一样,你可以通过像素单位指定它们的大小,它们将会继承其父HTML元素的字体大小。
你可以将 Font Awesome 图标库增添至任何一个应用中,方法很简单,只需要在你的 HTML 头部增加下列代码即可:
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css"/>
<button><i></i> Like</button> 点赞图标
<i></i> 提交图标
Input的class
<inputform-control'' type="text" placeholder="cat photo URL" required> 输入框样式。
Bootstrap 有一个 class 属性叫做 well,它的作用是为设定的列创造出一种视觉上的深度感。
jQuery
1,Class后面:animated后跟,bounce 、shake 、fadeOut data visualizaton
2,$(''button'').addClass(''animated bounce'') addClass,方法,为元素添加class
jQuery 有一个.remove() 的方法可以移除HTML元素
$(''#target4'').remove() 移除所属ID的元素
3,jQuery有一个叫做.css()的方法能让你改变元素的CSS样式。
$(''#target1'').css(''color'',''red'');
4,jQuery有一个.prop()的方法让你来调整元素的属性.
$(''#target1'').prop(''disabled'',true);
5,jQuery的.html()方法可以添加HTML标签和文字到元素,而元素之前的内容都会被方法的内容所替换掉。
6,jQuery 还有一个类似的方法叫.text(),它只能改变文本但不能修改标记。换句话说,这个方法只会把传进来的任何东西(包括标记)当成文本来显示。
7,jQuery有一个appendTo()方法可以把选中的元素加到其他元素中。
$(''#target2'').appendTo(''#right-well'') 添加到另一元素的子元素中
关于添加元素。
$(‘div’).instertAfter(‘p’):通过insertAfter()方法,将div元素移动到P元素的后面。
$(‘div’).appendTo($(‘p’));
$(‘p’).after(‘div’):通过after()方法,将p元素加到div元素的前面。
$(‘div’).append($(‘p’));
以上相当于剪切功能,下面相当于复制,用clone()方法
$(‘div’).clone().appendTo($(‘p’)); //将div复制一份,加到p元素的后面
JAVASCRIPT
1,.push() 接受把一个或多个参数,并把它“推”入到数组的末尾。
var myArray = [["John", 23], ["cat", 2]];
myArray.push([''dog'',3]);
现在最新的数组
myArray=[[‘John’,23] , ["cat", 2] ,[''dog'',3]];
2,.pop() 函数用来“抛出”一个数组末尾的值。我们可以把这个“抛出”的值赋给一个变量存储起来。
var myArray = [["John", 23], ["cat", 2]];
var removedFromMyArray=myArray.pop();
现在最新的数组
var removedFromMyArray=[["cat", 2]];
3,.shift() 它的工作原理就像 .pop(),但它移除的是第一个元素,而不是最后一个。
用法同上!
4, .unshift() 函数用起来就像 .push() 函数一样, 但不是在数组的末尾添加元素,而是在数组的头部添加元素。
5,Math.random()用来生成一个在0(包括0)到1(不包括1)之间的随机小数;
6,Math.floor() 向下取整,
7,null 是JavaScript中的一种数据类型,意味着空。
8 正则表达式:
我们可以把这个正则表达式分成几段:
/
是这个正则表达式的头部
the
是我们想要匹配的模式
/
是这个正则表达式的尾部
g
代表着 global
(全局),意味着返回所有的匹配而不仅仅是第一个。
i
代表着忽略大小写,意思是当我们寻找匹配的字符串的时候忽略掉字母的大小写。
选择器\d,意思是被用来获取一个字符串的数字。在选择器后面添加一个加号标记(+),例如:/\d+/g,它允许这个正则表达式匹配一个或更多数字。
选择器 \s 来选择一个字符串中的所有空白。
正则表达式选择器的大写版本 来转化任何匹配。举个例子:\s 匹配任何空白字符,\S 匹配任何非空白字符。
10,构造函数 通常使用大写字母开头,以便把自己和其他普通函数区别开。在 构造函数 中, this 指向被此 构造函数 创建出来的 对象 。所以,当我们在 构造函数 中写:
this.wheels = 4;
这时,它创建出来的新对象将带有 wheels 属性,并且赋值为 4.你可以认为 构造函数 描述了它所创建出来的对象。
构造函数,难以语言表达,以下例子:
var myCar = function() {
this.wheels = 4;
this.engines = 1;
this.seats = 1;
};
new myCar
var myCar=new myCar();
myCar.nickname=''adsf'';
11,全局变量和局部变量
在申明变量是凡是没有var关键字,而直接赋值的变量均为全局变量,在函数外定义的变量具有 全局 作用域,一个程序中有可能具有相同名称的 局部 变量 和 全局 变量。在这种情况下,局部 变量将会优先于 全局 变量。
12,我们可以把数据通过函数的 参数 来传入函数,也可以使用 return 语句把数据从一个函数中传出来。
function timesFive(time) {
return time*5;
}
timesFive(2);
结果是10;
13 删除对象的属性,例如:delete ourDog.bark;
var myDog = {
"name": "Happy Coder",
"legs": 4,
"tails": 1,
"friends": ["Free Code Camp Campers"],
"bark": "woof"
};
删除了tails属性。
delete myDog.tails;
14 检查一个对象是否存在:可以用.hasOwnProperty(propname)方法来检查对象是否有该属性。如果有返回true,反之返回 false。
15 数组的方法:
15-1 map 方法可以方便的迭代数组,在我们的例子中,回调函数只有一个参数,即数组中元素的值 (val
参数) ,但其实,你的回调函数也可以支持多个参数,譬如:元素的索引index
、原始数组arr
。
使用 map
方法来为 oldArray
中的每一项增加3,并且在 newArray
中保存它们。 oldArray
不应该被改变。
例子:
var oldArray = [1,2,3,4,5];
var newArray = oldArray.map(function(val){
return val+3;
});
返回结果,数组中每个元素加上3
15-2 数组方法 reduce 用来迭代一个数组,并且把它累积到一个值中。
var array = [4,5,6,7,8];
var singleVal = 0;
// reduce()传入两个,一个函数(函数传递参数,),另个一值是初始值;
singleVal = array.reduce(function(per,curr){
return per+curr;
},0);
15-3 filter 方法传入一个回调函数,这个回调函数会携带一个参数,参数为当前迭代的项(我们叫它 val )。
var oldArray = [1,2,3,4,5,6,7,8,9,10];
// 回调函数返回 true
的项会保留在数组中,返回false
的项会被过滤出数组。
var newArray = oldArray.filter(function(val){
return val<6;
});
所以数组newArray中,只有被剔除的小于6的数字。
15-4 sort 方法,你可以很容易的按字母顺序或数字顺序对数组中的元素进行排序。
var array = [1, 12, 21, 2];
array.sort(function(a,b){
return b-a;
});
数字从大到小排列
15-5 reverse 方法来翻转数组:
var myArray = [1, 2, 3];
myArray.reverse();
结果myArray 变成了 [3, 2, 1]
15-6 concat 方法的参数应该是一个数组。参数中的数组会拼接在原数组的后面,并作为一个新数组返回。
var oldArray = [1,2,3];
var concatMe = [4,5,6];
newArray = oldArray.concat(concatMe);
最新数组var newArray = [1,2,3,4,5,6];
15-7 split 方法按指定分隔符将字符串分割为数组。
var string = "Split me into an array";
var array = [];
array = string.split('' '');
创建的数组为[‘Split’,’me’,’ into’,’ an’,’ array’]
15-8 join 方法来把数组转换成字符串,里面的每一个元素可以用你指定的连接符来连接起来,这个连接符就是你要传入的参数。
15-9 slice(start,[end]) 方法可提取字符串的某个部分,并以新的字符串返回被提取的部分,传递两个参数,第一个表示截取的起始点[下标],第二个末尾点[下标]。
var ninini=[1,2,3,4,5,6,7,8,9];
var res=ninini.slice(1,-4)
数组返回的是[2, 3, 4, 5];
15-10 Splice(index,howMany[element])方法。传递两个参数指定删除的参数,从index开始删除howmany个元素。,并且创建新的数组。[element],添加元素到原数组。删除的位置上;改变了原数组。
Splice和slice除了splice可以删除之后修改之外,slice(英文,切下)尾部剪掉,splice(英文,绞接)保留尾部。
15-11 replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。
var array=[''a!'',''b!'',''c'',''d'']
var res=array.map(Trans);
function Trans(val){
return val.replace(/!/g,''?'').toUpperCase();
};
console.log(res)
结果是,’!’被替换成’?’
16 substr() 方法返回字符串中从指定位置开始到指定长度的子字符串。
语法
str.substr(start[, length])
17indexOf() 方法返回某个指定的字符串值在字符串中首次出现的位置(从左向右)。没有匹配的则返回-1,否则返回首次出现位置的字符串的下标值。
var src="images/off_1.png";
alert(src.indexOf(''t'')); //没有为-1
alert(src.indexOf(''i'')); //找到i下标为0
alert(src.indexOf(''g''));
弹出值依次为:-1,0,3
18 Json
.forEach()函数来循环遍历JSON数据写到htmll变量中。
16 道 JavaScript 基础算法 - freeCodeCamp
#1. Reverse a String
Reverse the provided string.
You may need to turn the string into an array before you can reverse it.
Your result must be a string.
function reverseString(str/*:string*/) {
if (str.length <= 1) return str;
let result = '''';
for (let i = str.length - 1; i >= 0; i--) {
result += str.charAt(i);
}
return result;
}
reverseString("hello");
#2. Factorialize a Number
Return the factorial of the provided integer.
If the integer is represented with the letter n, a factorial is the product of all positive integers less than or equal to n.
Factorials are often represented with the shorthand notation n!
.
For example: 5! = 1 * 2 * 3 * 4 * 5 = 120
.
function factorialize(num/*:number*/) {
if (num === 0) return 1;
let result = num;
while (--num > 0) {
result *= num;
}
return result;
}
factorialize(5);
#3. Check for Palindromes
Return true
if the given string is a palindrome. Otherwise, return false
.
A palindrome is a word or sentence that''s spelled the same way both forward and backward, ignoring punctuation, case, and spacing.
Note
You''ll need to remove all non-alphanumeric characters (punctuation, spaces and symbols) and turn everything lower case in order to check for palindromes.\
We''ll pass strings with varying formats, such as"racecar"
,"RaceCar"
, and"race CAR"
among others.\
We''ll also pass strings with special symbols, such as"2A3*3a2"
,"2A3 3a2"
, and"2_A3*3#A2"
.
function palindrome(str/*:string*/) {
const lstr = str.toLowerCase();
let low = 0, high = lstr.length - 1;
const reg = /[^0-9a-z]/;
while (low < high) {
const lchar = lstr.charAt(low);
if (reg.test(lchar)) {
low++;
continue;
}
const hchar = lstr.charAt(high);
if (reg.test(hchar)) {
high--;
continue;
}
if (lchar !== hchar) return false;
low++;
high--;
}
return true;
}
palindrome("eye");
#4. Find the Longest Word in a String
Return the length of the longest word in the provided sentence.
Your response should be a number.
function findLongestWord(str/*:string*/) {
let max = 0, len = 0;
for (let i = 0; i < str.length; i++) {
if (str.charAt(i) === '' '') {
if (len > max) max = len;
len = 0;
} else len++;
}
return Math.max(max, len);
}
findLongestWord("The quick brown fox jumped over the lazy dog");
#5. Title Case a Sentence
Return the provided string with the first letter of each word capitalized. Make sure the rest of the word is in lower case.
For the purpose of this exercise, you should also capitalize connecting words like "the" and "of".
function titleCase(str/*:string*/) {
let result = '''', len = 0;
for (let i = 0; i < str.length; i++) {
if (str.charAt(i) === '' '') {
if (len === 0) result += '' '';
else {
result += str.charAt(i - len).toUpperCase()
+ str.substr(i - len + 1, len).toLowerCase();
len = 0;
}
} else len++;
}
if (len === 0) return result;
return result + str.charAt(len = str.length - len).toUpperCase()
+ str.substr(len + 1).toLowerCase();
}
titleCase("I''m a little tea pot");
#6. Return Largest Numbers in Arrays
Return an array consisting of the largest number from each provided sub-array. For simplicity, the provided array will contain exactly 4 sub-arrays.
Remember, you can iterate through an array with a simple for loop, and access each member with array syntax arr[i]
.
function largestOfFour(arrs/*:number[][]*/) {
const results = [];
for (const arr of arrs) {
results.push(arr.reduce((max, current) => Math.max(max, current)));
}
return results;
}
largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);
#7. Confirm the Ending
Check if a string (first argument, str
) ends with the given target string (second argument, target
).
This challenge can be solved with the .endsWith()
method, which was introduced in ES2015. But for the purpose of this challenge, we would like you to use one of the JavaScript substring methods instead.
function confirmEnding(str/*:string*/, tar/*:string*/) {
const delta = str.length - tar.length;
if (delta < 0) return false;
for (let i = tar.length; i >= 0; i--) {
if (str.charAt(i + delta) !== tar.charAt(i)) return false;
}
return true;
}
confirmEnding("Bastian", "n");
#8. Repeat a string
Repeat a given string (first argument) num
times (second argument). Return an empty string if num
is not a positive number.
function repeatStringNumTimes(str/*:string*/, num/*:number*/) {
if (num <= 0) return '''';
if (num === 1) return str;
if (num % 2) return str
+ repeatStringNumTimes(str, num - 1);
str = repeatStringNumTimes(str, num >> 1);
return str + str;
}
repeatStringNumTimes("abc", 3);
#9. Truncate a string
Truncate a string (first argument) if it is longer than the given maximum string length (second argument). Return the truncated string with a ...
ending.
Note that inserting the three dots to the end will add to the string length.
However, if the given maximum string length num is less than or equal to 3, then the addition of the three dots does not add to the string length in determining the truncated string.
function truncateString(str/*:string*/, num/*:number*/) {
if (str.length <= num) return str;
if (num > 3) return str.substr(0, num - 3) + ''...'';
return str.substr(0, num) + ''...'';
}
truncateString("A-tisket a-tasket A green and yellow basket", 11);
#10. Chunky Monkey
Write a function that splits an array (first argument) into groups the length of size
(second argument) and returns them as a two-dimensional array.
function chunkArrayInGroups(arr/*:any[]*/, size/*:number*/) {
const results = [];
let start = 0;
while (start < arr.length) {
results.push(arr.slice(start, start = start + size));
}
return results;
}
chunkArrayInGroups(["a", "b", "c", "d"], 2);
#11. Slasher Flick
Return the remaining elements of an array after chopping off n
elements from the head.
The head means the beginning of the array, or the zeroth index.
function slasher(arr/*:any[]*/, howMany/*:number*/) {
return arr.slice(howMany);
}
slasher([1, 2, 3], 2);
#12. Mutations
Return true
if the string in the first element of the array contains all of the letters of the string in the second element of the array.
For example, ["hello", "Hello"]
, should return true
because all of the letters in the second string are present in the first, ignoring case.
The arguments ["hello", "hey"]
should return false
because the string "hello"
does not contain a "y"
.
Lastly, ["Alien", "line"]
, should return true
because all of the letters in "line"
are present in "Alien"
.
function mutation(arr/*:any[]*/) {
const str = arr[0].toLowerCase();
const tar = arr[1].toLowerCase();
for (let i = tar.length - 1; i >= 0; i--) {
if (str.indexOf(tar.charAt(i)) < 0) return false;
}
return true;
}
mutation(["hello", "hey"]);
#13. Falsy Bouncer
Remove all falsy values from an array.
Falsy values in JavaScript are false
, null
, 0
, ""
, undefined
, and NaN
.
function bouncer(arr/*:any[]*/) {
return arr.filter((item) => item);
}
bouncer([7, "ate", "", false, 9]);
#14. Seek and Destroy
You will be provided with an initial array (the first argument in the destroyer function), followed by one or more arguments. Remove all elements from the initial array that are of the same value as these arguments.
function destroyer(arr/*:any[]*/, ...rest/*:any[]*/) {
return arr.filter((item) => rest.indexOf(item) < 0);
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
#15. Where do I belong
Return the lowest index at which a value (second argument) should be inserted into an array (first argument) once it has been sorted. The returned value should be a number.
For example, getIndexToIns([1,2,3,4], 1.5)
should return 1
because it is greater than 1
(index 0), but less than 2 (index 1).
Likewise, getIndexToIns([20,3,5], 19)
should return 2
because once the array has been sorted it will look like [3,5,20]
and 19
is less than 20
(index 2) and greater than 5
(index 1).
function getIndexToIns(arr/*:any[]*/, num/*:number*/) {
return arr.reduce((index, current) => num > current ? index + 1 : index, 0);
}
getIndexToIns([40, 60], 50);
#16. Caesars Cipher
One of the simplest and most widely known ciphers is a Caesar cipher, also known as a shift cipher. In a shift cipher the meanings of the letters are shifted by some set amount.
A common modern use is the ROT13 cipher, where the values of the letters are shifted by 13 places. Thus ''A'' ↔ ''N''
, ''B'' ↔ ''O''
and so on.
Write a function which takes a ROT13 encoded string as input and returns a decoded string.
All letters will be uppercase. Do not transform any non-alphabetic character (i.e. spaces, punctuation), but do pass them on.
function rot13(str/*:string*/) {
const key = ''ABCDEFGHIJKLMNOPQRSTUVWXYZ'';
let decode = '''';
for (let i = 0; i < str.length; i++) {
const index = key.indexOf(str.charAt(i));
if (index < 0) decode += str.charAt(i);
else decode += key.charAt((index + 13) % 26);
}
return decode;
}
rot13("SERR PBQR PNZC");
Beam Search、GREEDY DECODER、SAMPLING DECODER等解码器工作原理可视化
图像标注的任务让我们可以构建和训练一个为任何给定图像生成字幕的神经网络。在设计时使用了解码器的来完成文字的生成。当我们描述了每个解码器的工作原理时,我发现当它们被可视化时,更容易理解它们。
图像标注任务流程图
与翻译模型类似,我们的图像字幕模型通过输入图像张量和特殊的句首标记(即<start>)来启动字幕生成过程。这个模型生成了我们单词的概率分布(实际上是logits)。橙色方框显示解码算法的选择,帮助我们选择使用哪个单词。然后,选择的单词和图像再次传递给模型,直到我们满足停止条件,即我们获得特殊的句子结束标记(即<STOP>)作为下一个单词,或者我们超过了预先定义的步骤数。一个步骤是将图像和单词的张量传递给字幕生成器模型,并使用解码算法选择单词。
在这篇文章中,我们关注的是橙色的盒子。帮助我们从整个词汇表的概率分布中选择单词的解码算法。
GREEDY DECODER(贪心解码器)
这是最直接的方法,我们选择的词有最高的可能性(贪婪的行动)。虽然它可以生成单词序列,但与其他解码算法相比,输出的质量往往较低。
所以我们选择了前60个单词来可视化。另外,它导致标签在每个时间步上切换。
BEAM SEARCH(定向搜索解码器)
在贪婪解码器中,我们在每一步都考虑一个字。如果我们可以在每一步跟踪多个单词并使用它们来生成多个假设会怎样呢?
这正是定向搜索算法所做的,我们定义了每一步需要保留多少个单词(k)。该算法跟踪k个单词及其得分,每个单词都是从之前得分最高的k个单词中获得种子。分数是由到目前为止生成的假设的概率的和计算出来的。
其中t为步长,x为输入图像,y为生成的单词。停止条件与贪心搜索相同,贪心搜索假设在遇到<stop>或超出预先定义的最大步数时停止。</stop>最终的结果是一个单词树多个假设),然后选择得分最高的一个作为最终的解。
单词树结构,橙色表示最终的解
当我们使用k=1时,它的工作方式和贪婪解码器算法一样,同样会产生低质量的输出。当我们增加k时,算法开始产生更好的质量的输出,尽管在更大的k时,输出变得非常短。另外,注意增加k是计算密集型的,因为我们需要在每一步跟踪k个单词。
例如一下图片
使用训练好的模型后生成文字的过程
开始和停止单词以绿色和红色突出显示,灰色文本显示该步骤或时间点的序列得分。
PURE SAMPLING DECODER(纯采样解码器)
纯采样译码器与贪婪搜索译码器非常相似,但不是从概率最高的单词中抽取,而是从整个词汇表的概率分布中随机抽取单词。纯抽样和Top-K抽样(下面)等抽样方法提供了更好的多样性,通常被认为更能生成自然语言。
上图的文字描述生成过程
您可能已经注意到解码器没有在“street<stop>”处停止,这是因为我们的stop条件需要精确的“<stop>”令牌。</stop></stop>
TOP-K SAMPLING DECODER(TOP-K抽样解码器)
该方法类似于纯采样译码器,但不是使用整个概率分布,而是只对top-k个可能单词进行采样。如果我们用k=1,它和贪婪搜索是一样的如果我们用词汇表的总长度作为k,那么它可以作为纯采样解码器。下面的可视化使用与纯采样示例相同的输入图像。
结论
这就是我在关于神经图像标题生成的文章中使用的各种解码算法的可视化。下面是最后一个示例,显示了四个解码器对同一输入图像的输出。
虽然这里生成的字幕的整体质量不如基于注意力的模式好,但我们可以看到不同的解码器对于结果的影响。
作者:Katnoria
原文地址:https://www.katnoria.com/nlg-decoders/
deephub翻译组
微信号 : deephub-imba
每日大数据和人工智能的重磅干货
大厂职位内推信息
长按识别二维码关注 ->

喜欢就请三连暴击!
本文分享自微信公众号 - DeepHub IMBA(deephub-imba)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
canvas 笔记整理
canvas 判断点是否在多边形内部
射线法判断点是否在多边形内部
/**
* @description 射线法判断点是否在多边形内部
* @param {Object} p 待判断的点,格式:{ x: X坐标, y: Y坐标 }
* @param {Array} poly 多边形顶点,数组成员的格式同 p
* @return {String} 点 p 和多边形 poly 的几何关系
*/
function rayCasting(p, poly) {
var px = p.x,
py = p.y,
flag = false
for(var i = 0, l = poly.length, j = l - 1; i < l; j = i, i++) {
var sx = poly[i].x,
sy = poly[i].y,
tx = poly[j].x,
ty = poly[j].y
// 点与多边形顶点重合
if((sx === px && sy === py) || (tx === px && ty === py)) {
return ''on''
}
// 判断线段两端点是否在射线两侧
if((sy < py && ty >= py) || (sy >= py && ty < py)) {
// 线段上与射线 Y 坐标相同的点的 X 坐标
var x = sx + (py - sy) * (tx - sx) / (ty - sy)
// 点在多边形的边上
if(x === px) {
return ''on''
}
// 射线穿过多边形的边界
if(x > px) {
flag = !flag
}
}
}
// 射线穿过多边形边界的次数为奇数时点在多边形内
return flag ? ''in'' : ''out''
}
回转数法实现 判断点是否在多边形内部
/**
* @description 回转数法判断点是否在多边形内部
* @param {Object} p 待判断的点,格式:{ x: X坐标, y: Y坐标 }
* @param {Array} poly 多边形顶点,数组成员的格式同 p
* @return {String} 点 p 和多边形 poly 的几何关系
*/
function windingNumber(p, poly) {
var px = p.x,
py = p.y,
sum = 0
for(var i = 0, l = poly.length, j = l - 1; i < l; j = i, i++) {
var sx = poly[i].x,
sy = poly[i].y,
tx = poly[j].x,
ty = poly[j].y
// 点与多边形顶点重合或在多边形的边上
if((sx - px) * (px - tx) >= 0 && (sy - py) * (py - ty) >= 0 && (px - sx) * (ty - sy) === (py - sy) * (tx - sx)) {
return ''on''
}
// 点与相邻顶点连线的夹角
var angle = Math.atan2(sy - py, sx - px) - Math.atan2(ty - py, tx - px)
// 确保夹角不超出取值范围(-π 到 π)
if(angle >= Math.PI) {
angle = angle - Math.PI * 2
} else if(angle <= -Math.PI) {
angle = angle + Math.PI * 2
}
sum += angle
}
// 计算回转数并判断点和多边形的几何关系
return Math.round(sum / Math.PI) === 0 ? ''out'' : ''in''
}
参考:
http://www.html-js.com/article/1538
isPointInPath()方法
定义与用法: isPointInPath()方法返回true,如果给定的点的坐标位于路径之内的话(包括路径的边),否则返回 false。
语法: context.isPointInPath(x,y);//其中x,y分别是给定点的横、纵坐标
isPointInStroke()
是 Canvas 2D API 用于检测某点是否在路径的描边线上的方法。返回值是一个布尔值,当这个点在路径的描边线上,则返回true,否则返回false。
结合 isPointInPath,然后判断 点与边界重合,这样兼容点在线上的点击事件;
canvas Retina 屏幕优化
/**
* HiDPI Canvas Polyfill (1.0.9)
*
* Author: Jonathan D. Johnson (http://jondavidjohn.com)
* Homepage: https://github.com/jondavidjohn/hidpi-canvas-polyfill
* Issue Tracker: https://github.com/jondavidjohn/hidpi-canvas-polyfill/issues
* License: Apache 2.0
*/
;(function(prototype) {
var pixelRatio = (function(context) {
var backingStore = context.backingStorePixelRatio ||
context.webkitBackingStorePixelRatio ||
context.mozBackingStorePixelRatio ||
context.msBackingStorePixelRatio ||
context.oBackingStorePixelRatio ||
context.backingStorePixelRatio || 1;
return (window.devicePixelRatio || 1) / backingStore;
})(prototype),
forEach = function(obj, func) {
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
func(obj[p], p);
}
}
},
ratioArgs = {
''fillRect'': ''all'',
''clearRect'': ''all'',
''strokeRect'': ''all'',
''moveTo'': ''all'',
''lineTo'': ''all'',
''arc'': [0,1,2],
''arcTo'': ''all'',
''bezierCurveTo'': ''all'',
''isPointinPath'': ''all'',
''isPointinStroke'': ''all'',
''quadraticCurveTo'': ''all'',
''rect'': ''all'',
''translate'': ''all'',
''createRadialGradient'': ''all'',
''createLinearGradient'': ''all''
};
if (pixelRatio === 1) return;
forEach(ratioArgs, function(value, key) {
prototype[key] = (function(_super) {
return function() {
var i, len,
args = Array.prototype.slice.call(arguments);
if (value === ''all'') {
args = args.map(function(a) {
return a * pixelRatio;
});
}
else if (Array.isArray(value)) {
for (i = 0, len = value.length; i < len; i++) {
args[value[i]] *= pixelRatio;
}
}
return _super.apply(this, args);
};
})(prototype[key]);
});
// Stroke lineWidth adjustment
prototype.stroke = (function(_super) {
return function() {
this.lineWidth *= pixelRatio;
_super.apply(this, arguments);
this.lineWidth /= pixelRatio;
};
})(prototype.stroke);
// Text
//
prototype.fillText = (function(_super) {
return function() {
var args = Array.prototype.slice.call(arguments);
args[1] *= pixelRatio; // x
args[2] *= pixelRatio; // y
this.font = this.font.replace(
/(\d+)(px|em|rem|pt)/g,
function(w, m, u) {
return (m * pixelRatio) + u;
}
);
_super.apply(this, args);
this.font = this.font.replace(
/(\d+)(px|em|rem|pt)/g,
function(w, m, u) {
return (m / pixelRatio) + u;
}
);
};
})(prototype.fillText);
prototype.strokeText = (function(_super) {
return function() {
var args = Array.prototype.slice.call(arguments);
args[1] *= pixelRatio; // x
args[2] *= pixelRatio; // y
this.font = this.font.replace(
/(\d+)(px|em|rem|pt)/g,
function(w, m, u) {
return (m * pixelRatio) + u;
}
);
_super.apply(this, args);
this.font = this.font.replace(
/(\d+)(px|em|rem|pt)/g,
function(w, m, u) {
return (m / pixelRatio) + u;
}
);
};
})(prototype.strokeText);
})(CanvasRenderingContext2D.prototype);
;(function(prototype) {
prototype.getContext = (function(_super) {
return function(type) {
var backingStore, ratio,
context = _super.call(this, type);
if (type === ''2d'') {
backingStore = context.backingStorePixelRatio ||
context.webkitBackingStorePixelRatio ||
context.mozBackingStorePixelRatio ||
context.msBackingStorePixelRatio ||
context.oBackingStorePixelRatio ||
context.backingStorePixelRatio || 1;
ratio = (window.devicePixelRatio || 1) / backingStore;
if (ratio > 1) {
this.style.height = this.height + ''px'';
this.style.width = this.width + ''px'';
this.width *= ratio;
this.height *= ratio;
}
}
return context;
};
})(prototype.getContext);
})(HTMLCanvasElement.prototype);
jcanvascript.js类库 备份
/*!
* jCanvaScript JavaScript Library v 1.5.18
* http://jcscript.com/
*
* Copyright 2012, Alexander Savin
* Dual licensed under the MIT or GPL Version 2 licenses.
*/
(function (window, undefined) {
var canvases = [],
m = Math,
m_pi = m.PI,
pi2 = m_pi * 2,
lastCanvas = 0, lastLayer = 0,
underMouse = false,
underMouseLayer = false,
regHasLetters = /[A-z]+?/,
regNumsWithMeasure = /\d.\w\w/,
FireFox = window.navigator.userAgent.match(/Firefox\/\w+\.\w+/i),
radian = 180 / m_pi,
m_max = m.max,
m_min = m.min,
m_cos = m.cos,
m_sin = m.sin,
m_floor = m.floor,
m_round = m.round,
m_abs = m.abs,
m_pow = m.pow,
m_sqrt = m.sqrt,
fps = 1000 / 60,
requestAnimFrame = (function () {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback, element) {
return setTimeout(callback, fps);
}
})(),
cancelRequestAnimFrame = (function () {
return window.cancelAnimationFrame ||
window.webkitCancelRequestAnimationFrame ||
window.mozCancelRequestAnimationFrame ||
window.oCancelRequestAnimationFrame ||
window.msCancelRequestAnimationFrame ||
clearTimeout
})();
if (FireFox != "" && FireFox !== null)
var FireFox_lt_7 = (parseInt(FireFox[0].split(/[ \/\.]/i)[1]) < 7);
function findById(i, j, stroke) {
var objs = canvases[i].layers[j].objs,
grdntsnptrns = canvases[i].layers[j].grdntsnptrns,
objsLength = objs.length,
grdntsnptrnsLength = grdntsnptrns.length;
stroke = stroke.slice(1);
for (var k = 0; k < objsLength; k++)
if (objs[k].optns.id == stroke)return objs[k];
for (k = 0; k < grdntsnptrnsLength; k++)
if (grdntsnptrns[k].optns.id == stroke)return grdntsnptrns[k];
return false;
}
function findByName(i, j, myGroup, stroke) {
var objs = canvases[i].layers[j].objs,
grdntsnptrns = canvases[i].layers[j].grdntsnptrns,
strokes = stroke.slice(1).split(''.'');
findByNames(myGroup, strokes, objs);
findByNames(myGroup, strokes, grdntsnptrns);
return myGroup;
function findByNames(myGroup, strokes, objs){
var objsLength = objs.length,
names, l, k, m;
for (k = 0; k < objsLength; k++) {
names = objs[k]._name.split('' '');
if(strokes.length > names.length){
continue;
}
var strokesClone = strokes.concat();
for(l = 0; l < names.length; l++){
for(m = 0; m < strokesClone.length; m++){
if (names[l] === strokesClone[m]) {
strokesClone.splice(m, 1);
m--;
continue;
}
}
if(!strokesClone.length){
myGroup.elements.push(objs[k]);
break;
}
}
}
}
}
function findByCanvasAndLayer(i, j, myGroup) {
var objs = canvases[i].layers[j].objs,
grdntsnptrns = canvases[i].layers[j].grdntsnptrns,
objsLength = objs.length,
grdntsnptrnsLength = grdntsnptrns.length;
for (var k = 0; k < objsLength; k++)
myGroup.elements.push(objs[k]);
for (k = 0; k < grdntsnptrnsLength; k++)
myGroup.elements.push(grdntsnptrns[k]);
return myGroup;
}
var jCanvaScript = function (stroke, map) {
if (stroke === undefined)return this;
if (typeof stroke == ''object'') {
map = stroke;
stroke = undefined;
}
var canvasNumber = -1, layerNumber = -1, limitC = canvases.length, myGroup = group(), i, j, canvas, layer, layers, element, limitL;
if (map === undefined) {
if (stroke.charAt(0) === ''#'') {
for (i = 0; i < limitC; i++) {
limitL = canvases[i].layers.length;
for (j = 0; j < limitL; j++) {
element = findById(i, j, stroke);
if (element)return element;
}
}
}
if (stroke.charAt(0) === ''.'') {
for (i = 0; i < limitC; i++) {
limitL = canvases[i].layers.length;
for (j = 0; j < limitL; j++)
myGroup = findByName(i, j, myGroup, stroke);
}
}
}
else {
if (map.canvas !== undefined) {
for (i = 0; i < limitC; i++)
if (canvases[i].optns.id == map.canvas) {
canvasNumber = i;
canvas = canvases[i];
break;
}
}
if (map.layer !== undefined) {
if (canvasNumber != -1) {
limitL = canvas.layers.length;
for (i = 0; i < limitL; i++)
if (canvas.layers[i].optns.id == map.layer) {
layerNumber = i;
layer = canvas.layers[i];
break;
}
}
else {
for (i = 0; i < limitC; i++) {
layers = canvases[i].layers;
limitL = layers.length;
for (j = 0; j < limitL; j++) {
if (layers[j].optns.id == map.layer) {
canvasNumber = i;
layerNumber = j;
canvas = canvases[i]
layer = canvas.layers[j];
break;
}
}
if (layer > -1)break;
}
}
}
if (layerNumber < 0 && canvasNumber < 0)return group();
if (layerNumber < 0) {
layers = canvas.layers;
limitL = layers.length;
if (stroke === undefined) {
for (j = 0; j < limitL; j++)
myGroup = findByCanvasAndLayer(canvasNumber, j, myGroup);
}
else if (stroke.charAt(0) === ''#'') {
for (j = 0; j < limitL; j++) {
element = findById(canvasNumber, j, stroke);
if (element)return element;
}
}
else if (stroke.charAt(0) === ''.'') {
for (j = 0; j < limitL; j++)
myGroup = findByName(canvasNumber, j, myGroup, stroke);
}
}
else {
if (stroke === undefined) {
myGroup = findByCanvasAndLayer(canvasNumber, layerNumber, myGroup);
}
if (stroke.charAt(0) === ''#'') {
return findById(canvasNumber, layerNumber, stroke);
}
if (stroke.charAt(0) === ''.'') {
myGroup = findByName(canvasNumber, layerNumber, myGroup, stroke)
}
}
}
if (map !== undefined)
if (map.attrs !== undefined || map.fns !== undefined)
return myGroup.find(map);
if (myGroup.elements.length)return myGroup;
return group();
}
function changeMatrix(object)
{
var optns=object.optns;
object.matrix(multiplyM(multiplyM(multiplyM(optns.transformMatrix,optns.translateMatrix),optns.scaleMatrix),optns.rotateMatrix));
redraw(object);
}
function checkDefaults(check,def)
{
for(var key in def)
{
if(check[key]===undefined)check[key]=def[key];
}
return check;
}
function redraw(object)
{
objectCanvas(object).optns.redraw=1;
}
function animating(canvasOptns)
{
var timeDiff=canvasOptns.timeDiff,
progress=1;
for(var q=0;q<this.animateQueue.length;q++)
{
var queue=this.animateQueue[q],
duration=queue[''duration''],
easing=queue[''easing''],
step=queue.step,
onstep=queue[''onstep''],
easingIn=easing[''type'']==''in'' || (easing[''type'']==''inOut'' && progress<0.5),
easingOut=easing[''type'']==''out'' || (easing[''type'']==''inOut'' && progress>0.5);
queue[''step'']+=timeDiff;
progress=step/duration;
for(var key in queue)
{
if(this[key]!==undefined && queue[key])
{
var property=queue[key],
to=property[''to''],
from=property[''from''];
animateTransforms(key,this,queue);
if(easingIn)this[key]=(to-from)*animateFunctions[easing[''fn'']](progress,easing)+from;
if(easingOut)this[key]=(to-from)*(1-animateFunctions[easing[''fn'']](1-progress,easing))+from;
if(onstep)onstep.fn.call(this,onstep);
if(step>=duration)
{
this[key]=to;
animateTransforms(key,this,queue);
queue[key]=false;
queue.animateKeyCount--;
if(!queue.animateKeyCount)
{
if(queue.animateFn)queue.animateFn.apply(this);
this.animateQueue.splice(q,1);
q--;
}
}
}
}
}
if (this.animateQueue.length)redraw(this);
else this.optns.animated=false;
return this;
}
function animateTransforms(key,object,queue)
{
var val=object[key];
var prev=queue[key][''prev''];
switch(key)
{
case ''_rotateAngle'':
object.rotate(val-prev,object._rotateX,object._rotateY);
break;
case ''_translateX'':
object.translate(val-prev,0);
break;
case ''_translateY'':
object.translate(0,val-prev);
break;
case ''_translateToX'':
object.translateTo(val,undefined);
break;
case ''_translateToY'':
object.translateTo(undefined,val);
break;
case ''_scaleX'':
if(!prev)prev=1;
object.scale(val/prev,1);
break;
case ''_scaleY'':
if(!prev)prev=1;
object.scale(1,val/prev);
break;
default:
return;
}
queue[key][''prev'']=val;
}
function keyEvent(e,key,optns)
{
e=e||window.event;
optns[key].event=e;
optns[key].code=e.charCode||e.keyCode;
optns[key].val=true;
optns.redraw=1;
}
function mouseEvent(e,key,optns)
{
if(!optns[key].val)return;
e=e||window.event;
var point= {
pageX:e.pageX||e.clientX,
pageY:e.pageY||e.clientY
};
optns[key].event=e;
optns[key].x=point.pageX - optns.x;
optns[key].y=point.pageY - optns.y;
optns.redraw=1;
}
function setMouseEvent(fn,eventName)
{
if(fn===undefined)this[''on''+eventName]();
else this[''on''+eventName] = fn;
if(eventName==''mouseover''||eventName==''mouseout'')eventName=''mousemove'';
objectCanvas(this).optns[eventName].val=true;
return this;
}
function setKeyEvent(fn,eventName)
{
if(fn===undefined)this[eventName]();
else this[eventName] = fn;
return this;
}
var animateFunctions={
linear:function(progress,params){
return progress;
},
exp:function(progress,params){
var n=params.n||2;
return m_pow(progress,n);
},
circ:function(progress,params){
return 1 - m_sqrt(1-progress*progress);
},
sine:function(progress,params){
return 1 - m_sin((1 - progress) * m_pi/2);
},
back:function(progress,params){
var n=params.n||2;
var x=params.x||1.5;
return m_pow(progress, n) * ((x + 1) * progress - x);
},
elastic:function(progress,params){
var n=params.n||2;
var m=params.m||20;
var k=params.k||3;
var x=params.x||1.5;
return m_pow(n,10 * (progress - 1)) * m_cos(m * progress * m_pi * x / k);
},
bounce:function(progress,params)
{
var n=params.n||4;
var b=params.b||0.25;
var sum = [1];
for(var i=1; i<n; i++) sum[i] = sum[i-1] + m_pow(b, i/2);
var x = 2*sum[n-1]-1;
for(i=0; i<n; i++)
{
if(x*progress >= (i>0 ? 2*sum[i-1]-1 : 0) && x*progress <= 2*sum[i]-1)
return m_pow(x*(progress-(2*sum[i]-1-m_pow(b, i/2))/x), 2)+1-m_pow(b, i);
}
return 1;
}
},
imageDataFilters={
color:{fn:function(width,height,matrix,type){
var old,i,j;
matrix=matrix[type];
for(i=0;i<width;i++)
for(j=0;j<height;j++)
{
old=this.getPixel(i,j);
old[matrix[0]]=old[matrix[0]]*2-old[matrix[1]]-old[matrix[2]];
old[matrix[1]]=0;
old[matrix[2]]=0;
old[matrix[0]]=old[matrix[0]]>255?255:old[matrix[0]];
this.setPixel(i,j,old);
}
},matrix:
{
red:[0,1,2],
green:[1,0,2],
blue:[2,0,1]
}},
linear:{fn:function(width,height,matrix,type){
var newMatrix=[],old,i,j,k,m,n;
matrix=matrix[type];
m=matrix.length;
n=matrix[0].length;
for(i=0;i<width;i++)
{
newMatrix[i]=[];
for(j=0;j<height;j++)
{
newMatrix[i][j]=[0,0,0,1];
for(m=0;m<3;m++)
for(n=0;n<3;n++)
{
old=this.getPixel(i-parseInt(m/2),j-parseInt(n/2));
for(k=0;k<3;k++)
{
newMatrix[i][j][k]+=old[k]*matrix[m][n];
}
}
}
}
for(i=0;i<width;i++)
{
for(j=0;j<height;j++)
this.setPixel(i,j,newMatrix[i][j]);
}
},
matrix:{
sharp:[[-0.375,-0.375,-0.375],[-0.375,4,-0.375],[-0.375,-0.375,-0.375]],
blur:[[0.111,0.111,0.111],[0.111,0.111,0.111],[0.111,0.111,0.111]]
}
}
}
function multiplyM(m1,m2)
{
return [[(m1[0][0]*m2[0][0]+m1[0][1]*m2[1][0]),(m1[0][0]*m2[0][1]+m1[0][1]*m2[1][1]),(m1[0][0]*m2[0][2]+m1[0][1]*m2[1][2]+m1[0][2])],[(m1[1][0]*m2[0][0]+m1[1][1]*m2[1][0]),(m1[1][0]*m2[0][1]+m1[1][1]*m2[1][1]),(m1[1][0]*m2[0][2]+m1[1][1]*m2[1][2]+m1[1][2])]];
}
function multiplyPointM(x,y,m)
{
return {
x:(x*m[0][0]+y*m[0][1]+m[0][2]),
y:(x*m[1][0]+y*m[1][1]+m[1][2])
}
}
function transformPoint(x,y,m)
{
return{
x:(x*m[1][1]-y*m[0][1]+m[0][1]*m[1][2]-m[1][1]*m[0][2])/(m[0][0]*m[1][1]-m[1][0]*m[0][1]),
y:(-x*m[1][0]+y*m[0][0]-m[0][0]*m[1][2]+m[1][0]*m[0][2])/(m[0][0]*m[1][1]-m[1][0]*m[0][1])
}
}
function getRect(object,rect,type)
{
if(type==''poor'')return rect;
var min={x:rect.x,y:rect.y},max={x:rect.x+rect.width,y:rect.y+rect.height},
m=multiplyM(object.matrix(),objectLayer(object).matrix()),
lt=multiplyPointM(min.x,min.y,m),
rt=multiplyPointM(max.x,min.y,m),
lb=multiplyPointM(min.x,max.y,m),
rb=multiplyPointM(max.x,max.y,m),
coords=[[lt.x,lt.y],[rt.x,rt.y],[lb.x,lb.y],[rb.x,rb.y]];
if(type==''coords'')return coords;
var minX, minY,
maxX=minX=lt.x,
maxY=minY=lt.y;
for(var i=0;i<4;i++)
{
if(maxX<coords[i][0])maxX=coords[i][0];
if(maxY<coords[i][1])maxY=coords[i][1];
if(minX>coords[i][0])minX=coords[i][0];
if(minY>coords[i][1])minY=coords[i][1];
}
return {x:minX,y:minY,width:maxX-minX,height:maxY-minY};
}
function getCenter(object,point,type)
{
if(type==''poor'')return point;
return multiplyPointM(point.x,point.y,multiplyM(object.matrix(),objectLayer(object).matrix()));
}
function parseColor(color)
{
var colorKeeper={
color:{
val:color,
notColor:undefined
},
r:0,
g:0,
b:0,
a:1};
if(color.id!==undefined)
{
colorKeeper.color.notColor={
level:color._level,
canvas:color.optns.canvas.number,
layer:color.optns.layer.number
}
return colorKeeper;
}
if(color.r!==undefined)
{
colorKeeper=checkDefaults(color,{r:0,g:0,b:0,a:1});
colorKeeper.color={
val:''rgba(''+colorKeeper.r+'',''+colorKeeper.g+'',''+colorKeeper.b+'',''+colorKeeper.a+'')'',
notColor:undefined
}
return colorKeeper;
}
if(color.charAt(0)==''#'')
{
if (color.length > 4) {
colorKeeper.r = parseInt(color.substr(1, 2), 16);
colorKeeper.g = parseInt(color.substr(3, 2), 16);
colorKeeper.b = parseInt(color.substr(5, 2), 16);
}
else {
var r = color.charAt(1), g = color.charAt(2), b = color.charAt(3);
colorKeeper.r = parseInt(r + r, 16);
colorKeeper.g = parseInt(g + g, 16);
colorKeeper.b = parseInt(b + b, 16);
}
}
else
{
var arr=color.split('','');
if(arr.length==4)
{
var colorR = arr[0].split(''('');
var alpha = arr[3].split('')'');
colorKeeper.r=parseInt(colorR[1]);
colorKeeper.g=parseInt(arr[1]);
colorKeeper.b=parseInt(arr[2]);
colorKeeper.a=parseFloat(alpha[0]);
}
if(arr.length==3)
{
colorR = arr[0].split(''('');
var colorB = arr[2].split('')'');
colorKeeper.r=parseInt(colorR[1]);
colorKeeper.g=parseInt(arr[1]);
colorKeeper.b=parseInt(colorB[0]);
}
}
colorKeeper.color.notColor = undefined;
return colorKeeper;
}
function getOffset(elem) {
if (elem.getBoundingClientRect) {
return getOffsetRect(elem)
} else {
return getOffsetSum(elem)
}
}
function getOffsetSum(elem) {
var top=0, left=0
while(elem) {
top = top + parseInt(elem.offsetTop)
left = left + parseInt(elem.offsetLeft)
elem = elem.offsetParent
}
return {
top: top,
left: left
}
}
function getOffsetRect(elem) {
var box = elem.getBoundingClientRect()
var body = document.body||{};
var docElem = document.documentElement
var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop
var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft
var clientTop = docElem.clientTop || body.clientTop || 0
var clientLeft = docElem.clientLeft || body.clientLeft || 0
var top = box.top + scrollTop - clientTop
var left = box.left + scrollLeft - clientLeft
return {
top: m_round(top),
left: m_round(left)
}
}
function checkEvents(object,optns)
{
checkMouseEvents(object,optns);
checkKeyboardEvents(object,optns);
}
function checkKeyboardEvents(object,optns)
{
if(!object.optns.focused)return;
if(optns.keyDown.val!=false)if(typeof object.onkeydown==''function'')object.onkeydown(optns.keyDown);
if(optns.keyUp.val!=false)if(typeof object.onkeyup==''function'')object.onkeyup(optns.keyUp);
if(optns.keyPress.val!=false)if(typeof object.onkeypress==''function'')object.onkeypress(optns.keyPress);
}
function isPointInPath(object,x,y)
{
var point={};
var canvas=objectCanvas(object);
var ctx=canvas.optns.ctx;
var layer=canvas.layers[object.optns.layer.number];
point.x=x;
point.y=y;
if(FireFox_lt_7)
{
point=transformPoint(x,y,layer.matrix());
point=transformPoint(point.x,point.y,object.matrix());
}
if(ctx.isPointInPath===undefined || object._img!==undefined || object._imgData!==undefined || object._proto==''text'')
{
var rectangle=object.getRect(''poor'');
var poorPoint=transformPoint(x,y,multiplyM(object.matrix(),layer.matrix()));
if(rectangle.x<=poorPoint.x && rectangle.y<=poorPoint.y && (rectangle.x+rectangle.width)>=poorPoint.x && (rectangle.y+rectangle.height)>=poorPoint.y)return point;
}
else
{
if(ctx.isPointInPath(point.x,point.y)){
return point;
}
}
return false
}
function checkMouseEvents(object,optns)
{
var point=false,
mm=optns.mousemove,
md=optns.mousedown,
mu=optns.mouseup,
c=optns.click,
dc=optns.dblclick,
x=mm.x||md.x||mu.x||dc.x||c.x,
y=mm.y||md.y||mu.y||dc.y||c.y;
if(x!=false)
{
point=isPointInPath(object,x,y);
}
if(point)
{
if(mm.x!=false)
mm.object=object;
if(md.x!=false)
md.objects[md.objects.length]=object;
if(c.x!=false)
c.objects[c.objects.length]=object;
if(dc.x!=false)
dc.objects[dc.objects.length]=object;
if(mu.x!=false)
mu.objects[mu.objects.length]=object;
optns.point=point;
}
}
function objectLayer(object)
{
return objectCanvas(object).layers[object.optns.layer.number];
}
function objectCanvas(object)
{
return canvases[object.optns.canvas.number];
}
function layer(idLayer,object,array)
{
redraw(object);
var objectCanvas=object.optns.canvas;
var objectLayer=object.optns.layer;
if (idLayer===undefined)return objectLayer.id;
if(objectLayer.id==idLayer)return object;
var oldIndex={
i:objectCanvas.number,
j:objectLayer.number
};
objectLayer.id=idLayer;
var newLayer=jCanvaScript.layer(idLayer);
var newIndex={
i:newLayer.optns.canvas.number,
j:newLayer.optns.number
};
var oldArray=canvases[oldIndex.i].layers[oldIndex.j][array],newArray=canvases[newIndex.i].layers[newIndex.j][array];
oldArray.splice(object.optns.number,1);
object._level=object.optns.number=newArray.length;
newArray[object._level]=object;
objectLayer.number=newIndex.j;
objectCanvas.number=newIndex.i;
objectCanvas.id=newLayer.optns.canvas.id;
redraw(object);
return object;
}
function take(f,s) {
for(var key in s)
{
switch(typeof s[key])
{
case ''function'':
if(key.substr(0,2)==''on'')break;
if(f[key]===undefined)f[key]=s[key];
break;
case ''object'':
if(key==''optns'' || key==''animateQueue'')break;
if(key==''objs'' || key==''grdntsnptrns'')
{
for(var i in s[key])
{
if(s[key].hasOwnProperty(i))
s[key][i].clone().layer(f.optns.id);
}
break;
}
if(!s[key] || key===''ctx'')continue;
f[key]=typeof s[key].pop === ''function'' ? []:{};
take(f[key],s[key]);
break;
default:
if(key==''_level'')break;
f[key]=s[key];
}
}
}
function canvas(idCanvas,object,array)
{
redraw(object);
var objectCanvas=object.optns.canvas;
var objectLayer=object.optns.layer;
if(idCanvas===undefined)return canvases[objectCanvas.number].optns.id;
if(canvases[objectCanvas.number].optns.id==idCanvas)return object;
var oldIndex={
i:objectCanvas.number,
j:objectLayer.number
};
jCanvaScript.canvas(idCanvas);
for(var i=0;i<canvases.length;i++)
{
var canvasItem=canvases[i];
if(canvasItem.optns.id==idCanvas)
{
var oldArray=canvases[oldIndex.i].layers[oldIndex.j][array],newArray=canvasItem.layers[0][array];
oldArray.splice(object.optns.number,1);
normalizeLevels(oldArray);
object._level=object.optns.number=newArray.length;
newArray[object._level]=object;
objectLayer.number=0;
objectCanvas.number=i;
objectCanvas.id=canvasItem.optns.id;
objectLayer.id=canvasItem.layers[0].optns.id;
}
}
redraw(object);
return object;
}
function normalizeLevels(array)
{
for(var i=0;i<array.length;i++)
{
array[i].optns.number=i;
}
}
function setLayerAndCanvasToArray(array,newLayerId,newLayerNumber,newCanvasId,newCanvasNumber)
{
var limit=array.length,
optns,canvas,layer;
for(var i=0;i<limit;i++)
{
optns=array[i].optns;
canvas=optns.canvas;
layer=optns.layer;
canvas.id=newCanvasId;
canvas.number=newCanvasNumber;
layer.id=newLayerId;
layer.number=newLayerNumber;
}
}
function levelChanger(array)
{
array.sort(function(a,b){
if(a._level>b._level)return 1;
if(a._level<b._level)return -1;
return 0;
});
normalizeLevels(array);
return array.length;
}
function objDeleter(array)
{
var isAnyObjectDeleted;
do{
isAnyObjectDeleted=false;
for(var i=0;i<array.length;i++)
{
if(array[i].optns.deleted)
{
array.splice(i,1);
isAnyObjectDeleted=true;
}
}
}while(isAnyObjectDeleted);
normalizeLevels(array);
return array.length;
}
var proto={};
proto.object=function()
{
this.getCenter=function(type){
var rect=this.getRect(''poor''),
point = {
x:(rect.x*2+rect.width)/2,
y:(rect.y*2+rect.height)/2
};
return getCenter(this,point,type);
}
this.position=function(){
return multiplyPointM(this._x,this._y,multiplyM(this.matrix(),objectLayer(this).matrix()));
}
this.buffer=function(doBuffering){
var bufOptns=this.optns.buffer;
if(doBuffering===undefined)
if(bufOptns.val)return bufOptns.cnv;
else return false;
if(bufOptns.val===doBuffering)return this;
if(doBuffering)
{
var cnv=bufOptns.cnv=document.createElement(''canvas''),
ctx=bufOptns.ctx=cnv.getContext(''2d''),
rect=bufOptns.rect=this.getRect(),
oldM=this.transform();
cnv.setAttribute(''width'',rect.width);
cnv.setAttribute(''height'',rect.height);
bufOptns.x=this._x;
bufOptns.y=this._y;
bufOptns.dx=this._transformdx;
bufOptns.dy=this._transformdy;
this._x=this._y=0;
this.transform(1, 0, 0, 1, -rect.x+bufOptns.dx, -rect.y+bufOptns.dy,true);
this.setOptns(ctx);
take(bufOptns.optns={},objectCanvas(this).optns);
bufOptns.optns.ctx=ctx;
this.draw(bufOptns.optns);
this._x=bufOptns.x;
this._y=bufOptns.y;
this.transform(oldM[0][0], oldM[1][0], oldM[0][1], oldM[1][1], rect.x, rect.y,true);
bufOptns.val=true;
}
else
{
this.translate(-bufOptns.rect.x+bufOptns.dx,-bufOptns.rect.y+bufOptns.dy);
this.optns.buffer={val:false};
}
return this;
}
this.clone=function(params)
{
var clone=new proto[this._proto];
proto[this._proto].prototype.base.call(clone);
take(clone,this);
clone.layer(objectLayer(this).optns.id);
take(clone.optns.transformMatrix,this.optns.transformMatrix);
take(clone.optns.translateMatrix,this.optns.translateMatrix);
take(clone.optns.scaleMatrix,this.optns.scaleMatrix);
take(clone.optns.rotateMatrix,this.optns.rotateMatrix);
if(params===undefined) return clone;
return clone.animate(params);
}
this.shadow= function(options)
{
for(var key in options)
switch (key)
{
case ''x'':
this._shadowX=options.x;
break;
case ''y'':
this._shadowY=options.y;
break;
case ''blur'':
this._shadowBlur=options.blur;
break;
case ''color'':
var colorKeeper = parseColor(options.color);
this._shadowColor = options.color.val;
this._shadowColorR = colorKeeper.r;
this._shadowColorG = colorKeeper.g;
this._shadowColorB = colorKeeper.b;
this._shadowColorA = colorKeeper.a;
break;
}
redraw(this);
return this;
}
this.setOptns=function(ctx)
{
ctx.globalAlpha = this._opacity;
ctx.shadowOffsetX = this._shadowX;
ctx.shadowOffsetY = this._shadowY;
ctx.shadowBlur = this._shadowBlur;
ctx.globalCompositeOperation=this._composite;
var rInt = parseInt(this._shadowColorR),
gInt = parseInt(this._shadowColorG),
bInt = parseInt(this._shadowColorB),
aInt = parseInt(this._shadowColorA * 100) / 100;
if (this._shadowColorRPrev !== rInt || this._shadowColorGPrev !== gInt || this._shadowColorBPrev !== bInt || this._shadowColorAPrev !== aInt) {
ctx.shadowColor = this._shadowColor = ''rgba('' + rInt + '', '' + gInt + '', '' + bInt + '', '' + aInt+ '')'';
this._shadowColorRPrev = rInt;
this._shadowColorGPrev = gInt;
this._shadowColorBPrev = bInt;
this._shadowColorAPrev = aInt;
}
else {
ctx.shadowColor = this._shadowColor;
}
ctx.transform(this._transform11,this._transform12,this._transform21,this._transform22,this._transformdx,this._transformdy);
return this;
}
this.up=function(n)
{
if(n === undefined)n=1;
if(n==''top'')this.level(n);
else {
var next=objectLayer(this).objs[this.optns.number+n];
if(next!==undefined)
{
n=next._level+1-this._level;
}
this.level(this._level+n);
}
return this;
}
this.down=function(n)
{
if(n == undefined)n=1;
if(n == ''bottom'')this.level(n);
else {
var previous=objectLayer(this).objs[this.optns.number-n];
if(previous!==undefined)
{
n=this._level-(previous._level-1);
}
this.level(this._level-n);
}
return this;
}
this.level=function(n)
{
if(n == undefined)return this._level;
var layer=objectLayer(this);
if(n==''bottom'')
{
if(this.optns.number==0)n=this._level;
else n=layer.objs[0]._level-1;
}
if(n==''top'')
{
if(this.optns.number==layer.objs.length)n=this._level;
else n=layer.objs[layer.objs.length-1]._level+1;
}
this._level=n;
layer.optns.anyObjLevelChanged = true;
redraw(this);
return this;
}
this.del=function()
{
this.optns.deleted=true;
objectLayer(this).optns.anyObjDeleted = true;
redraw(this);
}
this.focus=function(fn)
{
if(fn===undefined)
{
this.optns.focused=true;
if(typeof this.onfocus==''function'')this.onfocus();
}
else this.onfocus=fn;
return this;
}
this.blur=function(fn)
{
if(fn===undefined)
{
this.optns.focused=false;
if(typeof this.onblur == ''function'')this.onblur();
}
else this.onblur=fn;
return this;
}
this.click= function(fn)
{
return setMouseEvent.call(this,fn,''click'');
}
this.dblclick = function(fn)
{
return setMouseEvent.call(this,fn,''dblclick'');
}
this.keypress= function(fn)
{
return setKeyEvent.call(this,fn,''onkeypress'');
}
this.keydown= function(fn)
{
return setKeyEvent.call(this,fn,''onkeydown'');
}
this.keyup= function(fn)
{
return setKeyEvent.call(this,fn,''onkeyup'');
}
this.mousedown= function(fn)
{
return setMouseEvent.call(this,fn,''mousedown'');
}
this.mouseup= function(fn)
{
return setMouseEvent.call(this,fn,''mouseup'');
}
this.mousemove= function(fn)
{
return setMouseEvent.call(this,fn,''mousemove'');
}
this.mouseover= function(fn)
{
return setMouseEvent.call(this,fn,''mouseover'');
}
this.mouseout= function(fn)
{
return setMouseEvent.call(this,fn,''mouseout'');
}
this.attr=function(parameter,value)
{
if(typeof parameter===''object'')
var parameters=parameter;
else
{
if(value===undefined)
return this[''_''+parameter];
parameters={};
parameters[parameter]=value;
}
return this.animate(parameters);
}
this.queue=function(){
var animateQueueLength=this.animateQueue.length, queue,i,j,duration=0,longFn=0,fn,args=arguments;
for (i=0;i<args.length;i++)
{
if(typeof args[i]==''function''){
args[i].apply(this);
args[i]=false;
i++;
if(this.animateQueue.length>animateQueueLength)
{
for (j=animateQueueLength;j<this.animateQueue.length;j++)
{
queue=this.animateQueue[j];
if(queue.duration!==undefined){
if(queue.duration>duration)
{
duration=queue.duration;
longFn=j;
}
break;
}
}
if(duration){
queue=this.animateQueue[longFn];
if(queue.animateFn){
fn=queue.animateFn;
queue.animateFn=function(){
fn.apply(this);
this.queue.apply(this,args)
}
}
else queue.animateFn=function(){this.queue.apply(this,args)};
break;
}
}
}
}
}
this.stop=function(jumpToEnd,runCallbacks)
{
this.optns.animated=false;
if(runCallbacks===undefined)runCallbacks=false;
if(jumpToEnd===undefined)jumpToEnd=false;
for(var q=0;q<this.animateQueue.length;q++)
{
var queue=this.animateQueue[q];
if(runCallbacks)queue.animateFn.call(this);
if(jumpToEnd)
for(var key in queue)
{
if(queue[key][''from'']!==undefined)
{
this[key]=queue[key][''to''];
animateTransforms(key,this,queue);
}
}
}
this.animateQueue=[];
return this;
}
this.animate=function(options,duration,easing,onstep,fn)
{
if(duration===undefined)duration=1;
else
{
if(typeof duration == ''function'')
{
fn=duration;
duration=1;
}
if(typeof duration == ''object'')
{
easing=duration;
duration=1;
}
}
if (easing===undefined)easing={fn:''linear'',type:''in''};
else
{
if(typeof easing == ''function'')
{
fn=easing;
easing={fn:''linear'',type:''in''};
}
if (easing.type===undefined)easing.type=''in'';
}
if(onstep===undefined)onstep=false;
else
{
if(typeof onstep == ''function'')
{
fn=onstep;
onstep=false;
}
}
if(options.scale!==undefined)
{
this._scaleX=this._scaleY=1;
if(typeof options.scale!=''object'')
{
options.scaleX=options.scaleY=options.scale;
}
else
{
options.scaleX=options.scale.x||1;
options.scaleY=options.scale.y||1;
}
}
if(options.translate!==undefined)
{
this._translateX=this._translateY=0;
if(typeof options.translate!=''object'')
{
options.translateX=options.translateY=options.translate;
}
else
{
options.translateX=options.translate.x||0;
options.translateY=options.translate.y||0;
}
options.translate=undefined;
}
if(options.translateTo!==undefined)
{
var point=this.position();
this._translateToX=point.x;
this._translateToY=point.y;
if(typeof options.translateTo!=''object'')
{
options.translateToX=options.translateToY=options.translateTo;
}
else
{
options.translateToX=options.translateTo.x||0;
options.translateToY=options.translateTo.y||0;
}
options.translateTo=undefined;
}
if(options.rotate!==undefined)
{
options.rotateAngle=options.rotate.angle;
this._rotateAngle=0;
this._rotateX=options.rotate.x||0;
this._rotateY=options.rotate.y||0;
options.rotate=undefined;
}
if(options.color !== undefined)
{
var colorKeeper=parseColor(options.color);
if(colorKeeper.color.notColor)
this.optns.color.notColor=colorKeeper.color.notColor;
else
{
options.colorR=colorKeeper.r;
options.colorG=colorKeeper.g;
options.colorB=colorKeeper.b;
options.alpha=colorKeeper.a;
}
options.color = undefined;
}
if(options.shadowColor !== undefined)
{
colorKeeper=parseColor(options.shadowColor);
options.shadowColorR=colorKeeper.r;
options.shadowColorG=colorKeeper.g;
options.shadowColorB=colorKeeper.b;
options.shadowColorA=colorKeeper.a;
options.shadowColor = undefined;
}
if(duration>1)
{
var queue=this.animateQueue[this.animateQueue.length]={animateKeyCount:0};
queue.animateFn=fn||false;
this.optns.animated=true;
queue.duration=duration;
queue.step=0;
queue.easing=easing;
queue.onstep=onstep;
}
for(var key in options)
{
if(this[''_''+key] !== undefined && options[key]!==undefined)
{
var keyValue=options[key],privateKey=''_''+key;
if(keyValue!=this[privateKey])
{
if(keyValue.charAt)
{
if(key==''string'')this._string=keyValue;
else if(keyValue.charAt(1)==''='')
{
keyValue=this[privateKey]+parseInt(keyValue.charAt(0)+''1'')*parseInt(keyValue.substr(2));
}
else if(!regHasLetters.test(keyValue))keyValue=parseInt(keyValue);
else this[privateKey]=keyValue;
}
if(duration==1)this[privateKey]=keyValue;
else
{
queue[privateKey]={
from:this[privateKey],
to:keyValue,
prev:0
}
queue.animateKeyCount++;
}
}
}
}
if(duration==1)
{
if(options[''rotateAngle''])
this.rotate(this._rotateAngle,this._rotateX,this._rotateY);
if(options[''translateX'']||options[''translateY''])
this.translate(this._translateX,this._translateY);
if(options[''translateToX'']||options[''translateToY''])
this.translate(this._translateToX,this._translateToY);
if(options[''scaleX'']||options[''scaleY''])
this.scale(this._scaleX,this._scaleY);
}
redraw(this);
return this;
}
this.matrix=function(m)
{
if(m===undefined)return [[this._transform11,this._transform21,this._transformdx],[this._transform12,this._transform22,this._transformdy]];
this._transform11=m[0][0];
this._transform21=m[0][1];
this._transform12=m[1][0];
this._transform22=m[1][1];
this._transformdx=m[0][2];
this._transformdy=m[1][2];
return this;
}
this.translateTo=function(newX,newY,duration,easing,onstep,fn)
{
if(duration!==undefined)
return this.animate({translateTo:{x:newX,y:newY}},duration,easing,onstep,fn);
var point=this.position(),
x=0,y=0;
if(newX!==undefined)
x=newX-point.x;
if(newY!==undefined)
y=newY-point.y;
return this.translate(x,y);
}
this.translate=function(x,y,duration,easing,onstep,fn)
{
if(duration!==undefined)
return this.animate({translate:{x:x,y:y}},duration,easing,onstep,fn);
this.optns.translateMatrix=multiplyM(this.optns.translateMatrix,[[1,0,x],[0,1,y]]);
changeMatrix(this);
return this;
}
this.scale=function(x,y,duration,easing,onstep,fn)
{
if(duration!==undefined)
return this.animate({scale:{x:x,y:y}},duration,easing,onstep,fn);
if(y===undefined)y=x;
this.optns.scaleMatrix=multiplyM(this.optns.scaleMatrix,[[x,0,this._x*(1-x)],[0,y,this._y*(1-y)]]);
changeMatrix(this);
return this;
}
this.rotate=function(x,x1,y1,duration,easing,onstep,fn)
{
if(duration!==undefined)
return this.animate({rotate:{angle:x,x:x1,y:y1}},duration,easing,onstep,fn);
x=x/radian;
var cos=m_cos(x),
sin=m_sin(x),
translateX=0,
translateY=0;
if(x1!==undefined)
{
if(x1==''center'')
{
var point=this.getCenter(''poor'');
if(y1===undefined)
{
x1=point.x;
y1=point.y;
}
else
{
x1=point.x+y1.x;
y1=point.y+y1.y;
}
}
translateX=-x1*(cos-1)+y1*sin;
translateY=-y1*(cos-1)-x1*sin;
}
this.optns.rotateMatrix=multiplyM(this.optns.rotateMatrix,[[cos,-sin,translateX],[sin,cos,translateY]]);
changeMatrix(this);
return this;
}
this.transform=function(m11,m12,m21,m22,dx,dy,reset)
{
if(m11===undefined)return this.matrix();
var optns=this.optns;
if(reset!==undefined)
{
optns.transformMatrix=[[m11,m21,dx],[m12,m22,dy]];
optns.rotateMatrix=[[1,0,0],[0,1,0]];
optns.scaleMatrix=[[1,0,0],[0,1,0]];
optns.translateMatrix=[[1,0,0],[0,1,0]];
}
else
{
optns.transformMatrix=multiplyM(optns.transformMatrix,[[m11,m21,dx],[m12,m22,dy]]);
}
changeMatrix(this);
return this;
}
this.beforeDraw=function(canvasOptns)
{
if(!this._visible)return false;
var ctx=canvasOptns.ctx;
ctx.save();
if(this.optns.clipObject)
{
var clipObject=this.optns.clipObject;
clipObject._visible=true;
if (clipObject.optns.animated)animating.call(clipObject,canvasOptns);
clipObject.setOptns(ctx);
ctx.beginPath();
clipObject.draw(ctx);
ctx.clip();
}
this.setOptns(ctx);
if (this.optns.animated)animating.call(this,canvasOptns);
ctx.beginPath();
return true;
}
this.clip=function(object)
{
if(object===undefined)return this.optns.clipObject;
objectLayer(this).objs.splice(object.optns.number,1);
this.optns.clipObject=object;
return this;
}
this.afterDraw=function(optns)
{
optns.ctx.closePath();
checkEvents(this,optns);
optns.ctx.restore();
if(this.optns.clipObject)
{
proto.shape.prototype.afterDraw.call(this.optns.clipObject,optns);
}
}
this.isPointIn=function(x,y,global)
{
var canvasOptns=objectCanvas(this).optns,
ctx=canvasOptns.ctx,
thisAnimated=false,
optns=this.optns,
clipAnimated=false;
if(global!==undefined)
{
x-=canvasOptns.x;
y-=canvasOptns.y;
}
if(optns.animated)thisAnimated=true;
optns.animated=false;
if(optns.clipObject)
{
var clipObject=optns.clipObject,
clipOptns=clipObject.optns;
if(clipOptns.animated)
{
clipAnimated=true;
clipOptns.animated=false;
}
}
objectLayer(this).setOptns(ctx);
this.beforeDraw(canvasOptns);
this.draw(ctx);
var point=isPointInPath(this,x,y);
ctx.closePath();
ctx.restore();
ctx.setTransform(1,0,0,1,0,0);
optns.animated=thisAnimated;
if(clipAnimated)
{
clipOptns.animated=clipAnimated;
}
return point;
}
this.layer=function(idLayer)
{
return layer(idLayer,this,''objs'');
}
this.canvas=function(idCanvas)
{
return canvas(idCanvas,this,''objs'');
}
this.draggable=function(object,params,drag)
{
if(params===undefined && typeof object==''object'' && object.optns===undefined)
{
params=object.params;
drag=object.drag;
var start=object.start,
stop=object.stop,
disabled=object.disabled;
object=object.object;
}
var dragObj=this;
var dragOptns=this.optns.drag;
if(typeof params===''function'')
{
drag=params;
params=undefined;
}
if(typeof object==''function'')
{
drag=object;
object=undefined;
}
dragOptns.shiftX=0;
dragOptns.shiftY=0;
if(params!==undefined)
{
if(params.shiftX!==undefined){dragOptns.shiftX=params.shiftX;params.shiftX=undefined;}
if(params.shiftY!==undefined){dragOptns.shiftY=params.shiftY;params.shiftY=undefined;}
}
if(object!==undefined)
{
if(object.id)dragObj=(params===undefined)? object.visible(false) : object.animate(params).visible(false);
if(object==''clone'')
{
dragObj=this.clone(params).visible(false);
dragOptns.type=''clone'';
}
}
dragOptns.val=true;
dragOptns.x=this._x;
dragOptns.y=this._y;
dragOptns.dx=this._transformdx;
dragOptns.dy=this._transformdy;
dragOptns.object=dragObj;
dragOptns.params=params;
dragOptns.drag=drag||false;
dragOptns.start=start||false;
dragOptns.stop=stop||false;
dragOptns.disabled=disabled||false;
var optns=objectCanvas(this).optns;
optns.mousemove.val=true;
optns.mousedown.val=true;
optns.mouseup.val=true;
return this;
}
this.droppable=function(fn)
{
this.optns.drop.val=true;
if(fn!==undefined)this.optns.drop.fn=fn;
return this;
}
this.name = function(name)
{
return this.attr(''name'',name);
}
this.hasName = function(name){
var namesArray = this.attr(''name'').split('' ''), i = 0;
while(i < namesArray.length){
if(namesArray[i] === name){
return true;
}
i++;
}
return false;
}
this.addName = function(name)
{
var namesArray = this.attr(''name'').split('' ''), i = 0;
while(i < namesArray.length){
if(namesArray[i] === name){
return this;
}
i++;
}
namesArray.push(name);
return this.attr(''name'', namesArray.join('' ''));
}
this.removeName = function(name)
{
var namesArray = this.attr(''name'').split('' ''), i = 0;
while(i < namesArray.length){
if(namesArray[i] === name){
namesArray.splice(i, 1);
return this.attr(''name'', namesArray.join('' ''));
}
i++;
}
return this;
}
this.visible=function(visibility)
{
return this.attr(''visible'',visibility);
}
this.composite=function(composite)
{
return this.attr(''composite'',composite);
}
this.id=function(id)
{
if(id===undefined)return this.optns.id;
this.optns.id=id;
return this;
}
this.opacity=function(n)
{
return this.attr(''opacity'',n);
}
this.fadeIn=function(duration,easing,onstep,fn)
{
return this.fadeTo(1,duration,easing,onstep,fn);
}
this.fadeOut=function(duration,easing,onstep,fn)
{
return this.fadeTo(0,duration,easing,onstep,fn);
}
this.fadeTo=function(val,duration,easing,onstep,fn)
{
if(duration===undefined)duration=600;
return this.animate({opacity:val},duration,easing,onstep,fn);
}
this.fadeToggle=function(duration,easing,onstep,fn)
{
if(this._opacity)
this.fadeOut(duration,easing,onstep,fn);
else
this.fadeIn(duration,easing,onstep,fn);
return this;
}
this.instanceOf=function(name)
{
if(name===undefined)return this._proto;
return this instanceof proto[name];
}
this.base=function(x,y,service)
{
if(typeof x == ''object''){
x=checkDefaults(x,{x:0,y:0,service:false});
service=x.service;
y=x.y;
x=x.x;
}
else{if(service===undefined)service=false;}
var canvasItem=canvases[lastCanvas];
this.optns={
animated:false,
clipObject:false,
drop:{val:false,fn:function(){}},
drag:{val:false},
layer:{id:canvasItem.optns.id+"Layer0",number:0},
canvas:{number:0},
focused:false,
buffer:{val:false},
rotateMatrix:[[1,0,0],[0,1,0]],
scaleMatrix:[[1,0,0],[0,1,0]],
translateMatrix:[[1,0,0],[0,1,0]],
transformMatrix:[[1,0,0],[0,1,0]]
}
this.animateQueue = [];
this._x=x;
this._y=y;
if(service==false && canvasItem!==undefined && canvasItem.layers[0]!==undefined)
{
this.optns.layer.number=0;
this.optns.canvas.number=lastCanvas;
var layer=objectLayer(this),
limit=layer.objs.length;
this.optns.number=limit;
this._level=limit?(layer.objs[limit-1]._level+1):0;
layer.objs[limit]=this;
this.optns.layer.id=layer.optns.id;
redraw(this);
}
return this;
}
this._visible=true;
this._composite=''source-over'';
this._name="";
this._opacity=1;
this._shadowX=0;
this._shadowY=0;
this._shadowBlur= 0;
this._shadowColor= ''rgba(0,0,0,0)'';
this._shadowColorR= 0;
this._shadowColorG= 0;
this._shadowColorB= 0;
this._shadowColorA= 0;
this._shadowColorRPrev= 0;
this._shadowColorGPrev= 0;
this._shadowColorBPrev= 0;
this._shadowColorAPrev= 0;
this._translateX=0;
this._translateY=0;
this._scaleX=1;
this._scaleY=1;
this._rotateAngle=0;
this._rotateX=0;
this._rotateY=0;
this._transform11=1;
this._transform12=0;
this._transform21=0;
this._transform22=1;
this._transformdx=0;
this._transformdy=0;
this._matrixChanged=false;
}
proto.object.prototype=new proto.object();
proto.shape=function()
{
this.color = function(color)
{
if (color===undefined)return [this._colorR,this._colorG,this._colorB,this._alpha];
return this.attr(''color'',color);
}
this.lineStyle = function(options)
{
return this.attr(options);
}
this.setOptns = function(ctx)
{
proto.shape.prototype.setOptns.call(this,ctx);
ctx.lineWidth = this._lineWidth;
ctx.lineCap = this._cap;
ctx.lineJoin = this._join;
ctx.miterLimit = this._miterLimit;
var color=this.optns.color;
if(color.notColor===undefined){
var rInt = parseInt(this._colorR),
gInt = parseInt(this._colorG),
bInt = parseInt(this._colorB),
aInt = parseInt(this._alpha * 100) / 100;
if (this._colorRPrev !== rInt || this._colorGPrev !== gInt || this._colorBPrev !== bInt || this._alphaPrev !== aInt) {
color.val = this._color = ''rgba('' + rInt + '', '' + gInt + '', '' + bInt + '', '' + aInt + '')'';
this._colorRPrev = rInt;
this._colorGPrev = gInt;
this._colorBPrev = bInt;
this._alphaPrev = aInt;
}
else {
color.val = this._color;
}
}
else
{
var notColor=color.notColor;
var notColorLayer=canvases[notColor.canvas].layers[notColor.layer];
if(notColorLayer.grdntsnptrns[notColor.level]!==undefined){color.val=notColorLayer.grdntsnptrns[notColor.level].val;}
}
if(this._fill) ctx.fillStyle = color.val;
else ctx.strokeStyle = color.val;
}
this.afterDraw=function(optns)
{
if(this._fill)
optns.ctx.fill();
else
optns.ctx.stroke();
proto.shape.prototype.afterDraw.call(this,optns);
}
this.base=function(x)
{
if(x===undefined)x={};
if(x.color===undefined)x.color=''rgba(0,0,0,1)'';
else
{
if(!x.color.charAt && x.color.id===undefined && x.color.r===undefined)
{
x.fill=x.color;
x.color=''rgba(0,0,0,1)'';
}
}
x=checkDefaults(x,{color:''rgba(0,0,0,1)'',fill:0});
proto.shape.prototype.base.call(this,x);
this._fill=x.fill;
this.optns.color={val:x.color,notColor:undefined};
return this.color(x.color);
}
this._colorR=0;
this._colorG=0;
this._colorB=0;
this._alpha=0;
this._colorRPrev=0;
this._colorGPrev=0;
this._colorBPrev=0;
this._alphaPrev=0;
this._color = ''rgba(0,0,0,0)'';
this._lineWidth = 1;
this._cap = ''butt'';
this._join = ''miter'';
this._miterLimit= 1;
}
proto.shape.prototype=new proto.object;
proto.lines=function()
{
this.getCenter=function(type)
{
var point={
x:this._x0,
y:this._y0
};
for(var i=1;i<this.shapesCount;i++)
{
point.x+=this[''_x''+i];
point.y+=this[''_y''+i];
}
point.x=point.x/this.shapesCount;
point.y=point.y/this.shapesCount;
return getCenter(this,point,type);
}
this.position=function(){
return multiplyPointM(this._x0,this._y0,multiplyM(this.matrix(),objectLayer(this).matrix()));
}
this.getRect=function(type){
var minX, minY,
maxX=minX=this._x0,
maxY=minY=this._y0;
for(var i=1;i<this.shapesCount;i++)
{
if(maxX<this[''_x''+i])maxX=this[''_x''+i];
if(maxY<this[''_y''+i])maxY=this[''_y''+i];
if(minX>this[''_x''+i])minX=this[''_x''+i];
if(minY>this[''_y''+i])minY=this[''_y''+i];
}
var points={x:minX,y:minY,width:maxX-minX,height:maxY-minY};
return getRect(this,points,type);
}
this.addPoint=function(){
redraw(this);
var names=this.pointNames;
for(var i=0;i<names.length;i++)
this[names[i]+this.shapesCount]=arguments[i];
this.shapesCount++;
return this;
}
this.delPoint=function(x,y,radius){
redraw(this);
if(y===undefined)
{
var points=this.points();
points.splice(x,1)
this.points(points);
}
else{
radius=radius||0;
for(var j=0;j<this.shapesCount;j++)
if(this[''_x''+j]<x+radius && this[''_x''+j]>x-radius && this[''_y''+j]<y+radius && this[''_y''+j]<y+radius)
{
this.delPoint(j);
j--;
}
}
return this;
}
this.points=function(points)
{
var names=this.pointNames;
if(points===undefined){
points=[];
for(var j=0;j<this.shapesCount;j++)
{
points[j]=[];
for(var i=0;i<names.length;i++)
points[j][i]=this[names[i]+j];
}
return points;
}
redraw(this);
var oldCount=this.shapesCount;
this.shapesCount=points.length;
for(j=0;j<this.shapesCount;j++)
for(i=0;i<names.length;i++)
this[names[i]+j]=points[j][i];
for(j=this.shapesCount;j<oldCount;j++)
for(i=0;i<names.length;i++)
this[names[i]+j]=undefined;
return this;
}
this.base=function(points,color,fill)
{
if(points!==undefined)
{
if(typeof points.pop == ''function'')
points={points:points,color:color,fill:fill};
}
proto.lines.prototype.base.call(this,points);
this.shapesCount=0;
if(points!==undefined)
if(points.points!==undefined)
this.points(points.points);
return this;
}
}
proto.lines.prototype=new proto.shape;
proto.line=function(){
this.draw=function(ctx)
{
if(this._x0===undefined)return;
ctx.moveTo(this._x0,this._y0);
for(var j=1;j<this.shapesCount;j++)
{
ctx.lineTo(this[''_x''+j],this[''_y''+j]);
}
}
this.base=function(points,color,fill)
{
proto.line.prototype.base.call(this,points,color,fill);
return this;
}
this._proto=''line'';
this.pointNames=[''_x'',''_y''];
}
proto.line.prototype=new proto.lines;
proto.qCurve=function(){
this.draw=function(ctx)
{
if(this._x0===undefined)return;
ctx.moveTo(this._x0,this._y0);
for(var j=1;j<this.shapesCount;j++)
{
ctx.quadraticCurveTo(this[''_cp1x''+j],this[''_cp1y''+j],this[''_x''+j],this[''_y''+j]);
}
}
this.base=function(points,color,fill)
{
proto.qCurve.prototype.base.call(this,points,color,fill);
return this;
}
this._proto=''qCurve'';
this.pointNames=[''_x'',''_y'',''_cp1x'',''_cp1y''];
}
proto.qCurve.prototype=new proto.lines;
proto.bCurve=function(){
this.draw=function(ctx)
{
if(this._x0===undefined)return;
ctx.moveTo(this._x0,this._y0);
for(var j=1;j<this.shapesCount;j++)
{
ctx.bezierCurveTo(this[''_cp1x''+j],this[''_cp1y''+j],this[''_cp2x''+j],this[''_cp2y''+j],this[''_x''+j],this[''_y''+j]);
}
}
this.base=function(points,color,fill)
{
proto.bCurve.prototype.base.call(this,points,color,fill);
return this;
}
this._proto=''bCurve'';
this.pointNames=[''_x'',''_y'',''_cp1x'',''_cp1y'',''_cp2x'',''_cp2y''];
}
proto.bCurve.prototype=new proto.lines;
proto.circle = function () {
this.getCenter = function (type) {
return getCenter(this, {x:this._x, y:this._y}, type);
}
this.getRect = function (type) {
var points = {x:Math.floor(this._x - this._radius), y:Math.floor(this._y - this._radius)};
points.width = points.height = Math.ceil(this._radius) * 2;
return getRect(this, points, type);
}
this.draw = function (ctx) {
ctx.arc(this._x, this._y, this._radius, 0, pi2, true);
}
this.base = function (x, y, radius, color, fill) {
if (typeof x != ''object'')
x = {x:x, y:y, radius:radius, color:color, fill:fill};
x = checkDefaults(x, {radius:0});
proto.circle.prototype.base.call(this, x);
this._radius = x.radius;
return this;
}
this._proto = ''circle'';
}
proto.circle.prototype = new proto.shape;
proto.rect = function () {
this.getRect = function (type) {
return getRect(this, {x:this._x, y:this._y, width:this._width, height:this._height}, type);
}
this.draw = function (ctx) {
ctx.rect(this._x, this._y, this._width, this._height);
}
this.base = function (x, y, width, height, color, fill) {
if (typeof x != ''object'')
x = {x:x, y:y, width:width, height:height, color:color, fill:fill};
x = checkDefaults(x, {width:0, height:0});
proto.rect.prototype.base.call(this, x);
this._width = x.width;
this._height = x.height;
return this;
}
this._proto = ''rect'';
}
proto.rect.prototype = new proto.shape;
proto.arc = function () {
this.getRect = function (type) {
var points = {x:this._x, y:this._y},
startAngle = this._startAngle, endAngle = this._endAngle, radius = this._radius,
startY = m_floor(m_sin(startAngle / radian) * radius), startX = m_floor(m_cos(startAngle / radian) * radius),
endY = m_floor(m_sin(endAngle / radian) * radius), endX = m_floor(m_cos(endAngle / radian) * radius),
positiveXs = startX > 0 && endX > 0, negtiveXs = startX < 0 && endX < 0, positiveYs = startY > 0 && endY > 0, negtiveYs = startY < 0 && endY < 0;
points.width = points.height = radius;
if ((this._anticlockwise && startAngle < endAngle) || (!this._anticlockwise && startAngle > endAngle)) {
if (((negtiveXs || (positiveXs && (negtiveYs || positiveYs)))) || (startX == 0 && endX == 0)) {
points.y -= radius;
points.height += radius;
}
else {
if (positiveXs && endY < 0 && startY > 0) {
points.y += endY;
points.height += endY;
}
else
if (endX > 0 && endY < 0 && startX < 0) {
points.y += m_min(endY, startY);
points.height -= m_min(endY, startY);
}
else {
if (negtiveYs)points.y -= m_max(endY, startY);
else points.y -= radius;
points.height += m_max(endY, startY);
}
}
if (((positiveYs || (negtiveYs && (negtiveXs || positiveXs) ))) || (startY == 0 && endY == 0)) {
points.x -= radius;
points.width += radius;
}
else {
if (endY < 0 && startY > 0) {
points.x += m_min(endX, startX);
points.width -= m_min(endX, startX);
}
else {
if (negtiveXs)points.x -= m_max(endX, startX);
else points.x -= radius;
points.width += m_max(endX, startX);
}
}
}
else {
positiveXs = startX >= 0 && endX >= 0;
positiveYs = startY >= 0 && endY >= 0;
negtiveXs = startX <= 0 && endX <= 0;
negtiveYs = startY <= 0 && endY <= 0;
if (negtiveYs && positiveXs) {
points.x += m_min(endX, startX);
points.width -= m_min(endX, startX);
points.y += m_min(endY, startY);
points.height += m_max(endY, startY);
}
else if (negtiveYs && negtiveXs) {
points.x += m_min(endX, startX);
points.width += m_max(endX, startX);
points.y += m_min(endY, startY);
points.height += m_max(endY, startY);
}
else if (negtiveYs) {
points.x += m_min(endX, startX);
points.width += m_max(endX, startX);
points.y -= radius;
points.height += m_max(endY, startY);
}
else if (positiveXs && positiveYs) {
points.x += m_min(endX, startX);
points.width = m_abs(endX - startX);
points.y += m_min(endY, startY);
points.height -= m_min(endY, startY);
}
else if (positiveYs) {
points.x += m_min(endX, startX);
points.width = m_abs(endX) + m_abs(startX);
points.y += m_min(endY, startY);
points.height -= m_min(endY, startY);
}
else if (negtiveXs) {
points.x -= radius;
points.width += m_max(endX, startX);
points.y -= radius;
points.height += m_max(endY, startY);
}
else if (positiveXs) {
points.x -= radius;
points.width += m_max(endX, startX);
points.y -= radius;
points.height += radius;
}
}
return getRect(this, points, type);
}
this.draw = function (ctx) {
ctx.arc(this._x, this._y, this._radius, this._startAngle / radian, this._endAngle / radian, this._anticlockwise);
}
this.base = function (x, y, radius, startAngle, endAngle, anticlockwise, color, fill) {
if (anticlockwise !== undefined) {
if (anticlockwise.charAt)color = anticlockwise;
if (anticlockwise)anticlockwise = true;
else anticlockwise = false;
}
if (typeof x != ''object'')
x = {x:x, y:y, radius:radius, startAngle:startAngle, endAngle:endAngle, anticlockwise:anticlockwise, color:color, fill:fill};
x = checkDefaults(x, {radius:0, startAngle:0, endAngle:0, anticlockwise:true});
proto.arc.prototype.base.call(this, x);
this._radius = x.radius;
this._startAngle = x.startAngle;
this._endAngle = x.endAngle;
this._anticlockwise = x.anticlockwise;
return this;
}
this._proto = ''arc'';
}
proto.arc.prototype = new proto.shape;
proto.text = function () {
this.font = function (font) {
return this.attr(''font'', font);
}
this._font = "10px sans-serif";
this.align = function (align) {
return this.attr(''align'', align);
}
this._align = "start";
this.baseline = function (baseline) {
return this.attr(''baseline'', baseline);
}
this._baseline = "alphabetic";
this.string = function (string) {
return this.attr(''string'', string);
}
this.position = function () {
var points = {x:this._x, y:this._y}, ctx = objectCanvas(this).optns.ctx;
points.height = parseInt(this._font.match(regNumsWithMeasure)[0]);
points.y -= points.height;
ctx.save();
ctx.textBaseline = this._baseline;
ctx.font = this._font;
ctx.textAlign = this._align;
points.width = ctx.measureText(this._string).width;
ctx.restore();
return getRect(this, points);
}
this.getRect = function (type) {
var points = {x:this._x, y:this._y}, ctx = objectCanvas(this).optns.ctx;
points.height = parseInt(this._font.match(regNumsWithMeasure)[0]);
points.y -= points.height;
ctx.save();
ctx.textBaseline = this._baseline;
ctx.font = this._font;
ctx.textAlign = this._align;
points.width = ctx.measureText(this._string).width;
if (this._align == ''center'')points.x -= points.width / 2;
if (this._align == ''right'')points.x -= points.width;
ctx.restore();
return getRect(this, points, type);
}
this.setOptns = function (ctx) {
proto.text.prototype.setOptns.call(this, ctx);
ctx.textBaseline = this._baseline;
ctx.font = this._font;
ctx.textAlign = this._align;
}
this.draw = function (ctx) {
if (this._maxWidth === false) {
if (this._fill)ctx.fillText(this._string, this._x, this._y);
else ctx.strokeText(this._string, this._x, this._y);
}
else {
if (this._fill) ctx.fillText(this._string, this._x, this._y, this._maxWidth);
else ctx.strokeText(this._string, this._x, this._y, this._maxWidth);
}
}
this.base = function (string, x, y, maxWidth, color, fill) {
if (maxWidth !== undefined) {
if (maxWidth.charAt) {
if (color !== undefined)fill = color;
color = maxWidth;
maxWidth = false;
}
}
if (typeof string != ''object'')
string = {string:string, x:x, y:y, maxWidth:maxWidth, color:color, fill:fill};
string = checkDefaults(string, {string:'''', maxWidth:false, fill:1});
proto.text.prototype.base.call(this, string);
this._string = string.string;
this._maxWidth = string.maxWidth;
return this;
}
this._proto = ''text'';
}
proto.text.prototype = new proto.shape;
proto.grdntsnptrn=function()
{
this.layer=function(idLayer)
{
return layer(idLayer,this,''grdntsnptrns'');
}
this.canvas=function(idCanvas)
{
return canvas(idCanvas,this,''grdntsnptrns'');
}
var tmpObj=new proto.object;
this.animate=tmpObj.animate;
this.attr=tmpObj.attr;
this.id=tmpObj.id;
this.name=tmpObj.name;
this.level=tmpObj.level;
this.base=function()
{
this.animateQueue=[];
this.optns={
animated:false,
name:"",
layer:{id:canvases[0].optns.id+''Layer_0'',number:0},
canvas:{number:0},
visible:true
}
this.optns.layer.id=canvases[lastCanvas].optns.id+''Layer_0'';
this.optns.layer.number=0
this.optns.canvas.number=lastCanvas;
var grdntsnptrnsArray=canvases[lastCanvas].layers[0].grdntsnptrns;
this._level=grdntsnptrnsArray.length;
grdntsnptrnsArray[this._level]=this;
redraw(this);
}
return this;
}
proto.gradients=function()
{
this.colorStopsCount=0;
this.paramNames=[''_pos'',''_colorR'',''_colorG'',''_colorB'',''_alpha''];
this.addColorStop=function(pos,color){
redraw(this);
var colorKeeper = parseColor(color);
var i=this.colorStopsCount;
this[''_pos''+i] = pos;
this[''_colorR''+i] = colorKeeper.r;
this[''_colorG''+i] = colorKeeper.g;
this[''_colorB''+i] = colorKeeper.b;
this[''_alpha''+i] = colorKeeper.a;
this.colorStopsCount++;
return this;
}
this.animate=function(parameters,duration,easing,onstep,fn){
for(var key in parameters)
{
if(key.substr(0,5)==''color'')
{
var i=key.substring(5);
var colorKeeper=parseColor(parameters[key]);
parameters[''colorR''+i] = colorKeeper.r;
parameters[''colorG''+i] = colorKeeper.g;
parameters[''colorB''+i] = colorKeeper.b;
parameters[''alpha''+i] = colorKeeper.a;
}
}
proto.gradients.prototype.animate.call(this,parameters,duration,easing,onstep,fn);
}
this.delColorStop=function(i)
{
redraw(this);
var colorStops=this.colorStops();
colorStops.splice(i,1);
if(colorStops.length>0)this.colorStops(colorStops);
else this.colorStopsCount=0;
return this;
}
this.colorStops=function(array)
{
var names=this.paramNames;
if(array===undefined){
array=[];
for(var j=0;j<this.colorStopsCount;j++)
{
array[j]=[];
for(var i=0;i<names.length;i++)
array[j][i]=this[names[i]+j];
}
return array;
}
redraw(this);
var oldCount=this.colorStopsCount;
var limit=array.length;
if(array[0].length==2)
for(j=0;j<limit;j++)
this.addColorStop(array[j][0], array[j][1]);
else
for(j=0;j<limit;j++)
for(i=0;i<names.length;i++)
this[names[i]+j]=array[j][i];
for(j=limit;j<oldCount;j++)
for(i=0;i<names.length;i++)
this[names[i]+j]=undefined;
this.colorStopsCount=limit;
return this;
}
this.base=function(colors)
{
proto.gradients.prototype.base.call(this);
if (colors==undefined)
return this;
else return this.colorStops(colors);
}
}
proto.gradients.prototype=new proto.grdntsnptrn;
proto.pattern = function()
{
this.create = function(canvasOptns)
{
if(this.optns.animated)animating.call(this,canvasOptns);
this.val = canvasOptns.ctx.createPattern(this._img,this._type);
}
this.base=function(image,type)
{
if(image.onload)
image={image:image,type:type};
image=checkDefaults(image,{type:''repeat''});
proto.pattern.prototype.base.call(this);
this._img=image.image;
this._type=image.type;
return this;
}
this._proto=''pattern'';
}
proto.pattern.prototype=new proto.grdntsnptrn;
proto.lGradient=function()
{
this.create = function(canvasOptns)
{
if(this.optns.animated)animating.call(this,canvasOptns);
this.val=canvasOptns.ctx.createLinearGradient(this._x1,this._y1,this._x2,this._y2);
for(var i=0;i<this.colorStopsCount;i++)
{
this.val.addColorStop(this[''_pos''+i],''rgba(''+parseInt(this[''_colorR''+i])+'',''+parseInt(this[''_colorG''+i])+'',''+parseInt(this[''_colorB''+i])+'',''+this[''_alpha''+i]+'')'');
}
}
this.base=function(x1,y1,x2,y2,colors)
{
if(typeof x1!==''object'')
x1={x1:x1,y1:y1,x2:x2,y2:y2,colors:colors};
x1=checkDefaults(x1,{x1:0,y1:0,x2:0,y2:0})
proto.lGradient.prototype.base.call(this,x1.colors);
this._x1 = x1.x1;
this._y1 = x1.y1;
this._x2 = x1.x2;
this._y2 = x1.y2;
return this;
}
this._proto=''lGradient'';
}
proto.lGradient.prototype=new proto.gradients;
proto.rGradient=function()
{
this.create = function(canvasOptns)
{
if(this.optns.animated)animating.call(this);
this.val=canvasOptns.ctx.createRadialGradient(this._x1,this._y1,this._r1,this._x2,this._y2,this._r2);
for(var i=0;i<this.colorStopsCount;i++)
{
this.val.addColorStop(this[''_pos''+i],''rgba(''+parseInt(this[''_colorR''+i])+'',''+parseInt(this[''_colorG''+i])+'',''+parseInt(this[''_colorB''+i])+'',''+this[''_alpha''+i]+'')'');
}
}
this.base=function(x1,y1,r1,x2,y2,r2,colors)
{
if(typeof x1!==''object'')
x1={x1:x1,y1:y1,r1:r1,x2:x2,y2:y2,r2:r2,colors:colors};
x1=checkDefaults(x1,{x1:0,y1:0,r1:0,x2:0,y2:0,r2:0})
proto.rGradient.prototype.base.call(this,x1.colors);
this._x1 = x1.x1;
this._y1 = x1.y1;
this._r1 = x1.r1;
this._x2 = x1.x2;
this._y2 = x1.y2;
this._r2 = x1.r2;
return this;
}
this._proto=''rGradient'';
}
proto.rGradient.prototype=new proto.gradients;
proto.layer=function()
{
this.position=function(){
var objs=this.objs,
points,point,i,
limit=objs.length;
for(i=0;i<limit;i++)
{
point=objs[i].position();
if(points===undefined)points=point;
if(points.x>point.x)points.x=point.x;
if(points.y>point.y)points.y=point.y;
}
return points;
}
this.getRect=function(type){
var objs=this.objs,
points,rect,i,
limit=objs.length;
if (objs.length==0)return false;
if(type==''coords'')
{
for(i=0;i<limit;i++)
{
rect=objs[i].getRect(type);
if(points===undefined)points=rect;
if(points[0][0]>rect[0][0])points[0][0]=rect[0][0];
if(points[0][1]>rect[0][1])points[0][1]=rect[0][1];
if(points[1][0]<rect[1][0])points[1][0]=rect[1][0];
if(points[1][1]>rect[1][1])points[1][1]=rect[1][1];
if(points[2][0]>rect[2][0])points[2][0]=rect[2][0];
if(points[2][1]<rect[2][1])points[2][1]=rect[2][1];
if(points[3][0]<rect[3][0])points[3][0]=rect[3][0];
if(points[3][1]<rect[3][1])points[3][1]=rect[3][1];
}
return points;
}
for(i=0;i<limit;i++)
{
rect=objs[i].getRect(type);
rect.right=rect.width+rect.x;
rect.bottom=rect.height+rect.y;
if(points===undefined)points=rect;
if(points.x>rect.x)points.x=rect.x;
if(points.y>rect.y)points.y=rect.y;
if(points.right<rect.right)points.right=rect.right;
if(points.bottom<rect.bottom)points.bottom=rect.bottom;
}
points.width=points.right-points.x;
points.height=points.bottom-points.y;
return points;
}
this.canvas=function(idCanvas)
{
if (idCanvas===undefined)return this.idCanvas;
if(this.optns.canvas.id==idCanvas)return this;
var newCanvas=-1,oldCanvas=0,limitC=canvases.length;
for(var i=0;i<limitC;i++)
{
var idCanvasItem=canvases[i].optns.id;
if (idCanvasItem==idCanvas)newCanvas=i;
if (idCanvasItem==this.optns.canvas.id)oldCanvas=i;
}
if(newCanvas<0){newCanvas=canvases.length;jCanvaScript.canvas(idCanvas);}
this.optns.canvas.id=idCanvas;
this.optns.canvas.number=newCanvas;
canvases[oldCanvas].layers.splice(this.optns.number,1);
var layersArray=canvases[newCanvas].layers;
this._level=this.optns.number=layersArray.length;
layersArray[this._level]=this;
setLayerAndCanvasToArray(this.objs,this.optns.id,this._level,idCanvas,newCanvas);
setLayerAndCanvasToArray(this.grdntsnptrns,this.optns.id,this._level,idCanvas,newCanvas);
canvases[newCanvas].optns.redraw=1;
return this;
}
this.up=function(n)
{
if(n === undefined)n=1;
if(n==''top'')this.level(n);
else {
var next=objectCanvas(this).layers[this.optns.number+n];
if(next!==undefined)
{
n=next._level+1-this._level;
}
this.level(this._level+n);
}
return this;
}
this.down=function(n)
{
if(n == undefined)n=1;
if(n == ''bottom'')this.level(n);
else {
var previous=objectCanvas(this).layers[this.optns.number-n];
if(previous!==undefined)
{
n=this._level-(previous._level-1);
}
this.level(this._level-n);
}
return this;
}
this.level=function(n)
{
if(n == undefined)return this._level;
var canvas=objectCanvas(this),
optns=canvas.optns;
if(n==''bottom'')
if(this.optns.number==0)n=this._level;
else n=canvas.layers[0]._level-1;
if(n==''top'')
if(this.optns.number==canvas.layers.length-1)n=this._level;
else n=canvas.layers[canvas.layers.length-1]._level+1;
this._level=n;
optns.anyLayerLevelChanged = true;
optns.redraw=1;
return this;
}
this.del=function()
{
var optns=objectCanvas(this).optns;
optns.anyLayerDeleted = true;
this.optns.deleted = true;
this.draw = false;
optns.redraw=1;
return;
}
this.setOptns=function(ctx)
{
ctx.setTransform(1,0,0,1,0,0);
proto.layer.prototype.setOptns.call(this,ctx);
return this;
}
this.afterDraw=function(optns)
{
optns.ctx.closePath();
optns.ctx.restore();
if(this.optns.clipObject)
{
proto.layer.prototype.afterDraw.call(this.optns.clipObject,optns);
}
}
this.clone=function(idLayer,params)
{
var clone=jCanvaScript.layer(idLayer);
take(clone,this);
take(clone.optns.transformMatrix,this.optns.transformMatrix);
take(clone.optns.translateMatrix,this.optns.translateMatrix);
take(clone.optns.scaleMatrix,this.optns.scaleMatrix);
take(clone.optns.rotateMatrix,this.optns.rotateMatrix);
clone.canvas(objectCanvas(this).optns.id);
if(params===undefined) return clone;
return clone.animate(params);
}
this.isPointIn=function(x,y,global)
{
var objs=this.objs,i;
for(i=0;i<objs.length;i++)
if(objs[i].isPointIn(x,y,global))
return true;
return false;
}
this.opacity=function(n)
{
var objs=this.objs;
for(var i=0;i<objs.length;i++)
objs[i].attr(''opacity'',n);
return this;
}
this.fadeTo=function(val,duration,easing,onstep,fn)
{
if(duration===undefined)duration=600;
var objs=this.objs;
for(var i=0;i<objs.length;i++)
objs[i].animate({opacity:val},duration,easing,onstep,fn);
return this;
}
this.draw=function(canvasOptns)
{
var optns=this.optns,
bufOptns=optns.buffer,
ctx=canvasOptns.ctx;
if(bufOptns.val)
{
ctx.drawImage(bufOptns.cnv,bufOptns.x,bufOptns.y);
return this;
}
for(var i=0;i<this.grdntsnptrns.length;i++)
this.grdntsnptrns[i].create(canvasOptns);
if(optns.anyObjLevelChanged)
{
levelChanger(this.objs);
optns.anyObjLevelChanged = false;
}
if(optns.anyObjDeleted)
{
objDeleter(this.objs);
optns.anyObjDeleted = false;
}
ctx.globalCompositeOperation = optns.gCO;
for(i=0;i<this.objs.length;i++)
{
var object=this.objs[i];
if(typeof (object.draw)==''function'')
{
this.setOptns(ctx);
if(object.beforeDraw(canvasOptns))
{
if(typeof (object.draw)==''function'')
{
var objBufOptns=object.optns.buffer;
if(objBufOptns.val)
ctx.drawImage(objBufOptns.cnv,objBufOptns.x,objBufOptns.y);
else
object.draw(ctx);
if(bufOptns.optns)
object.afterDraw(bufOptns.optns);
else
object.afterDraw(canvasOptns);
}
}
}
}
return this;
}
this.objects=function(map)
{
var myGroup=group(),i=0;
while(this.objs[i]!==undefined)
myGroup.elements[i]=this.objs[i++];
if(map!==undefined)
return myGroup.find(map);
return myGroup;
}
this.base=function(idLayer)
{
var canvas=canvases[lastCanvas],
lastCanvasLayers=canvas.layers,
lastCanvasOptns=canvas.optns;
proto.layer.prototype.base.call(this,0,0,true);
var limit=lastCanvasLayers.length;
lastCanvasLayers[limit]=this;
this.objs = [];
this.grdntsnptrns = [];
this._level=limit?(lastCanvasLayers[limit-1]._level+1):0;
this.optns.number=limit;
this.optns.id=idLayer;
var thisOptns=this.optns
thisOptns.anyObjDeleted= false;
thisOptns.anyObjLevelChanged= false;
thisOptns.gCO= lastCanvasOptns.gCO;
thisOptns.canvas.id=lastCanvasOptns.id;
thisOptns.canvas.number=lastCanvas;
return this;
}
this._proto=''layer'';
}
proto.layer.prototype=new proto.object;
function layers(idLayer)
{
var layer=new proto.layer();
return layer.base(idLayer);
}
proto.imageData=function()
{
this.filter=function(filterName,filterType)
{
var filter=imageDataFilters[filterName];
filter.fn.call(this,this._width,this._height,filter.matrix,filterType);
return this;
};
this.getRect=function(type)
{
var points={x:this._x,y:this._y,width:this._width,height:this._height};
return getRect(this,points,type);
}
this.setPixel=function(x,y,color)
{
var colorKeeper,index=(x + y * this._width) * 4;
if (color.r !== undefined) colorKeeper=color;
else if (color[0] !== undefined)
if (!color.charAt) colorKeeper={r:color[0],g:color[1],b:color[2],a:color[3]};
else colorKeeper = parseColor(color);
this._data[index+0] = colorKeeper.r;
this._data[index+1] = colorKeeper.g;
this._data[index+2] = colorKeeper.b;
this._data[index+3] = colorKeeper.a*255;
redraw(this);
return this;
}
this.getPixel=function(x,y)
{
var index=(x + y * this._width) * 4;
return [this._data[index+0],this._data[index+1],this._data[index+2],this._data[index+3]/255];
}
this._getX=0;
this._getY=0;
this.getData=function(x,y,width,height)
{
this._getX=x;
this._getY=y;
this._width=width;
this._height=height;
var ctx=objectCanvas(this).optns.ctx;
try{
this._imgData=ctx.getImageData(this._getX,this._getY,this._width,this._height);
}catch(e){
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
this._imgData=ctx.getImageData(this._getX,this._getY,this._width,this._height);
}
this._data=this._imgData.data;
redraw(this);
return this;
}
this.putData=function(x,y)
{
if(x!==undefined)this._x=x;
if(y!==undefined)this._y=y;
this._putData=true;
redraw(this);
return this;
}
this.clone=function(){
var clone=proto.imageData.prototype.clone.call(this);
clone._imgData=undefined;
return clone;
}
this.draw=function(ctx)
{
if(this._imgData===undefined)
{
this._imgData=ctx.createImageData(this._width,this._height);
for(var i=0;i<this._width*this._height*4;i++)
this._imgData.data[i]=this._data[i];
this._data=this._imgData.data;
}
if(this._putData)
ctx.putImageData(this._imgData,this._x,this._y);
}
this.base=function(width,height)
{
proto.imageData.prototype.base.call(this);
if(height===undefined)
{
var oldImageData=width;
if(oldImageData._width!==undefined)
{
width=oldImageData._width;
height=oldImageData._height;
}
else
{
width=checkDefaults(width,{width:0,height:0});
height=width.height;
width=width.width;
}
}
this._width=width;
this._height=height;
this._data=[];
for(var i=0;i<this._width;i++)
for(var j=0;j<this._height;j++)
{
var index=(i+j*this._width)*4;
this._data[index+0]=0;
this._data[index+1]=0;
this._data[index+2]=0;
this._data[index+3]=0;
}
return this;
}
this._putData=false;
this._proto=''imageData'';
}
proto.imageData.prototype=new proto.object;
proto.image=function()
{
this.getRect=function(type)
{
var points={x:this._x,y:this._y,width:this._width,height:this._height};
return getRect(this,points,type);
}
this.draw=function(ctx)
{
ctx.drawImage(this._img,this._sx,this._sy,this._swidth,this._sheight,this._x,this._y,this._width,this._height);
}
this.base=function(image,x,y,width,height,sx,sy,swidth,sheight)
{
if(typeof image!=''object'' || image.src!==undefined || image.nodeName !== undefined)
image={image:image,x:x,y:y,width:width,height:height,sx:sx,sy:sy,swidth:swidth,sheight:sheight};
image=checkDefaults(image,{width:false,height:false,sx:0,sy:0,swidth:false,sheight:false});
if(image.width===false)
{
image.width=image.image.width;
image.height=image.image.height;
}
if(image.swidth===false)
{
image.swidth=image.image.width;
image.sheight=image.image.height;
}
proto.image.prototype.base.call(this,image);
this._img=image.image;
this._width=image.width;
this._height=image.height;
this._sx=image.sx;
this._sy=image.sy;
this._swidth=image.swidth;
this._sheight=image.sheight;
return this;
}
this._proto=''image'';
}
proto.image.prototype=new proto.object;
proto.groups=function()
{
for(var Class in proto)
{
if(Class==''group''||Class==''groups'')continue;
var tmp=new proto[Class];
for(var key in tmp)
{
if(typeof tmp[key]==''function'' && this[key]===undefined)
{
(function(group,key)
{
group[key]=function(){
var argumentsClone=[];
var args=[];
var i=0;
while(arguments[i]!==undefined)
args[i]=arguments[i++];
for(i=0;i<this.elements.length;i++)
{
var element=this.elements[i];
take(argumentsClone,args);
if(typeof element[key]==''function'')
{
element[key].apply(element,argumentsClone);
}
}
return this;
}
})(this,key);
}
}
}
this.reverse=function(){
var tmpArray=this.elements;
this.elements=this.unmatchedElements;
this.unmatchedElements=tmpArray;
return this;
}
this.end=function(n){
if(this.previousGroup===undefined || n===0)return this;
if(n!==undefined)n--;
return this.previousGroup.end(n);
}
this.find=function(map){
var subgroup=group(),
attrs=map.attrs,
fns=map.fns||[],
i,j,
element,rel,fn,value1,value2;
subgroup.previousGroup=this;
for(i=0;i<this.elements.length;i++)
{
subgroup.elements[i]=this.elements[i];
}
if(attrs!==undefined)
{
for(j in attrs)
{
if(attrs.hasOwnProperty(j))
{
if(typeof attrs[j]!=''object'')
{
attrs[j]={val:attrs[j],rel:''==''};
}
fns[fns.length]={
fn:''attr'',
args:[j],
val:attrs[j].val,
rel:attrs[j].rel
};
}
}
}
if(fns.length)
{
for(i=0;i<subgroup.elements.length;i++)
{
element=subgroup.elements[i];
for(j=0;j<fns.length;j++)
{
fn=fns[j];
value2=fn.val;
rel=fn.rel;
if(typeof element[fn.fn]==''function'')
value1=element[fn.fn].apply(element,fn.args);
else rel=''del'';
switch(rel)
{
case ''!='':
if(!(value1!=value2))rel=''del'';
break;
case ''!=='':
if(!(value1!==value2))rel=''del'';
break;
case ''=='':
if(!(value1==value2))rel=''del'';
break;
case ''==='':
if(!(value1===value2))rel=''del'';
break;
case ''>='':
if(!(value1>=value2))rel=''del'';
break;
case ''<='':
if(!(value1<=value2))rel=''del'';
break;
case ''>'':
if(!(value1>value2))rel=''del'';
break;
case ''<'':
if(!(value1<value2))rel=''del'';
break;
case ''typeof'':
if(!(typeof value1==value2))rel=''del'';
break;
}
if(rel==''del'')
{
subgroup.unmatchedElements[subgroup.unmatchedElements.length]=element;
subgroup.elements.splice(i,1);
i--;
break;
}
}
}
}
return subgroup;
}
this.base=function(){
this.elements=[];
this.unmatchedElements=[];
return this;
}
}
proto.group=function()
{
this._proto=''group'';
};
proto.group.prototype=new proto.groups;
function group()
{
var group=new proto.group;
return group.base();
}
jCanvaScript.addFunction=function(name,fn,prototype)
{
proto[prototype||''object''].prototype[name]=fn;
return jCanvaScript;
}
jCanvaScript.addObject=function(name,parameters,drawfn,parent)
{
proto[name]=function(name){
this.draw=proto[name].draw;
this.base=proto[name].base;
this._proto=name;
};
var protoItem=proto[name];
if(parent===undefined)parent=''shape'';
protoItem.prototype=new proto[parent];
protoItem.draw=drawfn;
protoItem.base=function(name,parameters,args)
{
protoItem.prototype.base.call(this,parameters);
var i=0;
for(var key in parameters)
{
var parameter = (args[i] !== undefined)?args[i]:parameters[key];
this[''_''+key]=parameter;
if(key==''color'')this.color(parameter);
i++;
}
return this;
};
(function(name,parameters)
{
jCanvaScript[name]=function()
{
var object=new proto[name](name);
return object.base(name,parameters,arguments);
}
})(name,parameters);
return jCanvaScript;
}
jCanvaScript.addAnimateFunction=function(name,fn)
{
animateFunctions[name]=fn;
return jCanvaScript;
}
jCanvaScript.addImageDataFilter=function(name,properties)
{
if(imageDataFilters[name]===undefined)imageDataFilters[name]={};
if(properties.fn!==undefined)imageDataFilters[name].fn=properties.fn;
if(properties.matrix!==undefined && properties.type===undefined)imageDataFilters[name].matrix=properties.matrix;
if(properties.type!==undefined)imageDataFilters[name].matrix[type]=properties.matrix;
return jCanvaScript;
}
jCanvaScript.clear=function(idCanvas)
{
if(canvases[0]===undefined)return jCanvaScript;
if(idCanvas===undefined){canvases[0].clear();return jCanvaScript;}
jCanvaScript.canvas(idCanvas).clear();
return jCanvaScript;
}
jCanvaScript.pause=function(idCanvas)
{
if(idCanvas===undefined){canvases[0].pause();return jCanvaScript;}
jCanvaScript.canvas(idCanvas).pause();
return jCanvaScript;
}
jCanvaScript.start=function(idCanvas,isAnimated)
{
jCanvaScript.canvas(idCanvas).start(isAnimated);
return jCanvaScript;
}
jCanvaScript.pattern = function(img,type)
{
var pattern = new proto.pattern;
return pattern.base(img,type);
}
jCanvaScript.lGradient=function(x1,y1,x2,y2,colors)
{
var lGrad = new proto.lGradient;
return lGrad.base(x1,y1,x2,y2,colors);
}
jCanvaScript.rGradient=function(x1,y1,r1,x2,y2,r2,colors)
{
var rGrad = new proto.rGradient;
return rGrad.base(x1,y1,r1,x2,y2,r2,colors);
}
jCanvaScript.line=function(points,color,fill)
{
var line = new proto.line;
return line.base(points,color,fill);
}
jCanvaScript.qCurve=function(points,color,fill)
{
var qCurve = new proto.qCurve;
return qCurve.base(points,color,fill);
}
jCanvaScript.bCurve=function(points,color,fill)
{
var bCurve = new proto.bCurve;
return bCurve.base(points,color,fill);
}
jCanvaScript.imageData=function(width,height)
{
var imageData=new proto.imageData;
return imageData.base(width,height);
}
jCanvaScript.image=function(img,x,y,width,height,sx,sy,swidth,sheight)
{
var image=new proto.image;
return image.base(img,x,y,width,height,sx,sy,swidth,sheight);
}
jCanvaScript.circle=function(x,y,radius,color,fill)
{
var circle=new proto.circle;
return circle.base(x,y,radius,color,fill);
}
jCanvaScript.rect=function(x,y,width,height,color,fill)
{
var rect = new proto.rect;
return rect.base(x,y,width,height,color,fill);
}
jCanvaScript.arc=function(x,y,radius,startAngle,endAngle,anticlockwise,color,fill)
{
var arc=new proto.arc;
return arc.base(x,y,radius,startAngle,endAngle,anticlockwise,color,fill);
}
jCanvaScript.text = function(string,x,y,maxWidth,color,fill)
{
var text=new proto.text;
return text.base(string,x,y,maxWidth,color,fill);
}
jCanvaScript.canvas = function(idCanvas)
{
if(idCanvas===undefined)return canvases[0];
var limit=canvases.length;
for (var i=0;i<limit;i++)
if(canvases[i].optns)
if(canvases[i].optns.id==idCanvas)return canvases[i];
var canvas={
id:function(id)
{
if(id===undefined)return this.optns.id;
this.optns.id=id;
return this;
}
};
canvases[limit]=canvas;
lastCanvas=limit;
canvas.cnv=document.getElementById(idCanvas);
if (''\v''==''v'')
{
if(typeof G_vmlCanvasManager!==''undefined'')
G_vmlCanvasManager.initElement(canvas.cnv);
if(typeof FlashCanvas !==''undefined'')
FlashCanvas.initElement(canvas.cnv);
}
canvas.width = function(width){
if(width === undefined)
return this.cnv.width;
this.optns.width = this.cnv.width = width;
this.cnv.style.width = width + ''px'';
this.optns.redraw = 1;
return this;
}
canvas.height = function(height){
if(height === undefined)
return this.cnv.height;
this.optns.heigth = this.cnv.height = height;
this.cnv.style.height = height + ''px'';
this.optns.redraw = 1;
return this;
}
canvas.optns =
{
id:idCanvas,
number:lastCanvas,
ctx: canvas.cnv.getContext(''2d''),
width: canvas.cnv.offsetWidth||canvas.cnv.width,
height: canvas.cnv.offsetHeight||canvas.cnv.height,
anyLayerDeleted: false,
anyLayerLevelChanged:false,
keyDown:{val:false,code:false},
keyUp:{val:false,code:false},
keyPress:{val:false,code:false},
mousemove:{val:false,x:false,y:false,object:false},
click:{val:false,x:false,y:false,objects:[]},
dblclick:{val:false,x:false,y:false,objects:[]},
mouseup:{val:false,x:false,y:false,objects:[]},
mousedown:{val:false,x:false,y:false,objects:[]},
drag:{object:false,x:0,y:0},
gCO: ''source-over'',
redraw:1
}
canvas.toDataURL=function(){return canvas.cnv.toDataURL.apply(canvas.cnv,arguments);}
canvas.layers=[];
canvas.interval=0;
jCanvaScript.layer(idCanvas+''Layer_0'').canvas(idCanvas);
canvas.recalculateOffset = function() {
var offset=getOffset(this.cnv);
this.optns.x=offset.left+(parseInt(this.cnv.style.borderTopWidth)||0);
this.optns.y=offset.top+(parseInt(this.cnv.style.borderLeftWidth)||0);
return this;
}
canvas.start=function(isAnimated) {
lastCanvas=this.optns.number;
if(isAnimated)
{
if(this.interval)return this;
this.isAnimated=isAnimated;
this.recalculateOffset();
var canvas=canvases[this.optns.number],
optns=canvas.optns;
this.cnv.onclick=function(e){
mouseEvent(e,''click'',optns);
}
this.cnv.ondblclick=function(e){
mouseEvent(e,''dblclick'',optns);
var tmp=optns.mousemove.val;
optns.mousemove.val=true;
setTimeout(function(){optns.mousemove.val=tmp;},3000);
}
this.cnv.onmousedown=function(e){
mouseEvent(e,''mousedown'',optns);
}
this.cnv.onmouseup=function(e){
mouseEvent(e,''mouseup'',optns);
}
this.cnv.onkeyup=function(e){
keyEvent(e,''keyUp'',optns);
}
this.cnv.onkeydown=function(e)
{
keyEvent(e,''keyDown'',optns);
}
this.cnv.onkeypress=function(e)
{
keyEvent(e,''keyPress'',optns);
}
this.cnv.onmouseout=this.cnv.onmousemove=function(e)
{
mouseEvent(e,''mousemove'',optns);
};
optns.timeLast=new Date();
this.interval=requestAnimFrame(function(time){
canvas.interval=canvas.interval||1;
canvas.frame(time);},
this.cnv);
}
else return this.frame();
return this;
}
canvas.pause=function() {
cancelRequestAnimFrame(this.interval);
this.interval=0;
return this;
}
canvas.restart = function() {
return this.pause().start(true);
}
canvas.del=function()
{
cancelRequestAnimFrame(this.interval);
this.layers=[];
canvases.splice(this.optns.number,1);
for(var i=0;i<canvases.length;i++)
{
var canvas=canvases[i],
layers=canvas.layers,
limitL=layers.length;
canvas.optns.number=i;
for(var j=0;j<limitL;j++)
{
var layer=layers[j];
layer.optns.canvas.number=i;
setLayerAndCanvasToArray(layer.objs,layer.optns.id,layer.optns.number,canvas.optns.id,canvas.optns.number);
setLayerAndCanvasToArray(layer.grdntsnptrns,layer.optns.id,layer.optns.number,canvas.optns.id,canvas.optns.number);
}
}
if(this.cnv.parentNode)this.cnv.parentNode.removeChild(this.cnv);
lastCanvas=0;
return false;
}
canvas.clear=function()
{
cancelRequestAnimFrame(this.interval);
this.interval=0;
this.layers=[];
jCanvaScript.layer(this.optns.id+''Layer_0'').canvas(this.optns.id);
this.optns.ctx.clearRect(0,0,this.optns.width,this.optns.height);
this.optns.redraw++;
return this;
}
canvas.frame=function(time)
{
var optns=this.optns,thisCanvas=this;
time=time||(new Date());
optns.timeDiff=time-optns.timeLast;
optns.timeLast=time;
if(this.interval)
{
this.interval=requestAnimFrame(function(time){thisCanvas.frame(time);},thisCanvas.cnv);
this.interval=this.interval||1;
}
if(!optns.redraw)return this;
optns.redraw--;
optns.ctx.clearRect(0,0,optns.width,optns.height);
if(this.layers.length==0)return this;
limit=this.layers.length;
if(optns.anyLayerLevelChanged)
limit=levelChanger(this.layers);
if(optns.anyLayerDeleted)
limit=objDeleter(this.layers);
if(optns.anyLayerLevelChanged || optns.anyLayerDeleted)
{
optns.anyLayerLevelChanged=optns.anyLayerDeleted=false;
for(var i=0;i<limit;i++)
{
var layer=this.layers[i],layerOptns=layer.optns;
setLayerAndCanvasToArray(layer.objs,layerOptns.id,layerOptns.number,this.optns.id,this.optns.number);
setLayerAndCanvasToArray(layer.grdntsnptrns,layerOptns.id,layerOptns.number,idCanvas,this.optns.number);
}
}
for(i=0;i<limit;i++)
{
var object=this.layers[i];
if(typeof (object.draw)==''function'')
if(object.beforeDraw(optns))
{
if(typeof (object.draw)==''function'')
{
object.draw(optns);
object.afterDraw(optns);
}
}
}
var mm=optns.mousemove;
var mouseDown=optns.mousedown;
var mouseUp=optns.mouseup;
var click=this.optns.click;
var dblClick=this.optns.dblclick;
if(mm.x!=false)
{
if(optns.drag.object!=false)
{
var drag=optns.drag,
dobject=drag.object;
dobject.translate(mm.x-drag.x,mm.y-drag.y);
drag.x=mm.x;
drag.y=mm.y;
if(drag.drag)drag.drag.call(dobject,{x:mm.x,y:mm.y});
}
var point = this.optns.point||{};
point.event=mm.event;
if(mm.object!=false)
{
var mousemoveObject=mm.object,
mousemoveLayer = objectLayer(mousemoveObject);
if(underMouse===mousemoveObject)
{
if(typeof mousemoveObject.onmousemove === ''function''){
mousemoveObject.onmousemove(point);
}
if(mousemoveLayer === underMouseLayer){
if(typeof mousemoveLayer.onmousemove === ''function''){
mousemoveLayer.onmousemove(point);
}
}
else {
if(underMouseLayer){
if(typeof underMouseLayer.onmouseout === ''function''){
underMouseLayer.onmouseout(point);
}
}
if(typeof mousemoveLayer.onmouseover === ''function''){
mousemoveLayer.onmouseover(point);
}
underMouseLayer = mousemoveLayer;
}
}
else
{
if(underMouse){
if(typeof underMouse.onmouseout === ''function''){
underMouse.onmouseout(point);
}
}
if(typeof mousemoveObject.onmouseover === ''function''){
mousemoveObject.onmouseover(point);
}
underMouse = mousemoveObject;
}
}
else
{
if(underMouse)
{
if(typeof underMouse.onmouseout==''function'')
{
underMouse.onmouseout(point);
}
underMouse=false;
}
if(underMouseLayer)
{
if(typeof underMouseLayer.onmouseout==''function'')
{
underMouseLayer.onmouseout(point);
}
underMouseLayer=false;
}
}
optns.mousemove.object=false;
}
if(mouseDown.objects.length)
{
var mdObjectsLength = mouseDown.objects.length - 1;
mdCicle:
for(i=mdObjectsLength;i>-1;i--)
{
var mouseDownObjects=[mouseDown.objects[i],objectLayer(mouseDown.objects[i])], mdObject;
for(var j=0;j<2;j++)
{
mdObject=mouseDownObjects[j];
if(mdObject.optns.drag.val==true && mdObject.optns.drag.disabled==false && i == mdObjectsLength)
{
drag=optns.drag;
dobject=drag.object=mdObject.optns.drag.object.visible(true);
drag.drag=mdObject.optns.drag.drag;
drag.init=mdObject;
var initoptns=drag.init.optns;
if(initoptns.drag.params!==undefined)dobject.animate(initoptns.drag.params);
drag.x=drag.startX=mouseDown.x;
drag.y=drag.startY=mouseDown.y;
if(dobject!=drag.init && initoptns.drag.type!=''clone'')
{
point=transformPoint(mouseDown.x,mouseDown.y,dobject.matrix());
dobject.translate(point.x-dobject._x,point.y-dobject._y);
}
dobject.translate(initoptns.drag.shiftX,initoptns.drag.shiftY);
if(typeof initoptns.drag.start==''function'')
initoptns.drag.start.call(dobject,{x:mouseDown.x,y:mouseDown.y});
}
if(typeof mdObject.onmousedown==''function'')
if(mdObject.onmousedown({x:mouseDown.x,y:mouseDown.y,event:mouseDown.event})===false)
break mdCicle;
}
}
mouseDown.objects=[];
}
if(mouseUp.objects.length)
{
muCicle:
for(i=mouseUp.objects.length-1;i>-1;i--)
{
var mouseUpObjects=[mouseUp.objects[i],objectLayer(mouseUp.objects[i])],muObject;
for(j=0;j<2;j++)
{
muObject=mouseUpObjects[j];
if(stopDrag(muObject, mouseUp, optns))click.objects=[];
if(typeof muObject.onmouseup==''function'')
if(muObject.onmouseup({x:mouseUp.x,y:mouseUp.y,event:mouseUp.event})===false)
break muCicle;
}
}
this.optns.drag={object:false,x:0,y:0};
mouseUp.objects=[];
}
if(click.objects.length)
{
cCicle:
for(i=click.objects.length-1;i>-1;i--)
{
var mouseClickObjects=[click.objects[i],objectLayer(click.objects[i])], clickObject;
for(j=0;j<2;j++)
{
clickObject = mouseClickObjects[j];
stopDrag(clickObject, click, optns);
if(typeof clickObject.onclick == ''function'')
if(clickObject.onclick({x:click.x,y:click.y,event:click.event})===false)
break cCicle;
}
}
this.optns.drag={object:false,x:0,y:0};
click.objects=[];
}
if(dblClick.objects.length)
{
dcCicle:
for(i=dblClick.objects.length-1;i>-1;i--)
{
var mouseDblClickObjects=[dblClick.objects[i],objectLayer(dblClick.objects[i])];
for(j=0;j<2;j++)
{
if(typeof mouseDblClickObjects[j].ondblclick == ''function'')
if(mouseDblClickObjects[j].ondblclick({x:dblClick.x,y:dblClick.y, event:dblClick.event})===false)
break dcCicle;
}
}
dblClick.objects=[];
}
optns.keyUp.val=optns.keyDown.val=optns.keyPress.val=click.x=dblClick.x=mouseUp.x=mouseDown.x=mm.x=false;
return this;
}
return canvas;
}
function stopDrag(object, event, optns){
var drag=optns.drag;
if(optns.drag.init && optns.drag.object)
{
if(object.optns.drop.val==true)
{
if(drag.init==drag.object)
drag.init.visible(true);
if(typeof object.optns.drop.fn==''function'')
object.optns.drop.fn.call(object,drag.init);
}
else
{
drag.object.visible(false);
drag.init.visible(true);
drag.init.optns.translateMatrix[0][2]=drag.object.optns.translateMatrix[0][2];
drag.init.optns.translateMatrix[1][2]=drag.object.optns.translateMatrix[1][2];
changeMatrix(drag.init);
if(drag.object!=drag.init)drag.object.visible(false);
if(typeof drag.init.optns.drag.stop==''function'')
drag.init.optns.drag.stop.call(drag.init,{x:event.x,y:event.y});
}
return (drag.x!=drag.startX || drag.y!==drag.startY)
}
return false;
}
jCanvaScript.layer=function(idLayer)
{
if(idLayer===undefined)return canvases[0].layers[0];
for(var i=0;i<canvases.length;i++)
{
var layersArray=canvases[i].layers;
for (var j=0;j<layersArray.length;j++)
if(layersArray[j].optns.id==idLayer)
return layersArray[j];
}
return layers(idLayer);
}
window.jCanvaScript = window.jc = jCanvaScript;
})(window, undefined);
实例
jCanvaScript使用心得1(—常用图绘制方法)
绘制圆形
第一种写法:
circle(x, y, radius, [color], [fill]);
x、y轴圆心坐标,半径,颜色,是否填充(默认为false||0不填充)如:
jc.circle(100,120,50,''rgba(255,0,0,0.5)'',true);
第二种写法1
circle(object parameters);
将对象作为参数,如:
jc.circle({x:100,y:120,radius:50,color:''#ff0000'',fill:1});
绘制矩形
rect(x, y, width, height, [color], [fill]);
x、y轴左上角坐标,宽高,颜色,是否填充(默认为false||0不填充)如:
jc.rect(80,100,120,50,''rgba(255,156,135,0.5)'',1);
绘制弧线
arc(x, y, radius, startAngle, endAngle, [anticlockwise], [color], [fill]);
x、y轴圆心坐标,半径,起始结束角度,方向(默认为true||1逆时针),颜色,是否填充(默认为false||0不填充)如:
jc.arc(60,100,60,90,180,1,''rgb(25,99,253)'',0);
绘制路径
line(points, [color], [fill])
用多个[X,Y]设置路径的点,颜色,是否填充(默认为false||0不填充)如:
jc.line([[60,20],[75,132],[220,60]],''#ff5587'');
绘制二次曲线,数组的点包含数组(x,y,x控制点,控制点y),用于创建曲线应至少两个数组。
qCurve(points, [color], [fill])
用多个[x,y,x of control point,y of control point]设置路径的点,颜色,是否填充(默认为false||0不填充)如:
var arr=[];
arr[0]=[40,30,30,40];
arr[1]=[30,40,40,30];
arr[2]=[30,180,180,30];
arr[3]=[40,190,190,40];
arr[4]=[180,190,190,180];
arr[5]=[190,180,180,190];
arr[6]=[190,40,40,190];
arr[7]=[180,30,30,180];
jc.qCurve(arr,''#ffbbcc'',true);
绘制贝塞尔曲线绘制贝塞尔曲线,数组的点包含数组(x,y,x控制点1,y控制点1,x控制点2,y控制点2]。用于创建曲线应至少两个数组。
bCurve(points, [color], [fill])
用多个 [x, y, x of control point 1, y of control point 1, x of control point 2, y of control point 2]设置路径的点,颜色,是否填充(默认为false||0不填充)如:
var arr=[];
arr[0]=[40,30,30,40,40,30];
arr[1]=[130,140,40,130,130,40];
arr[2]=[30,180,180,30,30,180];
jc.bCurve(arr,true);
绘制渐变创建一个新的空白jCanvaScript ImageData对象与指定的尺寸。通过循环改变setPixel里面颜色的方式绘制渐变
var imgData=jc.imageData(100,100); //设置渐变区域的大小
for(var i=0;i<100;i++){
for(var j=0;j<100;j++){
imgData.setPixel(i,j,''rgba(''+i+'',''+j+'',''+(i+j)+'',''+(i/100)+'')'');
//绘制像素点i,j为像素点坐标
}
}
imgData.putData(0,0); //设置渐变区域的位置
绘制图像
image(img, x, y, width, height, sX, sY, sWidth, sHeight);
图像对象,x、y轴坐标,图像宽高,从图像X、Y位置选择宽高的图像,如:
var img=new Image(); //创建图像对象
img.src="logo.png"; //设置图像地址
img.onload=function(){ //加载图片(canvas绘制图像需要在图片加载结束后)
jc.start("can1");
jc.image(img,0,0);
jc.rect(50, 50, 24, 24, ''#FF0000'');
jc.image(img,140,140,48,48,50,50,24,24); //将rect所选区域放大后绘制
jc.start("can1");}
绘制文字
text(text, x, y, [maxWidth], [color], [fill]);
文字字符串,x、y轴坐标,文字显示最大宽度(如果超出会整体压缩文字),颜色,是否填充(默认为true||1不填充)如:
jc.text("Colored stroked text",80,140,80,''rgb(255,0,0)'', 0);
--------------------------------------------------------------分割线--------------------------------------------------------
canvas 公式
// 把角度转换为弧度
function angleToRadian( angle ) {
return Math.PI / 180 * angle;
}
## 角度旋转
dx = mouse.x - object.x;
dy = mouse.y - object.y;
object.rotation = Math.atan2(dy,dx)*180/Math.PI
## 平滑运动
value = center + Math.sin(angle)*range;
angle += speed;
## 正圆运动
x_position = centerX + Math.sin(angle)*radius;
y_position = centerY + Math.cos(angle)*radius;
angle += speed;
## 椭圆运动
x_position = centerX + Math.cos(angle)*radiusX;
y_position = centerY + Math.sin(angle)*radiusY;
angle += speed;
##两点间距离
dx = x2 - x1;
dy = y2 - y1;
dist = Math.sqrt(dx*dx + dy*dy);
canvas文字居中
context.textAlign = ''center'';
context.textBaseline = ''middle'';
context.strokeText(n.toFixed(0) + ''%'', centerX, centerY);
//计算两点间的中点:
function middle(start,end){
return [(start.x+end.x)/2, (start.y+end.y)/2];
}
//计算两点间的角度:
function angle(start,end){
var diff_x = end.x - start.x,
diff_y = end.y - start.y;
return 360*Math.atan(diff_y/diff_x)/(2*Math.PI);
}
//注意:角度的计算方式要在地图上使用,需要先转换成地理坐标
function angleFn(start,end,map) {
var p_start = map.lngLatToContainer(new AMap.LngLat(start[0],start[1]));
var p_end = map.lngLatToContainer(new AMap.LngLat(end[0],end[1]));
var diff_x = p_end.x - p_start.x,
diff_y = p_end.y - p_start.y;
return 360*Math.atan(diff_y/diff_x)/(2*Math.PI);
}
Canvas
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div>
<h2>绘制圆形</h2>
<canvas id="canvas_1" width="1000" height="500">
当前浏览器不支持 canvas
</canvas>
</div>
</body>
<script type="text/javascript">
/*
该方法负责绘制圆角矩形
x1 , y2 : 圆角矩形左上角的坐标
width,height:控制圆角矩形的宽度和高度
radius:控制圆角矩形的四个圆角的半径
*/
function creatRoundRect(ctx, x1, y1, width, height, radius){
// 移动到左上角的开始点
ctx.moveTo(x1 + radius, y1);
// 添加一条连接开始点到右上角的线段
ctx.lineTo(x1 + width - radius, y1);
// 添加右上角的一段圆弧
ctx.arcTo(x1 + width, y1, x1 + width, y1 + radius, radius);
// 添加一条连接到右下角的线段
ctx.lineTo(x1 + width, y1 + height - radius);
// 添加右下角的一段圆弧
ctx.arcTo(x1 + width, y1 + height, x1 + width - radius, y1 + height, radius);
// 添加一条由右下角连接到左下角的线段
ctx.lineTo(x1 + radius, y1 + height);
// 添加左下的圆弧
ctx.arcTo(x1, y1 + height, x1, y1 + height - radius,radius);
// 添加一条由左下角连接到左上角的线段
ctx.lineTo(x1, y1 + radius);
// 添加一段圆弧
ctx.arcTo(x1, y1, x1 + radius, y1, radius);
ctx.closePath();
}
// 获取 canvas 元素对应的 DOM 对象
var canvas_1 = document.getElementById("canvas_1");
// 获取在 canvas 上绘图的 canvasRenderingContent2D 对象
var ctx = canvas_1.getContext("2d");
ctx.lineWidth = 3;
creatRoundRect(ctx, 30, 30, 200, 100, 20);
ctx.stroke();
</script>
</html>
---------------------
作者:MR_LP
来源:CSDN
原文:https://blog.csdn.net/MR_LP/article/details/51919800?utm_source=copy
版权声明:本文为博主原创文章,转载请附上博文链接!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div>
<h2>绘制多角形</h2>
<canvas id="canvas_1" width="1000" height="500">
当前浏览器不支持 canvas
</canvas>
</div>
</body>
<script type="text/javascript">
/*
该方法用于绘制多角形
n:该参数通常设置为奇数,控制绘制 N 角星
dx、dy:控制 N 角星的位置
size:控制 N 角星的大小
*/
function creatStar(context, n, dx, dy, size){
// 开始创建路径
context.beginPath();
var dig = Math.PI / n * 4;
context.moveTo(dx, y + dy);
for(var i = 0; i <= n; i++){
var x = Math.sin(i * dig);
var y = Math.cos(i * dig);
// 绘制从当前点连接到指定点的线条
context.lineTo(x * size + dx, y * size + dy);
}
// 关闭路径
context.closePath();
}
// 获取 canvas 元素对应的 DOM 对象
var canvas_1 = document.getElementById("canvas_1");
// 获取在 canvas 上绘图的 canvasRenderingContent2D 对象
var ctx = canvas_1.getContext("2d");
// 绘制三角星
creatStar(ctx, 3, 60, 60, 50);
ctx.fill#f00'';
ctx.fill();
// 绘制五角星
creatStar(ctx, 5, 160, 60, 50);
ctx.fill#0f0'';
ctx.fill();
// 绘制七角星
creatStar(ctx, 7, 260, 60, 50);
ctx.fill#00f'';
ctx.fill();
// 绘制九角星
creatStar(ctx, 9, 360, 60, 50);
ctx.fill#f0f'';
ctx.fill();
</script>
</html>
---------------------
作者:MR_LP
来源:CSDN
原文:https://blog.csdn.net/MR_LP/article/details/51919800?utm_source=copy
版权声明:本文为博主原创文章,转载请附上博文链接!
多边形
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div>
<h2>绘制花朵</h2>
<canvas id="canvas_1" width="1000" height="500">
当前浏览器不支持 canvas
</canvas>
</div>
</body>
<script type="text/javascript">
/*
该方法负责绘制花朵
n:该参数控制花朵的花瓣数
dx,dy:控制花朵的位置
size:控制花朵的大小
length:控制花瓣的长度
*/
function creatFlower(context, n, dx, dy, size, length){
// 开始创建路径
context.beginPath();
context.moveTo(dx, dy + size);
var dig = 2 * Math.PI / n;
for(var i = 1; i < n + 1; i++){
// 计算控制点的坐标
var ctrlX = Math.sin((i - 0.5) * dig) * length + dx;
var ctrlY = Math.cos((i - 0.5) * dig) * length + dy;
// 计算结束点的坐标
var x = Math.sin(i * dig) * size + dx;
var y = Math.cos(i * dig) * size + dy;
// 绘制二次曲线
context.quadraticCurveTo(ctrlX, ctrlY, x, y);
}
context.closePath();
}
// 获取 canvas 元素对应的 DOM 对象
var canvas_1 = document.getElementById("canvas_1");
// 获取在 canvas 上绘图的 canvasRenderingContent2D 对象
var ctx = canvas_1.getContext("2d");
// 绘制五瓣的花朵
creatFlower(ctx, 5, 70, 100, 30, 80);
ctx.fill;
ctx.fill();
// 绘制六瓣的花朵
creatFlower(ctx, 6, 220, 100, 30, 80);
ctx.fill;
ctx.fill();
// 绘制七瓣的花朵
creatFlower(ctx, 7, 370, 100, 30, 80);
ctx.fill;
ctx.fill();
</script>
</html>
---------------------
作者:MR_LP
来源:CSDN
原文:https://blog.csdn.net/MR_LP/article/details/51919800?utm_source=copy
版权声明:本文为博主原创文章,转载请附上博文链接!
雷达图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
canvas{
}
</style>
</head>
<body>
<script type="text/javascript">
var mW = 400;
var mH = 400;
var mData = [[''速度'', 77],
[''力量'', 72],
[''防守'', 46],
[''射门'', 50],
[''传球'', 80],
[''耐力'', 60]];
var mCount = mData.length; //边数
var mCenter = mW /2; //中心点
var mRadius = mCenter - 50; //半径(减去的值用于给绘制的文本留空间)
var mAngle = Math.PI * 2 / mCount; //角度
var mCtx = null;
var mColorPolygon = ''#B8B8B8''; //多边形颜色
var mColorLines = ''#B8B8B8''; //顶点连线颜色
var mColorText = ''#000000'';
//初始化
(function(){
var canvas = document.createElement(''canvas'');
document.body.appendChild(canvas);
canvas.height = mH;
canvas.width = mW;
mCtx = canvas.getContext(''2d'');
drawPolygon(mCtx);
drawLines(mCtx);
drawText(mCtx);
drawRegion(mCtx);
drawCircle(mCtx);
})();
// 绘制多边形边
function drawPolygon(ctx){
ctx.save();
ctx.strokeStyle = mColorPolygon;
var r = mRadius/ mCount; //单位半径
//画6个圈
for(var i = 0; i < mCount; i ++){
ctx.beginPath();
var currR = r * ( i + 1); //当前半径
//画6条边
for(var j = 0; j < mCount; j ++){
var x = mCenter + currR * Math.cos(mAngle * j);
var y = mCenter + currR * Math.sin(mAngle * j);
ctx.lineTo(x, y);
}
ctx.closePath()
ctx.stroke();
}
ctx.restore();
}
//顶点连线
function drawLines(ctx){
ctx.save();
ctx.beginPath();
ctx.strokeStyle = mColorLines;
for(var i = 0; i < mCount; i ++){
var x = mCenter + mRadius * Math.cos(mAngle * i);
var y = mCenter + mRadius * Math.sin(mAngle * i);
ctx.moveTo(mCenter, mCenter);
ctx.lineTo(x, y);
}
ctx.stroke();
ctx.restore();
}
//绘制文本
function drawText(ctx){
ctx.save();
var fontSize = mCenter / 12;
ctx.font = fontSize + ''px Microsoft Yahei'';
ctx.fillStyle = mColorText;
for(var i = 0; i < mCount; i ++){
var x = mCenter + mRadius * Math.cos(mAngle * i);
var y = mCenter + mRadius * Math.sin(mAngle * i);
if( mAngle * i >= 0 && mAngle * i <= Math.PI / 2 ){
ctx.fillText(mData[i][0], x, y + fontSize);
}else if(mAngle * i > Math.PI / 2 && mAngle * i <= Math.PI){
ctx.fillText(mData[i][0], x - ctx.measureText(mData[i][0]).width, y + fontSize);
}else if(mAngle * i > Math.PI && mAngle * i <= Math.PI * 3 / 2){
ctx.fillText(mData[i][0], x - ctx.measureText(mData[i][0]).width, y);
}else{
ctx.fillText(mData[i][0], x, y);
}
}
ctx.restore();
}
//绘制数据区域
function drawRegion(ctx){
ctx.save();
ctx.beginPath();
for(var i = 0; i < mCount; i ++){
var x = mCenter + mRadius * Math.cos(mAngle * i) * mData[i][1] / 100;
var y = mCenter + mRadius * Math.sin(mAngle * i) * mData[i][1] / 100;
ctx.lineTo(x, y);
}
ctx.closePath();
ctx.fillrgba(255, 0, 0, 0.5)'';
ctx.fill();
ctx.restore();
}
//画点
function drawCircle(ctx){
ctx.save();
var r = mCenter / 18;
for(var i = 0; i < mCount; i ++){
var x = mCenter + mRadius * Math.cos(mAngle * i) * mData[i][1] / 100;
var y = mCenter + mRadius * Math.sin(mAngle * i) * mData[i][1] / 100;
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI * 2);
ctx.fillrgba(255, 0, 0, 0.8)'';
ctx.fill();
}
ctx.restore();
}
</script>
</body>
</html>
---------------------
作者:王乐平
来源:CSDN
原文:https://blog.csdn.net/lecepin/article/details/60466711?utm_source=copy
版权声明:本文为博主原创文章,转载请附上博文链接!
基础图标
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
</head>
<body>
<canvas id="bar" width="450" height="250">
</canvas>
<canvas id="pie" width="450" height="250"></canvas>
<br />
<canvas id="line" width="450" height="250"></canvas>
<canvas id="curve" width="450" height="250"></canvas>
<script>
window.onload = function() {
var bar = document.getElementById("bar"),
data = {
label: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],//x轴的标题
dataSets: [{
bDistance: 30, //绘制的边框距离画布边框的距离
bInterval: 20, //两个柱状图之间的距离
values: [300, 50, 100, 50, 80, 150, 120], //对应标签的值
fillColor: "rgba(0,0,255,0.5)" //矩形填充颜色
}, {
txtfont: "14px microsoft yahei",//绘制文本的字体
txtalgin: "center",//文本对齐方式
txtbaseline: "middle"//文本的基线
}, {
fillColor: "black", //矩形填充颜色
xtitle: "订单总数(个)", //x轴标题
ytitle: "星期几" //y轴标题
}]
};
barChart(bar, data); //画柱状图
var pie = document.getElementById("pie"),
datasets = {
colors: ["blue", "yellow", "black", "red", "green"], //颜色
labels: ["第一周", "第二周", "第三周", "第四周", "第五周"], //标签
values: [30, 60, 80, 70, 150], //值
x: 125, //圆心x坐标
y: 125, //圆心y坐标
radius: 100 //半径
};
pieChart(pie, datasets); //画饼状图
var line = document.getElementById("line"),
datas = {
labels: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],//标签
values: [50, 180, 100, 150, 110, 130, 30],//值
txtSet: {//绘制文本设置
txtfont: "14px microsoft yahei",
txtalgin: "center",
txtbaseline: "middle",
txtColor:"#000000"
},
bgSet:{//绘制背景线设置
lineColor:"#C0C0C0",
lineWidth:1,
},
lineColor:"#000000",//折线颜色
circleColor:"blue",//折线上原点颜色
yAxis:{//y轴表示什么,及绘制文本的位置
x:50,
y:11,
title:"完成件数(个)"
}
},
newData = {
labels: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
values: [100, 40, 200, 50, 10, 80, 100],
txtSet: {
txtfont: "14px microsoft yahei",
txtalgin: "center",
txtbaseline: "middle",
txtColor:"#000000"
},
bgSet:{
lineColor:"#C0C0C0",
lineWidth:1,
},
lineColor:"blue",
circleColor:"red",
yAxis:{
x:50,
y:11,
title:"完成件数(个)"
}
};
lineChart(line,datas);//画折线图
//lineChart(line,newData);//在同一个canvas画第二条折线图
//curveChart();//绘制曲线
var bg = document.getElementById("curve")
linedata = {
labels: ["1月", "2月", "3月", "4月", "5月", "6月", "7月"],//标签
datas: [115, 35, 210, 100, 300, 220, 40],//数据
xTitle: "月份",//x轴标题
yTitle: "产量(个)",//y轴标题
ctxSets:{
strokeColor:"#C0C0C0",//背景线颜色
lineWidth:1,//线的宽度
txtColor:"#000000",//绘制文本颜色
txtFont:"12px microsoft yahei",//字体
txtAlign:"center",//对齐方式
txtBase:"middle",//基线
lineColor:"blue",//折线颜色
circleColor:"#FF0000"//折线上圆点颜色
}
};
setBg(bg,linedata);//绘制图标背景及折线
}
//数组sort()排序传的参数为该函数(降序排列),绘制柱状图需要
function compare(value1, value2) {
return value2 - value1;
}
/*柱状图
* elem:要操作的画布元素
* data:所需格式的数据*/
function barChart(elem, data) {
if (elem.getContext) {
var ctx = elem.getContext("2d"),
mywidth = elem.width, //画布的宽高
myheight = elem.height,
bDistance = parseInt(data.dataSets[0].bDistance), //图标边框到画布间距
bInterval = data.dataSets[0].bInterval, //矩形间间距
labels = data.label, //矩形对应标题
len = labels.length,//标签/数据个数
//矩形宽度
bWidth = Math.floor((mywidth - bDistance * 2 - (len + 1) * bInterval) / len),
bheight = myheight - bDistance * 2, //边框高度
values = data.dataSets[0].values, //绘图的值
sortValues = values.slice(0), //基于当前数组中的一个或多个项创建一个新数组(解决了该数组排序原数组也被排序的问题)
serialValues = new Array(); //用于存储序列化后的值
sortValues.sort(compare);
if (sortValues[0] > bheight) {
(function() {
//数值超过边框高度时序列化值
for (var i = 0; i < len; i++) {
serialValues[i] = values[i] * bheight / sortValues[0];
}
})(); //块级作用域
}
//绘制边框
ctx.beginPath(); //要绘制路径,必须先调用该方法,表示开始绘制新路径
ctx.moveTo(bDistance, bDistance);
ctx.lineTo(bDistance, myheight - bDistance);
ctx.lineTo(mywidth - bDistance, myheight - bDistance);
ctx.stroke(); //把图形绘制到画布上
//绘制矩形,组成条形图
ctx.fillStyle = data.dataSets[0].fillColor;
//绘制文字
ctx.font = data.dataSets[1].txtfont; //字体样式、大小、字体
ctx.textAlign = data.dataSets[1].txtalgin; //文本对齐方式
ctx.textBaseline = data.dataSets[1].txtbaseline; //文本的基线
for (var i = 0; i < len; i++) {
var x = (bInterval + bDistance) + i * (bWidth + bInterval),
y = myheight - serialValues[i] - bDistance,
x1 = x + Math.round(bWidth / 2);
y1 = myheight - bDistance + 15,
y2 = y - 10;
ctx.fillRect(x, y, bWidth, serialValues[i]); //x,y,width,height单位都为px
ctx.fillText(labels[i], x1, y1); //绘制标题文字
ctx.fillText(values[i], x1, y2); //绘制柱状图数据
}
ctx.fillStyle = data.dataSets[2].fillColor;
ctx.fillText(data.dataSets[2].xtitle, 49, 7); //x轴代表什么
ctx.fillText(data.dataSets[2].ytitle, mywidth - bDistance, myheight - bDistance + 15); //y轴代表什么
}
}
//求和,计算百分比(画饼图时需要)
function sumFunc(data) {
var sum = 0;
for (var i = 0, len = data.length; i < len; i++) {
sum += data[i];
}
return sum;
}
/*饼图
* elem:要操作的画布元素
* data:所需格式的数据*/
function pieChart(elem, data) {
if (elem.getContext) {
var ctx = elem.getContext("2d"),
vdata = data.values, //绘图数据
sum = sumFunc(vdata), //对绘图数据求和,用于计算百分比
startangle = 0, //绘制扇形的开始角度
labels = data.labels, //绘图的对应文字
x = data.x, //圆心x坐标
y = data.y, //圆心y坐标
rad = data.radius, //圆半径
x1 = x + rad + 30, //绘制右侧文字和标注的x坐标
y1 = y - rad, //绘制右侧文字和标注的y坐标
endangle; //绘制扇形的结束角度
for (var i = 0, len = vdata.length; i < len; i++) {
//绘制饼图
//计算下一次绘制扇形的结束角度,即根据绘制数据占有总数据和的比例求的弧度
var percent = vdata[i] / sum;
endangle = startangle + Math.PI * 2 * (percent);
ctx.beginPath(); //开始绘制新路径
ctx.fillStyle = data.colors[i]; //绘制颜色
ctx.moveTo(x, y); //移动到圆心(注:画饼图一定要回到圆心,不然会有问题)
ctx.arc(x, y, rad, startangle, endangle, false); //画扇形
//绘制右侧文字和标注
ctx.moveTo(x1, y1); //移动到绘制文字和标注的位置
ctx.fillRect(x1, y1, 30, 14); //绘制矩形表示比列图
//计算四舍五入后的扇形每份的百分比
var perc = (percent * 100).toFixed(2) + "%"; //tofixed()自动四舍五入返回指定小数位数的字符串
//设置绘制文字的属性
ctx.font = "bold 12px microsoft yahei";
ctx.txtalgin = "center";
ctx.textBaseline = "top";
//绘制文字
ctx.fillText(labels[i] + ":" + perc, x1 + 35, y1);
ctx.fill(); //指定颜色填充以上绘制
startangle = endangle; //下一次绘制扇形的开始角度
y1 += 20; //下一次绘制文字和标注的y坐标
}
}
}
/*绘制折线
elem:操作的元素
data:所需格式数据*/
function lineChart(elem, data) {
if (elem.getContext) {
var ctx = elem.getContext("2d"),
labels = data.labels,//数值对应标签
values = data.values,//数值
len = labels.length,//标签/数值个数
elemWidth = elem.width,//画布宽度
elemHeight = elem.height,//画布高度
gridHeight = Math.ceil(elemHeight / 5),//每行之间高度
gridWidth = Math.floor(elemWidth / len),//每列之间看度
actualHeight = 4 * gridHeight + 20;//绘制区域实际高度
//设置绘制直线的属性
ctx.strokeStyle = data.bgSet.lineColor;
ctx.lineWidth = data.bgSet.lineWidth;
//设置绘制文本的属性
ctx.font = data.txtSet.txtfont;
ctx.textAlign = data.txtSet.txtalgin;
ctx.txtbaseline = data.txtSet.txtbaseline;
//绘制背景
//绘制背景横线
ctx.beginPath();
for (var i = 0; i < 5; i++) {
var hgridY = gridHeight * i + 20,
hgridX = gridWidth * len;
ctx.moveTo(0, hgridY);
ctx.lineTo(hgridX, hgridY);
}
ctx.stroke();
//绘制背景的竖线,表示每个label
ctx.beginPath();
for (var j = 0; j < len + 1; j++) {
var vgridX = gridWidth * j,
vgridY = actualHeight;
ctx.moveTo(vgridX, vgridY);
ctx.lineTo(vgridX, vgridY + 10);
}
ctx.stroke();
//绘制标签文字
ctx.fillStyle = data.txtSet.txtColor;
for (var k = 0; k < len; k++) {
var txtX = gridWidth * (k + 0.5),
txtY = actualHeight + 15;
ctx.fillText(labels[k], txtX, txtY);
}
ctx.fill();
//获取画图数据的最大值用于序列换数据
var maxValue = 0,
cData = new Array();
for (var i = 0; i < len; i++) {
if (values[i] > maxValue) {
maxValue = values[i];
}
}
//当最大值大于画布可绘制区域的高度时,对数据进行转化,然后进行画图
if ((4 * gridHeight) < maxValue) {
for (var i = 0; i < len; i++) {
//转换后的数据
cData[i] = values[i] * 4 * gridHeight / maxValue;
}
} else {
cData = values;
}
//绘制折线
ctx.strokeStyle = data.lineColor;
ctx.beginPath();
var pointX = gridWidth / 2,
pointY = actualHeight - cData[0];
ctx.moveTo(pointX, pointY);
for (var i = 1; i < len; i++) {
pointX += gridWidth;
pointY = actualHeight - cData[i];
ctx.lineTo(pointX, pointY);
}
ctx.stroke();
//绘制坐标圆形
ctx.beginPath();
ctx.fillStyle = data.circleColor; //圆点的颜色
for (var i = 0; i < len; i++) {
var circleX = gridWidth / 2 + gridWidth * i,
circleY = actualHeight - cData[i];
ctx.moveTo(circleX, circleY); //假如不每次绘制之前确定开始绘制新路径,可以每次绘制之前移动到新的圆心
ctx.arc(circleX, circleY, 4, 0, Math.PI * 2, false);
}
ctx.fill();
//绘制坐标圆形对应的值
ctx.beginPath();
ctx.fillStyle = data.txtSet.txtColor;; //文本颜色
for (var i = 0; i < len; i++) {
var circleX = gridWidth / 2 + gridWidth * i,
circleY = actualHeight - cData[i];
ctx.fillText(values[i], circleX, circleY - 8);
}
ctx.fill();
//绘制y轴代表什么
ctx.fillText(data.yAxis.title, data.yAxis.x, data.yAxis.y);
ctx.fill();
}
}
function curveChart() {
var elem = document.getElementById("curve");
if (elem.getContext) {
var ctx = elem.getContext("2d");
// ctx.lineWidth = 2;
ctx.lineCap = "square";
ctx.beginPath();
ctx.moveTo(100, 70);
ctx.bezierCurveTo(120, 150, 150, 150, 200, 60); //三次贝赛尔曲线
ctx.moveTo(40, 100);
ctx.quadraticCurveTo(60, 60, 100, 70); //二次贝塞尔曲线
ctx.moveTo(200, 60);
ctx.arcTo(240, 40, 300, 50, 50); //绘制弧线
ctx.stroke();
}
}
/* 绘制背景
* elem:要操作的元素
* data:所需格式的数据*/
function setBg(elem, data) {
if (elem.getContext) {
var ctx = elem.getContext("2d"),//获取元素上下文
startX = 40,//左上角开始绘制的x坐标
startY = 40,//左上角开始绘制的y坐标
labels = data.labels,//对应数据的标签,即列数
cols = labels.length,//数据个数
datas = data.datas,//数据
gWidth = elem.width - 80,//背景总宽度,elem.width为画布宽度
gHeight = elem.height - 80,//背景总长度
pgWidth = gWidth / cols,//背景每个格的宽度
rows = 10,//背景表格行数
pgHeight = gHeight / rows;//背景表格高度
//绘制背景
ctx.beginPath(); //开始绘制新路径
ctx.strokeStyle = data.ctxSets.strokeColor;//描边颜色
ctx.lineWidth = data.ctxSets.lineWidth;//描边线条宽度
//绘制横线
for (var i = 0; i < rows; i++) {
var pY = startX + pgHeight * i;
ctx.moveTo(startX, pY); //移动到绘制的起点
ctx.lineTo(gWidth + startX, pY);
}
//最后一根横线
var pY1 = startY + pgHeight * rows;
ctx.moveTo(startX, pY1); //移动到绘制的起点
ctx.lineTo(gWidth + startX + 20, pY1);
//绘制竖线
//第一根竖线
ctx.moveTo(startX, startY - 20); //移动到绘制的起点
ctx.lineTo(startX, gHeight + startY + 10);
for (var i = 1; i < cols + 1; i++) {
var pX = startX + pgWidth * i;
ctx.moveTo(pX, startY); //移动到绘制的起点
ctx.lineTo(pX, gHeight + startY + 10);
}
ctx.stroke();//把图形绘制到画布上
//绘制文字
ctx.fillStyle = data.ctxSets.txtColor;//填充颜色
ctx.font = data.ctxSets.txtFont;//文本字体
ctx.textAlign = data.ctxSets.txtAlign;//文本对齐方式
ctx.textBaseline = data.ctxSets.txtBase;//文本基线
//绘制横轴文字
for (var i = 0; i < cols; i++) {
var px = startX + pgWidth / 2 + pgWidth * i;
ctx.fillText(labels[i], px, startY + gHeight + 10);
}
//绘制竖轴文字
//判断最大值是否大于行高,确定每行的数值
var maxValue = 0,
newValues = new Array(),
j = 0;
for (var i = 0; i < cols; i++) {
if (datas[i] > maxValue) {
maxValue = datas[i];
}
}
//重新计算每隔数据值及转换值
if (maxValue > gHeight) {
pgValues = maxValue / rows;
for (var i = 0; i < cols; i++) {
newValues[i] = datas[i] * gHeight / maxValue;
}
} else {
pgValues = pgHeight;
newValues = datas;
}
//绘制竖轴文字
for (var i = rows; i >= 0; i--) {
ctx.fillText(pgValues * i, 20, startY + pgHeight * j);
j++;
}
//绘制标题
//x轴标题
ctx.fillText(data.xTitle, gWidth + startX + 15, gHeight + startY + 10);
//y轴标题
ctx.fillText(data.yTitle, startX + 25, startY - 10);
//画图
//绘制折线
ctx.strokeStyle = data.ctxSets.lineColor;;
ctx.beginPath();
var pointX = pgWidth / 2 + startX,
pointY = startY + gHeight - newValues[0];
ctx.moveTo(pointX, pointY);
for (var i = 1; i < cols; i++) {
pointX += pgWidth;
pointY = startY + gHeight - newValues[i];
ctx.lineTo(pointX, pointY);
}
ctx.stroke();
//绘制坐标圆形
ctx.beginPath();
ctx.fillStyle = data.ctxSets.circleColor;; //圆点的颜色
for (var i = 0; i < cols; i++) {
var circleX = pgWidth / 2 + startX + pgWidth * i,
circleY = startY + gHeight - newValues[i];
ctx.moveTo(circleX, circleY); //假如不每次绘制之前确定开始绘制新路径,可以每次绘制之前移动到新的圆心
ctx.arc(circleX, circleY, 4, 0, Math.PI * 2, false);
}
ctx.fill();
//绘制坐标圆形对应的值
ctx.beginPath();
ctx.fillStyle = data.ctxSets.txtColor; //文本颜色
for (var i = 0; i < cols; i++) {
var circleX = pgWidth / 2 + startX + pgWidth * i,
circleY = startY + gHeight - newValues[i];
ctx.fillText(datas[i], circleX, circleY - 10);
}
ctx.fill();
}
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<style>
.main{
padding: 50px;
text-align: center;
}
</style>
</head>
<body>
https://www.cnblogs.com/linxin/p/6892389.html
<div><canvas id="canvas" width="500" height="400"></canvas></div>
<script >
function sBarChart(canvas, data, options) {
this.canvas = document.getElementById(canvas);
this.ctx = this.canvas.getContext(''2d'');
this.data = data; // 存放图表数据
this.dataLength = this.data.length; // 图表数据的长度
this.width = this.canvas.width; // canvas 宽度
this.height = this.canvas.height; // canvas 高度
this.padding = 50; // canvas 内边距
this.yEqual = 5; // y轴分成5等分
this.yLength = 0; // y轴坐标点之间的真实长度
this.xLength = 0; // x轴坐标点之间的真实长度
this.yFictitious = 0; // y轴坐标点之间显示的间距
this.yRatio = 0; // y轴坐标真实长度和坐标间距的比
this.bgColor = ''#ffffff''; // 默认背景颜色
this.fillColor = ''#1E9FFF''; // 默认填充颜色
this.axisColor = ''#666666''; // 坐标轴颜色
this.contentColor = ''#eeeeee''; // 内容横线颜色
this.titleColor = ''#000000''; // 图表标题颜色
this.title = ''''; // 图表标题
this.titlePosition = ''top''; // 图表标题位置: top / bottom
this.looped = null; // 是否循环
this.current = 0; // 当前加载柱状图高度的百分数
this.currentIndex = -1;
this.onceMove = -1;
this.init(options);
}
sBarChart.prototype = {
init: function(options) {
if(options){
this.padding = options.padding || 50;
this.yEqual = options.yEqual || 5;
this.bgColor = options.bgColor || ''#ffffff'';
this.fillColor = options.fillColor || ''#1E9FFF'';
this.axisColor = options.axisColor || ''#666666'';
this.contentColor = options.contentColor || ''#eeeeee'';
this.titleColor = options.titleColor || ''#000000'';
this.title = options.title;
this.titlePosition = options.titlePosition || ''top'';
}
this.yLength = Math.floor((this.height - this.padding * 2 - 10) / this.yEqual);
this.xLength = Math.floor((this.width - this.padding * 1.5 - 10) / this.dataLength);
this.yFictitious = this.getYFictitious(this.data);
this.yRatio = this.yLength / this.yFictitious;
this.looping();
},
looping: function() {
this.looped = requestAnimationFrame(this.looping.bind(this));
if(this.current < 100){
this.current = (this.current + 3) > 100 ? 100 : (this.current + 3);
this.drawAnimation();
}else{
window.cancelAnimationFrame(this.looped);
this.looped = null;
this.watchHover();
}
},
drawAnimation: function() {
for(var i = 0; i < this.dataLength; i++) {
var x = Math.ceil(this.data[i].value * this.current / 100 * this.yRatio);
var y = this.height - this.padding - x;
this.data[i].left = this.padding + this.xLength * (i + 0.25);
this.data[i].top = y;
this.data[i].right = this.padding + this.xLength * (i + 0.75);
this.data[i].bottom = this.height - this.padding;
this.drawUpdate();
}
},
drawUpdate: function() {
this.ctx.fillStyle = this.bgColor;
this.ctx.fillRect(0, 0, this.width, this.height);
this.drawAxis();
this.drawPoint();
this.drawTitle();
this.drawChart();
},
drawChart: function() {
this.ctx.fillStyle = this.fillColor;
for(var i = 0; i < this.dataLength; i++) {
this.ctx.fillRect(
this.data[i].left,
this.data[i].top,
this.data[i].right - this.data[i].left,
this.data[i].bottom - this.data[i].top
);
this.ctx.font = ''12px Arial''
this.ctx.fillText(
this.data[i].value * this.current / 100,
this.data[i].left + this.xLength / 4,
this.data[i].top - 5
);
}
},
drawAxis: function() {
this.ctx.beginPath();
this.ctx.strokeStyle = this.axisColor;
// y轴线, +0.5是为了解决canvas画1像素会显示成2像素的问题
this.ctx.moveTo(this.padding + 0.5, this.height - this.padding + 0.5);
this.ctx.lineTo(this.padding + 0.5, this.padding + 0.5);
// x轴线
this.ctx.moveTo(this.padding + 0.5, this.height - this.padding + 0.5);
this.ctx.lineTo(this.width - this.padding / 2 + 0.5, this.height - this.padding + 0.5);
this.ctx.stroke();
},
drawPoint: function() {
// x轴坐标点
this.ctx.beginPath();
this.ctx.font = ''12px Microsoft YaHei'';
this.ctx.textAlign = ''center'';
this.ctx.fillStyle = this.axisColor;
for(var i = 0; i < this.dataLength; i ++){
var xAxis = this.data[i].xAxis;
var xlen = this.xLength * (i + 1);
this.ctx.moveTo(this.padding + xlen + 0.5, this.height - this.padding + 0.5);
this.ctx.lineTo(this.padding + xlen + 0.5, this.height - this.padding + 5.5);
this.ctx.fillText(xAxis, this.padding + xlen - this.xLength / 2, this.height - this.padding + 15);
}
this.ctx.stroke();
// y轴坐标点
this.ctx.beginPath();
this.ctx.font = ''12px Microsoft YaHei'';
this.ctx.textAlign = ''right'';
this.ctx.fillStyle = this.axisColor;
this.ctx.moveTo(this.padding + 0.5, this.height - this.padding + 0.5);
this.ctx.lineTo(this.padding - 4.5, this.height - this.padding + 0.5);
this.ctx.fillText(0, this.padding - 10, this.height - this.padding + 5);
for(var i=0; i < this.yEqual; i ++){
var y = this.yFictitious * (i + 1);
var ylen = this.yLength * (i + 1);
this.ctx.beginPath();
this.ctx.strokeStyle = this.axisColor;
this.ctx.moveTo(this.padding + 0.5, this.height - this.padding - ylen + 0.5);
this.ctx.lineTo(this.padding - 4.5, this.height - this.padding - ylen + 0.5);
this.ctx.stroke();
this.ctx.fillText(y,this.padding - 10, this.height - this.padding - ylen + 5);
this.ctx.beginPath();
this.ctx.strokeStyle = this.contentColor;
this.ctx.moveTo(this.padding + 0.5, this.height - this.padding - ylen + 0.5)
this.ctx.lineTo(this.width - this.padding / 2 + 0.5, this.height - this.padding - ylen+0.5);
this.ctx.stroke();
}
},
drawTitle: function() {
if(this.title){
this.ctx.beginPath();
this.ctx.textAlign = ''center'';
this.ctx.fillStyle = this.titleColor;
this.ctx.font = ''16px Microsoft YaHei'';
if(this.titlePosition === ''bottom'' && this.padding >= 40){
this.ctx.fillText(this.title, this.width / 2, this.height - 5)
}else{
this.ctx.fillText(this.title, this.width / 2, this.padding / 2)
}
}
},
/**
* 监听鼠标移动事件
*/
watchHover: function() {
var self = this;
self.canvas.addEventListener(''mousemove'', function(ev) {
ev = ev || window.event;
self.currentIndex = -1;
for (var i = 0; i < self.data.length; i ++){
if( ev.offsetX > self.data[i].left &&
ev.offsetX < self.data[i].right &&
ev.offsetY > self.data[i].top &&
ev.offsetY < self.data[i].bottom )
{
self.currentIndex = i;
}
}
self.drawHover();
})
},
drawHover: function() {
if(this.currentIndex !== -1){
if(this.onceMove === -1){
this.onceMove = this.currentIndex;
this.canvas.style.cursor = ''pointer'';
}
}else{
if(this.onceMove !== -1){
this.onceMove = -1;
this.canvas.style.cursor = ''inherit'';
}
}
},
/**
* y轴坐标点之间显示的间距
* @param data
* @return y轴坐标间距
*/
getYFictitious: function(data) {
var arr = data.slice(0);
arr.sort(function(a,b){
return -(a.value-b.value);
});
var len = Math.ceil(arr[0].value / this.yEqual);
var pow = len.toString().length - 1;
pow = pow > 2 ? 2 : pow;
return Math.ceil(len / Math.pow(10,pow)) * Math.pow(10,pow);
}
}
</script>
<script>
var data = [
{xAxis:''2012'',value:2141},
{xAxis:''2013'',value:1499},
{xAxis:''2014'',value:3260},
{xAxis:''2015'',value:1170},
{xAxis:''2016'',value:970},
{xAxis:''2017'',value:2350}
]
var chart = new sBarChart(''canvas'',data,{
title: ''xxx公司年度盈利'',
bgColor: ''#829dba'',
titleColor: ''#ffffff'', // 标题颜色
titlePosition: ''top'', // 标题位置
fillColor: ''#72f6ff'', // 柱状填充色
axisColor: ''#eeeeee'', // 坐标轴颜色
contentColor: ''#bbbbbb'' // 内容横线颜色
});
</script>
</body>
</html>
多个环形
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>asd</title>
</head>
<body>
<div>
<canvas id="pTestPassRate1" width="242" height="270"></canvas>
<divcanvasTxt''>用例通过数</div>
<canvas id="canvas2" width="242" height="270"></canvas>
</div>
<script></script>
<script>
window.onload=function(){
function degToRad(deg){//角度转弧度
return deg*(Math.PI/180); ;
}
var pTestPassRate1 =document.getElementById("pTestPassRate1");
var ctx = pTestPassRate1.getContext("2d");
ctx.lineWidth = 10;
//Background
// gradient = ctx.createRadialGradient(250, 250, 5, 250, 250, 300);
// gradient.addColorStop(0, "#03303a");
// gradient.addColorStop(1, "black");
// ctx.fillStyle = gradient;
ctx.fill#999'';
ctx.fillRect(0, 0, 500, 500);
//用例数
ctx.beginPath();
ctx.stroke#FE47FC''
ctx.arc(60, 100, 50, degToRad(-90), degToRad(-300),true ); //总数
ctx.stroke();
//Minutes
ctx.beginPath();
ctx.stroke#3AF8F8'';
ctx.arc(60, 100, 38, degToRad(-90), degToRad(-220),true );//通过
ctx.stroke();
ctx.beginPath();
ctx.stroke#f00'';
ctx.arc(60, 100, 24, degToRad(-90), degToRad(-180),true ); //未通过
ctx.stroke();
//font
ctx.font = "oblique 12px Helvetica"; //设置字体样式
ctx.fill#3AF8F8''
ctx.fillText(" 通过数", 92, 80);// 多个ctx.fillText可以达到文字换行效果
ctx.fillText("______", 92, 82);
ctx.fillred''
ctx.fillText(" 未通过数", 92, 110);
ctx.fillText("_____", 92, 112);
ctx.fill#FE47FC''
ctx.fillText(" 总用例数", 92, 140);
ctx.fillText("_____", 92, 142);
}
//--------------------------
var oQuadraticCurveTo = document.getElementById("canvas2");
var oContext = oQuadraticCurveTo.getContext("2d");
var x=2;
function drawLine(){
oContext.beginPath();
oContext.moveTo(0,0); //起始点(x,y)
oContext.quadraticCurveTo(100, 0, 200, 200); //创建二次贝塞尔曲线
oContext.lineWidth = 2;
oContext.stroke;
oContext.stroke();
oContext.closePath();
}
function drawPoint(x,y){
oContext.beginPath();
oContext.arc(x, y, 3, 0, 2 * Math.PI, false);
oContext.fill;
oContext.fill();
oContext.stroke();
oContext.closePath();
}
//画移动的线
function drawMivie(){
y=Math.pow(x,2)*0.005;
if(x > 198){
x=0;
}else{
//防止首位相连<br> //清楚之前的图,重新绘制
oContext.clearRect(0, 0, 500, 500);
oContext.closePath();
drawStatic(oContext);
//
x=x+1;
y=Math.pow(x,2)*0.005;
//画圆球
oContext.beginPath();
oContext.stroke;
oContext.arc(x,y,5,0,2*Math.PI,false);
oContext.fill;
oContext.fill();
oContext.stroke();
oContext.closePath();
}
}
//画静态元素,红线和两端
function drawStatic(){
drawLine();
drawPoint(0,0);
drawPoint(200,200);
}
setInterval(function(){
drawMivie(oContext);
},20);
</script>
//原文:https://blog.csdn.net/qq_36436877/article/details/80184749?utm_source=copy
//版权声明:本文为博主原创文章,转载请附上博文链接!
</body>
</html>
canvas 简易扇形图
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
#graph {
/* border: 1px solid black;
height: 100%;
width: 100%;
box-sizing: border-box;*/
}
</style>
</head>
<body>
<div id="circle"></div>
</body>
</html>
<script type="text/javascript">
Math.formatFloat = function(f, digit) {
var m = Math.pow(10, digit);
return parseInt(f * m, 10) / m;
}
var A = 0.1;
var B = 0.2;
console.log("浮点",Math.formatFloat(A + B, 1) === 0.3);
(function(window,undefined){
var data = [
{"product":"产品1","value":25,"color":"green"},
{"product":"产品2","value":5,"color":"red"},
{"product":"产品3","value":60,"color":"yellow"},
{"product":"产品4","value":10,"color":"blue"}
]
// 把角度转换为弧度
function angleToRadian( angle ) {
return Math.PI / 180 * angle;
// var val=Math.PI / 180 * angle;
// var num=num||2;
// var m= Math.pow(10,num)
//
// return parseInt(val * m, 10) / m;
}
// 弧度 换为角度
function RadianToangle( hd,num ) {
var val=180/Math.PI * hd;
var num=num||2;
var m= Math.pow(10,num)
return parseInt(val * m, 10) / m;
}
var dom_circle = document.getElementById(''circle'');
if(dom_circle){
var canvas = document.createElement("canvas");
dom_circle.appendChild(canvas);
var ctx = canvas.getContext(''2d'');
var speed=6;
var defaultStyle = function(Dom,canvas){
if(Dom.clientWidth <= 300)
{
canvas.width = 300;
Dom.style.overflowX = "auto";
}
else{
canvas.width = Dom.clientWidth;
}
if(Dom.clientHeight <= 300)
{
canvas.height = 300;
Dom.style.overflowY = "auto";
}
else
{
canvas.height = Dom.clientHeight;
}
//坐标轴区域
//注意,实际画折线图区域还要比这个略小一点
return {
p1:''green'',
p2:''red'',
p3:''yellow'',
p4:''blue'',
x: 0 , //坐标轴在canvas上的left坐标
y: 0 , //坐标轴在canvas上的top坐标
maxX: canvas.width , //坐标轴在canvas上的right坐标
maxY: canvas.height , //坐标轴在canvas上的bottom坐标
r:(canvas.width)/2, //起点
ry:(canvas.height)/2, //起点
cr: (canvas.width)/4, //半径
startAngle:angleToRadian(-90), //开始角度 起始角,以弧度计。(弧的圆形的三点钟位置是 0 度)。
endAngle:angleToRadian(270), //结束角度
xAngle:angleToRadian(speed) //每次偏移量
};
}
//画圆
var tmpAngle = -(1/2*Math.PI);//90弧度 每个结束角度
var ds = null;
var sum = 0;
for(var s=0;s<data.length;s++){
sum+=data[s].value;
}
console.log("tmpAngle弧度",tmpAngle,angleToRadian(-90))
////每个数据占据的比重弧度
var percent1 = data[0].value/sum * Math.PI * 2 ;//36*1=36
var percent2 = data[1].value/sum * Math.PI * 2 + percent1; //36*2+36=108
var percent3 = data[2].value/sum * Math.PI * 2 + percent2;//36*6+108=324
var percent4 = data[3].value/sum * Math.PI * 2 + percent3;//36*1+324=360
console.log(data[0].value/sum,"1结束角度",RadianToangle(percent1));
console.log(data[1].value/sum,"2结束角度",RadianToangle(percent2));
console.log(data[2].value/sum,"3结束角度",RadianToangle(percent3));
console.log(data[3].value/sum,"4结束角度",RadianToangle(percent4));
var arrs=[];
var sta=null;
for(var i=0;i<data.length;i++){
}
function draw2(x,y,r,startAngle,endAngle,color){
ctx.save();
ctx.beginPath();
ctx.moveTo(x, y);
ctx.arc(x, y, r, startAngle, endAngle,false);
ctx.fillStyle = color;
ctx.fill();
ctx.closePath();
ctx.restore();
}
var tmpSum = 0;
var drawCircle = function(){
if(tmpAngle >= ds.endAngle){
console.log("绘制完成1",ds.xAngle);
return false;
}else if(tmpAngle+ ds.xAngle > ds.endAngle){
console.log("绘制完成2");
tmpAngle = ds.endAngle;
}else{
// if(RadianToangle(ds.xAngle)>speed*0.25){
// ds.xAngle=ds.xAngle*0.21;
// }
tmpAngle += (ds.xAngle);// 每个结束
tmpSum += (ds.xAngle); //每个开始 弧度
//console.log("之前",tmpSum,RadianToangle(tmpSum))
tmpAngle=RadianToangle(angleToRadian(tmpAngle),2);//弧度转角度 角度转弧度
tmpSum=RadianToangle(angleToRadian(tmpSum),2);//弧度转角度 角度转弧度
console.log("之后",RadianToangle(tmpSum))
// tmpAngle=float_calculator.add(tmpAngle+ds.xAngle)
//tmpSum=float_calculator.add(tmpSum+ds.xAngle)
}
// console.log(tmpSum,ds.startAngle+''***''+tmpAngle);
// console.log(tmpSum);
// ctx.clearRect(ds.x,ds.y,canvas.width,canvas.height);
//if(RadianToangle(tmpSum) > RadianToangle(percent1) && RadianToangle(tmpSum) <=RadianToangle(percent2))
if(tmpSum > percent1 && tmpSum<=percent2)
{
var srartAngel= ds.startAngle+percent1;
console.log("最小2red",RadianToangle(percent1),"第一个运动感角度",RadianToangle(tmpSum),"最大",RadianToangle(percent2));
draw2(ds.r,ds.ry,ds.cr,srartAngel,tmpAngle,ds.p2)
}
else if(tmpSum > percent2 &&tmpSum <=percent3)
{
//console.log("最小3yellow",RadianToangle(percent1),"第一个运动感角度",RadianToangle(tmpSum),"最大",RadianToangle(percent2));
draw2(ds.r,ds.ry,ds.cr,ds.startAngle+percent2,tmpAngle,ds.p3)
}
else if(tmpSum > percent3 )
{
draw2(ds.r,ds.ry,ds.cr,ds.startAngle+percent3,tmpAngle,ds.p4)
}
else{
draw2(ds.r,ds.ry,ds.cr,ds.startAngle,tmpAngle,ds.p1)
}
requestAnimationFrame(drawCircle);
}
this.toDraw = function(){
ds= defaultStyle(dom_circle,canvas);
// console.log(tmpAngle);
// console.log(ds.xAngle)
ctx.clearRect(ds.x,ds.y,canvas.width,canvas.height);
drawCircle();
}
this.toDraw();
var self = this;
window.onresize = function(){
//self.toDraw()
}
}
})(window);
</script>
上面的存在bug,扇形2 可以
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
canvas{
border: 1px solid #A4E2F9;
}
</style>
</head>
<body>
https://github.com/sutianbinde/charts
https://www.cnblogs.com/chengduxiaoc/p/7649048.html
https://www.cnblogs.com/chengduxiaoc/p/7705727.html
<div height="400" width="600">
<canvas id="chart"> 你的浏览器不支持HTML5 canvas </canvas>
</div>
<script type="text/javascript">
function goChart(dataArr){
// 把角度转换为弧度
function angleToRadian( angle ) {
return Math.PI / 180 * angle;
// var val=Math.PI / 180 * angle;
// var num=num||2;
// var m= Math.pow(10,num)
//
// return parseInt(val * m, 10) / m;
}
// 弧度 换为角度
function RadianToangle( hd,num ) {
var val=180/Math.PI * hd;
var num=num||2;
var m= Math.pow(10,num)
return parseInt(val * m, 10) / m;
}
var animated=true;
// 声明所需变量
var canvas,ctx;
// 图表属性
var cWidth, cHeight, cMargin, cSpace;
// 饼状图属性
var radius,ox,oy;//半径 圆心
var tWidth, tHeight;//图例宽高
var posX, posY, textX, textY;
var startAngle, endAngle;
var totleNb;
// 运动相关变量
var ctr, numctr, speed;
//鼠标移动
var mousePosition = {};
//线条和文字
var lineStartAngle,line,textPadding,textMoveDis;
// 获得canvas上下文
canvas = document.getElementById("chart");
if(canvas && canvas.getContext){
ctx = canvas.getContext("2d");
}
initChart();
// 图表初始化
function initChart(){
// 图表信息
cMargin = 20;
cSpace = 40;
canvas.width = canvas.parentNode.getAttribute("width")* 2 ;
canvas.height = canvas.parentNode.getAttribute("height")* 2;
canvas.style.height = canvas.height/2 + "px";
canvas.style.width = canvas.width/2 + "px";
cHeight = canvas.height - cMargin*2;
cWidth = canvas.width - cMargin*2;
//饼状图信息
radius = cHeight*2/6; //半径 高度的2/6
ox = canvas.width/2 + cSpace; //圆心
oy = canvas.height/2;
tWidth = 60; //图例宽和高
tHeight = 20;
posX = cMargin;
posY = cMargin; //
textX = posX + tWidth + 15
textY = posY + 18;
startAngle = endAngle = -90*Math.PI/180; //起始弧度 结束弧度
//将传入的数据转化百分比
totleNb = 0;
new_data_arr = [];
for (var i = 0; i < dataArr.length; i++){
totleNb += dataArr[i][0];
}
console.log("总数值totleNb",totleNb);
for (var i = 0; i < dataArr.length; i++){
new_data_arr.push( dataArr[i][0]/totleNb );
}
// 运动相关
ctr = 3;//初始步骤
numctr = 50;//步骤
speed = 1.2; //毫秒 timer速度
//指示线 和 文字
lineStartAngle = -startAngle;
line=40; //画线的时候超出半径的一段线长
textPadding=10; //文字与线之间的间距
textMoveDis = 200; //文字运动开始的间距
}
console.log("每个 百分比 new_data_arr",new_data_arr);
//绘制动画
pieDraw();
function pieDraw(mouseMove){
//设置旋转
ctx.save();
// ctx.translate(ox, oy);
// ctx.rotate((Math.PI*2/numctr)*ctr/2);
var percent=ctr/numctr;//运动的百分比
for (var j = 0; j < dataArr.length; j++){
//绘制饼图
//endAngle = endAngle + (new_data_arr[j]*percent)* Math.PI * 2; //结束弧度
if(animated){
endAngle = endAngle + (new_data_arr[j]*percent)* Math.PI * 2; //结束弧度
}else{
endAngle = endAngle + new_data_arr[j]* Math.PI * 2; //结束弧度
}
ctx.beginPath();
// ctx.moveTo(0,0); //移动到到圆心
// ctx.arc(0, 0, radius*ctr/numctr, startAngle, endAngle, false); //绘制圆弧
ctx.moveTo(ox, oy); //移动到到圆心
ctx.arc(ox, oy, radius, startAngle, endAngle, false); //绘制圆弧
ctx.fillStyle = dataArr[j][1];
ctx.fill();
ctx.closePath();
startAngle = endAngle; //设置起始弧度
if( j == dataArr.length-1 ){
startAngle = endAngle =270*Math.PI/180; //起始弧度 结束弧度
}
}
ctx.restore();
//console.log("ctr",ctr,"numctr",numctr,(ctr/numctr).toFixed(2));
if(ctr<numctr){
ctr++;
setTimeout(function(){
//ctx.clearRect(-canvas.width,-canvas.width,canvas.width*2, canvas.height*2);
//ctx.clearRect(-canvas.width, -canvas.height,canvas.width*2, canvas.height*2);
pieDraw();
}, speed*=1.02);
}
}
}
var chartData = [[25,"#2dc6c8","瓜子"], [12.5,"#b6a2dd", "花生"], [12.5,"#5ab1ee","土豆"], [50,"#d7797f","南瓜四号"]];
goChart(chartData);
</script>
</body>
</html>
canvas 火花漂移
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<style>
:root {
--blur: 2;
}
* {
box-sizing: border-box;
}
html,
body {
font-family: ''Arial'', sans-serif;
background: #111;
}
canvas {
position: fixed;
height: 100vh;
width: 100vw;
-webkit-filter: blur(calc(var(--blur) * 1px));
filter: blur(calc(var(--blur) * 1px));
}
input {
cursor: pointer;
display: block;
}
label {
margin-bottom: 30px;
}
label:last-of-type {
margin-bottom: 0;
}
.menu {
position: absolute;
top: 0;
left: 0;
color: #fafafa;
background: rgba(0,0,0,0.15);
display: flex;
flex-direction: column;
padding: 30px;
-webkit-transform: translate(-100%, 0);
transform: translate(-100%, 0);
transition: -webkit-transform 0.25s ease-out;
transition: transform 0.25s ease-out;
transition: transform 0.25s ease-out, -webkit-transform 0.25s ease-out;
}
.menu--open {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
.icon {
height: 60%;
width: 60%;
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
button {
height: 44px;
width: 44px;
background: 0;
cursor: pointer;
border: 0;
background: rgba(0,0,0,0.15);
padding: 0;
margin: 0;
position: absolute;
left: 100%;
top: 0;
}
button span {
width: 100%;
height: 20%;
border-radius: 4px;
background: #fff;
display: block;
position: absolute;
top: 0;
transition: -webkit-transform 0.25s ease-out;
transition: transform 0.25s ease-out;
transition: transform 0.25s ease-out, -webkit-transform 0.25s ease-out;
}
button span:nth-child(1) {
-webkit-transform-origin: top left;
transform-origin: top left;
}
button span:nth-child(2) {
top: 40%;
}
button span:nth-child(3) {
-webkit-transform-origin: top left;
transform-origin: top left;
top: 80%;
}
.menu--open span:nth-child(1) {
-webkit-transform: translate(5px, 3px) rotate(45deg);
transform: translate(5px, 3px) rotate(45deg);
}
.menu--open span:nth-child(2) {
-webkit-transform: scaleX(0);
transform: scaleX(0);
}
.menu--open span:nth-child(3) {
-webkit-transform: translate(2px, 0) rotate(-45deg);
transform: translate(2px, 0) rotate(-45deg);
}
</style>
<canvas></canvas>
<div class="menu">
<button>
<div class="icon"><span></span><span></span><span></span></div>
</button>
<label>Amount
<input type="range" min="1" max="500" step="1" value="100" id="AMOUNT"/>
</label>
<label>Upper Velocity Bounds
<input type="range" min="1" max="50" step="1" value="20" id="UPPER_LIMIT"/>
</label>
<label>Lower Velocity Bounds
<input type="range" min="1" max="50" step="1" value="1" id="LOWER_LIMIT"/>
</label>
<label>Blur
<input type="range" min="0" max="10" step="1" value="2" id="BLUR"/>
</label>
</div>
<script>
var canvas = document.querySelector(''canvas'');
var context = canvas.getContext(''2d'');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
requestAnimationFrame = requestAnimationFrame || webkitRequestAnimationFrame;
var menu = document.querySelector(''.menu'');
var modify = function modify(e) {
OPTIONS[e.target.id] = parseInt(e.target.value, 10);
if (e.target.id === ''AMOUNT'') {
context.clearRect(0, 0, canvas.width, canvas.height);
particles = genParticles();
}
if (e.target.id === ''BLUR'') {
document.documentElement.style.setProperty(''--blur'', parseInt(e.target.value, 10));
}
};
menu.addEventListener(''change'', modify);
var button = document.querySelector(''button'');
var handleClick = function handleClick(e) {
return menu.classList.toggle(''menu--open'');
};
button.addEventListener(''click'', handleClick);
var OPTIONS = {
AMOUNT: 100,
UPPER_LIMIT: 20,
LOWER_LIMIT: 1
};
var UPPER_SIZE = 10;
var LOWER_SIZE = 4;
var doIt = function doIt() {
return Math.random() > 0.5;
};
var update = function update(p) {
return doIt() ? Math.max(OPTIONS.LOWER_LIMIT, p - 1) : Math.min(p + 1, OPTIONS.UPPER_LIMIT);
};
var reset = function reset(p) {
p.x = p.startX;
p.y = p.startY;
};
var floored = function floored(r) {
return Math.floor(Math.random() * r);
};
var genParticles = function genParticles() {
return new Array(OPTIONS.AMOUNT).fill().map(function (p) {
var size = floored(UPPER_SIZE) + LOWER_SIZE;
var c = document.createElement(''canvas'');
var ctx = c.getContext(''2d'');
var r = Math.PI / 180 * floored(360);
var color = ''rgba(255,'' + (100 + Math.floor(Math.random() * 70)) + '', 0, '' + Math.random() + '')'';
var xDelayed = doIt();
var startX = xDelayed ? -(size + floored(canvas.width)) : floored(canvas.width * 0.25);
var startY = xDelayed ? size + floored(canvas.height * 0.25) + Math.floor(canvas.height * 0.75) : canvas.height + size + floored(canvas.height);
c.height = size;
c.width = size;
context.globalCompositeOperation = ''multiply'';
// ctx.filter = `blur(${Math.random() * size}px)`
ctx.translate(size / 2, size / 2);
ctx.rotate(r);
ctx.translate(-(size / 2), -(size / 2));
ctx.fillStyle = color;
ctx.fillRect(0, 0, size, size);
return {
x: startX,
y: startY,
startY: startY,
startX: startX,
c: c,
r: r,
vx: floored(OPTIONS.UPPER_LIMIT / 4),
vy: floored(OPTIONS.UPPER_LIMIT / 4),
size: size
};
});
};
var particles = genParticles();
var FRAME_COUNT = 0;
var draw = function draw() {
if (canvas.width !== window.innerWidth || canvas.height !== window.innerHeight) {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
particles = genParticles();
}
// context.restore()
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = particles[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var particle = _step.value;
context.clearRect(particle.x, particle.y, particle.size, particle.size);
FRAME_COUNT++;
if (particle.y < canvas.height || particle.startX < 0) particle.x += particle.vx;
if (particle.x > 0 || particle.startY > canvas.height) particle.y -= particle.vy;
if (FRAME_COUNT % 11 === 0 && doIt()) particle.vx = update(particle.vx);
if (FRAME_COUNT % 13 === 0 && doIt()) particle.vy = update(particle.vy);
context.drawImage(particle.c, particle.x, particle.y);
if (particle.x > canvas.width || particle.y < -particle.size) reset(particle);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
requestAnimationFrame(draw);
};
requestAnimationFrame(draw);
</script>
</body>
</html>
参考
https://github.com/sutianbinde/charts
https://www.cnblogs.com/chengduxiaoc/p/7705727.html
CSS部分1课件学习笔记整理
CSS:层叠样式表
用于设置HTML页面中的文本内容(字体,大小,对方式等),图片外形(宽高,边框样式,边距等)以及版面的布局等外观显示样式。
一:基础部分
1.css书写位置
(1)内嵌式:直接嵌在HTML文件中
(2)外链式:css文件<link>引入
(3)导入式:eg:<style>@import url();</style>
(4)行内式:只能给一个标签设置样式
2.基本语法
(1)选择器
a:标签选择器(元素,类型)
eg:span{} p{} b{} h系列{}
属性:
list-style:none 去掉无序列表的小圆点
text-decoration:none 去掉超级链接下划线
b:
b1:id选择器 以“#”来定义
HTML中唯一标识一个元素的名称,每个元素只能有一个id属性,id属性值唯一。由数字、字母、下划线组成,首字母不能是数字,严格区分大小写。
b2:类选择器 用来选择class属性,以“.”定义
定义一组具有相同特征的元素,一个元素可以有多个class属性,并且多个元素可以共享同一个class属性。
c:复合选择器
c1:后代选择器(后代,后辈)
eg:.box .spec 选择类名为box的标签内部的类名为spec的标签
c2:交集选择器
eg:li.spec 选择既是li标签也属于spec类的标签
c3:并集选择器
eg:ul,ol 选择所有ul和ol标签
d:伪类
超级链接a
a:link 没有被访问
a:visited 已经被访问
a:hover:正在被鼠标悬停
a:active:正在别激活的超级链接(按下键但是还没有松开)
为确保生效,按顺序依次声明::link->:visited->:hover->:active
e:元素关系选择器
e1:子选择器(只能是子,不能是孙子,兄弟等) 例:div>p div的子标签
e2:相邻兄弟选择器 例:img+p 图片后面紧跟着的段落将被选中
e3:通用兄弟选择器 例:p~span p元素之后的所有同层级span元素
f:属性选择器
img[alt] 选择有alt属性的img标签
img[alt+"A"] 选择有alt属性的是A的img标签
img[alt^"A"] 选择有alt属性的以A开头的img标签
img[alt$"A"] 选择有alt属性的以A结尾的img标签
img[alt*="A"] 选择有alt属性的含有A的img标签
img[alt~="A"] 选择有alt属性的有格隔开的A字样的img标签
img[alt|="A"] 选择有alt属性的以A-开头的img标签
g:CSS3新增伪类
:empty 选空标签
:focus 选当前获得焦点的表单元素
:enabled 选当前有效的表单元素
:disabled 选当前无效的表单元素
:checked 选当前已经勾选的单选按钮或复选框
:root 根元素,即<html>标签
h:伪元素(::)
h1 ::before 创建一个伪元素,其将成为匹配选中的元素得到第一个子元素,必须设置content属性表示其中的内容。
例如a::before{content:"★";}
h2 ::after 最后一个元素
h3 ::selection 用于文档中被用户高亮的部分(使用鼠标圈选的部分)
h4 ::first-letter 会选中某元素(必须是块级元素)第一行的第一个字母
h5 ::first-line 选中第一行的全部文字
i:层叠性(多个选择器可以同时作用于同一个标签,效果叠加)
id权重>class权重>表标签选择器权重
!important 可以提升权重
!important>id权重>class权重>表标签选择器权重
k:序号选择器
k1 :first-child 第一个子元素
k2 :last-child 最后一个子元素
k3 :nth-child() 任意位置、任意序号元素;(odd)奇,(even)偶
k4 :nth-of-type(3) 第三个某一类型子元素
k5 :nth-laat-child(3) 倒数第三个子元素
k6 :nth-last-of-type(3) 倒数第三个某一类型子元素
二:文本与字体属性
1.常用
(1)color:文本前景色,临时设置颜色
有16进制表示法,rgb( , , )表示法,rgba( , , , )表示法
(2)font-size 单位:px,em,rem
(3)font-weight 加粗
属性:normal/400;bold/700;
(4)font-style
属性:normal 取消倾斜; italic 倾斜; oblique
(5)text-decoration
属性:none 无修饰线;underline 下划线;line-through 删除线
2.段落和行
(1)text-indent 首行缩进 单位:em
(2)line-height 行高 单位:px/无单位(即表示字号的倍数)/百分数
(3)单行文本居中:行高=盒子高度 text-align:center 水平居中
(4)font合成属性 font-style,font-weight,font-size,font-family\
eg:font:italic bold 20px/1.5 Ariral,"微软雅黑"
3.继承性:给祖先先设,后代中生效
就近原则:样式指向同一元素,权重规则生效,权重大的被应用;权重相同时,就近原则生效,后面定义的被应用。样式不指向同一元素,权重失效,就近原则生效,离最近优先。
4.字体属性
font-family;设置字体: 英,“汉”
(1)添加值为sans-serif的font-family属性来更改body中的所有文本
(2)hr元素默认属性将使其显示为浅灰色曲线
(3)边缘borders
(4)font-varian:small-caps 显示成大写;normal:正常
三:盒模型
1.认识盒模型
所有HTML标签都可以看成矩形盒子,由width,height,padding,border构成。
盒子总宽度=width+左右padding+上下border
(1)width:宽度 单位:px/rem/百分数
块级元素如果没有设置width属性时,它将自动撑满
(2)hieght内容高度 单位:px/rem/百分数
(3)padding:内边距
属性:top right bottom left
灵活设置padding(用小属性层叠大属性)
a1:四数值写法 padding:上 右 下 左
a2:三数值写法 padding:上 左右 下
a3:二数值写法 padding:上下 左右
a1:一数值写法 padding:上下左右
(4)margin外边距
a1:top right bottom left
a2:margin垂直方向上有塌陷:小的margin会塌陷到大的margin中,从而margin不叠加,以大值为准。
a3:body,ul,p等都有默认的margin,清除如下:
*{
margin:0;
padding:0;
}
或者使用并集选择器也可以
a4:盒子的水平居中:左右设置为auto
2.盒模型计算
(1)内容宽度(实际可用的):width和height
(2)box-sizing属性
将盒子添加了box-sizing:border-box;之后,盒子的width,height数字就表示盒子实际占有的宽高了,即padding,border变为“内缩的”,不再“外扩”
(3)display属性
块级元素不并排显示,可以设置宽高,不设置width属性时自动撑满;
行内元素可以并排显示,不可以设置宽高,不设置width属性时自动收缩
(4)行内块
img和表单元素,可以并排显示,可以设置宽高
(5)行内元素和块级元素相互转换
display:block;将元素转为块级元素
display:inline;将元素转为行内元素
display:inline-block;将元素转为行内块
3.元素隐藏
display:none;元素将彻底放弃位置,如同没有写它的标签一样
visibility:hidden;元素不放弃自己的位置
关于free code camp部分笔记整理和.free code camp的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于16 道 JavaScript 基础算法 - freeCodeCamp、Beam Search、GREEDY DECODER、SAMPLING DECODER等解码器工作原理可视化、canvas 笔记整理、CSS部分1课件学习笔记整理等相关知识的信息别忘了在本站进行查找喔。
本文标签: