Maison >interface Web >Tutoriel H5 >API Canvas, bases populaires du Canvas (6)

API Canvas, bases populaires du Canvas (6)

黄舟
黄舟original
2017-02-25 11:55:281871parcourir

Cet article est le début et la fin de la série d'API canvas.Après cet article, toutes les propriétés et méthodes du canevas seront terminées. Oh, non, elles devraient être les plus couramment utilisées, et il existe également des propriétés et méthodes inhabituelles. Pour diverses raisons, je ne les présenterai pas. L'objectif dans la période ultérieure est d'écrire des exemples plus pratiques de toile. Eh bien, je pense que c'est le plus pratique. Comme le dit le proverbe, un exemple vaut mille mots. plus tard, jetons un coup d'oeil. Voici les propriétés et méthodes restantes !
1. createPattern
createPattern(image,"repeat|repeat-x|repeat-y|no-repeat") Répète l'élément spécifié dans la direction spécifiée
Paramètres : l'image fait référence à une image pratique, un canevas Ou la façon dont le deuxième paramètre de l'objet vidéo représente la répétition
En regardant les paramètres suivants, il est facile de penser à la répétition d'arrière-plan en CSS. Je dois dire quelque chose à propos du premier paramètre. C'est différent de l'arrière-plan, il. n'est pas une image référencée, mais un objet image. Examinons ici les performances de ces méthodes répétées :

var aImg = new Image();
aImg.src = '4.jpg';
aImg.onload = function(){
    draw(this);
}
function draw(obj){
    //这里为了演示方便,把其他的先注释
    //var bg = ctx.createPattern(obj,"repeat");
    //var bg = ctx.createPattern(obj,"repeat-x");
    //var bg = ctx.createPattern(obj,"repeat-y");
    var bg = ctx.createPattern(obj,"no-repeat");
    ctx.fillStyle = bg;
    ctx.fillRect(0,0,400,400);
}


API Canvas, bases populaires du Canvas (6)

API Canvas, bases populaires du Canvas (6)

API Canvas, bases populaires du Canvas (6)

API Canvas, bases populaires du Canvas (6)
Eh bien, l'effet est le même que la répétition en arrière-plan du CSS, il est donc facile de je comprends, mais le canevas n'a pas de position d'arrière-plan Oui, eh bien, cet effet est comme ça, il n'y a rien à dire !
Voir ici pour les effets spécifiques - répétition de l'arrière-plan du canevas

2. gloableCompositeOperation
gloableCompositeOperation() Définit ou renvoie comment dessiner une nouvelle image sur une image existante

Paramètres :

source-over Par défaut, l'image source est affichée sur l'image cible.

source-atop Affiche l'image source au-dessus de l'image cible. Les parties de l'image source qui se trouvent en dehors de l'image cible sont invisibles.

source-in Affiche l'image source dans l'image cible. Seule la partie de l'image source dans l'image de destination est affichée ;

source-out Affiche l'image source en plus de l'image cible. Seule la partie de l'image source autre que l'image cible sera affichée et l'image cible sera transparente.

destination-over Affiche l'image de destination au-dessus de l'image source.

destination-atop Affiche l'image de destination au-dessus de l'image source. Les parties de l'image cible en dehors de l'image source ne seront pas affichées.

destination-in Affiche l'image de destination dans l'image source. Seule la partie de l'image cible dans l'image source sera affichée ; l'image source est transparente.

destination-out Affiche l'image de destination en dehors de l'image source. Seule la partie de l'image cible en dehors de l'image source est affichée ; l'image source est transparente.

plus clair Afficher l'image source et l'image cible, c'est-à-dire que les parties qui se croisent du graphique sont remplies successivement pour augmenter la luminosité

copie Afficher l'image source. Ignorer l'image cible, c'est-à-dire afficher uniquement l'image source

xor Utilisez l'opération XOR pour combiner l'image source et l'image cible, c'est-à-dire que la partie d'intersection est transparente

Peu couramment utilisé :

multiplier Multiplier les pixels de l'image source par les pixels de l'image cible

écran

superposition

assombrir Approfondir, les parties qui se croisent du graphique sont remplis successivement pour réduire la luminosité

éclaircir Ajouter brillant, les parties qui se croisent des graphiques sont remplies successivement pour augmenter la luminosité

color-dodge Ajustez le calque inférieur au calque supérieur, c'est-à-dire , ajustez l'image cible au-dessus de l'image source

color-burn Ajustez le calque inférieur sur le calque supérieur, puis inversez Tournez

lumière dure et ajustez le calque inférieur sur le calque supérieur, puis multipliez l'effet avec l'écran

lumière douce

différence

exclusion

teinte

saturation

couleur

luminosité

En raison d'un anglais médiocre, la signification de certains paramètres couramment utilisés n'est pas facile à expliquer, afin de ne pas induire tout le monde en erreur, je ne le traduirai pas si quelqu'un l'a fait. meilleur anglais, jetez un œil à l'explication des paramètres gloableCompositeOperation ici. Si vous pouvez le traduire plus clairement, j'espère que vous pourrez me dire le sens de la traduction. Merci beaucoup. L'anglais est un défaut ! Cependant, je vous donnerai les résultats d'exécution ultérieurs pour votre référence !

Il existe de nombreux paramètres. Jetons d'abord un coup d'œil à ceux couramment utilisés. Les huit premiers sont faciles à comprendre et sont tout le contraire. Tout d'abord, nous devons comprendre quel est le graphique cible ? Qu'est-ce qu'un graphique source ?
Image de destination = le dessin que vous avez placé sur la toile ; image source = le dessin que vous comptez placer sur la toile. C'est l'explication officielle. Si vous ne comprenez pas cette explication, nous pouvons la comprendre de cette façon, c'est-à-dire que l'image dessinée en premier est le graphique cible, et l'image dessinée plus tard est l'image source, par exemple :


//目标图像
ctx.fillStyle="red";
ctx.fillRect(20,20,75,50);
ctx.globalCompositeOperation="source-over";
//源图像
ctx.fillStyle="blue";
ctx.fillRect(50,50,75,50);


API Canvas, bases populaires du Canvas (6)
Bien entendu, la position de cette gloableCompositeOperation n'est pas fixe. Elle peut être placée devant l'image cible ou derrière la cible. image, mais elle ne peut pas être placée derrière l'image source (vous savez), si la signification des paramètres n'est pas facile à comprendre, regardez l'image ci-dessous pour voir à quoi elle ressemble :


var arr = ['source-over','source-atop','source-in','source-out','destination-over','destination-atop','destination-in','destination-out','lighter','copy','xor','multiply','screen','overlay','darken','lighten','color-dodge','color-burn','hard-light','soft-light','difference','exclusion','hue','saturation','color','luminosity'];
        for(var i=0;i<arr.length;i++){
            document.write("<p id=&#39;p_" + i + "&#39; style=&#39;float:left;&#39;>" + arr[i] + ":<br>");
            var canvas = document.createElement("canvas");
            canvas.width = 120;
            canvas.height = 100;
            canvas.style.border = "1px solid #000";
            canvas.style.marginRight = &#39;10px&#39;;
            document.getElementById("p_" + i).appendChild(canvas);
            var ctx = canvas.getContext("2d");
            ctx.fillStyle="red";
            ctx.fillRect(10,10,50,50);
            ctx.globalCompositeOperation=arr[i];
            ctx.beginPath();
            ctx.fillStyle="green";
            ctx.fillRect(30,30,50,50);
            ctx.fill();
            document.write("</p>");
                
        }

红与绿
API Canvas, bases populaires du Canvas (6)

红与蓝

API Canvas, bases populaires du Canvas (6)

具体效果你也可以看这里 —— canvas图形组合模式

里面的代码我故意把canvas的代码留在上面,方便你们查看,不知道你看到这些参数有什么感想,我的第一感觉就是有些熟悉比clip好用,也让我第一时间想到了这一个效果:

ctx.fillStyle="red";
ctx.arc(150,150,100,0,360*Math.PI/180,false);
ctx.fill();
ctx.globalCompositeOperation="xor";
ctx.beginPath();
ctx.arc(150,150,80,0,360*Math.PI/180,false);
ctx.fill();



API Canvas, bases populaires du Canvas (6)

如果配合前面的扇形方法,很容易做一个圆形进度条什么的,当然,还有很多属性可以有大的作用,比如说裁切一个图形,发挥的发达的大脑吧,这里我就不演示了

3、setLineDash

setLineDash(arr)  在画布上画一条虚线

参数:arr 表示的是一个数组集合,里面的参数可以有多个,这里面的参数很有意思,举个栗子说明:

ctx.beginPath();
ctx.moveTo(0,100);
ctx.lineTo(400, 100);
ctx.setLineDash([10,20]);
ctx.stroke();


API Canvas, bases populaires du Canvas (6)

API Canvas, bases populaires du Canvas (6)

对比代码看图,如果有2个参数,则第一个参数表示虚线的线宽,第二个参数表示虚线的线与线的距离,后面一直循环

如果是3个参数呢?

ctx.beginPath();
ctx.moveTo(0,100);
ctx.lineTo(400, 100);
ctx.setLineDash([10,20,30]);
ctx.stroke();


API Canvas, bases populaires du Canvas (6)

API Canvas, bases populaires du Canvas (6)

此时会这样,第一条线长为10,然后间距为20,第2条线长为30,然后间距为10,第3条线长20,然后间距为30,到处为一个循环,后面重复

那么4个参数就好理解了,

ctx.beginPath();
ctx.moveTo(0,100);
ctx.lineTo(400, 100);
ctx.setLineDash([10,20,30,40]);
ctx.stroke();

API Canvas, bases populaires du Canvas (6)

规律和上面的一样,只是循环的长度要长一些,更多参数的规则也是这样的,那么一个参数是否有效呢

ctx.beginPath();
ctx.moveTo(0,100);
ctx.lineTo(400, 100);
ctx.setLineDash([10]);
ctx.stroke();


API Canvas, bases populaires du Canvas (6)

显然是有效的,此时线宽为10,间距为10,这就是华丽的分割线的做法

它还有一个兄弟用法,这个是设置虚线,那么就会有一个获取虚线

getLineDash()  获取当前虚线的样式

它没有参数,它得到的结果就是设置虚线的线宽数组arr,我们看一下怎么用:

ctx.beginPath();
ctx.moveTo(0,100);
ctx.lineTo(400, 100);
ctx.setLineDash([10]);
var txt = ctx.getLineDash();
ctx.stroke();
ctx.fillStyle = &#39;red&#39;;
ctx.font = "30px Arial";
ctx.fillText(txt,180,140);


API Canvas, bases populaires du Canvas (6)

ctx.beginPath();
ctx.moveTo(0,100);
ctx.lineTo(400, 100);
ctx.setLineDash([10,20]);
var txt = ctx.getLineDash();
ctx.stroke();
ctx.fillStyle = &#39;red&#39;;
ctx.font = "30px Arial";
ctx.fillText(txt,180,140);


API Canvas, bases populaires du Canvas (6)

从这两组图可以看出,当只有一个参数数,会默认为2个一样的参数

4、isPointInPath
isPointInPath(x,y)  指定点是否在路径区域中,如果在则返回true,不在则返回false
参数: x,y表示指定的坐标点

举个栗子:

var canvas = document.getElementById("canvas");
        var ctx = canvas.getContext("2d");
        
        ctx.beginPath();
        ctx.fillStyle = &#39;red&#39;;
        ctx.rect(50,50,100,100);
        ctx.fill();

        canvas.onclick = function(ev){
            var ev = ev || event;    
            ctx.clearRect(200,0,200,200);
            var l = ev.clientX - canvas.offsetLeft; 
            var t = ev.clientY - canvas.offsetTop;
            if(ctx.isPointInPath(l,t)){
                ctx.font = "40px Arial";
                ctx.fillText((l+&#39;,&#39;+t),200,120);
            }
        }


API Canvas, bases populaires du Canvas (6)

看看这个gif图,当点击红色区域时,我将坐标打印出来,如果点击的地方不在红色区域,则不显示坐标,具体效果看这里 —— canvas判断是否在路径区域

这里有一点需要注意,就是在绘制矩形时,不能用fillRect或strokeRect,为什么呢?因为这里判断是是否在指定的路径中,而fillRect或strokeRect此时已经不是路径了,而是变成了填充过的图形,所以这里必须先用Rect()定义一下路径,再填充,这样才能回去到指定图形的路径,此点须知!

还有一个方法:

isPointInStroke(x,y)  指定点是否在路径中,如果在则返回true,不在则返回false

此方法跟上面的方法很相似,不同点在于,isPointInPath是在一个区域中,不管是用fill还是stroke,但是isPointInStroke只能用stroke填充,且指定的区域是在线框上,看下面的例子:

var canvas = document.getElementById("canvas");
        var ctx = canvas.getContext("2d");
        
        ctx.beginPath();
        ctx.strokeStyle = &#39;red&#39;;
        ctx.lineWidth = 5;
        ctx.rect(50,50,100,100);
        ctx.stroke();
        canvas.onclick = function(ev){
            var ev = ev || event;    
            ctx.clearRect(200,0,200,200);
            var l = ev.clientX - canvas.offsetLeft; 
            var t = ev.clientY - canvas.offsetTop;
            if(ctx.isPointInStroke(l,t)){
                ctx.font = "40px Arial";
                ctx.fillText((l+&#39;,&#39;+t),200,120);
            }
        }


API Canvas, bases populaires du Canvas (6)

从这个gif中可以看出端倪来,只有点到线框才会触发,具体效果看这里 —— canvas 判断是否在线框中

这2个方法的基本用法就是这样,但是会有一个问题,就是目前只有一个图形在上面,如果有2个图形在上面,而且分别的方法不一样,比如说,一个是区域路径,一个是线框路径,分别点击他们,弹出不同的值,我们看行不行:

var canvas = document.getElementById("canvas");
        var ctx = canvas.getContext("2d");
        
        ctx.beginPath();
        ctx.strokeStyle = &#39;red&#39;;
        ctx.lineWidth = 5;
        ctx.rect(50,50,100,100);
        ctx.stroke();
        ctx.closePath();
        ctx.beginPath();
        ctx.fillStyle = &#39;green&#39;;
        ctx.rect(200,50,100,100);
        ctx.fill();
        ctx.closePath();
        
        canvas.onclick = function(ev){
            var ev = ev || event;    
            var l = ev.clientX - canvas.offsetLeft; 
            var t = ev.clientY - canvas.offsetTop;
            if(ctx.isPointInStroke(l,t)){
                console.log(&#39;线框路径&#39;);
            }
        }
        canvas.onclick = function(ev){
            var ev = ev || event;    
            var l = ev.clientX - canvas.offsetLeft; 
            var t = ev.clientY - canvas.offsetTop;
            if(ctx.isPointInPath(l,t)){
                console.log(&#39;区域路径&#39;);
            }
        }


API Canvas, bases populaires du Canvas (6)

看看console里面的提示,当点击区域路径的时候,触发了操作,但是点击线框路径时,无论我怎么点击,都无济于事,这是为什么呢?把2图形的执行顺序颠倒一下,发现效果也相反了,说明谁最后绘制就执行谁,其实这也是可以理解的,因为此时的ctx指的是当前的路径,它不能分当前路径一,路径二什么的,如果要实现多个图形执行不同的事件,又改如何做呢?由于实现方法有点复杂,就在这里留一个思考题?你们先思考一下,该怎么弄?我会到后期单独写一篇文章,专门来说这个的解决方案,供大家参考!

恩,到处所有该讲的canvas API就全部讲完了,看了这一系列的文章,不知道你是否对canvas有了那么一点点的感觉,是否canvas已经不那么神秘了,如果你嘴上不说,心里觉得,恩,好像有点感觉了,那我的目的就达到了,要是你还能写一些效果,那恭喜你,距离大神你有近了一步,如果有时间,有能力,我希望能多写一下有点深度的canvas实例给大家参考,但愿能对大家有帮助!

 以上就是canvas API ,通俗的canvas基础知识(六) 的内容,更多相关内容请关注PHP中文网(www.php.cn)!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn